1 19 package org.netbeans.mdr.handlers.gen; 20 21 import org.netbeans.lib.jmi.util.ClassFileGenerator; 22 import org.netbeans.mdr.storagemodel.*; 23 import org.netbeans.mdr.util.DebugException; 24 import org.netbeans.mdr.util.Logger; 25 import org.netbeans.mdr.util.MOFConstants; 26 import javax.jmi.model.MultiplicityType; 27 import java.io.ByteArrayOutputStream ; 28 import java.io.DataOutputStream ; 29 import java.io.IOException ; 30 import java.lang.reflect.Method ; 31 import java.lang.reflect.Modifier ; 32 import java.util.*; 33 34 39 public abstract class HandlerGenerator extends ClassFileGenerator { 40 41 42 43 44 45 private static final String PRE_TYPE = "Ljava/lang/Object;"; private static final String POST_DESCRIPTOR = "Ljava/lang/Object;Z)V"; private static final String POST_VOID_DESCRIPTOR = "(Ljava/lang/Object;Z)V"; 49 50 51 52 53 protected static final String DT_MULTIVALUED = "java.util.Collection"; protected static final String DT_ORDERED = "java.util.List"; protected static final String PRE_PREFIX = "_pre"; protected static final String POST_PREFIX = "_post"; protected static final String HANDLE_PREFIX = "_handle"; protected static final String CUSTOM_PREFIX = "super_"; 60 private static final int PROXY_DEF_LENGTH = 3200; 61 private static final int INSTANCE_DEF_LENGTH = 32000; 62 63 64 65 66 67 71 public static byte[] generateHandler(final String name, Class ifc, StorableBaseObject storable) { 72 HandlerGenerator gen; 73 int def_length; 74 try { 75 if (storable instanceof StorableAssociation) { 76 gen = new AssociationGenerator(name, ifc, ((StorableAssociation)storable).getAssociationSuperclass(), (StorableAssociation)storable, ((StorableAssociation)storable).getAssociationCustomImpl()); 77 def_length = PROXY_DEF_LENGTH; 78 } else if (storable instanceof StorableClass) { 79 gen = new ClassGenerator(name, ifc, ((StorableClass) storable).getClassSuperclass(), (StorableClass)storable, ((StorableClass) storable).getClassCustomImpl()); 80 def_length = PROXY_DEF_LENGTH; 81 } else if (storable instanceof StorablePackage) { 82 gen = new PackageGenerator(name, ifc, ((StorablePackage) storable).getPackageSuperclass(), (StorablePackage)storable, ((StorablePackage) storable).getPackageCustomImpl()); 83 def_length = INSTANCE_DEF_LENGTH; 84 } else if (storable instanceof StorableObject) { 85 StorableClass proxy = ((StorableObject) storable).getClassProxy(); 86 gen = new InstanceGenerator(name, ifc, proxy.getInstanceSuperclass(), (StorableObject)storable, proxy.getInstanceCustomImpl()); 87 def_length = INSTANCE_DEF_LENGTH; 88 } else { 89 throw new InternalError ("Unknow dispatcher type."); } 91 } catch (Exception e) { 92 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 93 } 94 95 ByteArrayOutputStream bout = new ByteArrayOutputStream (def_length); 96 gen.generateClassFile(bout); 97 return bout.toByteArray(); 98 } 99 100 public static boolean customImplContainsMethod(Class customImpl, String name, String descriptor) { 101 if (customImpl == null) 102 return false; 103 synchronized (customImplInfos) { 104 HashSet methods = (HashSet)customImplInfos.get(customImpl); 105 if (methods == null) { 106 methods = new HashSet(); 107 Method [] m = customImpl.getMethods(); 108 for (int i = 0; i < m.length; i++) { 109 if (Modifier.isAbstract(m[i].getModifiers())) 110 continue; 111 ArrayList params = new ArrayList(); 112 Class [] p = m[i].getParameterTypes(); 113 for(int j = 0; j < p.length; j++) 114 params.add(p[j].getName()); 115 methods.add(m[i].getName() + getMethodDescriptor((String [])params.toArray(new String [params.size()]), m[i].getReturnType().getName())); 116 } 117 customImplInfos.put(customImpl, methods); 118 } 119 return methods.contains(name + descriptor); 120 } 121 } 122 123 124 125 126 127 private static Map customImplInfos = new LinkedHashMap(10, .5f, true) { 128 private static final int MAX_SIZE = 5; 129 130 protected boolean removeEldestEntry(Map.Entry entry) { 131 return size() > MAX_SIZE; 132 } 133 }; 134 135 136 137 138 139 protected final StorableBaseObject obj; 140 protected final Class customImpl; 141 protected final HashMap dispatchMethods = new HashMap(); 142 143 144 145 146 147 151 protected HandlerGenerator(String className, Class ifc, Class handler, StorableBaseObject storable, Class custom) { 152 super(className, new String [] {ifc.getName()}, handler.getName(), ACC_PUBLIC | ACC_FINAL | ACC_SUPER); 153 obj = storable; 154 customImpl = custom; 155 } 156 157 158 159 protected FieldInfo[] generateFields() throws IOException { 160 return new FieldInfo[0]; 161 } 162 163 166 protected MethodInfo generateConstructor() throws IOException { 167 MethodInfo minfo = new MethodInfo( 168 "<init>", getConstructorDescriptor(), ACC_PUBLIC); 170 171 DataOutputStream out = new DataOutputStream (minfo.getCodeStream()); 172 173 code_aload(0, out); 174 code_aload(1, out); 175 176 out.writeByte(opc_invokespecial); 178 out.writeShort(cp.getMethodRef(dotToSlash(superclassName), "<init>", getConstructorDescriptor())); 180 out.writeByte(opc_return); 181 182 minfo.setMaxStack((short)2); 183 minfo.setMaxLocals((short)2); 184 return minfo; 185 } 186 187 protected abstract String getConstructorDescriptor(); 188 189 protected short getHandlerIndex(String methodName, String methodDescriptor, String methodType) { 190 return cp.getMethodRef(dotToSlash(superclassName), HANDLE_PREFIX + methodName, methodDescriptor + methodType); 191 } 192 193 protected short getPreIndex(String methodName, String methodDescriptor) { 194 return cp.getMethodRef(dotToSlash(superclassName), PRE_PREFIX + methodName, methodDescriptor + PRE_TYPE); 195 } 196 197 protected short getPostIndex(String methodName, String methodType) { 198 return cp.getMethodRef(dotToSlash(superclassName), POST_PREFIX + methodName, (methodType.equals("V") ? POST_VOID_DESCRIPTOR : ("(" + methodType + POST_DESCRIPTOR))); } 200 201 protected Collection getHandlerMethod(String methodName, String [] parameterTypes, String returnType, String handlerName, String handlerDescriptor, String handlerType, String featureName) throws IOException { 202 short delegateMethod = getHandlerIndex(handlerName, handlerDescriptor, handlerType); 203 short preMethod = getPreIndex(handlerName, handlerDescriptor); 204 short postMethod = getPostIndex(handlerName, handlerType); 205 String methodDescriptor = getMethodDescriptor(parameterTypes, returnType); 206 boolean isCustom = customImplContainsMethod(customImpl, methodName, methodDescriptor); 207 208 int[] parameterSlot = new int[parameterTypes.length]; 209 int nextSlot = 1; 210 for (int i = 0; i < parameterSlot.length; i++) { 211 parameterSlot[i] = nextSlot; 212 nextSlot += getWordsPerType(parameterTypes[i]); 213 } 214 int localSlot0 = nextSlot; 215 216 short fail = (short) localSlot0; 217 short extraInfo = (short) (localSlot0 + 1); 218 short result = (short) (localSlot0 + 2); 219 short addr = (short) (localSlot0 + 3); 220 short exception = (short) (localSlot0 + 4); 221 short customResult = (short) (localSlot0 + 5); 222 223 MethodInfo minfo = new MethodInfo(methodName, methodDescriptor, ACC_PUBLIC | ACC_FINAL); 224 DataOutputStream out = new DataOutputStream (minfo.getCodeStream()); 225 MethodInfo cminfo = null; 226 DataOutputStream cout = null; 227 if (isCustom) { 228 cminfo = new MethodInfo(CUSTOM_PREFIX + methodName, methodDescriptor, ACC_PUBLIC | ACC_FINAL); 229 cout = new DataOutputStream (cminfo.getCodeStream()); 230 } 231 232 out.writeByte(opc_iconst_1); 234 code_istore(fail, out); 235 out.writeByte(opc_aconst_null); 237 out.writeByte(opc_dup); 238 code_astore(extraInfo, out); 239 code_astore(result, out); 241 242 code_aload(0, out); 244 245 if (featureName != null) 246 code_ldc(cp.getString(featureName), out); 248 249 for (int i = 0; i < parameterTypes.length; i++) { 251 codeWrapArgument(parameterTypes[i], parameterSlot[i], out); 252 } 253 254 out.writeByte(opc_invokespecial); 256 out.writeShort(preMethod); 257 258 short tryStart = (short) out.size(); 260 261 code_astore(extraInfo, out); 263 264 if (isCustom) { 265 code_aload(0, out); 267 268 for (int i = 0; i < parameterTypes.length; i++) { 270 codeLoad(parameterSlot[i], parameterTypes[i], out); 271 } 272 273 out.writeByte(opc_invokespecial); 275 out.writeShort(cp.getMethodRef(dotToSlash(superclassName), methodName, methodDescriptor)); 276 277 if (!returnType.equals("void")) { if (PrimitiveTypeInfo.get(returnType) == null) 279 code_astore(result, out); 280 else { 281 codeStore(customResult, returnType, out); 282 codeWrapArgument(returnType, customResult, out); 283 code_astore(result, out); 284 } 285 } 286 287 code_aload(0, cout); 289 290 if (featureName != null) 291 code_ldc(cp.getString(featureName), cout); 293 294 for (int i = 0; i < parameterTypes.length; i++) { 296 codeWrapArgument(parameterTypes[i], parameterSlot[i], cout); 297 } 298 299 cout.writeByte(opc_invokespecial); 301 cout.writeShort(delegateMethod); 302 303 if (returnType.equals("void")) cout.writeByte(opc_return); 305 else 306 codeUnwrapReturnValue(returnType, cout); 307 } 308 else { 309 code_aload(0, out); 311 312 if (featureName != null) 313 code_ldc(cp.getString(featureName), out); 315 316 for (int i = 0; i < parameterTypes.length; i++) { 318 codeWrapArgument(parameterTypes[i], parameterSlot[i], out); 319 } 320 321 out.writeByte(opc_invokespecial); 323 out.writeShort(delegateMethod); 324 325 if (!returnType.equals("void")) { code_astore(result, out); 327 } 328 } 329 out.writeByte(opc_iconst_0); 331 code_istore(fail, out); 332 333 out.writeByte(opc_jsr); 335 if (returnType.equals("void")) { out.writeShort(3 + 1 + 2*getBytesForLoadOrStore(exception) + 4); 337 out.writeByte(opc_return); 338 } else { 339 if (isCustom) { 340 if (PrimitiveTypeInfo.get(returnType) != null) { 341 out.writeShort(3 + getBytesForLoadOrStore(customResult) + 1 + 2*getBytesForLoadOrStore(exception) + 4); 342 codeLoad(customResult, returnType, out); 343 if (returnType.equals("int") || returnType.equals("boolean") || returnType.equals("byte") || returnType.equals("char") || returnType.equals("short")) out.writeByte(opc_ireturn); 345 else if (returnType.equals("long")) out.writeByte(opc_lreturn); 347 else if (returnType.equals("float")) out.writeByte(opc_freturn); 349 else if (returnType.equals("double")) out.writeByte(opc_dreturn); 351 else 352 _assert(false); 353 } else { 354 out.writeShort(3 + getBytesForLoadOrStore(result) + 1 + 2*getBytesForLoadOrStore(exception) + 4); 355 code_aload(result, out); 356 out.writeByte(opc_areturn); 357 } 358 } 359 else { 360 out.writeShort(3 + getBytesForLoadOrStore(result) + getBytesForUnwrapReturn(returnType) + 2*getBytesForLoadOrStore(exception) + 4); 361 code_aload(result, out); 363 codeUnwrapReturnValue(returnType, out); 365 } 366 } 367 short catchStart = (short) out.size(); 369 370 code_astore(exception, out); 372 373 out.writeByte(opc_jsr); 375 out.writeShort(3 + getBytesForLoadOrStore(exception) + 1); 376 377 code_aload(exception, out); 379 380 out.writeByte(opc_athrow); 382 383 code_astore(addr, out); 386 387 code_aload(0, out); 389 if (!returnType.equals("void")) { code_aload(result, out); 391 } 392 code_aload(extraInfo, out); 393 code_iload(fail, out); 394 395 out.writeByte(opc_invokespecial); 397 out.writeShort(postMethod); 398 399 out.writeByte(opc_ret); 401 out.writeByte(addr); 402 403 minfo.getExceptionTable().add(new ExceptionTableEntry(tryStart, catchStart, catchStart, (short) 0)); 404 405 minfo.setMaxStack((short)15); 406 minfo.setMaxLocals((short)(localSlot0 + 6)); 407 408 if (isCustom) { 409 cminfo.setMaxStack((short)15); 410 cminfo.setMaxLocals((short)(localSlot0 + 5)); 411 } 412 413 ArrayList ret = new ArrayList(); 414 ret.add(minfo); 415 if (isCustom) 416 ret.add(cminfo); 417 return ret; 418 } 419 420 protected void codeStore(int index, String type, DataOutputStream out) throws IOException { 421 if (type.equals("int") || type.equals("boolean") || type.equals("byte") || type.equals("char") || type.equals("short")) code_istore(index, out); 423 else if (type.equals("long")) code_lstore(index, out); 425 else if (type.equals("float")) code_fstore(index, out); 427 else if (type.equals("double")) code_dstore(index, out); 429 else 430 code_astore(index, out); 431 } 432 433 protected void codeLoad(int index, String type, DataOutputStream out) throws IOException { 434 if (type.equals("int") || type.equals("boolean") || type.equals("byte") || type.equals("char") || type.equals("short")) code_iload(index, out); 436 else if (type.equals("long")) code_lload(index, out); 438 else if (type.equals("float")) code_fload(index, out); 440 else if (type.equals("double")) code_dload(index, out); 442 else 443 code_aload(index, out); 444 } 445 446 protected int getBytesForLoadOrStore(int idx) { 447 if (idx <= 3) 448 return 1; 449 if (idx <= 0xFF) 450 return 2; 451 return 4; 452 } 453 454 protected void codeWrapArgument(String typeName, int slot, DataOutputStream out) throws IOException { 455 PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName); 456 if (prim != null) { 457 if (typeName.equals("boolean")) { 458 code_iload(slot, out); 459 out.writeByte(opc_invokestatic); 460 out.writeShort(cp.getMethodRef("java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;")); 461 } else { 462 out.writeByte(opc_new); 463 out.writeShort(cp.getClass(prim.wrapperClassName)); 464 465 out.writeByte(opc_dup); 466 467 if (typeName.equals("int") || typeName.equals("byte") || typeName.equals("char") || typeName.equals("short")) { code_iload(slot, out); 469 } else if (typeName.equals("long")) { code_lload(slot, out); 471 } else if (typeName.equals("float")) { code_fload(slot, out); 473 } else if (typeName.equals("double")) { code_dload(slot, out); 475 } else { 476 _assert(false); 477 } 478 479 out.writeByte(opc_invokespecial); 480 out.writeShort(cp.getMethodRef(prim.wrapperClassName, "<init>", prim.wrapperConstructorDesc)); } 482 } else { 483 code_aload(slot, out); 484 } 485 } 486 487 protected void codeUnwrapReturnValue(String typeName, DataOutputStream out) throws IOException { 488 PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName); 489 if (prim != null) { 490 out.writeByte(opc_dup); 491 out.writeByte(opc_ifnull); 492 out.writeShort(10); 493 494 out.writeByte(opc_checkcast); 495 out.writeShort(cp.getClass(prim.wrapperClassName)); 496 497 out.writeByte(opc_invokevirtual); 498 out.writeShort(cp.getMethodRef(prim.wrapperClassName, prim.unwrapMethodName, prim.unwrapMethodDesc)); 499 500 if (typeName.equals("int") || typeName.equals("boolean") || typeName.equals("byte") || typeName.equals("char") || typeName.equals("short")) { out.writeByte(opc_ireturn); 502 out.writeByte(opc_iconst_0); 503 out.writeByte(opc_ireturn); 504 } else if (typeName.equals("long")) { out.writeByte(opc_lreturn); 506 out.writeByte(opc_lconst_0); 507 out.writeByte(opc_lreturn); 508 } else if (typeName.equals("float")) { out.writeByte(opc_freturn); 510 out.writeByte(opc_fconst_0); 511 out.writeByte(opc_freturn); 512 } else if (typeName.equals("double")) { out.writeByte(opc_dreturn); 514 out.writeByte(opc_dconst_0); 515 out.writeByte(opc_dreturn); 516 } else { 517 _assert(false); 518 } 519 520 } else { 521 out.writeByte(opc_checkcast); 522 out.writeShort(cp.getClass(dotToSlash(typeName))); 523 524 out.writeByte(opc_areturn); 525 } 526 } 527 528 protected int getBytesForUnwrapReturn(String typeName) { 529 if (PrimitiveTypeInfo.get(typeName) != null) { 530 return 13; 531 } else { 532 return 4; 533 } 534 } 535 536 protected StorableObject getAttrType(StorableObject attr) { 537 try { 538 StorableObject curType = (StorableObject) attr.getReference(MOFConstants.SH_MODEL_TYPED_ELEMENT_TYPE); 539 String typeName = (String ) curType.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME); 540 if (typeName.equals(MOFConstants.SH_MODEL_ALIAS_TYPE)) 541 curType = getAttrType(curType); 542 return curType; 543 } catch (Exception e) { 544 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 545 } 546 } 547 548 protected String getAttrTypeName(StorableObject attr) { 550 try { 551 MultiplicityType mp = (MultiplicityType) attr.getAttribute(MOFConstants.SH_MODEL_STRUCTURAL_FEATURE_MULTIPLICITY); 552 553 if (mp.getUpper() > 1 || mp.getUpper() == -1) { 554 return (mp.isOrdered() ? DT_ORDERED : DT_MULTIVALUED); 555 } else if (mp.getLower() < 1) { 556 return TagSupport.getDataTypeName(getAttrType(attr)); 557 } else { 558 return getTypeName2(attr); 559 } 560 } catch (Exception e) { 561 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 562 } 563 } 564 565 protected String getTypeName2(StorableObject te) { 566 return getPrimitiveName(TagSupport.getDataTypeName(getAttrType(te))); 567 } 568 569 protected String getPrimitiveName(String typeName) { 571 String name = (String ) objectToPrimitive.get(typeName); 572 return name == null ? typeName : name; 573 } 574 575 protected static final HashMap objectToPrimitive = new HashMap(7); 577 static { 578 objectToPrimitive.put("java.lang.Short", "short"); objectToPrimitive.put("java.lang.Integer", "int"); objectToPrimitive.put("java.lang.Float", "float"); objectToPrimitive.put("java.lang.Double", "double"); objectToPrimitive.put("java.lang.Boolean", "boolean"); objectToPrimitive.put("java.lang.Character", "char"); objectToPrimitive.put("java.lang.Long", "long"); } 586 587 protected MethodInfo getDispatcherMethod(String methodName, String [] parameterTypes, String returnType, HashMap features) throws IOException { 588 String desc = getMethodDescriptor(parameterTypes, returnType); 589 MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL); 590 int[] parameterSlot = new int[parameterTypes.length]; 591 int nextSlot = 1; 592 for (int i = 0; i < parameterSlot.length; i++) { 593 parameterSlot[i] = nextSlot; 594 nextSlot += getWordsPerType(parameterTypes[i]); 595 } 596 int localSlot0 = nextSlot; 597 int maxStack = 0; 598 599 DataOutputStream out = new DataOutputStream (minfo.getCodeStream()); 600 601 for (Iterator it = features.keySet().iterator(); it.hasNext();) { 602 String featureName = (String ) it.next(); 603 MethodDescHolder item = (MethodDescHolder) features.get(featureName); 604 605 code_ldc(cp.getString(featureName), out); 607 608 code_aload(1, out); 610 out.writeByte(opc_invokevirtual); 611 out.writeShort(cp.getMethodRef("java/lang/String", "equals", "(Ljava/lang/Object;)Z")); 613 out.writeByte(opc_ifeq); 615 out.writeShort(7 + getBytesForArgUnwrap(methodName, item.getParameterTypes()) + getBytesForReturn(methodName, item.getReturnType()) + getBytesForPreReturn(item.getReturnType())); 616 codePreReturn(item.getReturnType(), out); 618 out.writeByte(opc_aload_0); 619 codeUnwrapArguments(methodName, item.getParameterTypes(), out); 620 out.writeByte(opc_invokevirtual); 621 out.writeShort(cp.getMethodRef(dotToSlash(className), item.getName(), getMethodDescriptor(item.getParameterTypes(), item.getReturnType()))); 622 codeReturn(methodName, item.getReturnType(), out); 623 if (item.getParameterTypes().length > maxStack) 624 maxStack = item.getParameterTypes().length; 625 } 626 short tryStop = (short) out.size(); 627 628 out.writeByte(opc_new); out.writeShort(cp.getClass("javax/jmi/reflect/InvalidNameException")); out.writeByte(opc_dup); code_aload(1, out); 633 out.writeByte(opc_invokespecial); 634 out.writeShort(cp.getMethodRef("javax/jmi/reflect/InvalidNameException", "<init>", "(Ljava/lang/String;)V")); out.writeByte(opc_athrow); 636 637 if (tryStop != 0) { 638 short catchStart = (short) out.size(); 639 640 code_astore(localSlot0, out); 641 out.writeByte(opc_new); 642 out.writeShort(cp.getClass("javax/jmi/reflect/TypeMismatchException")); out.writeByte(opc_dup); 644 out.writeByte(opc_aconst_null); 645 out.writeByte(opc_dup); 646 out.writeByte(opc_dup); 647 out.writeByte(opc_invokespecial); 648 out.writeShort(cp.getMethodRef("javax/jmi/reflect/TypeMismatchException", "<init>", "(Ljava/lang/Class;Ljava/lang/Object;Ljavax/jmi/reflect/RefObject;)V")); out.writeByte(opc_athrow); 650 651 minfo.getExceptionTable().add(new ExceptionTableEntry((short)0, tryStop, catchStart, cp.getClass("java/lang/ClassCastException"))); } 653 minfo.setMaxStack((short)(maxStack + 6)); 654 minfo.setMaxLocals((short) (localSlot0 + 2)); 655 656 return minfo; 657 } 658 659 protected void codeUnwrapArguments(String methodName, String [] paramTypeNames, DataOutputStream out) throws IOException { 660 if (methodName.equals("_invokeOperation") || methodName.equals("_createStruct")) { code_aload(2, out); 662 out.writeByte(opc_arraylength); 663 code_ipush(paramTypeNames.length, out); 664 out.writeByte(opc_if_icmpeq); 665 out.writeShort(12); 666 out.writeByte(opc_new); 667 out.writeShort(cp.getClass("javax/jmi/reflect/WrongSizeException")); out.writeByte(opc_dup); 669 out.writeByte(opc_aconst_null); 670 out.writeByte(opc_invokespecial); 671 out.writeShort(cp.getMethodRef("javax/jmi/reflect/WrongSizeException", "<init>", "(Ljavax/jmi/reflect/RefObject;)V")); out.writeByte(opc_athrow); 673 for (int i = 0; i < paramTypeNames.length; i++) { 674 code_aload(2, out); 675 out.writeByte(opc_sipush); 676 out.writeShort(i & 0xFFFF); 677 out.writeByte(opc_aaload); 678 codeUnwrapArgument(paramTypeNames[i], out); 679 } 680 } else { 681 for (int i = 0; i < paramTypeNames.length; i++) { 682 out.writeByte(opc_aload); 683 out.writeByte(i + 2); 684 codeUnwrapArgument(paramTypeNames[i], out); 685 } 686 } 687 } 688 689 protected void codeUnwrapArgument(String typeName, DataOutputStream out) throws IOException { 690 PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName); 691 if (prim != null) { 692 out.writeByte(opc_checkcast); 693 out.writeShort(cp.getClass(prim.wrapperClassName)); 694 695 out.writeByte(opc_invokevirtual); 696 out.writeShort(cp.getMethodRef( 697 prim.wrapperClassName, 698 prim.unwrapMethodName, prim.unwrapMethodDesc)); 699 } else { 700 out.writeByte(opc_checkcast); 701 out.writeShort(cp.getClass(getParamType(typeName))); 702 } 703 } 704 705 protected static String getParamType(String typeName) { 706 if (typeName.endsWith("[]")) return "[" + getFieldType(typeName.substring(0, typeName.length()-2).trim()); else 709 return dotToSlash(typeName); 710 } 711 712 713 protected int getBytesForArgUnwrap(String methodName, String [] parameterTypeNames) { 714 int result = 0; 715 if (methodName.equals("_invokeOperation") || methodName.equals("_createStruct")) { result += 14 + getBytesForIPush(parameterTypeNames.length); 717 for (int i = 0; i < parameterTypeNames.length; i++) { 718 result += 5; 719 result += getBytesForOneArgUnwrap(parameterTypeNames[i]); 720 } 721 } else { 722 for (int i = 0; i < parameterTypeNames.length; i++) { 723 result += 2; 724 result += getBytesForOneArgUnwrap(parameterTypeNames[i]); 725 } 726 } 727 return result; 728 } 729 730 protected int getBytesForOneArgUnwrap(String typeName) { 731 if (PrimitiveTypeInfo.get(typeName) != null) 732 return 6; 733 else 734 return 3; 735 } 736 737 protected int getBytesForIPush(int value) { 738 if (value >= -1 && value <= 5) 739 return 1; 740 if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) 741 return 2; 742 return 3; 743 } 744 745 protected int getBytesForReturn(String methodName, String typeName) { 746 if (typeName.equals("void")) { return (methodName.equals("_invokeOperation") ? 2 : 1); } else if (PrimitiveTypeInfo.get(typeName) != null) { 749 return 4; 750 } else { 751 return 1; 752 } 753 } 754 755 protected int getBytesForPreReturn(String typeName) { 756 if (!"void".equals(typeName) && !"boolean".equals(typeName) && (PrimitiveTypeInfo.get(typeName) != null)) { return 4; 758 } else { 759 return 0; 760 } 761 } 762 763 protected void codePreReturn(String typeName, DataOutputStream out) throws IOException { 764 PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName); 765 if (!"void".equals(typeName) && !"boolean".equals(typeName) && (prim != null)) { out.writeByte(opc_new); 767 out.writeShort(cp.getClass(prim.wrapperClassName)); 768 out.writeByte(opc_dup); 769 } 770 } 771 772 protected void codeReturn(String methodName, String typeName, DataOutputStream out) throws IOException { 773 if (typeName.equals("void")) { if (methodName.equals("_invokeOperation")) { out.writeByte(opc_aconst_null); 776 out.writeByte(opc_areturn); 777 } else { 778 out.writeByte(opc_return); 779 } 780 } else { 781 PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName); 782 if (prim != null) { 783 if ("boolean".equals(typeName)) { 784 out.writeByte(opc_invokestatic); 785 out.writeShort(cp.getMethodRef("java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;")); 786 } else { 787 out.writeByte(opc_invokespecial); 788 out.writeShort(cp.getMethodRef(prim.wrapperClassName, "<init>", prim.wrapperConstructorDesc)); } 790 } 791 out.writeByte(opc_areturn); 792 } 793 } 794 795 796 protected class MethodDescHolder { 797 798 private String name; 799 private String [] params; 800 private String ret; 801 802 public MethodDescHolder(String methodName, String []parameterTypes, String returnType) { 803 name = methodName; 804 params = parameterTypes; 805 ret = returnType; 806 } 807 808 public String getName() { 809 return name; 810 } 811 812 public String [] getParameterTypes() { 813 return params; 814 } 815 816 public String getReturnType() { 817 return ret; 818 } 819 } 820 } 821 | Popular Tags |