public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); ((ProgramMethod) method).attributesAccept(programClass, new CodeAttributeEditorResetter(codeAttributeEditor)); codeAttributeEditor.insertBeforeOffset(0, instructions); codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); }
if (canPerformSimpleReplacements(codeAttribute)) performSimpleReplacements(codeAttribute); updateFrameSizes(clazz, method, codeAttribute); updateInstructions(clazz, method, codeAttribute); removeEmptyExceptions(codeAttribute.exceptionTable, codeAttribute.u2exceptionTableLength); updateFrameSizes(clazz, method, codeAttribute);
public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction) { // Check if the instruction is a nop instruction. if (simpleInstruction.opcode == InstructionConstants.OP_NOP && !codeAttributeEditor.isModified(offset)) { codeAttributeEditor.deleteInstruction(offset); // Visit the instruction, if required. if (extraInstructionVisitor != null) { extraInstructionVisitor.visitSimpleInstruction(clazz, method, codeAttribute, offset, simpleInstruction); } } } }
/** * Makes sure there is a code attribute editor for the given code attribute. */ private void ensureCodeAttributeEditor() { if (codeAttributeEditor == null) { codeAttributeEditor = new CodeAttributeEditor(); codeAttributeEditor.reset(codeLength); } } }
@Override public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { codeAttributeEditor.reset(codeAttribute.u4codeLength); codeAttribute.instructionsAccept(clazz, method, this); if (codeAttributeEditor.isModified()) { codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); } }
codeAttributeEditor.replaceInstruction(offset, instruction); codeAttributeEditor.insertBeforeInstruction(offset, instruction); codeAttributeEditor.insertAfterInstruction(offset, instruction);
codeAttributeEditor.isModified(offset)) codeAttributeEditor.replaceInstruction(instructionSequenceMatcher.matchedInstructionOffset(index), replacementInstructionFactory.create(clazz, codeAttribute, index)); codeAttributeEditor.deleteInstruction(instructionSequenceMatcher.matchedInstructionOffset(index)); codeAttributeEditor.replaceInstruction(instructionSequenceMatcher.matchedInstructionOffset(index), replacementInstructionFactory.create(clazz, codeAttribute, index)); codeAttributeEditor.insertAfterInstruction(instructionSequenceMatcher.matchedInstructionOffset(patternCount - 1), extraInstructions);
codeAttributeEditor.reset(codeLength); if (!isInstructionNecessary(offset)) codeAttributeEditor.deleteInstruction(offset); codeAttributeEditor.insertBeforeInstruction(offset, (Instruction)null); codeAttributeEditor.replaceInstruction(offset, (Instruction)null); codeAttributeEditor.insertAfterInstruction(offset, (Instruction)null); codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);
if (branchTargetFinder.isInstruction(deleteOffset)) codeAttributeEditor.replaceInstruction( deleteOffset, (Instruction)null); codeAttributeEditor.insertBeforeInstruction(deleteOffset, (Instruction)null); codeAttributeEditor.insertAfterInstruction( deleteOffset, (Instruction)null); codeAttributeEditor.deleteInstruction(deleteOffset); codeAttributeEditor.replaceInstruction(offset, newGotoInstruction);
int newLength = mapInstructions(oldCode, oldLength); moveInstructions(clazz, method, codeAttribute,
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) { codeAttributeEditor.deleteInstruction(offset); // We're allowing edits on deleted instructions. //codeAttributeEditor.insertBeforeInstruction(offset, (Instruction)null); //codeAttributeEditor.replaceInstruction(offset, (Instruction)null); //codeAttributeEditor.insertAfterInstruction(offset, (Instruction)null); // Visit the instruction, if required. if (extraDeletedInstructionVisitor != null) { instruction.accept(clazz, method, codeAttribute, offset, extraDeletedInstructionVisitor); } } }
/** * Remembers to place the given instruction right before the instruction * at the given offset. */ private void insertBeforeInstruction(int instructionOffset, Instruction instruction) { ensureCodeAttributeEditor(); // Replace the instruction. codeAttributeEditor.insertBeforeInstruction(instructionOffset, instruction); }
public LambdaExpressionConverter(ClassPool programClassPool, ClassPool libraryClassPool, MultiValueMap<String, String> injectedClassNameMap, ClassVisitor extraClassVisitor) { this.programClassPool = programClassPool; this.libraryClassPool = libraryClassPool; this.injectedClassNameMap = injectedClassNameMap; this.extraClassVisitor = extraClassVisitor; this.lambdaExpressionMap = new HashMap<Integer, LambdaExpression>(); this.codeAttributeEditor = new CodeAttributeEditor(true, true); this.memberRemover = new MemberRemover(); }
codeAttributeEditor.replaceInstruction(lastInstructionOffset, new ConstantInstruction(InstructionConstants.OP_LDC, constantIndex)); codeAttributeEditor.deleteInstruction(offset); offset <= arrayInitializationEnd) codeAttributeEditor.deleteInstruction(offset);
/** * Pushes a specified type of stack entry before or at the given offset. * The instruction is marked as necessary. */ private void insertPushInstructions(int offset, boolean replace, int computationalType) { // Mark this instruction. markInstruction(offset); // Create a simple push instrucion. Instruction replacementInstruction = new SimpleInstruction(pushOpcode(computationalType)); if (DEBUG) System.out.println(": "+replacementInstruction.toString(offset)); // Replace or insert the push instruction. if (replace) { // Replace the push instruction. codeAttributeEditor.replaceInstruction(offset, replacementInstruction); } else { // Insert the push instruction. codeAttributeEditor.insertBeforeInstruction(offset, replacementInstruction); if (extraAddedInstructionVisitor != null) { replacementInstruction.accept(null, null, null, offset, extraAddedInstructionVisitor); } } }
codeAttributeEditor.replaceInstruction(offset, popInstruction); codeAttributeEditor.insertAfterInstruction(offset, popInstruction); codeAttributeEditor.replaceInstruction(offset, popInstruction); codeAttributeEditor.insertAfterInstruction(offset, popInstruction); codeAttributeEditor.replaceInstruction(offset, popInstructions); codeAttributeEditor.insertAfterInstruction(offset, popInstructions);
instructions = builder.instructions(); CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); ((ProgramMethod) method).attributesAccept(programClass, new CodeAttributeEditorResetter(codeAttributeEditor)); codeAttributeEditor.insertBeforeOffset(0, instructions); ((ProgramMethod) method).attributesAccept(programClass, codeAttributeEditor);
public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction) { // First try to simplify it to a simple branch. replaceBranchInstruction(clazz, offset, switchInstruction); // Otherwise make sure all branch targets are valid. if (!codeAttributeEditor.isModified(offset)) { replaceSwitchInstruction(clazz, offset, switchInstruction); } }
/** * Remembers to place the given instruction right after the instruction * at the given offset. */ private void insertAfterInstruction(int instructionOffset, Instruction instruction) { ensureCodeAttributeEditor(); // Replace the instruction. codeAttributeEditor.insertAfterInstruction(instructionOffset, instruction); }
/** * Fills out the instruction offset map for the given code block. * @param oldCode the instructions to be moved. * @param oldLength the code length. * @return the new code length. */ private int mapInstructions(byte[] oldCode, int oldLength) { // Start mapping instructions at the beginning. newOffset = 0; lengthIncreased = false; int oldOffset = 0; do { // Get the next instruction. Instruction instruction = InstructionFactory.create(oldCode, oldOffset); // Compute the mapping of the instruction. mapInstruction(oldOffset, instruction); oldOffset += instruction.length(oldOffset); if (newOffset > oldOffset) { lengthIncreased = true; } } while (oldOffset < oldLength); // Also add an entry for the first offset after the code. newInstructionOffsets[oldOffset] = newOffset; return newOffset; }