295 NA, // putfield = 181 (0xb5)
296 NA, // invokevirtual = 182 (0xb6)
297 NA, // invokespecial = 183 (0xb7)
298 NA, // invokestatic = 184 (0xb8)
299 NA, // invokeinterface = 185 (0xb9)
300 NA, // invokedynamic = 186 (0xba)
301 1, // new = 187 (0xbb)
302 0, // newarray = 188 (0xbc)
303 0, // anewarray = 189 (0xbd)
304 0, // arraylength = 190 (0xbe)
305 NA, // athrow = 191 (0xbf)
306 0, // checkcast = 192 (0xc0)
307 0, // instanceof = 193 (0xc1)
308 -1, // monitorenter = 194 (0xc2)
309 -1, // monitorexit = 195 (0xc3)
310 NA, // wide = 196 (0xc4)
311 NA, // multianewarray = 197 (0xc5)
312 -1, // ifnull = 198 (0xc6)
313 -1, // ifnonnull = 199 (0xc7)
314 NA, // goto_w = 200 (0xc8)
315 NA // jsr_w = 201 (0xc9)
316 };
317
318 /** Where the constants used in this MethodWriter must be stored. */
319 private final SymbolTable symbolTable;
320
321 // Note: fields are ordered as in the method_info structure, and those related to attributes are
322 // ordered as in Section 4.7 of the JVMS.
323
324 /**
325 * The access_flags field of the method_info JVMS structure. This field can contain ASM specific
326 * access flags, such as {@link Opcodes#ACC_DEPRECATED}, which are removed when generating the
327 * ClassFile structure.
328 */
329 private final int accessFlags;
330
331 /** The name_index field of the method_info JVMS structure. */
332 private final int nameIndex;
333
334 /** The name of this method. */
335 private final String name;
991 // theory, a basic block (since execution can jump from this instruction to the exception
992 // handler). As a consequence, the local variable types at the beginning of the handler
993 // block should be the merge of the local variable types at all the instructions within the
994 // handler range. However, instead of creating a basic block for each instruction, we can
995 // get the same result in a more efficient way. Namely, by starting a new basic block after
996 // each xSTORE instruction, which is what we do here.
997 visitLabel(new Label());
998 }
999 }
1000
1001 @Override
1002 public void visitTypeInsn(final int opcode, final String type) {
1003 lastBytecodeOffset = code.length;
1004 // Add the instruction to the bytecode of the method.
1005 Symbol typeSymbol = symbolTable.addConstantClass(type);
1006 code.put12(opcode, typeSymbol.index);
1007 // If needed, update the maximum stack size and number of locals, and stack map frames.
1008 if (currentBasicBlock != null) {
1009 if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
1010 currentBasicBlock.frame.execute(opcode, lastBytecodeOffset, typeSymbol, symbolTable);
1011 } else if (opcode == Opcodes.NEW) {
1012 // The stack size delta is 1 for NEW, and 0 for ANEWARRAY, CHECKCAST, or INSTANCEOF.
1013 int size = relativeStackSize + 1;
1014 if (size > maxRelativeStackSize) {
1015 maxRelativeStackSize = size;
1016 }
1017 relativeStackSize = size;
1018 }
1019 }
1020 }
1021
1022 @Override
1023 public void visitFieldInsn(
1024 final int opcode, final String owner, final String name, final String descriptor) {
1025 lastBytecodeOffset = code.length;
1026 // Add the instruction to the bytecode of the method.
1027 Symbol fieldrefSymbol = symbolTable.addConstantFieldref(owner, name, descriptor);
1028 code.put12(opcode, fieldrefSymbol.index);
1029 // If needed, update the maximum stack size and number of locals, and stack map frames.
1030 if (currentBasicBlock != null) {
1031 if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
1032 currentBasicBlock.frame.execute(opcode, 0, fieldrefSymbol, symbolTable);
1033 } else {
1034 int size;
1035 char firstDescChar = descriptor.charAt(0);
1036 switch (opcode) {
1037 case Opcodes.GETSTATIC:
1038 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? 2 : 1);
1039 break;
1040 case Opcodes.PUTSTATIC:
1041 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? -2 : -1);
1042 break;
1043 case Opcodes.GETFIELD:
1044 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? 1 : 0);
1045 break;
1046 case Opcodes.PUTFIELD:
1047 default:
1048 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? -3 : -2);
1049 break;
1050 }
1051 if (size > maxRelativeStackSize) {
1052 maxRelativeStackSize = size;
1053 }
1054 relativeStackSize = size;
1055 }
1056 }
|
295 NA, // putfield = 181 (0xb5)
296 NA, // invokevirtual = 182 (0xb6)
297 NA, // invokespecial = 183 (0xb7)
298 NA, // invokestatic = 184 (0xb8)
299 NA, // invokeinterface = 185 (0xb9)
300 NA, // invokedynamic = 186 (0xba)
301 1, // new = 187 (0xbb)
302 0, // newarray = 188 (0xbc)
303 0, // anewarray = 189 (0xbd)
304 0, // arraylength = 190 (0xbe)
305 NA, // athrow = 191 (0xbf)
306 0, // checkcast = 192 (0xc0)
307 0, // instanceof = 193 (0xc1)
308 -1, // monitorenter = 194 (0xc2)
309 -1, // monitorexit = 195 (0xc3)
310 NA, // wide = 196 (0xc4)
311 NA, // multianewarray = 197 (0xc5)
312 -1, // ifnull = 198 (0xc6)
313 -1, // ifnonnull = 199 (0xc7)
314 NA, // goto_w = 200 (0xc8)
315 NA, // jsr_w = 201 (0xc9)
316 NA, // breakpoint = 202 (0xca)
317 NA, // default = 203 (0xcb)
318 NA, // withfield = 204 (0xcc)
319 };
320
321 /** Where the constants used in this MethodWriter must be stored. */
322 private final SymbolTable symbolTable;
323
324 // Note: fields are ordered as in the method_info structure, and those related to attributes are
325 // ordered as in Section 4.7 of the JVMS.
326
327 /**
328 * The access_flags field of the method_info JVMS structure. This field can contain ASM specific
329 * access flags, such as {@link Opcodes#ACC_DEPRECATED}, which are removed when generating the
330 * ClassFile structure.
331 */
332 private final int accessFlags;
333
334 /** The name_index field of the method_info JVMS structure. */
335 private final int nameIndex;
336
337 /** The name of this method. */
338 private final String name;
994 // theory, a basic block (since execution can jump from this instruction to the exception
995 // handler). As a consequence, the local variable types at the beginning of the handler
996 // block should be the merge of the local variable types at all the instructions within the
997 // handler range. However, instead of creating a basic block for each instruction, we can
998 // get the same result in a more efficient way. Namely, by starting a new basic block after
999 // each xSTORE instruction, which is what we do here.
1000 visitLabel(new Label());
1001 }
1002 }
1003
1004 @Override
1005 public void visitTypeInsn(final int opcode, final String type) {
1006 lastBytecodeOffset = code.length;
1007 // Add the instruction to the bytecode of the method.
1008 Symbol typeSymbol = symbolTable.addConstantClass(type);
1009 code.put12(opcode, typeSymbol.index);
1010 // If needed, update the maximum stack size and number of locals, and stack map frames.
1011 if (currentBasicBlock != null) {
1012 if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
1013 currentBasicBlock.frame.execute(opcode, lastBytecodeOffset, typeSymbol, symbolTable);
1014 } else if (opcode == Opcodes.NEW || opcode == Opcodes.DEFAULT) {
1015 // The stack size delta is 1 for NEW, and 0 for ANEWARRAY, CHECKCAST, or INSTANCEOF.
1016 int size = relativeStackSize + 1;
1017 if (size > maxRelativeStackSize) {
1018 maxRelativeStackSize = size;
1019 }
1020 relativeStackSize = size;
1021 }
1022 }
1023 }
1024
1025 @Override
1026 public void visitFieldInsn(
1027 final int opcode, final String owner, final String name, final String descriptor) {
1028 lastBytecodeOffset = code.length;
1029 // Add the instruction to the bytecode of the method.
1030 Symbol fieldrefSymbol = symbolTable.addConstantFieldref(owner, name, descriptor);
1031 code.put12(opcode, fieldrefSymbol.index);
1032 // If needed, update the maximum stack size and number of locals, and stack map frames.
1033 if (currentBasicBlock != null) {
1034 if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
1035 currentBasicBlock.frame.execute(opcode, 0, fieldrefSymbol, symbolTable);
1036 } else {
1037 int size;
1038 char firstDescChar = descriptor.charAt(0);
1039 switch (opcode) {
1040 case Opcodes.WITHFIELD:
1041 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? -2 : -1);
1042 break;
1043 case Opcodes.GETSTATIC:
1044 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? 2 : 1);
1045 break;
1046 case Opcodes.PUTSTATIC:
1047 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? -2 : -1);
1048 break;
1049 case Opcodes.GETFIELD:
1050 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? 1 : 0);
1051 break;
1052 case Opcodes.PUTFIELD:
1053 default:
1054 size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? -3 : -2);
1055 break;
1056 }
1057 if (size > maxRelativeStackSize) {
1058 maxRelativeStackSize = size;
1059 }
1060 relativeStackSize = size;
1061 }
1062 }
|