1 11 package org.eclipse.swt.tools.internal; 12 13 import java.lang.reflect.*; 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 17 public class NativesGenerator extends JNIGenerator { 18 19 boolean enterExitMacro; 20 21 public NativesGenerator() { 22 enterExitMacro = true; 23 } 24 25 public void generateCopyright() { 26 generateMetaData("swt_copyright"); 27 } 28 29 public void generateIncludes() { 30 String outputName = getOutputName(); 31 outputln("#include \"swt.h\""); 32 output("#include \""); 33 output(outputName); 34 outputln("_structs.h\""); 35 output("#include \""); 36 output(outputName); 37 outputln("_stats.h\""); 38 outputln(); 39 } 40 41 public void generate(Class clazz, String methodName) { 42 Method[] methods = clazz.getDeclaredMethods(); 43 int count = 0; 44 for (int i = 0; i < methods.length; i++) { 45 if (methods[i].getName().startsWith(methodName)) count++; 46 } 47 Method[] result = new Method[count]; 48 count = 0; 49 for (int i = 0; i < methods.length; i++) { 50 if (methods[i].getName().startsWith(methodName)) result[count++] = methods[i]; 51 } 52 generate(result); 53 } 54 55 public void generate(Class clazz) { 56 Method[] methods = clazz.getDeclaredMethods(); 57 int i = 0; 58 for (; i < methods.length; i++) { 59 Method method = methods[i]; 60 if ((method.getModifiers() & Modifier.NATIVE) != 0) break; 61 } 62 if (i == methods.length) return; 63 sort(methods); 64 if (isCPP) { 65 outputln("extern \"C\" {"); 66 outputln(); 67 } 68 generateNativeMacro(clazz); 69 generateExcludes(methods); 70 generate(methods); 71 if (isCPP) { 72 outputln("}"); 73 } 74 } 75 76 public void generate(Method[] methods) { 77 sort(methods); 78 for (int i = 0; i < methods.length; i++) { 79 Method method = methods[i]; 80 if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; 81 generate(method); 82 if (progress != null) progress.step(); 83 } 84 } 85 86 public void generate(Method method) { 87 MethodData methodData = getMetaData().getMetaData(method); 88 if (methodData.getFlag("no_gen")) return; 89 Class returnType = method.getReturnType(); 90 Class [] paramTypes = method.getParameterTypes(); 91 String function = getFunctionName(method); 92 93 if (!(returnType == Void.TYPE || returnType.isPrimitive() || isSystemClass(returnType) || returnType == String .class)) { 94 output("Warning: bad return type. :"); 95 outputln(method.toString()); 96 return; 97 } 98 99 generateSourceStart(function); 100 generateFunctionPrototype(method, function, paramTypes, returnType); 101 generateFunctionBody(method, methodData, function, paramTypes, returnType); 102 generateSourceEnd(function); 103 outputln(); 104 } 105 106 public void setEnterExitMacro(boolean enterExitMacro) { 107 this.enterExitMacro = enterExitMacro; 108 } 109 110 void generateExcludes(Method[] methods) { 111 HashSet excludes = new HashSet (); 112 for (int i = 0; i < methods.length; i++) { 113 Method method = methods[i]; 114 if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; 115 MethodData methodData = getMetaData().getMetaData(method); 116 String exclude = methodData.getExclude(); 117 if (exclude.length() != 0) { 118 excludes.add(exclude); 119 } 120 } 121 for (Iterator iter = excludes.iterator(); iter.hasNext();) { 122 String exclude = (String )iter.next(); 123 outputln(exclude); 124 for (int i = 0; i < methods.length; i++) { 125 Method method = methods[i]; 126 if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; 127 MethodData methodData = getMetaData().getMetaData(method); 128 String methodExclude = methodData.getExclude(); 129 if (exclude.equals(methodExclude)) { 130 output("#define NO_"); 131 outputln(getFunctionName(method)); 132 } 133 } 134 outputln("#endif"); 135 outputln(); 136 } 137 } 138 139 void generateNativeMacro(Class clazz) { 140 output("#define "); 141 output(getClassName(clazz)); 142 output("_NATIVE(func) Java_"); 143 output(toC(clazz.getName())); 144 outputln("_##func"); 145 outputln(); 146 } 147 148 boolean generateGetParameter(Method method, int i, Class paramType, ParameterData paramData, boolean critical, int indent) { 149 if (paramType.isPrimitive() || isSystemClass(paramType)) return false; 150 String iStr = String.valueOf(i); 151 for (int j = 0; j < indent; j++) output("\t"); 152 output("if (arg"); 153 output(iStr); 154 output(") if ((lparg"); 155 output(iStr); 156 output(" = "); 157 if (paramType.isArray()) { 158 Class componentType = paramType.getComponentType(); 159 if (componentType.isPrimitive()) { 160 if (critical) { 161 if (isCPP) { 162 output("env->GetPrimitiveArrayCritical(arg"); 163 } else { 164 output("(*env)->GetPrimitiveArrayCritical(env, arg"); 165 } 166 output(iStr); 167 output(", NULL)"); 168 } else { 169 if (isCPP) { 170 output("env->Get"); 171 } else { 172 output("(*env)->Get"); 173 } 174 output(getTypeSignature1(componentType)); 175 if (isCPP) { 176 output("ArrayElements(arg"); 177 } else { 178 output("ArrayElements(env, arg"); 179 } 180 output(iStr); 181 output(", NULL)"); 182 } 183 } else { 184 throw new Error ("not done"); 185 } 186 } else if (paramType == String .class) { 187 if (paramData.getFlag("unicode")) { 188 if (isCPP) { 189 output("env->GetStringChars(arg"); 190 } else { 191 output("(*env)->GetStringChars(env, arg"); 192 } 193 output(iStr); 194 output(", NULL)"); 195 } else { 196 if (isCPP) { 197 output("env->GetStringUTFChars(arg"); 198 } else { 199 output("(*env)->GetStringUTFChars(env, arg"); 200 } 201 output(iStr); 202 output(", NULL)"); 203 } 204 } else { 205 if (paramData.getFlag("no_in")) { 206 output("&_arg"); 207 output(iStr); 208 } else { 209 output("get"); 210 output(getClassName(paramType)); 211 output("Fields(env, arg"); 212 output(iStr); 213 output(", &_arg"); 214 output(iStr); 215 output(")"); 216 } 217 } 218 outputln(") == NULL) goto fail;"); 219 return true; 220 } 221 222 void generateSetParameter(int i, Class paramType, ParameterData paramData, boolean critical) { 223 if (paramType.isPrimitive() || isSystemClass(paramType)) return; 224 String iStr = String.valueOf(i); 225 if (paramType.isArray()) { 226 output("\tif (arg"); 227 output(iStr); 228 output(" && lparg"); 229 output(iStr); 230 output(") "); 231 Class componentType = paramType.getComponentType(); 232 if (componentType.isPrimitive()) { 233 if (critical) { 234 if (isCPP) { 235 output("env->ReleasePrimitiveArrayCritical(arg"); 236 } else { 237 output("(*env)->ReleasePrimitiveArrayCritical(env, arg"); 238 } 239 output(iStr); 240 } else { 241 if (isCPP) { 242 output("env->Release"); 243 } else { 244 output("(*env)->Release"); 245 } 246 output(getTypeSignature1(componentType)); 247 if (isCPP) { 248 output("ArrayElements(arg"); 249 } else { 250 output("ArrayElements(env, arg"); 251 } 252 output(iStr); 253 } 254 output(", lparg"); 255 output(iStr); 256 output(", "); 257 if (paramData.getFlag("no_out")) { 258 output("JNI_ABORT"); 259 } else { 260 output("0"); 261 } 262 output(");"); 263 } else { 264 throw new Error ("not done"); 265 } 266 outputln(); 267 } else if (paramType == String .class) { 268 output("\tif (arg"); 269 output(iStr); 270 output(" && lparg"); 271 output(iStr); 272 output(") "); 273 if (paramData.getFlag("unicode")) { 274 if (isCPP) { 275 output("env->ReleaseStringChars(arg"); 276 } else { 277 output("(*env)->ReleaseStringChars(env, arg"); 278 } 279 } else { 280 if (isCPP) { 281 output("env->ReleaseStringUTFChars(arg"); 282 } else { 283 output("(*env)->ReleaseStringUTFChars(env, arg"); 284 } 285 } 286 output(iStr); 287 output(", lparg"); 288 output(iStr); 289 outputln(");"); 290 } else { 291 if (!paramData.getFlag("no_out")) { 292 output("\tif (arg"); 293 output(iStr); 294 output(" && lparg"); 295 output(iStr); 296 output(") "); 297 output("set"); 298 output(getClassName(paramType)); 299 output("Fields(env, arg"); 300 output(iStr); 301 output(", lparg"); 302 output(iStr); 303 outputln(");"); 304 } 305 } 306 } 307 308 void generateExitMacro(Method method, String function) { 309 if (!enterExitMacro) return; 310 output("\t"); 311 output(getClassName(method.getDeclaringClass())); 312 output("_NATIVE_EXIT(env, that, "); 313 output(function); 314 outputln("_FUNC);"); 315 } 316 317 void generateEnterMacro(Method method, String function) { 318 if (!enterExitMacro) return; 319 output("\t"); 320 output(getClassName(method.getDeclaringClass())); 321 output("_NATIVE_ENTER(env, that, "); 322 output(function); 323 outputln("_FUNC);"); 324 } 325 326 boolean generateLocalVars(Method method, Class [] paramTypes, Class returnType) { 327 boolean needsReturn = enterExitMacro; 328 for (int i = 0; i < paramTypes.length; i++) { 329 Class paramType = paramTypes[i]; 330 if (paramType.isPrimitive() || isSystemClass(paramType)) continue; 331 ParameterData paramData = getMetaData().getMetaData(method, i); 332 output("\t"); 333 if (paramType.isArray()) { 334 Class componentType = paramType.getComponentType(); 335 if (componentType.isPrimitive()) { 336 output(getTypeSignature2(componentType)); 337 output(" *lparg" + i); 338 output("=NULL;"); 339 } else { 340 throw new Error ("not done"); 341 } 342 } else if (paramType == String .class) { 343 if (paramData.getFlag("unicode")) { 344 output("const jchar *lparg" + i); 345 } else { 346 output("const char *lparg" + i); 347 } 348 output("= NULL;"); 349 } else { 350 output(getClassName(paramType)); 351 output(" _arg" + i); 352 if (paramData.getFlag("init")) output("={0}"); 353 output(", *lparg" + i); 354 output("=NULL;"); 355 } 356 outputln(); 357 needsReturn = true; 358 } 359 if (needsReturn) { 360 if (returnType != Void.TYPE) { 361 output("\t"); 362 output(getTypeSignature2(returnType)); 363 outputln(" rc = 0;"); 364 } 365 } 366 return needsReturn; 367 } 368 369 boolean generateGetters(Method method, Class [] paramTypes) { 370 boolean genFailTag = false; 371 int criticalCount = 0; 372 for (int i = 0; i < paramTypes.length; i++) { 373 Class paramType = paramTypes[i]; 374 ParameterData paramData = getMetaData().getMetaData(method, i); 375 if (!isCritical(paramType, paramData)) { 376 genFailTag |= generateGetParameter(method, i, paramType, paramData, false, 1); 377 } else { 378 criticalCount++; 379 } 380 } 381 if (criticalCount != 0) { 382 outputln("#ifdef JNI_VERSION_1_2"); 383 outputln("\tif (IS_JNI_1_2) {"); 384 for (int i = 0; i < paramTypes.length; i++) { 385 Class paramType = paramTypes[i]; 386 ParameterData paramData = getMetaData().getMetaData(method, i); 387 if (isCritical(paramType, paramData)) { 388 genFailTag |= generateGetParameter(method, i, paramType, paramData, true, 2); 389 } 390 } 391 outputln("\t} else"); 392 outputln("#endif"); 393 outputln("\t{"); 394 for (int i = 0; i < paramTypes.length; i++) { 395 Class paramType = paramTypes[i]; 396 ParameterData paramData = getMetaData().getMetaData(method, i); 397 if (isCritical(paramType, paramData)) { 398 genFailTag |= generateGetParameter(method, i, paramType, paramData, false, 2); 399 } 400 } 401 outputln("\t}"); 402 } 403 return genFailTag; 404 } 405 406 void generateSetters(Method method, Class [] paramTypes) { 407 int criticalCount = 0; 408 for (int i = paramTypes.length - 1; i >= 0; i--) { 409 Class paramType = paramTypes[i]; 410 ParameterData paramData = getMetaData().getMetaData(method, i); 411 if (isCritical(paramType, paramData)) { 412 criticalCount++; 413 } 414 } 415 if (criticalCount != 0) { 416 outputln("#ifdef JNI_VERSION_1_2"); 417 outputln("\tif (IS_JNI_1_2) {"); 418 for (int i = paramTypes.length - 1; i >= 0; i--) { 419 Class paramType = paramTypes[i]; 420 ParameterData paramData = getMetaData().getMetaData(method, i); 421 if (isCritical(paramType, paramData)) { 422 output("\t"); 423 generateSetParameter(i, paramType, paramData, true); 424 } 425 } 426 outputln("\t} else"); 427 outputln("#endif"); 428 outputln("\t{"); 429 for (int i = paramTypes.length - 1; i >= 0; i--) { 430 Class paramType = paramTypes[i]; 431 ParameterData paramData = getMetaData().getMetaData(method, i); 432 if (isCritical(paramType, paramData)) { 433 output("\t"); 434 generateSetParameter(i, paramType, paramData, false); 435 } 436 } 437 outputln("\t}"); 438 } 439 for (int i = paramTypes.length - 1; i >= 0; i--) { 440 Class paramType = paramTypes[i]; 441 ParameterData paramData = getMetaData().getMetaData(method, i); 442 if (!isCritical(paramType, paramData)) { 443 generateSetParameter(i, paramType, paramData, false); 444 } 445 } 446 } 447 448 void generateDynamicFunctionCall(Method method, MethodData methodData, Class [] paramTypes, Class returnType, boolean needsReturn) { 449 outputln("/*"); 450 generateFunctionCall(method, methodData, paramTypes, returnType, needsReturn); 451 outputln("*/"); 452 outputln("\t{"); 453 454 String name = method.getName(); 455 if (name.startsWith("_")) name = name.substring(1); 456 if (getPlatform().equals("win32")) { 457 outputln("\t\tstatic int initialized = 0;"); 458 outputln("\t\tstatic HMODULE hm = NULL;"); 459 outputln("\t\tstatic FARPROC fp = NULL;"); 460 if (returnType != Void.TYPE) { 461 if (needsReturn) { 462 outputln("\t\trc = 0;"); 463 } 464 } 465 outputln("\t\tif (!initialized) {"); 466 output("\t\t\tif (!hm) hm = LoadLibrary("); 467 output(name); 468 outputln("_LIB);"); 469 output("\t\t\tif (hm) fp = GetProcAddress(hm, \""); 470 output(name); 471 outputln("\");"); 472 outputln("\t\t\tinitialized = 1;"); 473 outputln("\t\t}"); 474 outputln("\t\tif (fp) {"); 475 output("\t\t"); 476 generateFunctionCallLeftSide(method, methodData, returnType, needsReturn); 477 output("fp"); 478 generateFunctionCallRightSide(method, methodData, paramTypes, 0); 479 outputln(); 480 outputln("\t\t}"); 481 } else if (getPlatform().equals("carbon")) { 482 outputln("\t\tstatic int initialized = 0;"); 483 outputln("\t\tstatic CFBundleRef bundle = NULL;"); 484 output("\t\ttypedef "); 485 output(getTypeSignature2(returnType)); 486 output(" (*FPTR)("); 487 for (int i = 0; i < paramTypes.length; i++) { 488 if (i != 0) output(", "); 489 Class paramType = paramTypes[i]; 490 ParameterData paramData = getMetaData().getMetaData(method, i); 491 String cast = paramData.getCast(); 492 if (cast.length() > 2) { 493 output(cast.substring(1, cast.length() - 1)); 494 } else { 495 output(getTypeSignature4(paramType)); 496 } 497 } 498 outputln(");"); 499 outputln("\t\tstatic FPTR fptr;"); 500 if (returnType != Void.TYPE) { 501 if (needsReturn) { 502 outputln("\t\trc = 0;"); 503 } 504 } 505 outputln("\t\tif (!initialized) {"); 506 output("\t\t\tif (!bundle) bundle = CFBundleGetBundleWithIdentifier(CFSTR("); 507 output(name); 508 outputln("_LIB));"); 509 output("\t\t\tif (bundle) fptr = (FPTR)CFBundleGetFunctionPointerForName(bundle, CFSTR(\""); 510 output(name); 511 outputln("\"));"); 512 outputln("\t\t\tinitialized = 1;"); 513 outputln("\t\t}"); 514 outputln("\t\tif (fptr) {"); 515 output("\t\t"); 516 generateFunctionCallLeftSide(method, methodData, returnType, needsReturn); 517 output("(*fptr)"); 518 generateFunctionCallRightSide(method, methodData, paramTypes, 0); 519 outputln(); 520 outputln("\t\t}"); 521 } else { 522 outputln("\t\tstatic int initialized = 0;"); 523 outputln("\t\tstatic void *handle = NULL;"); 524 output("\t\ttypedef "); 525 output(getTypeSignature2(returnType)); 526 output(" (*FPTR)("); 527 for (int i = 0; i < paramTypes.length; i++) { 528 if (i != 0) output(", "); 529 Class paramType = paramTypes[i]; 530 ParameterData paramData = getMetaData().getMetaData(method, i); 531 String cast = paramData.getCast(); 532 if (cast.length() > 2) { 533 output(cast.substring(1, cast.length() - 1)); 534 } else { 535 output(getTypeSignature4(paramType)); 536 } 537 } 538 outputln(");"); 539 outputln("\t\tstatic FPTR fptr;"); 540 if (returnType != Void.TYPE) { 541 if (needsReturn) { 542 outputln("\t\trc = 0;"); 543 } 544 } 545 outputln("\t\tif (!initialized) {"); 546 output("\t\t\tif (!handle) handle = dlopen("); 547 output(name); 548 outputln("_LIB, RTLD_LAZY);"); 549 output("\t\t\tif (handle) fptr = (FPTR)dlsym(handle, \""); 550 output(name); 551 outputln("\");"); 552 outputln("\t\t\tinitialized = 1;"); 553 outputln("\t\t}"); 554 outputln("\t\tif (fptr) {"); 555 output("\t\t"); 556 generateFunctionCallLeftSide(method, methodData, returnType, needsReturn); 557 output("(*fptr)"); 558 generateFunctionCallRightSide(method, methodData, paramTypes, 0); 559 outputln(); 560 outputln("\t\t}"); 561 } 562 563 outputln("\t}"); 564 } 565 566 void generateFunctionCallLeftSide(Method method, MethodData methodData, Class returnType, boolean needsReturn) { 567 output("\t"); 568 if (returnType != Void.TYPE) { 569 if (needsReturn) { 570 output("rc = "); 571 } else { 572 output("return "); 573 } 574 output("("); 575 output(getTypeSignature2(returnType)); 576 output(")"); 577 } 578 if (methodData.getFlag("address")) { 579 output("&"); 580 } 581 if (methodData.getFlag("jni")) { 582 output(isCPP ? "env->" : "(*env)->"); 583 } 584 } 585 586 void generateFunctionCallRightSide(Method method, MethodData methodData, Class [] paramTypes, int paramStart) { 587 if (!methodData.getFlag("const")) { 588 output("("); 589 if (methodData.getFlag("jni")) { 590 if (!isCPP) output("env, "); 591 } 592 for (int i = paramStart; i < paramTypes.length; i++) { 593 Class paramType = paramTypes[i]; 594 ParameterData paramData = getMetaData().getMetaData(method, i); 595 if (i != paramStart) output(", "); 596 if (paramData.getFlag("struct")) output("*"); 597 output(paramData.getCast()); 598 if (!paramType.isPrimitive() && !isSystemClass(paramType)) output("lp"); 599 output("arg" + i); 600 } 601 output(")"); 602 } 603 output(";"); 604 } 605 606 void generateFunctionCall(Method method, MethodData methodData, Class [] paramTypes, Class returnType, boolean needsReturn) { 607 String copy = (String )methodData.getParam("copy"); 608 boolean makeCopy = copy.length() != 0 && isCPP && returnType != Void.TYPE; 609 if (makeCopy) { 610 output("\t"); 611 output(copy); 612 output(" temp = "); 613 } else { 614 generateFunctionCallLeftSide(method, methodData, returnType, needsReturn); 615 } 616 int paramStart = 0; 617 String name = method.getName(); 618 if (name.startsWith("_")) name = name.substring(1); 619 if (name.equalsIgnoreCase("call")) { 620 output("("); 621 ParameterData paramData = getMetaData().getMetaData(method, 0); 622 String cast = paramData.getCast(); 623 if (cast.length() != 0 && !cast.equals("()")) { 624 output(cast); 625 } else { 626 output("("); 627 output(getTypeSignature2(returnType)); 628 output(" (*)())"); 629 } 630 output("arg0)"); 631 paramStart = 1; 632 } else if (name.startsWith("VtblCall")) { 633 output("(("); 634 output(getTypeSignature2(returnType)); 635 output(" (STDMETHODCALLTYPE *)("); 636 for (int i = 1; i < paramTypes.length; i++) { 637 if (i != 1) output(", "); 638 Class paramType = paramTypes[i]; 639 output(getTypeSignature4(paramType)); 640 } 641 output("))(*("); 642 output(getTypeSignature4(paramTypes[1])); 643 output(" **)arg1)[arg0])"); 644 paramStart = 1; 645 } else if (methodData.getFlag("cpp")) { 646 output("("); 647 ParameterData paramData = getMetaData().getMetaData(method, 0); 648 if (paramData.getFlag("struct")) output("*"); 649 String cast = paramData.getCast(); 650 if (cast.length() != 0 && !cast.equals("()")) { 651 output(cast); 652 } 653 output("arg0)->"); 654 String accessor = methodData.getAccessor(); 655 if (accessor.length() != 0) { 656 output(accessor); 657 } else { 658 int index = -1; 659 if ((index = name.indexOf('_')) != -1) { 660 output(name.substring(index + 1, name.length())); 661 } else { 662 output(name); 663 } 664 } 665 paramStart = 1; 666 } else if (methodData.getFlag("new")) { 667 output("new "); 668 String accessor = methodData.getAccessor(); 669 if (accessor.length() != 0) { 670 output(accessor); 671 } else { 672 int index = -1; 673 if ((index = name.indexOf('_')) != -1) { 674 output(name.substring(0, index)); 675 } else { 676 output(name); 677 } 678 } 679 } else if (methodData.getFlag("delete")) { 680 output("delete "); 681 ParameterData paramData = getMetaData().getMetaData(method, 0); 682 String cast = paramData.getCast(); 683 if (cast.length() != 0 && !cast.equals("()")) { 684 output(cast); 685 } else { 686 output("("); 687 output(name.substring(0, name.indexOf("_"))); 688 output(" *)"); 689 } 690 outputln("arg0;"); 691 return; 692 } else { 693 String accessor = methodData.getAccessor(); 694 if (accessor.length() != 0) { 695 output(accessor); 696 } else { 697 output(name); 698 } 699 } 700 generateFunctionCallRightSide(method, methodData, paramTypes, paramStart); 701 outputln(); 702 if (makeCopy) { 703 outputln("\t{"); 704 output("\t\t"); 705 output(copy); 706 output("* copy = new "); 707 output(copy); 708 outputln("();"); 709 outputln("\t\t*copy = temp;"); 710 output("\t\trc = "); 711 output("("); 712 output(getTypeSignature2(returnType)); 713 output(")"); 714 outputln("copy;"); 715 outputln("\t}"); 716 } 717 } 718 719 void generateReturn(Method method, Class returnType, boolean needsReturn) { 720 if (needsReturn && returnType != Void.TYPE) { 721 outputln("\treturn rc;"); 722 } 723 } 724 725 void generateGTKmemmove(Method method, String function, Class [] paramTypes) { 726 generateEnterMacro(method, function); 727 output("\t"); 728 boolean get = paramTypes[0].isPrimitive(); 729 String className = getClassName(paramTypes[get ? 1 : 0]); 730 output(get ? "if (arg1) get" : "if (arg0) set"); 731 output(className); 732 output(get ? "Fields(env, arg1, (" : "Fields(env, arg0, ("); 733 output(className); 734 output(get ? " *)arg0)" : " *)arg1)"); 735 outputln(";"); 736 generateExitMacro(method, function); 737 } 738 739 void generateFunctionBody(Method method, MethodData methodData, String function, Class [] paramTypes, Class returnType) { 740 outputln("{"); 741 742 743 String name = method.getName(); 744 if (name.startsWith("_")) name = name.substring(1); 745 boolean isGTKmemove = name.equals("memmove") && paramTypes.length == 2 && returnType == Void.TYPE; 746 if (isGTKmemove) { 747 generateGTKmemmove(method, function, paramTypes); 748 } else { 749 boolean needsReturn = generateLocalVars(method, paramTypes, returnType); 750 generateEnterMacro(method, function); 751 boolean genFailTag = generateGetters(method, paramTypes); 752 if (methodData.getFlag("dynamic")) { 753 generateDynamicFunctionCall(method, methodData, paramTypes, returnType, needsReturn); 754 } else { 755 generateFunctionCall(method, methodData, paramTypes, returnType, needsReturn); 756 } 757 if (genFailTag) outputln("fail:"); 758 generateSetters(method, paramTypes); 759 generateExitMacro(method, function); 760 generateReturn(method, returnType, needsReturn); 761 } 762 763 outputln("}"); 764 } 765 766 void generateFunctionPrototype(Method method, String function, Class [] paramTypes, Class returnType) { 767 output("JNIEXPORT "); 768 output(getTypeSignature2(returnType)); 769 output(" JNICALL "); 770 output(getClassName(method.getDeclaringClass())); 771 output("_NATIVE("); 772 output(function); 773 outputln(")"); 774 output("\t(JNIEnv *env, "); 775 if ((method.getModifiers() & Modifier.STATIC) != 0) { 776 output("jclass"); 777 } else { 778 output("jobject"); 779 } 780 output(" that"); 781 for (int i = 0; i < paramTypes.length; i++) { 782 Class paramType = paramTypes[i]; 783 output(", "); 784 output(getTypeSignature2(paramType)); 785 output(" arg" + i); 786 } 787 outputln(")"); 788 } 789 790 void generateSourceStart(String function) { 791 output("#ifndef NO_"); 792 outputln(function); 793 } 794 795 void generateSourceEnd(String function) { 796 outputln("#endif"); 797 } 798 799 boolean isCritical(Class paramType, ParameterData paramData) { 800 return paramType.isArray() && paramType.getComponentType().isPrimitive() && paramData.getFlag("critical"); 801 } 802 803 boolean isSystemClass(Class type) { 804 return type == Object .class || type == Class .class; 805 } 806 807 public static void main(String [] args) { 808 if (args.length < 1) { 810 System.out.println("Usage: java NativesGenerator <className1> <className2>"); 811 return; 812 } 813 try { 814 NativesGenerator gen = new NativesGenerator(); 815 for (int i = 0; i < args.length; i++) { 816 String clazzName = args[i]; 817 Class clazz = Class.forName(clazzName); 818 gen.generate(clazz); 819 } 821 } catch (Exception e) { 822 System.out.println("Problem"); 823 e.printStackTrace(System.out); 824 } 825 } 826 827 } 828 | Popular Tags |