001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.optimize.peephole;
022:
023: import proguard.classfile.constant.Constant;
024: import proguard.classfile.editor.CodeAttributeEditor;
025: import proguard.classfile.instruction.Instruction;
026: import proguard.classfile.instruction.visitor.*;
027:
028: /**
029: * This InstructionVisitor replaces multiple instruction sequences at once.
030: *
031: * @see InstructionSequenceReplacer
032: * @author Eric Lafortune
033: */
034: public class InstructionSequencesReplacer extends
035: MultiInstructionVisitor implements InstructionVisitor {
036: private static final int PATTERN_INDEX = 0;
037: private static final int REPLACEMENT_INDEX = 1;
038:
039: /**
040: * Creates a new InstructionSequencesReplacer.
041: * @param patternConstants any constants referenced by the pattern
042: * instruction.
043: * @param instructionSequences the instruction sequences to be replaced,
044: * with subsequently the sequence pair index,
045: * the patten/replacement index (0 or 1),
046: * and the instruction index in the sequence.
047: * @param branchTargetFinder a branch target finder that has been
048: * initialized to indicate branch targets
049: * in the visited code.
050: * @param codeAttributeEditor a code editor that can be used for
051: * accumulating changes to the code.
052: */
053: public InstructionSequencesReplacer(Constant[] patternConstants,
054: Instruction[][][] instructionSequences,
055: BranchTargetFinder branchTargetFinder,
056: CodeAttributeEditor codeAttributeEditor) {
057: this (patternConstants, instructionSequences,
058: branchTargetFinder, codeAttributeEditor, null);
059: }
060:
061: /**
062: * Creates a new InstructionSequenceReplacer.
063: * @param patternConstants any constants referenced by the pattern
064: * instruction.
065: * @param instructionSequences the instruction sequences to be replaced,
066: * with subsequently the sequence pair index,
067: * the patten/replacement index (0 or 1),
068: * and the instruction index in the sequence.
069: * @param branchTargetFinder a branch target finder that has been
070: * initialized to indicate branch targets
071: * in the visited code.
072: * @param codeAttributeEditor a code editor that can be used for
073: * accumulating changes to the code.
074: * @param extraInstructionVisitor an optional extra visitor for all deleted
075: * load instructions.
076: */
077: public InstructionSequencesReplacer(Constant[] patternConstants,
078: Instruction[][][] instructionSequences,
079: BranchTargetFinder branchTargetFinder,
080: CodeAttributeEditor codeAttributeEditor,
081: InstructionVisitor extraInstructionVisitor) {
082: super (createInstructionSequenceReplacers(patternConstants,
083: instructionSequences, branchTargetFinder,
084: codeAttributeEditor, extraInstructionVisitor));
085: }
086:
087: /**
088: * Creates an array of InstructionSequenceReplacer instances.
089: * @param patternConstants any constants referenced by the pattern
090: * instruction.
091: * @param instructionSequences the instruction sequences to be replaced,
092: * with subsequently the sequence pair index,
093: * the from/to index (0 or 1), and the
094: * instruction index in the sequence.
095: * @param branchTargetFinder a branch target finder that has been
096: * initialized to indicate branch targets
097: * in the visited code.
098: * @param codeAttributeEditor a code editor that can be used for
099: * accumulating changes to the code.
100: * @param extraInstructionVisitor an optional extra visitor for all deleted
101: * load instructions.
102: */
103: private static InstructionVisitor[] createInstructionSequenceReplacers(
104: Constant[] patternConstants,
105: Instruction[][][] instructionSequences,
106: BranchTargetFinder branchTargetFinder,
107: CodeAttributeEditor codeAttributeEditor,
108: InstructionVisitor extraInstructionVisitor) {
109: InstructionVisitor[] instructionSequenceReplacers = new InstructionSequenceReplacer[instructionSequences.length];
110:
111: for (int index = 0; index < instructionSequenceReplacers.length; index++) {
112: Instruction[][] instructionSequencePair = instructionSequences[index];
113: instructionSequenceReplacers[index] = new InstructionSequenceReplacer(
114: patternConstants,
115: instructionSequencePair[PATTERN_INDEX],
116: instructionSequencePair[REPLACEMENT_INDEX],
117: branchTargetFinder, codeAttributeEditor,
118: extraInstructionVisitor);
119: }
120:
121: return instructionSequenceReplacers;
122: }
123: }
|