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