@Override public void visitTypeInsn(final int opcode, final String type) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. Symbol typeSymbol = symbolTable.addConstantClass(type); code.put12(opcode, typeSymbol.index); // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) { currentBasicBlock.frame.execute(opcode, lastBytecodeOffset, typeSymbol, symbolTable); } else if (opcode == Opcodes.NEW) { // The stack size delta is 1 for NEW, and 0 for ANEWARRAY, CHECKCAST, or INSTANCEOF. int size = relativeStackSize + 1; if (size > maxRelativeStackSize) { maxRelativeStackSize = size; } relativeStackSize = size; } } }
@Override public void visitInsn(final int opcode) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. code.putByte(opcode); // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) { currentBasicBlock.frame.execute(opcode, 0, null, null); } else { int size = relativeStackSize + STACK_SIZE_DELTA[opcode]; if (size > maxRelativeStackSize) { maxRelativeStackSize = size; } relativeStackSize = size; } if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) { endCurrentBasicBlockWithNoSuccessor(); } } }
@Override public void visitIntInsn(final int opcode, final int operand) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. if (opcode == Opcodes.SIPUSH) { code.put12(opcode, operand); } else { // BIPUSH or NEWARRAY code.put11(opcode, operand); } // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) { currentBasicBlock.frame.execute(opcode, operand, null, null); } else if (opcode != Opcodes.NEWARRAY) { // The stack size delta is 1 for BIPUSH or SIPUSH, and 0 for NEWARRAY. int size = relativeStackSize + 1; if (size > maxRelativeStackSize) { maxRelativeStackSize = size; } relativeStackSize = size; } } }
currentBasicBlock.frame.execute(opcode, 0, fieldrefSymbol, symbolTable); } else { int size;
/** * Sets this CurrentFrame to the input stack map frame of the next "current" instruction, i.e. the * instruction just after the given one. It is assumed that the value of this object when this * method is called is the stack map frame status just before the given instruction is executed. */ @Override void execute( final int opcode, final int arg, final Symbol symbolArg, final SymbolTable symbolTable) { super.execute(opcode, arg, symbolArg, symbolTable); Frame successor = new Frame(null); merge(symbolTable, successor, 0); copyFrom(successor); } }
@Override public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. Symbol descSymbol = symbolTable.addConstantClass(descriptor); code.put12(Opcodes.MULTIANEWARRAY, descSymbol.index).putByte(numDimensions); // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) { currentBasicBlock.frame.execute( Opcodes.MULTIANEWARRAY, numDimensions, descSymbol, symbolTable); } else { // No need to update maxRelativeStackSize (the stack size delta is always negative). relativeStackSize += 1 - numDimensions; } } }
currentBasicBlock.frame.execute(Opcodes.LDC, 0, constantSymbol, symbolTable); } else { int size = relativeStackSize + (isLongOrDouble ? 2 : 1);
@Override public void visitInvokeDynamicInsn( final String name, final String descriptor, final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. Symbol invokeDynamicSymbol = symbolTable.addConstantInvokeDynamic( name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); code.put12(Opcodes.INVOKEDYNAMIC, invokeDynamicSymbol.index); code.putShort(0); // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) { currentBasicBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, invokeDynamicSymbol, symbolTable); } else { int argumentsAndReturnSize = invokeDynamicSymbol.getArgumentsAndReturnSizes(); int stackSizeDelta = (argumentsAndReturnSize & 3) - (argumentsAndReturnSize >> 2) + 1; int size = relativeStackSize + stackSizeDelta; if (size > maxRelativeStackSize) { maxRelativeStackSize = size; } relativeStackSize = size; } } }
@Override public void visitIincInsn(final int var, final int increment) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. if ((var > 255) || (increment > 127) || (increment < -128)) { code.putByte(Constants.WIDE).put12(Opcodes.IINC, var).putShort(increment); } else { code.putByte(Opcodes.IINC).put11(var, increment); } // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null && (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES)) { currentBasicBlock.frame.execute(Opcodes.IINC, var, null, null); } if (compute != COMPUTE_NOTHING) { int currentMaxLocals = var + 1; if (currentMaxLocals > maxLocals) { maxLocals = currentMaxLocals; } } }
currentBasicBlock.frame.execute(opcode, var, null, null); } else { if (opcode == Opcodes.RET) {
currentBasicBlock.frame.execute(opcode, 0, methodrefSymbol, symbolTable); } else { int argumentsAndReturnSize = methodrefSymbol.getArgumentsAndReturnSizes();
private void visitSwitchInsn(final Label dflt, final Label[] labels) { if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES) { currentBasicBlock.frame.execute(Opcodes.LOOKUPSWITCH, 0, null, null); // Add all the labels as successors of the current basic block. addSuccessorToCurrentBasicBlock(Edge.JUMP, dflt); dflt.getCanonicalInstance().flags |= Label.FLAG_JUMP_TARGET; for (Label label : labels) { addSuccessorToCurrentBasicBlock(Edge.JUMP, label); label.getCanonicalInstance().flags |= Label.FLAG_JUMP_TARGET; } } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL) { // No need to update maxRelativeStackSize (the stack size delta is always negative). --relativeStackSize; // Add all the labels as successors of the current basic block. addSuccessorToCurrentBasicBlock(relativeStackSize, dflt); for (Label label : labels) { addSuccessorToCurrentBasicBlock(relativeStackSize, label); } } // End the current basic block. endCurrentBasicBlockWithNoSuccessor(); } }
/** * Sets this CurrentFrame to the input stack map frame of the next "current" instruction, i.e. the * instruction just after the given one. It is assumed that the value of this object when this * method is called is the stack map frame status just before the given instruction is executed. */ @Override void execute( final int opcode, final int arg, final Symbol symbolArg, final SymbolTable symbolTable) { super.execute(opcode, arg, symbolArg, symbolTable); Frame successor = new Frame(null); merge(symbolTable, successor, 0); copyFrom(successor); } }
/** * Sets this CurrentFrame to the input stack map frame of the next "current" * instruction, i.e. the instruction just after the given one. It is assumed * that the value of this object when this method is called is the stack map * frame status just before the given instruction is executed. */ @Override void execute(int opcode, int arg, ClassWriter cw, Item item) { super.execute(opcode, arg, cw, item); Frame successor = new Frame(); merge(cw, successor, 0); set(successor); owner.inputStackTop = 0; } }
/** * Sets this CurrentFrame to the input stack map frame of the next "current" instruction, i.e. the * instruction just after the given one. It is assumed that the value of this object when this * method is called is the stack map frame status just before the given instruction is executed. */ @Override void execute( final int opcode, final int arg, final Symbol symbolArg, final SymbolTable symbolTable) { super.execute(opcode, arg, symbolArg, symbolTable); Frame successor = new Frame(null); merge(symbolTable, successor, 0); copyFrom(successor); } }
/** * Sets this CurrentFrame to the input stack map frame of the next "current" instruction, i.e. the * instruction just after the given one. It is assumed that the value of this object when this * method is called is the stack map frame status just before the given instruction is executed. */ @Override void execute( final int opcode, final int arg, final Symbol symbolArg, final SymbolTable symbolTable) { super.execute(opcode, arg, symbolArg, symbolTable); Frame successor = new Frame(null); merge(symbolTable, successor, 0); copyFrom(successor); } }
@Override public void visitMultiANewArrayInsn(final String desc, final int dims) { lastCodeOffset = code.length; Item i = cw.newClassItem(desc); // Label currentBlock = this.currentBlock; if (currentBlock != null) { if (compute == FRAMES || compute == INSERTED_FRAMES) { currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i); } else { // updates current stack size (max stack size unchanged because // stack size variation always negative or null) stackSize += 1 - dims; } } // adds the instruction to the bytecode of the method code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims); }
@Override public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. Symbol descSymbol = symbolTable.addConstantClass(descriptor); code.put12(Opcodes.MULTIANEWARRAY, descSymbol.index).putByte(numDimensions); // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) { currentBasicBlock.frame.execute( Opcodes.MULTIANEWARRAY, numDimensions, descSymbol, symbolTable); } else { // No need to update maxRelativeStackSize (the stack size delta is always negative). relativeStackSize += 1 - numDimensions; } } }
@Override public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. Symbol descSymbol = symbolTable.addConstantClass(descriptor); code.put12(Opcodes.MULTIANEWARRAY, descSymbol.index).putByte(numDimensions); // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) { currentBasicBlock.frame.execute( Opcodes.MULTIANEWARRAY, numDimensions, descSymbol, symbolTable); } else { // No need to update maxRelativeStackSize (the stack size delta is always negative). relativeStackSize += 1 - numDimensions; } } }