📄 codeattributeeditor.java
字号:
newOffset, variableInstruction); } public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) { // Adjust the branch offset. branchInstruction.branchOffset = remapBranchOffset(offset, branchInstruction.branchOffset); // Write out the instruction. instructionWriter.visitBranchInstruction(clazz, method, codeAttribute, newOffset, branchInstruction); } public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction) { // Adjust the default jump offset. tableSwitchInstruction.defaultOffset = remapBranchOffset(offset, tableSwitchInstruction.defaultOffset); // Adjust the jump offsets. remapJumpOffsets(offset, tableSwitchInstruction.jumpOffsets, tableSwitchInstruction.highCase - tableSwitchInstruction.lowCase + 1); // Write out the instruction. instructionWriter.visitTableSwitchInstruction(clazz, method, codeAttribute, newOffset, tableSwitchInstruction); } public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) { // Adjust the default jump offset. lookUpSwitchInstruction.defaultOffset = remapBranchOffset(offset, lookUpSwitchInstruction.defaultOffset); // Adjust the jump offsets. remapJumpOffsets(offset, lookUpSwitchInstruction.jumpOffsets, lookUpSwitchInstruction.jumpOffsetCount); // Write out the instruction. instructionWriter.visitLookUpSwitchInstruction(clazz, method, codeAttribute, newOffset, lookUpSwitchInstruction); } // Implementations for ExceptionInfoVisitor. public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) { // Remap 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); } // Implementations for StackMapFrameVisitor. public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) { // Remap the stack map frame offset. int stackMapFrameOffset = remapInstructionOffset(offset); int offsetDelta = stackMapFrameOffset; // Compute the offset delta if the frame is part of a stack map frame // table (for JDK 6.0) instead of a stack map (for Java Micro Edition). if (expectedStackMapFrameOffset >= 0) { offsetDelta -= expectedStackMapFrameOffset; expectedStackMapFrameOffset = stackMapFrameOffset + 1; } stackMapFrame.u2offsetDelta = offsetDelta; } public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame) { // Remap the stack map frame offset. visitAnyStackMapFrame(clazz, method, codeAttribute, offset, sameOneFrame); // Remap 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. visitAnyStackMapFrame(clazz, method, codeAttribute, offset, moreZeroFrame); // Remap 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. visitAnyStackMapFrame(clazz, method, codeAttribute, offset, fullFrame); // Remap the verification type offsets. fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this); fullFrame.stackAccept(clazz, method, codeAttribute, offset, this); } // Implementations for VerificationTypeVisitor. public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {} 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); } // Implementations for LineNumberInfoVisitor. public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo) { // Remap the code offset. lineNumberInfo.u2startPC = remapInstructionOffset(lineNumberInfo.u2startPC); } // Implementations for LocalVariableInfoVisitor. 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); } // Implementations for LocalVariableTypeInfoVisitor. 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); } // Small utility methods. /** * Adjusts the given jump offsets for the instruction at the given offset. */ private void remapJumpOffsets(int offset, int[] jumpOffsets, int length) { for (int index = 0; index < length; index++) { jumpOffsets[index] = remapBranchOffset(offset, jumpOffsets[index]); } } /** * Computes the new branch offset for the instruction at the given offset * with the given branch offset. */ private int remapBranchOffset(int offset, int branchOffset) { return remapInstructionOffset(offset + branchOffset) - remapInstructionOffset(offset); } /** * Computes the new instruction offset for the instruction at the given offset. */ private int remapInstructionOffset(int offset) { if (offset < 0 || offset > codeLength) { throw new IllegalArgumentException("Invalid instruction offset ["+offset+"] in code with length ["+codeLength+"]"); } return instructionOffsetMap[offset]; } /** * Returns the given list of exceptions, without the ones that have empty * code blocks. */ private int removeEmptyExceptions(ExceptionInfo[] exceptionInfos, int exceptionInfoCount) { // Overwrite all empty exceptions. int newIndex = 0; for (int index = 0; index < exceptionInfoCount; index++) { ExceptionInfo exceptionInfo = exceptionInfos[index]; if (exceptionInfo.u2startPC < exceptionInfo.u2endPC) { exceptionInfos[newIndex++] = exceptionInfo; } } return newIndex; } /** * Returns the given list of line numbers, without the ones that have empty * code blocks or that exceed the code size. */ private int removeEmptyLineNumbers(LineNumberInfo[] lineNumberInfos, int lineNumberInfoCount, int codeLength) { // Overwrite all empty line number entries. int newIndex = 0; for (int index = 0; index < lineNumberInfoCount; index++) { LineNumberInfo lineNumberInfo = lineNumberInfos[index]; int startPC = lineNumberInfo.u2startPC; if (startPC < codeLength && (index == 0 || startPC > lineNumberInfos[index-1].u2startPC)) { lineNumberInfos[newIndex++] = lineNumberInfo; } } return newIndex; } /** * Returns the given list of local variables, without the ones that have empty * code blocks or that exceed the actual number of local variables. */ 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -