1 30 package com.tc.asm.commons; 31 32 import java.util.ArrayList ; 33 import java.util.Arrays ; 34 import java.util.List ; 35 36 import com.tc.asm.ClassVisitor; 37 import com.tc.asm.Label; 38 import com.tc.asm.MethodVisitor; 39 import com.tc.asm.Opcodes; 40 import com.tc.asm.Type; 41 42 82 public class GeneratorAdapter extends LocalVariablesSorter { 83 84 private final static Type BYTE_TYPE = Type.getType("Ljava/lang/Byte;"); 85 86 private final static Type BOOLEAN_TYPE = Type.getType("Ljava/lang/Boolean;"); 87 88 private final static Type SHORT_TYPE = Type.getType("Ljava/lang/Short;"); 89 90 private final static Type CHARACTER_TYPE = Type.getType("Ljava/lang/Character;"); 91 92 private final static Type INTEGER_TYPE = Type.getType("Ljava/lang/Integer;"); 93 94 private final static Type FLOAT_TYPE = Type.getType("Ljava/lang/Float;"); 95 96 private final static Type LONG_TYPE = Type.getType("Ljava/lang/Long;"); 97 98 private final static Type DOUBLE_TYPE = Type.getType("Ljava/lang/Double;"); 99 100 private final static Type NUMBER_TYPE = Type.getType("Ljava/lang/Number;"); 101 102 private final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;"); 103 104 private final static Method BOOLEAN_VALUE = Method.getMethod("boolean booleanValue()"); 105 106 private final static Method CHAR_VALUE = Method.getMethod("char charValue()"); 107 108 private final static Method INT_VALUE = Method.getMethod("int intValue()"); 109 110 private final static Method FLOAT_VALUE = Method.getMethod("float floatValue()"); 111 112 private final static Method LONG_VALUE = Method.getMethod("long longValue()"); 113 114 private final static Method DOUBLE_VALUE = Method.getMethod("double doubleValue()"); 115 116 119 public final static int ADD = Opcodes.IADD; 120 121 124 public final static int SUB = Opcodes.ISUB; 125 126 129 public final static int MUL = Opcodes.IMUL; 130 131 134 public final static int DIV = Opcodes.IDIV; 135 136 139 public final static int REM = Opcodes.IREM; 140 141 144 public final static int NEG = Opcodes.INEG; 145 146 149 public final static int SHL = Opcodes.ISHL; 150 151 154 public final static int SHR = Opcodes.ISHR; 155 156 159 public final static int USHR = Opcodes.IUSHR; 160 161 164 public final static int AND = Opcodes.IAND; 165 166 169 public final static int OR = Opcodes.IOR; 170 171 174 public final static int XOR = Opcodes.IXOR; 175 176 179 public final static int EQ = Opcodes.IFEQ; 180 181 184 public final static int NE = Opcodes.IFNE; 185 186 189 public final static int LT = Opcodes.IFLT; 190 191 194 public final static int GE = Opcodes.IFGE; 195 196 199 public final static int GT = Opcodes.IFGT; 200 201 204 public final static int LE = Opcodes.IFLE; 205 206 209 private final int access; 210 211 214 private final Type returnType; 215 216 219 private final Type[] argumentTypes; 220 221 224 private final List localTypes; 225 226 234 public GeneratorAdapter( 235 MethodVisitor mv, 236 int access, 237 String name, 238 String desc) 239 { 240 super(access, desc, mv); 241 this.access = access; 242 this.returnType = Type.getReturnType(desc); 243 this.argumentTypes = Type.getArgumentTypes(desc); 244 this.localTypes = new ArrayList (); 245 } 246 247 254 public GeneratorAdapter( 255 final int access, 256 final Method method, 257 final MethodVisitor mv) 258 { 259 super(access, method.getDescriptor(), mv); 260 this.access = access; 261 this.returnType = method.getReturnType(); 262 this.argumentTypes = method.getArgumentTypes(); 263 this.localTypes = new ArrayList (); 264 } 265 266 277 public GeneratorAdapter( 278 final int access, 279 final Method method, 280 final String signature, 281 final Type[] exceptions, 282 final ClassVisitor cv) 283 { 284 this(access, method, cv.visitMethod(access, 285 method.getName(), 286 method.getDescriptor(), 287 signature, 288 getInternalNames(exceptions))); 289 } 290 291 297 private static String [] getInternalNames(final Type[] types) { 298 if (types == null) { 299 return null; 300 } 301 String [] names = new String [types.length]; 302 for (int i = 0; i < names.length; ++i) { 303 names[i] = types[i].getInternalName(); 304 } 305 return names; 306 } 307 308 312 317 public void push(final boolean value) { 318 push(value ? 1 : 0); 319 } 320 321 326 public void push(final int value) { 327 if (value >= -1 && value <= 5) { 328 mv.visitInsn(Opcodes.ICONST_0 + value); 329 } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { 330 mv.visitIntInsn(Opcodes.BIPUSH, value); 331 } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { 332 mv.visitIntInsn(Opcodes.SIPUSH, value); 333 } else { 334 mv.visitLdcInsn(new Integer (value)); 335 } 336 } 337 338 343 public void push(final long value) { 344 if (value == 0L || value == 1L) { 345 mv.visitInsn(Opcodes.LCONST_0 + (int) value); 346 } else { 347 mv.visitLdcInsn(new Long (value)); 348 } 349 } 350 351 356 public void push(final float value) { 357 int bits = Float.floatToIntBits(value); 358 if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { mv.visitInsn(Opcodes.FCONST_0 + (int) value); 360 } else { 361 mv.visitLdcInsn(new Float (value)); 362 } 363 } 364 365 370 public void push(final double value) { 371 long bits = Double.doubleToLongBits(value); 372 if (bits == 0L || bits == 0x3ff0000000000000L) { mv.visitInsn(Opcodes.DCONST_0 + (int) value); 374 } else { 375 mv.visitLdcInsn(new Double (value)); 376 } 377 } 378 379 384 public void push(final String value) { 385 if (value == null) { 386 mv.visitInsn(Opcodes.ACONST_NULL); 387 } else { 388 mv.visitLdcInsn(value); 389 } 390 } 391 392 397 public void push(final Type value) { 398 if (value == null) { 399 mv.visitInsn(Opcodes.ACONST_NULL); 400 } else { 401 mv.visitLdcInsn(value); 402 } 403 } 404 405 409 417 private int getArgIndex(final int arg) { 418 int index = ((access & Opcodes.ACC_STATIC) == 0 ? 1 : 0); 419 for (int i = 0; i < arg; i++) { 420 index += argumentTypes[i].getSize(); 421 } 422 return index; 423 } 424 425 431 private void loadInsn(final Type type, final int index) { 432 mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), index); 433 } 434 435 442 private void storeInsn(final Type type, final int index) { 443 mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), index); 444 } 445 446 449 public void loadThis() { 450 if ((access & Opcodes.ACC_STATIC) != 0) { 451 throw new IllegalStateException ("no 'this' pointer within static method"); 452 } 453 mv.visitVarInsn(Opcodes.ALOAD, 0); 454 } 455 456 461 public void loadArg(final int arg) { 462 loadInsn(argumentTypes[arg], getArgIndex(arg)); 463 } 464 465 472 public void loadArgs(final int arg, final int count) { 473 int index = getArgIndex(arg); 474 for (int i = 0; i < count; ++i) { 475 Type t = argumentTypes[arg + i]; 476 loadInsn(t, index); 477 index += t.getSize(); 478 } 479 } 480 481 484 public void loadArgs() { 485 loadArgs(0, argumentTypes.length); 486 } 487 488 492 public void loadArgArray() { 493 push(argumentTypes.length); 494 newArray(OBJECT_TYPE); 495 for (int i = 0; i < argumentTypes.length; i++) { 496 dup(); 497 push(i); 498 loadArg(i); 499 box(argumentTypes[i]); 500 arrayStore(OBJECT_TYPE); 501 } 502 } 503 504 510 public void storeArg(final int arg) { 511 storeInsn(argumentTypes[arg], getArgIndex(arg)); 512 } 513 514 518 524 public int newLocal(final Type type) { 525 int local = super.newLocal(type.getSize()); 526 setLocalType(local, type); 527 return local; 528 } 529 530 537 public Type getLocalType(final int local) { 538 return (Type) localTypes.get(local - firstLocal); 539 } 540 541 548 private void setLocalType(final int local, final Type type) { 549 int index = local - firstLocal; 550 while (localTypes.size() < index + 1) 551 localTypes.add(null); 552 localTypes.set(index, type); 553 } 554 555 561 public void loadLocal(final int local) { 562 loadInsn(getLocalType(local), local); 563 } 564 565 572 public void loadLocal(final int local, final Type type) { 573 setLocalType(local, type); 574 loadInsn(type, local); 575 } 576 577 584 public void storeLocal(final int local) { 585 storeInsn(getLocalType(local), local); 586 } 587 588 596 public void storeLocal(final int local, final Type type) { 597 setLocalType(local, type); 598 storeInsn(type, local); 599 } 600 601 606 public void arrayLoad(final Type type) { 607 mv.visitInsn(type.getOpcode(Opcodes.IALOAD)); 608 } 609 610 615 public void arrayStore(final Type type) { 616 mv.visitInsn(type.getOpcode(Opcodes.IASTORE)); 617 } 618 619 623 626 public void pop() { 627 mv.visitInsn(Opcodes.POP); 628 } 629 630 633 public void pop2() { 634 mv.visitInsn(Opcodes.POP2); 635 } 636 637 640 public void dup() { 641 mv.visitInsn(Opcodes.DUP); 642 } 643 644 647 public void dup2() { 648 mv.visitInsn(Opcodes.DUP2); 649 } 650 651 654 public void dupX1() { 655 mv.visitInsn(Opcodes.DUP_X1); 656 } 657 658 661 public void dupX2() { 662 mv.visitInsn(Opcodes.DUP_X2); 663 } 664 665 668 public void dup2X1() { 669 mv.visitInsn(Opcodes.DUP2_X1); 670 } 671 672 675 public void dup2X2() { 676 mv.visitInsn(Opcodes.DUP2_X2); 677 } 678 679 682 public void swap() { 683 mv.visitInsn(Opcodes.SWAP); 684 } 685 686 692 public void swap(final Type prev, final Type type) { 693 if (type.getSize() == 1) { 694 if (prev.getSize() == 1) { 695 swap(); } else { 697 dupX2(); 698 pop(); 699 } 700 } else { 701 if (prev.getSize() == 1) { 702 dup2X1(); 703 pop2(); 704 } else { 705 dup2X2(); 706 pop2(); 707 } 708 } 709 } 710 711 715 723 public void math(final int op, final Type type) { 724 mv.visitInsn(type.getOpcode(op)); 725 } 726 727 731 public void not() { 732 mv.visitInsn(Opcodes.ICONST_1); 733 mv.visitInsn(Opcodes.IXOR); 734 } 735 736 742 public void iinc(final int local, final int amount) { 743 mv.visitIincInsn(local, amount); 744 } 745 746 753 public void cast(final Type from, final Type to) { 754 if (from != to) { 755 if (from == Type.DOUBLE_TYPE) { 756 if (to == Type.FLOAT_TYPE) { 757 mv.visitInsn(Opcodes.D2F); 758 } else if (to == Type.LONG_TYPE) { 759 mv.visitInsn(Opcodes.D2L); 760 } else { 761 mv.visitInsn(Opcodes.D2I); 762 cast(Type.INT_TYPE, to); 763 } 764 } else if (from == Type.FLOAT_TYPE) { 765 if (to == Type.DOUBLE_TYPE) { 766 mv.visitInsn(Opcodes.F2D); 767 } else if (to == Type.LONG_TYPE) { 768 mv.visitInsn(Opcodes.F2L); 769 } else { 770 mv.visitInsn(Opcodes.F2I); 771 cast(Type.INT_TYPE, to); 772 } 773 } else if (from == Type.LONG_TYPE) { 774 if (to == Type.DOUBLE_TYPE) { 775 mv.visitInsn(Opcodes.L2D); 776 } else if (to == Type.FLOAT_TYPE) { 777 mv.visitInsn(Opcodes.L2F); 778 } else { 779 mv.visitInsn(Opcodes.L2I); 780 cast(Type.INT_TYPE, to); 781 } 782 } else { 783 if (to == Type.BYTE_TYPE) { 784 mv.visitInsn(Opcodes.I2B); 785 } else if (to == Type.CHAR_TYPE) { 786 mv.visitInsn(Opcodes.I2C); 787 } else if (to == Type.DOUBLE_TYPE) { 788 mv.visitInsn(Opcodes.I2D); 789 } else if (to == Type.FLOAT_TYPE) { 790 mv.visitInsn(Opcodes.I2F); 791 } else if (to == Type.LONG_TYPE) { 792 mv.visitInsn(Opcodes.I2L); 793 } else if (to == Type.SHORT_TYPE) { 794 mv.visitInsn(Opcodes.I2S); 795 } 796 } 797 } 798 } 799 800 804 810 public void box(final Type type) { 811 if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { 812 return; 813 } 814 if (type == Type.VOID_TYPE) { 815 push((String ) null); 816 } else { 817 Type boxed = type; 818 switch (type.getSort()) { 819 case Type.BYTE: 820 boxed = BYTE_TYPE; 821 break; 822 case Type.BOOLEAN: 823 boxed = BOOLEAN_TYPE; 824 break; 825 case Type.SHORT: 826 boxed = SHORT_TYPE; 827 break; 828 case Type.CHAR: 829 boxed = CHARACTER_TYPE; 830 break; 831 case Type.INT: 832 boxed = INTEGER_TYPE; 833 break; 834 case Type.FLOAT: 835 boxed = FLOAT_TYPE; 836 break; 837 case Type.LONG: 838 boxed = LONG_TYPE; 839 break; 840 case Type.DOUBLE: 841 boxed = DOUBLE_TYPE; 842 break; 843 } 844 newInstance(boxed); 845 if (type.getSize() == 2) { 846 dupX2(); 848 dupX2(); 849 pop(); 850 } else { 851 dupX1(); 853 swap(); 854 } 855 invokeConstructor(boxed, new Method("<init>", 856 Type.VOID_TYPE, 857 new Type[] { type })); 858 } 859 } 860 861 867 public void unbox(final Type type) { 868 Type t = NUMBER_TYPE; 869 Method sig = null; 870 switch (type.getSort()) { 871 case Type.VOID: 872 return; 873 case Type.CHAR: 874 t = CHARACTER_TYPE; 875 sig = CHAR_VALUE; 876 break; 877 case Type.BOOLEAN: 878 t = BOOLEAN_TYPE; 879 sig = BOOLEAN_VALUE; 880 break; 881 case Type.DOUBLE: 882 sig = DOUBLE_VALUE; 883 break; 884 case Type.FLOAT: 885 sig = FLOAT_VALUE; 886 break; 887 case Type.LONG: 888 sig = LONG_VALUE; 889 break; 890 case Type.INT: 891 case Type.SHORT: 892 case Type.BYTE: 893 sig = INT_VALUE; 894 } 895 if (sig == null) { 896 checkCast(type); 897 } else { 898 checkCast(t); 899 invokeVirtual(t, sig); 900 } 901 } 902 903 907 912 public Label newLabel() { 913 return new Label(); 914 } 915 916 921 public void mark(final Label label) { 922 mv.visitLabel(label); 923 } 924 925 930 public Label mark() { 931 Label label = new Label(); 932 mv.visitLabel(label); 933 return label; 934 } 935 936 945 public void ifCmp(final Type type, final int mode, final Label label) { 946 int intOp = -1; 947 int jumpMode = mode; 948 switch (mode) { 949 case GE: 950 jumpMode = LT; 951 break; 952 case LE: 953 jumpMode = GT; 954 break; 955 } 956 switch (type.getSort()) { 957 case Type.LONG: 958 mv.visitInsn(Opcodes.LCMP); 959 break; 960 case Type.DOUBLE: 961 mv.visitInsn(Opcodes.DCMPG); 962 break; 963 case Type.FLOAT: 964 mv.visitInsn(Opcodes.FCMPG); 965 break; 966 case Type.ARRAY: 967 case Type.OBJECT: 968 switch (mode) { 969 case EQ: 970 mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label); 971 return; 972 case NE: 973 mv.visitJumpInsn(Opcodes.IF_ACMPNE, label); 974 return; 975 } 976 throw new IllegalArgumentException ("Bad comparison for type " 977 + type); 978 default: 979 switch (mode) { 980 case EQ: 981 intOp = Opcodes.IF_ICMPEQ; 982 break; 983 case NE: 984 intOp = Opcodes.IF_ICMPNE; 985 break; 986 case GE: 987 intOp = Opcodes.IF_ICMPGE; 988 break; 989 case LT: 990 intOp = Opcodes.IF_ICMPLT; 991 break; 992 case LE: 993 intOp = Opcodes.IF_ICMPLE; 994 break; 995 case GT: 996 intOp = Opcodes.IF_ICMPGT; 997 break; 998 } 999 mv.visitJumpInsn(intOp, label); 1000 return; 1001 } 1002 mv.visitJumpInsn(jumpMode, label); 1003 } 1004 1005 1013 public void ifICmp(final int mode, final Label label) { 1014 ifCmp(Type.INT_TYPE, mode, label); 1015 } 1016 1017 1025 public void ifZCmp(final int mode, final Label label) { 1026 mv.visitJumpInsn(mode, label); 1027 } 1028 1029 1035 public void ifNull(final Label label) { 1036 mv.visitJumpInsn(Opcodes.IFNULL, label); 1037 } 1038 1039 1045 public void ifNonNull(final Label label) { 1046 mv.visitJumpInsn(Opcodes.IFNONNULL, label); 1047 } 1048 1049 1054 public void goTo(final Label label) { 1055 mv.visitJumpInsn(Opcodes.GOTO, label); 1056 } 1057 1058 1064 public void ret(final int local) { 1065 mv.visitVarInsn(Opcodes.RET, local); 1066 } 1067 1068 1074 public void tableSwitch( 1075 final int[] keys, 1076 final TableSwitchGenerator generator) 1077 { 1078 float density; 1079 if (keys.length == 0) { 1080 density = 0; 1081 } else { 1082 density = (float) keys.length 1083 / (keys[keys.length - 1] - keys[0] + 1); 1084 } 1085 tableSwitch(keys, generator, density >= 0.5f); 1086 } 1087 1088 1096 public void tableSwitch( 1097 final int[] keys, 1098 final TableSwitchGenerator generator, 1099 final boolean useTable) 1100 { 1101 for (int i = 1; i < keys.length; ++i) { 1102 if (keys[i] < keys[i - 1]) { 1103 throw new IllegalArgumentException ("keys must be sorted ascending"); 1104 } 1105 } 1106 Label def = newLabel(); 1107 Label end = newLabel(); 1108 if (keys.length > 0) { 1109 int len = keys.length; 1110 int min = keys[0]; 1111 int max = keys[len - 1]; 1112 int range = max - min + 1; 1113 if (useTable) { 1114 Label[] labels = new Label[range]; 1115 Arrays.fill(labels, def); 1116 for (int i = 0; i < len; ++i) { 1117 labels[keys[i] - min] = newLabel(); 1118 } 1119 mv.visitTableSwitchInsn(min, max, def, labels); 1120 for (int i = 0; i < range; ++i) { 1121 Label label = labels[i]; 1122 if (label != def) { 1123 mark(label); 1124 generator.generateCase(i + min, end); 1125 } 1126 } 1127 } else { 1128 Label[] labels = new Label[len]; 1129 for (int i = 0; i < len; ++i) { 1130 labels[i] = newLabel(); 1131 } 1132 mv.visitLookupSwitchInsn(def, keys, labels); 1133 for (int i = 0; i < len; ++i) { 1134 mark(labels[i]); 1135 generator.generateCase(keys[i], end); 1136 } 1137 } 1138 } 1139 mark(def); 1140 generator.generateDefault(); 1141 mark(end); 1142 } 1143 1144 1147 public void returnValue() { 1148 mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN)); 1149 } 1150 1151 1155 1163 private void fieldInsn( 1164 final int opcode, 1165 final Type ownerType, 1166 final String name, 1167 final Type fieldType) 1168 { 1169 mv.visitFieldInsn(opcode, 1170 ownerType.getInternalName(), 1171 name, 1172 fieldType.getDescriptor()); 1173 } 1174 1175 1183 public void getStatic(final Type owner, final String name, final Type type) 1184 { 1185 fieldInsn(Opcodes.GETSTATIC, owner, name, type); 1186 } 1187 1188 1195 public void putStatic(final Type owner, final String name, final Type type) 1196 { 1197 fieldInsn(Opcodes.PUTSTATIC, owner, name, type); 1198 } 1199 1200 1208 public void getField(final Type owner, final String name, final Type type) { 1209 fieldInsn(Opcodes.GETFIELD, owner, name, type); 1210 } 1211 1212 1220 public void putField(final Type owner, final String name, final Type type) { 1221 fieldInsn(Opcodes.PUTFIELD, owner, name, type); 1222 } 1223 1224 1228 1235 private void invokeInsn( 1236 final int opcode, 1237 final Type type, 1238 final Method method) 1239 { 1240 String owner = type.getSort() == Type.ARRAY 1241 ? type.getDescriptor() 1242 : type.getInternalName(); 1243 mv.visitMethodInsn(opcode, 1244 owner, 1245 method.getName(), 1246 method.getDescriptor()); 1247 } 1248 1249 1255 public void invokeVirtual(final Type owner, final Method method) { 1256 invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method); 1257 } 1258 1259 1265 public void invokeConstructor(final Type type, final Method method) { 1266 invokeInsn(Opcodes.INVOKESPECIAL, type, method); 1267 } 1268 1269 1275 public void invokeStatic(final Type owner, final Method method) { 1276 invokeInsn(Opcodes.INVOKESTATIC, owner, method); 1277 } 1278 1279 1285 public void invokeInterface(final Type owner, final Method method) { 1286 invokeInsn(Opcodes.INVOKEINTERFACE, owner, method); 1287 } 1288 1289 1293 1299 private void typeInsn(final int opcode, final Type type) { 1300 String desc; 1301 if (type.getSort() == Type.ARRAY) { 1302 desc = type.getDescriptor(); 1303 } else { 1304 desc = type.getInternalName(); 1305 } 1306 mv.visitTypeInsn(opcode, desc); 1307 } 1308 1309 1314 public void newInstance(final Type type) { 1315 typeInsn(Opcodes.NEW, type); 1316 } 1317 1318 1323 public void newArray(final Type type) { 1324 int typ; 1325 switch (type.getSort()) { 1326 case Type.BOOLEAN: 1327 typ = Opcodes.T_BOOLEAN; 1328 break; 1329 case Type.CHAR: 1330 typ = Opcodes.T_CHAR; 1331 break; 1332 case Type.BYTE: 1333 typ = Opcodes.T_BYTE; 1334 break; 1335 case Type.SHORT: 1336 typ = Opcodes.T_SHORT; 1337 break; 1338 case Type.INT: 1339 typ = Opcodes.T_INT; 1340 break; 1341 case Type.FLOAT: 1342 typ = Opcodes.T_FLOAT; 1343 break; 1344 case Type.LONG: 1345 typ = Opcodes.T_LONG; 1346 break; 1347 case Type.DOUBLE: 1348 typ = Opcodes.T_DOUBLE; 1349 break; 1350 default: 1351 typeInsn(Opcodes.ANEWARRAY, type); 1352 return; 1353 } 1354 mv.visitIntInsn(Opcodes.NEWARRAY, typ); 1355 } 1356 1357 1361 1364 public void arrayLength() { 1365 mv.visitInsn(Opcodes.ARRAYLENGTH); 1366 } 1367 1368 1371 public void throwException() { 1372 mv.visitInsn(Opcodes.ATHROW); 1373 } 1374 1375 1382 public void throwException(final Type type, final String msg) { 1383 newInstance(type); 1384 dup(); 1385 push(msg); 1386 invokeConstructor(type, Method.getMethod("void <init> (String)")); 1387 throwException(); 1388 } 1389 1390 1396 public void checkCast(final Type type) { 1397 if (!type.equals(OBJECT_TYPE)) { 1398 typeInsn(Opcodes.CHECKCAST, type); 1399 } 1400 } 1401 1402 1408 public void instanceOf(final Type type) { 1409 typeInsn(Opcodes.INSTANCEOF, type); 1410 } 1411 1412 1415 public void monitorEnter() { 1416 mv.visitInsn(Opcodes.MONITORENTER); 1417 } 1418 1419 1422 public void monitorExit() { 1423 mv.visitInsn(Opcodes.MONITOREXIT); 1424 } 1425 1426 1430 1433 public void endMethod() { 1434 if ((access & Opcodes.ACC_ABSTRACT) == 0) { 1435 mv.visitMaxs(0, 0); 1436 } 1437 } 1438 1439 1447 public void catchException( 1448 final Label start, 1449 final Label end, 1450 final Type exception) 1451 { 1452 mv.visitTryCatchBlock(start, end, mark(), exception.getInternalName()); 1453 } 1454} 1455 | Popular Tags |