1 21 package proguard.optimize.peephole; 22 23 import proguard.classfile.*; 24 import proguard.classfile.attribute.CodeAttribute; 25 import proguard.classfile.editor.CodeAttributeEditor; 26 import proguard.classfile.instruction.*; 27 import proguard.classfile.instruction.visitor.InstructionVisitor; 28 import proguard.classfile.util.SimplifiedVisitor; 29 30 36 public class GotoReturnReplacer 37 extends SimplifiedVisitor 38 implements InstructionVisitor 39 { 40 private CodeAttributeEditor codeAttributeEditor; 41 private InstructionVisitor extraInstructionVisitor; 42 43 44 49 public GotoReturnReplacer(CodeAttributeEditor codeAttributeEditor) 50 { 51 this(codeAttributeEditor, null); 52 } 53 54 55 62 public GotoReturnReplacer(CodeAttributeEditor codeAttributeEditor, 63 InstructionVisitor extraInstructionVisitor) 64 { 65 this.codeAttributeEditor = codeAttributeEditor; 66 this.extraInstructionVisitor = extraInstructionVisitor; 67 } 68 69 70 72 public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} 73 74 75 public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) 76 { 77 byte opcode = branchInstruction.opcode; 79 if (opcode == InstructionConstants.OP_GOTO || 80 opcode == InstructionConstants.OP_GOTO_W) 81 { 82 int targetOffset = offset + branchInstruction.branchOffset; 84 85 if (!codeAttributeEditor.isModified(offset) && 86 !codeAttributeEditor.isModified(targetOffset)) 87 { 88 Instruction targetInstruction = InstructionFactory.create(codeAttribute.code, 89 targetOffset); 90 switch (targetInstruction.opcode) 91 { 92 case InstructionConstants.OP_IRETURN: 93 case InstructionConstants.OP_LRETURN: 94 case InstructionConstants.OP_FRETURN: 95 case InstructionConstants.OP_DRETURN: 96 case InstructionConstants.OP_ARETURN: 97 case InstructionConstants.OP_RETURN: 98 Instruction returnInstruction = 100 new SimpleInstruction(targetInstruction.opcode); 101 codeAttributeEditor.replaceInstruction(offset, 102 returnInstruction); 103 104 if (extraInstructionVisitor != null) 106 { 107 extraInstructionVisitor.visitBranchInstruction(clazz, method, codeAttribute, offset, branchInstruction); 108 } 109 110 break; 111 } 112 } 113 } 114 } 115 } 116 | Popular Tags |