diff options
Diffstat (limited to 'src/proguard/classfile/editor/CodeAttributeEditor.java')
-rw-r--r-- | src/proguard/classfile/editor/CodeAttributeEditor.java | 400 |
1 files changed, 218 insertions, 182 deletions
diff --git a/src/proguard/classfile/editor/CodeAttributeEditor.java b/src/proguard/classfile/editor/CodeAttributeEditor.java index 9658c98..337e0d4 100644 --- a/src/proguard/classfile/editor/CodeAttributeEditor.java +++ b/src/proguard/classfile/editor/CodeAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -28,7 +28,9 @@ import proguard.classfile.attribute.visitor.*; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.ClassPrinter; +import proguard.util.ArrayUtil; + +import java.util.Arrays; /** * This AttributeVisitor accumulates specified changes to code, and then applies @@ -50,10 +52,12 @@ implements AttributeVisitor, //* private static final boolean DEBUG = false; /*/ - private static boolean DEBUG = true; + public static boolean DEBUG = false; //*/ - private boolean updateFrameSizes; + + private final boolean updateFrameSizes; + private final boolean shrinkInstructions; private int codeLength; private boolean modified; @@ -64,7 +68,7 @@ implements AttributeVisitor, /*private*/public Instruction[] postInsertions = new Instruction[ClassConstants.TYPICAL_CODE_LENGTH]; /*private*/public boolean[] deleted = new boolean[ClassConstants.TYPICAL_CODE_LENGTH]; - private int[] instructionOffsetMap = new int[ClassConstants.TYPICAL_CODE_LENGTH]; + private int[] newInstructionOffsets = new int[ClassConstants.TYPICAL_CODE_LENGTH]; private int newOffset; private boolean lengthIncreased; @@ -75,15 +79,28 @@ implements AttributeVisitor, private final InstructionWriter instructionWriter = new InstructionWriter(); + /** + * Creates a new CodeAttributeEditor that automatically updates frame + * sizes and shrinks instructions. + */ public CodeAttributeEditor() { - this(true); + this(true, true); } - public CodeAttributeEditor(boolean updateFrameSizes) + /** + * Creates a new CodeAttributeEditor. + * @param updateFrameSizes specifies whether frame sizes of edited code + * should be updated. + * @param shrinkInstructions specifies whether added instructions should + * automatically be shrunk before being written. + */ + public CodeAttributeEditor(boolean updateFrameSizes, + boolean shrinkInstructions) { - this.updateFrameSizes = updateFrameSizes; + this.updateFrameSizes = updateFrameSizes; + this.shrinkInstructions = shrinkInstructions; } @@ -93,8 +110,6 @@ implements AttributeVisitor, */ public void reset(int codeLength) { - this.codeLength = codeLength; - // Try to reuse the previous arrays. if (preInsertions.length < codeLength) { @@ -105,18 +120,42 @@ implements AttributeVisitor, } else { - for (int index = 0; index < codeLength; index++) - { - preInsertions[index] = null; - replacements[index] = null; - postInsertions[index] = null; - deleted[index] = false; - } + Arrays.fill(preInsertions, 0, codeLength, null); + Arrays.fill(replacements, 0, codeLength, null); + Arrays.fill(postInsertions, 0, codeLength, null); + Arrays.fill(deleted, 0, codeLength, false); } + this.codeLength = codeLength; + modified = false; simple = true; + } + + + /** + * Extends the size of the accumulated code changes. + * @param codeLength the length of the code that will be edited next. + */ + public void extend(int codeLength) + { + // Try to reuse the previous arrays. + if (preInsertions.length < codeLength) + { + preInsertions = (Instruction[])ArrayUtil.extendArray(preInsertions, codeLength); + replacements = (Instruction[])ArrayUtil.extendArray(replacements, codeLength); + postInsertions = (Instruction[])ArrayUtil.extendArray(postInsertions, codeLength); + deleted = ArrayUtil.extendArray(deleted, codeLength); + } + else + { + Arrays.fill(preInsertions, this.codeLength, codeLength, null); + Arrays.fill(replacements, this.codeLength, codeLength, null); + Arrays.fill(postInsertions, this.codeLength, codeLength, null); + Arrays.fill(deleted, this.codeLength, codeLength, false); + } + this.codeLength = codeLength; } @@ -134,7 +173,9 @@ implements AttributeVisitor, throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } - preInsertions[instructionOffset] = instruction; + preInsertions[instructionOffset] = shrinkInstructions ? + instruction.shrink() : + instruction; modified = true; simple = false; @@ -156,7 +197,12 @@ implements AttributeVisitor, throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } - preInsertions[instructionOffset] = new CompositeInstruction(instructions); + CompositeInstruction instruction = + new CompositeInstruction(instructions); + + preInsertions[instructionOffset] = shrinkInstructions ? + instruction.shrink() : + instruction; modified = true; simple = false; @@ -178,7 +224,9 @@ implements AttributeVisitor, throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } - replacements[instructionOffset] = instruction; + replacements[instructionOffset] = shrinkInstructions ? + instruction.shrink() : + instruction; modified = true; } @@ -198,7 +246,12 @@ implements AttributeVisitor, throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } - replacements[instructionOffset] = new CompositeInstruction(instructions); + CompositeInstruction instruction = + new CompositeInstruction(instructions); + + replacements[instructionOffset] = shrinkInstructions ? + instruction.shrink() : + instruction; modified = true; } @@ -218,7 +271,9 @@ implements AttributeVisitor, throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } - postInsertions[instructionOffset] = instruction; + postInsertions[instructionOffset] = shrinkInstructions ? + instruction.shrink() : + instruction; modified = true; simple = false; @@ -239,7 +294,12 @@ implements AttributeVisitor, throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } - postInsertions[instructionOffset] = new CompositeInstruction(instructions); + CompositeInstruction instruction = + new CompositeInstruction(instructions); + + postInsertions[instructionOffset] = shrinkInstructions ? + instruction.shrink() : + instruction; modified = true; simple = false; @@ -282,6 +342,34 @@ implements AttributeVisitor, /** + * Clears all modifications of the instruction at the given offset. + * @param instructionOffset the offset of the instruction to be deleted. + */ + public void clearModifications(int instructionOffset) + { + if (instructionOffset < 0 || + instructionOffset >= codeLength) + { + throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); + } + + preInsertions[instructionOffset] = null; + replacements[instructionOffset] = null; + postInsertions[instructionOffset] = null; + deleted[instructionOffset] = false; + } + + + /** + * Returns whether the code has been modified in any way. + */ + public boolean isModified() + { + return modified; + } + + + /** * Returns whether the instruction at the given offset has been modified * in any way. */ @@ -326,54 +414,53 @@ implements AttributeVisitor, public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute) { - if (DEBUG) - { - System.out.println("CodeAttributeEditor: ["+clazz.getName()+"."+method.getName(clazz)+"]"); - } - - // Avoid doing any work if nothing is changing anyway. - if (!modified) + // Do we have to update the code? + if (modified) { - return; - } + if (DEBUG) + { + System.out.println("CodeAttributeEditor: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)); + } - // Check if we can perform a faster simple replacement of instructions. - if (canPerformSimpleReplacements(codeAttribute)) - { - // Simply overwrite the instructions. - performSimpleReplacements(codeAttribute); + // Can we perform a faster simple replacement of instructions? + if (canPerformSimpleReplacements(codeAttribute)) + { + if (DEBUG) + { + System.out.println(" Simple editing"); + } - // Update the maximum stack size and local variable frame size. - updateFrameSizes(clazz, method, codeAttribute); - } - else - { - // Move and remap the instructions. - codeAttribute.u4codeLength = - updateInstructions(clazz, method, codeAttribute); + // Simply overwrite the instructions. + performSimpleReplacements(codeAttribute); + } + else + { + if (DEBUG) + { + System.out.println(" Full editing"); + } - // Remap the exception table. - codeAttribute.exceptionsAccept(clazz, method, this); + // Move and remap the instructions. + codeAttribute.u4codeLength = + updateInstructions(clazz, method, codeAttribute); - // Remove exceptions with empty code blocks. - codeAttribute.u2exceptionTableLength = - removeEmptyExceptions(codeAttribute.exceptionTable, - codeAttribute.u2exceptionTableLength); + // Update the exception table. + codeAttribute.exceptionsAccept(clazz, method, this); - // Update the maximum stack size and local variable frame size. - updateFrameSizes(clazz, method, codeAttribute); + // Remove exceptions with empty code blocks. + codeAttribute.u2exceptionTableLength = + removeEmptyExceptions(codeAttribute.exceptionTable, + codeAttribute.u2exceptionTableLength); - // Remap the line number table and the local variable table. - codeAttribute.attributesAccept(clazz, method, this); + // Update the line number table and the local variable tables. + codeAttribute.attributesAccept(clazz, method, this); + } // Make sure instructions are widened if necessary. instructionWriter.visitCodeAttribute(clazz, method, codeAttribute); } - } - - private void updateFrameSizes(Clazz clazz, Method method, CodeAttribute codeAttribute) - { + // Update the maximum stack size and local variable frame size. if (updateFrameSizes) { stackSizeUpdater.visitCodeAttribute(clazz, method, codeAttribute); @@ -384,7 +471,7 @@ implements AttributeVisitor, public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) { - // Remap all stack map entries. + // Update all stack map entries. expectedStackMapFrameOffset = -1; stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); } @@ -392,7 +479,7 @@ implements AttributeVisitor, public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) { - // Remap all stack map table entries. + // Update all stack map table entries. expectedStackMapFrameOffset = 0; stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); } @@ -400,7 +487,7 @@ implements AttributeVisitor, public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) { - // Remap all line number table entries. + // Update all line number table entries. lineNumberTableAttribute.lineNumbersAccept(clazz, method, codeAttribute, this); // Remove line numbers with empty code blocks. @@ -413,27 +500,15 @@ implements AttributeVisitor, public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) { - // Remap all local variable table entries. + // Update all local variable table entries. localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - - // Remove local variables with empty code blocks. - localVariableTableAttribute.u2localVariableTableLength = - removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable, - localVariableTableAttribute.u2localVariableTableLength, - codeAttribute.u2maxLocals); } public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) { - // Remap all local variable table entries. + // Update all local variable table entries. localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - - // Remove local variables with empty code blocks. - localVariableTypeTableAttribute.u2localVariableTypeTableLength = - removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, - localVariableTypeTableAttribute.u2localVariableTypeTableLength, - codeAttribute.u2maxLocals); } @@ -491,7 +566,7 @@ implements AttributeVisitor, if (DEBUG) { - System.out.println(" Replaced "+replacementInstruction.toString(newOffset)); + System.out.println(" Replaced "+replacementInstruction.toString(offset)); } } } @@ -513,9 +588,9 @@ implements AttributeVisitor, int oldLength = codeAttribute.u4codeLength; // Make sure there is a sufficiently large instruction offset map. - if (instructionOffsetMap.length < oldLength + 1) + if (newInstructionOffsets.length < oldLength + 1) { - instructionOffsetMap = new int[oldLength + 1]; + newInstructionOffsets = new int[oldLength + 1]; } // Fill out the instruction offset map. @@ -574,7 +649,7 @@ implements AttributeVisitor, while (oldOffset < oldLength); // Also add an entry for the first offset after the code. - instructionOffsetMap[oldOffset] = newOffset; + newInstructionOffsets[oldOffset] = newOffset; return newOffset; } @@ -588,7 +663,7 @@ implements AttributeVisitor, private void mapInstruction(int oldOffset, Instruction instruction) { - instructionOffsetMap[oldOffset] = newOffset; + newInstructionOffsets[oldOffset] = newOffset; // Account for the pre-inserted instruction, if any. Instruction preInstruction = preInsertions[oldOffset]; @@ -670,52 +745,53 @@ implements AttributeVisitor, int oldOffset, Instruction instruction) { - // Remap and insert the pre-inserted instruction, if any. + // Update and insert the pre-inserted instruction, if any. Instruction preInstruction = preInsertions[oldOffset]; if (preInstruction != null) { if (DEBUG) { - System.out.println(" Pre-inserted "+preInstruction.toString(newOffset)); + System.out.println(" Pre-inserted ["+oldOffset+"] -> "+preInstruction.toString(newOffset)); } - // Remap the instruction. + // Update the instruction. preInstruction.accept(clazz, method, codeAttribute, oldOffset, this); } - // Remap and insert the replacement instruction, or the current + // Update and insert the replacement instruction, or the current // instruction, if it shouldn't be deleted. Instruction replacementInstruction = replacements[oldOffset]; if (replacementInstruction != null) { if (DEBUG) { - System.out.println(" Replaced "+replacementInstruction.toString(newOffset)); + System.out.println(" Replaced ["+oldOffset+"] -> "+replacementInstruction.toString(newOffset)); } - // Remap the instruction. + + // Update the instruction. replacementInstruction.accept(clazz, method, codeAttribute, oldOffset, this); } else if (!deleted[oldOffset]) { if (DEBUG) { - System.out.println(" Copied "+instruction.toString(newOffset)); + System.out.println(" Copied ["+oldOffset+"] -> "+instruction.toString(newOffset)); } - // Remap the instruction. + // Update the instruction. instruction.accept(clazz, method, codeAttribute, oldOffset, this); } - // Remap and insert the post-inserted instruction, if any. + // Update and insert the post-inserted instruction, if any. Instruction postInstruction = postInsertions[oldOffset]; if (postInstruction != null) { if (DEBUG) { - System.out.println(" Post-inserted "+postInstruction.toString(newOffset)); + System.out.println(" Post-inserted ["+oldOffset+"] -> "+postInstruction.toString(newOffset)); } - // Remap the instruction. + // Update the instruction. postInstruction.accept(clazz, method, codeAttribute, oldOffset, this); } } @@ -765,8 +841,8 @@ implements AttributeVisitor, public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) { // Adjust the branch offset. - branchInstruction.branchOffset = remapBranchOffset(offset, - branchInstruction.branchOffset); + branchInstruction.branchOffset = newBranchOffset(offset, + branchInstruction.branchOffset); // Write out the instruction. instructionWriter.visitBranchInstruction(clazz, @@ -782,11 +858,11 @@ implements AttributeVisitor, public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction) { // Adjust the default jump offset. - tableSwitchInstruction.defaultOffset = remapBranchOffset(offset, - tableSwitchInstruction.defaultOffset); + tableSwitchInstruction.defaultOffset = newBranchOffset(offset, + tableSwitchInstruction.defaultOffset); // Adjust the jump offsets. - remapJumpOffsets(offset, + newJumpOffsets(offset, tableSwitchInstruction.jumpOffsets); // Write out the instruction. @@ -803,11 +879,11 @@ implements AttributeVisitor, public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) { // Adjust the default jump offset. - lookUpSwitchInstruction.defaultOffset = remapBranchOffset(offset, - lookUpSwitchInstruction.defaultOffset); + lookUpSwitchInstruction.defaultOffset = newBranchOffset(offset, + lookUpSwitchInstruction.defaultOffset); // Adjust the jump offsets. - remapJumpOffsets(offset, + newJumpOffsets(offset, lookUpSwitchInstruction.jumpOffsets); // Write out the instruction. @@ -825,11 +901,11 @@ implements AttributeVisitor, public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) { - // Remap the code offsets. Note that the instruction offset map also has + // Update the code offsets. Note that the instruction offset map also has // an entry for the first offset after the code, for u2endPC. - exceptionInfo.u2startPC = remapInstructionOffset(exceptionInfo.u2startPC); - exceptionInfo.u2endPC = remapInstructionOffset(exceptionInfo.u2endPC); - exceptionInfo.u2handlerPC = remapInstructionOffset(exceptionInfo.u2handlerPC); + exceptionInfo.u2startPC = newInstructionOffset(exceptionInfo.u2startPC); + exceptionInfo.u2endPC = newInstructionOffset(exceptionInfo.u2endPC); + exceptionInfo.u2handlerPC = newInstructionOffset(exceptionInfo.u2handlerPC); } @@ -837,8 +913,8 @@ implements AttributeVisitor, public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) { - // Remap the stack map frame offset. - int stackMapFrameOffset = remapInstructionOffset(offset); + // Update the stack map frame offset. + int stackMapFrameOffset = newInstructionOffset(offset); int offsetDelta = stackMapFrameOffset; @@ -857,30 +933,30 @@ implements AttributeVisitor, public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame) { - // Remap the stack map frame offset. + // Update the stack map frame offset. visitAnyStackMapFrame(clazz, method, codeAttribute, offset, sameOneFrame); - // Remap the verification type offset. + // Update the verification type offset. sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this); } public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame) { - // Remap the stack map frame offset. + // Update the stack map frame offset. visitAnyStackMapFrame(clazz, method, codeAttribute, offset, moreZeroFrame); - // Remap the verification type offsets. + // Update the verification type offsets. moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this); } public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame) { - // Remap the stack map frame offset. + // Update the stack map frame offset. visitAnyStackMapFrame(clazz, method, codeAttribute, offset, fullFrame); - // Remap the verification type offsets. + // Update the verification type offsets. fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this); fullFrame.stackAccept(clazz, method, codeAttribute, offset, this); } @@ -893,8 +969,8 @@ implements AttributeVisitor, public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType) { - // Remap the offset of the 'new' instruction. - uninitializedType.u2newInstructionOffset = remapInstructionOffset(uninitializedType.u2newInstructionOffset); + // Update the offset of the 'new' instruction. + uninitializedType.u2newInstructionOffset = newInstructionOffset(uninitializedType.u2newInstructionOffset); } @@ -902,8 +978,8 @@ implements AttributeVisitor, public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo) { - // Remap the code offset. - lineNumberInfo.u2startPC = remapInstructionOffset(lineNumberInfo.u2startPC); + // Update the code offset. + lineNumberInfo.u2startPC = newInstructionOffset(lineNumberInfo.u2startPC); } @@ -911,11 +987,13 @@ implements AttributeVisitor, public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) { - // Remap the code offset and length. - // TODO: The local variable frame might not be strictly preserved. - localVariableInfo.u2length = remapBranchOffset(localVariableInfo.u2startPC, - localVariableInfo.u2length); - localVariableInfo.u2startPC = remapInstructionOffset(localVariableInfo.u2startPC); + // Update the code offset and length. + int newStartPC = newInstructionOffset(localVariableInfo.u2startPC); + int newEndPC = newInstructionOffset(localVariableInfo.u2startPC + + localVariableInfo.u2length); + + localVariableInfo.u2length = newEndPC - newStartPC; + localVariableInfo.u2startPC = newStartPC; } @@ -923,11 +1001,13 @@ implements AttributeVisitor, public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) { - // Remap the code offset and length. - // TODO: The local variable frame might not be strictly preserved. - localVariableTypeInfo.u2length = remapBranchOffset(localVariableTypeInfo.u2startPC, - localVariableTypeInfo.u2length); - localVariableTypeInfo.u2startPC = remapInstructionOffset(localVariableTypeInfo.u2startPC); + // Update the code offset and length. + int newStartPC = newInstructionOffset(localVariableTypeInfo.u2startPC); + int newEndPC = newInstructionOffset(localVariableTypeInfo.u2startPC + + localVariableTypeInfo.u2length); + + localVariableTypeInfo.u2length = newEndPC - newStartPC; + localVariableTypeInfo.u2startPC = newStartPC; } @@ -936,11 +1016,11 @@ implements AttributeVisitor, /** * Adjusts the given jump offsets for the instruction at the given offset. */ - private void remapJumpOffsets(int offset, int[] jumpOffsets) + private void newJumpOffsets(int oldInstructionOffset, int[] oldJumpOffsets) { - for (int index = 0; index < jumpOffsets.length; index++) + for (int index = 0; index < oldJumpOffsets.length; index++) { - jumpOffsets[index] = remapBranchOffset(offset, jumpOffsets[index]); + oldJumpOffsets[index] = newBranchOffset(oldInstructionOffset, oldJumpOffsets[index]); } } @@ -949,24 +1029,24 @@ implements AttributeVisitor, * Computes the new branch offset for the instruction at the given offset * with the given branch offset. */ - private int remapBranchOffset(int offset, int branchOffset) + private int newBranchOffset(int oldInstructionOffset, int oldBranchOffset) { - return remapInstructionOffset(offset + branchOffset) - newOffset; + return newInstructionOffset(oldInstructionOffset + oldBranchOffset) - newOffset; } /** * Computes the new instruction offset for the instruction at the given offset. */ - private int remapInstructionOffset(int offset) + private int newInstructionOffset(int oldInstructionOffset) { - if (offset < 0 || - offset > codeLength) + if (oldInstructionOffset < 0 || + oldInstructionOffset > codeLength) { - throw new IllegalArgumentException("Invalid instruction offset ["+offset+"] in code with length ["+codeLength+"]"); + throw new IllegalArgumentException("Invalid instruction offset ["+oldInstructionOffset+"] in code with length ["+codeLength+"]"); } - return instructionOffsetMap[offset]; + return newInstructionOffsets[oldInstructionOffset]; } @@ -1018,53 +1098,9 @@ implements AttributeVisitor, /** - * Returns the given list of local variables, without the ones that have empty - * code blocks or that exceed the actual number of local variables. + * This instruction is a composite of other instructions, for local use + * inside the editor class only. */ - private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, - int localVariableInfoCount, - int maxLocals) - { - // Overwrite all empty local variable entries. - int newIndex = 0; - for (int index = 0; index < localVariableInfoCount; index++) - { - LocalVariableInfo localVariableInfo = localVariableInfos[index]; - if (localVariableInfo.u2length > 0 && - localVariableInfo.u2index < maxLocals) - { - localVariableInfos[newIndex++] = localVariableInfo; - } - } - - return newIndex; - } - - - /** - * Returns the given list of local variable types, without the ones that - * have empty code blocks or that exceed the actual number of local variables. - */ - private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, - int localVariableTypeInfoCount, - int maxLocals) - { - // Overwrite all empty local variable type entries. - int newIndex = 0; - for (int index = 0; index < localVariableTypeInfoCount; index++) - { - LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; - if (localVariableTypeInfo.u2length > 0 && - localVariableTypeInfo.u2index < maxLocals) - { - localVariableTypeInfos[newIndex++] = localVariableTypeInfo; - } - } - - return newIndex; - } - - private class CompositeInstruction extends Instruction { |