InstructionSequenceReplacer.java revision b72c5c2e5482cf10117b2b25f642f7616b2326c3
1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 5b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.optimize.peephole; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.CodeAttribute; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.Constant; 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.visitor.ConstantVisitor; 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.editor.CodeAttributeEditor; 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.instruction.*; 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.instruction.visitor.InstructionVisitor; 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.*; 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This InstructionVisitor replaces a given pattern instruction sequence by 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * another given replacement instruction sequence. The arguments of the 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * instruction sequences can be wildcards that are matched and replaced. 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see InstructionSequenceMatcher 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class InstructionSequenceReplacer 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends SimplifiedVisitor 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements InstructionVisitor, 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConstantVisitor 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private static final boolean DEBUG = false; 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final InstructionSequenceMatcher instructionSequenceMatcher; 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final Instruction[] replacementInstructions; 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final BranchTargetFinder branchTargetFinder; 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final CodeAttributeEditor codeAttributeEditor; 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final InstructionVisitor extraInstructionVisitor; 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final MyReplacementInstructionFactory replacementInstructionFactory = new MyReplacementInstructionFactory(); 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new InstructionSequenceReplacer. 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param patternConstants any constants referenced by the pattern 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * instruction. 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param patternInstructions the pattern instruction sequence. 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param replacementInstructions the replacement instruction sequence. 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param branchTargetFinder a branch target finder that has been 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * initialized to indicate branch targets 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * in the visited code. 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param codeAttributeEditor a code editor that can be used for 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * accumulating changes to the code. 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public InstructionSequenceReplacer(Constant[] patternConstants, 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction[] patternInstructions, 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction[] replacementInstructions, 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato BranchTargetFinder branchTargetFinder, 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato CodeAttributeEditor codeAttributeEditor) 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this(patternConstants, 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato patternInstructions, 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstructions, 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato branchTargetFinder, 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor, 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato null); 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new InstructionSequenceReplacer. 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param patternConstants any constants referenced by the pattern 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * instruction. 88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param branchTargetFinder a branch target finder that has been 89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * initialized to indicate branch targets 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * in the visited code. 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param codeAttributeEditor a code editor that can be used for 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * accumulating changes to the code. 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param extraInstructionVisitor an optional extra visitor for all deleted 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * load instructions. 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public InstructionSequenceReplacer(Constant[] patternConstants, 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction[] patternInstructions, 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction[] replacementInstructions, 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato BranchTargetFinder branchTargetFinder, 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato CodeAttributeEditor codeAttributeEditor, 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato InstructionVisitor extraInstructionVisitor) 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.instructionSequenceMatcher = new InstructionSequenceMatcher(patternConstants, patternInstructions); 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.replacementInstructions = replacementInstructions; 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.branchTargetFinder = branchTargetFinder; 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.codeAttributeEditor = codeAttributeEditor; 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.extraInstructionVisitor = extraInstructionVisitor; 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for InstructionVisitor. 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Reset the instruction sequence matcher if the instruction is a branch 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // target or if it has already been modified. 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (branchTargetFinder.isTarget(offset) || 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.isModified(offset)) 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.reset(); 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Try to match the instruction. 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instruction.accept(clazz, method, codeAttribute, offset, instructionSequenceMatcher); 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Did the instruction sequence match and is it still unmodified? 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (instructionSequenceMatcher.isMatching() && 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato matchedInstructionsUnmodified()) 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (DEBUG) 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println("InstructionSequenceReplacer: ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"]"); 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" Matched:"); 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < instructionSequenceMatcher.instructionCount(); index++) 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int matchedOffset = instructionSequenceMatcher.matchedInstructionOffset(index); 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" "+InstructionFactory.create(codeAttribute.code, matchedOffset).toString(matchedOffset)); 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" Replacement:"); 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < replacementInstructions.length; index++) 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int matchedOffset = instructionSequenceMatcher.matchedInstructionOffset(index); 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" "+replacementInstructionFactory.create(index).shrink().toString(matchedOffset)); 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Replace the instruction sequence. 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < replacementInstructions.length; index++) 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.replaceInstruction(instructionSequenceMatcher.matchedInstructionOffset(index), 151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstructionFactory.create(index).shrink()); 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Delete any remaining instructions in the from sequence. 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = replacementInstructions.length; index < instructionSequenceMatcher.instructionCount(); index++) 156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.deleteInstruction(instructionSequenceMatcher.matchedInstructionOffset(index)); 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Visit the instruction, if required. 161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (extraInstructionVisitor != null) 162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instruction.accept(clazz, 164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato method, 165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttribute, 166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato offset, 167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato extraInstructionVisitor); 168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Small utility methods. 174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns whether the matched pattern instructions haven't been modified 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * before. 178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private boolean matchedInstructionsUnmodified() 180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < instructionSequenceMatcher.instructionCount(); index++) 182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (codeAttributeEditor.isModified(instructionSequenceMatcher.matchedInstructionOffset(index))) 184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return false; 186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return true; 190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This class creates replacement instructions for matched sequences, with 195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any matched arguments filled out. 196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private class MyReplacementInstructionFactory 198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato implements InstructionVisitor 199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Instruction replacementInstruction; 201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates the replacement instruction for the given index in the 205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * instruction sequence. 206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public Instruction create(int index) 208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Create the instruction. 210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstructions[index].accept(null, 211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato null, 212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato null, 213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedInstructionOffset(index), 214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this); 215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Return it. 217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return replacementInstruction.shrink(); 218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for InstructionVisitor. 222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction) 224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstruction = 226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new SimpleInstruction(simpleInstruction.opcode, 227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedArgument(simpleInstruction.constant)); 228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) 232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstruction = 234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new VariableInstruction(variableInstruction.opcode, 235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedArgument(variableInstruction.variableIndex), 236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedArgument(variableInstruction.constant)); 237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) 241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstruction = 243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new ConstantInstruction(constantInstruction.opcode, 244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedConstantIndex(constantInstruction.constantIndex), 245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedArgument(constantInstruction.constant)); 246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) 250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstruction = 252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new BranchInstruction(branchInstruction.opcode, 253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedBranchOffset(offset, branchInstruction.branchOffset)); 254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction) 258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstruction = 260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new TableSwitchInstruction(tableSwitchInstruction.opcode, 261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedBranchOffset(offset, tableSwitchInstruction.defaultOffset), 262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedArgument(tableSwitchInstruction.lowCase), 263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedArgument(tableSwitchInstruction.highCase), 264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedJumpOffsets(offset, tableSwitchInstruction.jumpOffsets)); 265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) 270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato replacementInstruction = 272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new LookUpSwitchInstruction(lookUpSwitchInstruction.opcode, 273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedBranchOffset(offset, lookUpSwitchInstruction.defaultOffset), 274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedArguments(lookUpSwitchInstruction.cases), 275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato instructionSequenceMatcher.matchedJumpOffsets(offset, lookUpSwitchInstruction.jumpOffsets)); 276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 279