1 21 package proguard.optimize.peephole; 22 23 import proguard.classfile.*; 24 import proguard.classfile.visitor.ClassPrinter; 25 import proguard.classfile.attribute.CodeAttribute; 26 import proguard.classfile.editor.CodeAttributeEditor; 27 import proguard.classfile.instruction.*; 28 import proguard.classfile.instruction.visitor.InstructionVisitor; 29 import proguard.classfile.util.SimplifiedVisitor; 30 31 37 public class GotoGotoReplacer 38 extends SimplifiedVisitor 39 implements InstructionVisitor 40 { 41 private CodeAttributeEditor codeAttributeEditor; 42 private InstructionVisitor extraInstructionVisitor; 43 44 45 50 public GotoGotoReplacer(CodeAttributeEditor codeAttributeEditor) 51 { 52 this(codeAttributeEditor, null); 53 } 54 55 56 63 public GotoGotoReplacer(CodeAttributeEditor codeAttributeEditor, 64 InstructionVisitor extraInstructionVisitor) 65 { 66 this.codeAttributeEditor = codeAttributeEditor; 67 this.extraInstructionVisitor = extraInstructionVisitor; 68 } 69 70 71 73 public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} 74 75 76 public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) 77 { 78 byte opcode = branchInstruction.opcode; 80 if (opcode == InstructionConstants.OP_GOTO || 81 opcode == InstructionConstants.OP_GOTO_W) 82 { 83 int branchOffset = branchInstruction.branchOffset; 86 int targetOffset = offset + branchOffset; 87 88 if (branchOffset != branchInstruction.length(offset) && 89 !codeAttributeEditor.isModified(offset) && 90 !codeAttributeEditor.isModified(targetOffset)) 91 { 92 Instruction targetInstruction = 93 InstructionFactory.create(codeAttribute.code, targetOffset); 94 95 if (targetInstruction.opcode == InstructionConstants.OP_GOTO) 96 { 97 int targetBranchOffset = ((BranchInstruction)targetInstruction).branchOffset; 99 100 Instruction newBranchInstruction = 101 new BranchInstruction(opcode, 102 (branchOffset + targetBranchOffset)); 103 codeAttributeEditor.replaceInstruction(offset, 104 newBranchInstruction); 105 106 if (extraInstructionVisitor != null) 108 { 109 extraInstructionVisitor.visitBranchInstruction(clazz, method, codeAttribute, offset, branchInstruction); 110 } 111 } 112 } 113 } 114 } 115 } 116 | Popular Tags |