/** * Visits an instruction with a single int operand. * * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH * or NEWARRAY. * @param operand the operand of the instruction to be visited.<br> * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE. * <br> * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE. * <br> * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link * Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE}, * {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. */ public void visitIntInsn(final int opcode, final int operand) { if (mv != null) { mv.visitIntInsn(opcode, operand); } }
/** * Visits an instruction with a single int operand. * * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH * or NEWARRAY. * @param operand the operand of the instruction to be visited.<br> * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE. * <br> * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE. * <br> * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link * Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE}, * {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. */ public void visitIntInsn(final int opcode, final int operand) { if (mv != null) { mv.visitIntInsn(opcode, operand); } }
/** * Create the optimal instruction for loading a number on the stack. * @param mv where to insert the bytecode * @param value the value to be loaded */ public static void insertOptimalLoad(MethodVisitor mv, int value) { if (value < 6) { mv.visitInsn(ICONST_0+value); } else if (value < Byte.MAX_VALUE) { mv.visitIntInsn(BIPUSH, value); } else if (value < Short.MAX_VALUE) { mv.visitIntInsn(SIPUSH, value); } else { mv.visitLdcInsn(value); } }
/** * Create the optimal instruction for loading a number on the stack. * @param mv where to insert the bytecode * @param value the value to be loaded */ public static void insertOptimalLoad(MethodVisitor mv, int value) { if (value < 6) { mv.visitInsn(ICONST_0+value); } else if (value < Byte.MAX_VALUE) { mv.visitIntInsn(BIPUSH, value); } else if (value < Short.MAX_VALUE) { mv.visitIntInsn(SIPUSH, value); } else { mv.visitLdcInsn(value); } }
/** * Produce the correct bytecode to build an array. The opcode to use and the * signature to pass along with the opcode can vary depending on the signature * of the array type. * @param mv the methodvisitor into which code should be inserted * @param size the size of the array * @param arraytype the type of the array */ public static void insertNewArrayCode(MethodVisitor mv, int size, String arraytype) { insertOptimalLoad(mv, size); if (arraytype.length() == 1) { mv.visitIntInsn(NEWARRAY, CodeFlow.arrayCodeFor(arraytype)); } else { if (arraytype.charAt(0) == '[') { // Handling the nested array case here. // If vararg is [[I then we want [I and not [I; if (CodeFlow.isReferenceTypeArray(arraytype)) { mv.visitTypeInsn(ANEWARRAY, arraytype + ";"); } else { mv.visitTypeInsn(ANEWARRAY, arraytype); } } else { mv.visitTypeInsn(ANEWARRAY, arraytype.substring(1)); } } }
/** * Produce the correct bytecode to build an array. The opcode to use and the * signature to pass along with the opcode can vary depending on the signature * of the array type. * @param mv the methodvisitor into which code should be inserted * @param size the size of the array * @param arraytype the type of the array */ public static void insertNewArrayCode(MethodVisitor mv, int size, String arraytype) { insertOptimalLoad(mv, size); if (arraytype.length() == 1) { mv.visitIntInsn(NEWARRAY, CodeFlow.arrayCodeFor(arraytype)); } else { if (arraytype.charAt(0) == '[') { // Handling the nested array case here. // If vararg is [[I then we want [I and not [I; if (CodeFlow.isReferenceTypeArray(arraytype)) { mv.visitTypeInsn(ANEWARRAY, arraytype + ";"); } else { mv.visitTypeInsn(ANEWARRAY, arraytype); } } else { mv.visitTypeInsn(ANEWARRAY, arraytype.substring(1)); } } }
case Constants.BIPUSH: case Constants.NEWARRAY: methodVisitor.visitIntInsn(opcode, classFileBuffer[currentOffset + 1]); currentOffset += 2; break; case Constants.SIPUSH: methodVisitor.visitIntInsn(opcode, readShort(currentOffset + 1)); currentOffset += 3; break;
case Constants.BIPUSH: case Constants.NEWARRAY: methodVisitor.visitIntInsn(opcode, classFileBuffer[currentOffset + 1]); currentOffset += 2; break; case Constants.SIPUSH: methodVisitor.visitIntInsn(opcode, readShort(currentOffset + 1)); currentOffset += 3; break;
/** * Visits an instruction with a single int operand. * * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH * or NEWARRAY. * @param operand the operand of the instruction to be visited.<br> * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE. * <br> * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE. * <br> * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link * Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE}, * {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. */ public void visitIntInsn(final int opcode, final int operand) { if (mv != null) { mv.visitIntInsn(opcode, operand); } }
/** * Visits an instruction with a single int operand. * * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH * or NEWARRAY. * @param operand the operand of the instruction to be visited.<br> * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE. * <br> * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE. * <br> * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link * Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE}, * {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. */ public void visitIntInsn(final int opcode, final int operand) { if (mv != null) { mv.visitIntInsn(opcode, operand); } }
/** * Create the optimal instruction for loading a number on the stack. * @param mv where to insert the bytecode * @param value the value to be loaded */ public static void insertOptimalLoad(MethodVisitor mv, int value) { if (value < 6) { mv.visitInsn(ICONST_0+value); } else if (value < Byte.MAX_VALUE) { mv.visitIntInsn(BIPUSH, value); } else if (value < Short.MAX_VALUE) { mv.visitIntInsn(SIPUSH, value); } else { mv.visitLdcInsn(value); } }
/** * Produce the correct bytecode to build an array. The opcode to use and the * signature to pass along with the opcode can vary depending on the signature * of the array type. * @param mv the methodvisitor into which code should be inserted * @param size the size of the array * @param arraytype the type of the array */ public static void insertNewArrayCode(MethodVisitor mv, int size, String arraytype) { insertOptimalLoad(mv, size); if (arraytype.length() == 1) { mv.visitIntInsn(NEWARRAY, CodeFlow.arrayCodeFor(arraytype)); } else { if (arraytype.charAt(0) == '[') { // Handling the nested array case here. // If vararg is [[I then we want [I and not [I; if (CodeFlow.isReferenceTypeArray(arraytype)) { mv.visitTypeInsn(ANEWARRAY, arraytype + ";"); } else { mv.visitTypeInsn(ANEWARRAY, arraytype); } } else { mv.visitTypeInsn(ANEWARRAY, arraytype.substring(1)); } } }
mv.visitIntInsn(Opcodes.BIPUSH, 0);
mv.visitIntInsn(Opcodes.SIPUSH, i); });
case Constants.BIPUSH: case Constants.NEWARRAY: methodVisitor.visitIntInsn(opcode, classFileBuffer[currentOffset + 1]); currentOffset += 2; break; case Constants.SIPUSH: methodVisitor.visitIntInsn(opcode, readShort(currentOffset + 1)); currentOffset += 3; break;