1/* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21package proguard.optimize.peephole; 22 23import proguard.classfile.constant.Constant; 24import proguard.classfile.editor.CodeAttributeEditor; 25import proguard.classfile.instruction.Instruction; 26import proguard.classfile.instruction.visitor.*; 27 28/** 29 * This InstructionVisitor replaces multiple instruction sequences at once. 30 * 31 * @see InstructionSequenceReplacer 32 * @author Eric Lafortune 33 */ 34public class InstructionSequencesReplacer 35extends MultiInstructionVisitor 36implements InstructionVisitor 37{ 38 private static final int PATTERN_INDEX = 0; 39 private static final int REPLACEMENT_INDEX = 1; 40 41 42 /** 43 * Creates a new InstructionSequencesReplacer. 44 * @param patternConstants any constants referenced by the pattern 45 * instruction. 46 * @param instructionSequences the instruction sequences to be replaced, 47 * with subsequently the sequence pair index, 48 * the patten/replacement index (0 or 1), 49 * and the instruction index in the sequence. 50 * @param branchTargetFinder a branch target finder that has been 51 * initialized to indicate branch targets 52 * in the visited code. 53 * @param codeAttributeEditor a code editor that can be used for 54 * accumulating changes to the code. 55 */ 56 public InstructionSequencesReplacer(Constant[] patternConstants, 57 Instruction[][][] instructionSequences, 58 BranchTargetFinder branchTargetFinder, 59 CodeAttributeEditor codeAttributeEditor) 60 { 61 this(patternConstants, 62 instructionSequences, 63 branchTargetFinder, 64 codeAttributeEditor, 65 null); 66 } 67 68 69 /** 70 * Creates a new InstructionSequenceReplacer. 71 * @param patternConstants any constants referenced by the pattern 72 * instruction. 73 * @param instructionSequences the instruction sequences to be replaced, 74 * with subsequently the sequence pair index, 75 * the patten/replacement index (0 or 1), 76 * and the instruction index in the sequence. 77 * @param branchTargetFinder a branch target finder that has been 78 * initialized to indicate branch targets 79 * in the visited code. 80 * @param codeAttributeEditor a code editor that can be used for 81 * accumulating changes to the code. 82 * @param extraInstructionVisitor an optional extra visitor for all deleted 83 * load instructions. 84 */ 85 public InstructionSequencesReplacer(Constant[] patternConstants, 86 Instruction[][][] instructionSequences, 87 BranchTargetFinder branchTargetFinder, 88 CodeAttributeEditor codeAttributeEditor, 89 InstructionVisitor extraInstructionVisitor) 90 { 91 super(createInstructionSequenceReplacers(patternConstants, 92 instructionSequences, 93 branchTargetFinder, 94 codeAttributeEditor, 95 extraInstructionVisitor)); 96 } 97 98 99 /** 100 * Creates an array of InstructionSequenceReplacer instances. 101 * @param patternConstants any constants referenced by the pattern 102 * instruction. 103 * @param instructionSequences the instruction sequences to be replaced, 104 * with subsequently the sequence pair index, 105 * the from/to index (0 or 1), and the 106 * instruction index in the sequence. 107 * @param branchTargetFinder a branch target finder that has been 108 * initialized to indicate branch targets 109 * in the visited code. 110 * @param codeAttributeEditor a code editor that can be used for 111 * accumulating changes to the code. 112 * @param extraInstructionVisitor an optional extra visitor for all deleted 113 * load instructions. 114 */ 115 private static InstructionVisitor[] createInstructionSequenceReplacers(Constant[] patternConstants, 116 Instruction[][][] instructionSequences, 117 BranchTargetFinder branchTargetFinder, 118 CodeAttributeEditor codeAttributeEditor, 119 InstructionVisitor extraInstructionVisitor) 120 { 121 InstructionVisitor[] instructionSequenceReplacers = 122 new InstructionSequenceReplacer[instructionSequences.length]; 123 124 for (int index = 0; index < instructionSequenceReplacers.length; index++) 125 { 126 Instruction[][] instructionSequencePair = instructionSequences[index]; 127 instructionSequenceReplacers[index] = 128 new InstructionSequenceReplacer(patternConstants, 129 instructionSequencePair[PATTERN_INDEX], 130 instructionSequencePair[REPLACEMENT_INDEX], 131 branchTargetFinder, 132 codeAttributeEditor, 133 extraInstructionVisitor); 134 } 135 136 return instructionSequenceReplacers; 137 } 138} 139