summaryrefslogtreecommitdiff
path: root/src/proguard/classfile/editor/InstructionWriter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/classfile/editor/InstructionWriter.java')
-rw-r--r--src/proguard/classfile/editor/InstructionWriter.java320
1 files changed, 0 insertions, 320 deletions
diff --git a/src/proguard/classfile/editor/InstructionWriter.java b/src/proguard/classfile/editor/InstructionWriter.java
deleted file mode 100644
index cafdd87..0000000
--- a/src/proguard/classfile/editor/InstructionWriter.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * ProGuard -- shrinking, optimization, obfuscation, and preverification
- * of Java bytecode.
- *
- * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-package proguard.classfile.editor;
-
-import proguard.classfile.*;
-import proguard.classfile.attribute.CodeAttribute;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
-import proguard.classfile.instruction.*;
-import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
-
-/**
- * This InstructionVisitor writes out the instructions that it visits,
- * collecting instructions that have to be widened. As an AttributeVisitor,
- * it then applies the collected changes. The process will be repeated
- * recursively, if necessary. The caller still has to update the frame sizes.
- *
- * @author Eric Lafortune
- */
-public class InstructionWriter
-extends SimplifiedVisitor
-implements InstructionVisitor,
- AttributeVisitor
-{
- //*
- private static final boolean DEBUG = false;
- /*/
- public static boolean DEBUG = false;
- //*/
-
-
- private int codeLength;
-
- private CodeAttributeEditor codeAttributeEditor;
-
-
- /**
- * Resets the accumulated code.
- * @param codeLength the length of the code that will be edited next.
- */
- public void reset(int codeLength)
- {
- this.codeLength = codeLength;
-
- if (codeAttributeEditor != null)
- {
- codeAttributeEditor.reset(codeLength);
- }
- }
-
-
- /**
- * Extends the size of the accumulated code.
- * @param codeLength the length of the code that will be edited next.
- */
- public void extend(int codeLength)
- {
- this.codeLength = codeLength;
-
- if (codeAttributeEditor != null)
- {
- codeAttributeEditor.extend(codeLength);
- }
- }
-
-
- // Implementations for InstructionVisitor.
-
- public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
- {
- // Try to write out the instruction.
- // Simple instructions should always fit.
- simpleInstruction.write(codeAttribute, offset);
- }
-
-
- public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
- {
- try
- {
- // Try to write out the instruction.
- constantInstruction.write(codeAttribute, offset);
- }
- catch (IllegalArgumentException exception)
- {
- // Create a new constant instruction that will fit.
- Instruction replacementInstruction =
- new ConstantInstruction(constantInstruction.opcode,
- constantInstruction.constantIndex,
- constantInstruction.constant);
-
- if (DEBUG)
- {
- System.out.println(" "+constantInstruction.toString(offset)+" will be widened to "+replacementInstruction.toString());
- }
-
- replaceInstruction(offset, replacementInstruction);
-
- // Write out a dummy constant instruction for now.
- constantInstruction.constantIndex = 0;
- constantInstruction.constant = 0;
- constantInstruction.write(codeAttribute, offset);
- }
- }
-
-
- public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
- {
- try
- {
- // Try to write out the instruction.
- variableInstruction.write(codeAttribute, offset);
- }
- catch (IllegalArgumentException exception)
- {
- // Create a new variable instruction that will fit.
- Instruction replacementInstruction =
- new VariableInstruction(variableInstruction.opcode,
- variableInstruction.variableIndex,
- variableInstruction.constant);
-
- replaceInstruction(offset, replacementInstruction);
-
- if (DEBUG)
- {
- System.out.println(" "+variableInstruction.toString(offset)+" will be widened to "+replacementInstruction.toString());
- }
-
- // Write out a dummy variable instruction for now.
- variableInstruction.variableIndex = 0;
- variableInstruction.constant = 0;
- variableInstruction.write(codeAttribute, offset);
- }
- }
-
-
- public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
- {
- try
- {
- // Try to write out the instruction.
- branchInstruction.write(codeAttribute, offset);
- }
- catch (IllegalArgumentException exception)
- {
- // Create a new unconditional branch that will fit.
- Instruction replacementInstruction =
- new BranchInstruction(InstructionConstants.OP_GOTO_W,
- branchInstruction.branchOffset);
-
- // Create a new instruction that will fit.
- switch (branchInstruction.opcode)
- {
- default:
- {
- // Create a new branch instruction that will fit.
- replacementInstruction =
- new BranchInstruction(branchInstruction.opcode,
- branchInstruction.branchOffset);
-
- break;
- }
-
- // Some special cases, for which a wide branch doesn't exist.
- case InstructionConstants.OP_IFEQ:
- case InstructionConstants.OP_IFNE:
- case InstructionConstants.OP_IFLT:
- case InstructionConstants.OP_IFGE:
- case InstructionConstants.OP_IFGT:
- case InstructionConstants.OP_IFLE:
- case InstructionConstants.OP_IFICMPEQ:
- case InstructionConstants.OP_IFICMPNE:
- case InstructionConstants.OP_IFICMPLT:
- case InstructionConstants.OP_IFICMPGE:
- case InstructionConstants.OP_IFICMPGT:
- case InstructionConstants.OP_IFICMPLE:
- case InstructionConstants.OP_IFACMPEQ:
- case InstructionConstants.OP_IFACMPNE:
- {
- // Insert the complementary conditional branch.
- Instruction complementaryConditionalBranch =
- new BranchInstruction((byte)(((branchInstruction.opcode+1) ^ 1) - 1),
- (1+2) + (1+4));
-
- insertBeforeInstruction(offset, complementaryConditionalBranch);
-
- // Create a new unconditional branch that will fit.
- break;
- }
-
- case InstructionConstants.OP_IFNULL:
- case InstructionConstants.OP_IFNONNULL:
- {
- // Insert the complementary conditional branch.
- Instruction complementaryConditionalBranch =
- new BranchInstruction((byte)(branchInstruction.opcode ^ 1),
- (1+2) + (1+4));
-
- insertBeforeInstruction(offset, complementaryConditionalBranch);
-
- // Create a new unconditional branch that will fit.
- break;
- }
- }
-
- if (DEBUG)
- {
- System.out.println(" "+branchInstruction.toString(offset)+" will be widened to "+replacementInstruction.toString());
- }
-
- replaceInstruction(offset, replacementInstruction);
-
- // Write out a dummy branch instruction for now.
- branchInstruction.branchOffset = 0;
- branchInstruction.write(codeAttribute, offset);
- }
- }
-
-
- public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction)
- {
- // Try to write out the instruction.
- // Switch instructions should always fit.
- switchInstruction.write(codeAttribute, offset);
- }
-
-
- // Implementations for AttributeVisitor.
-
- public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
- {
- // Avoid doing any work if nothing is changing anyway.
- if (codeAttributeEditor != null)
- {
- if (DEBUG)
- {
- System.out.println("InstructionWriter: widening instructions in "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
- }
-
- // Apply the collected expansions.
- codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);
-
- // Don't keep the editor around. We're assuming it won't be needed
- // very often, so we don't want to be resetting it all the time.
- codeAttributeEditor = null;
- }
- }
-
-
- // Small utility methods.
-
- /**
- * Remembers to place the given instruction right before the instruction
- * at the given offset.
- */
- private void insertBeforeInstruction(int instructionOffset, Instruction instruction)
- {
- ensureCodeAttributeEditor();
-
- // Replace the instruction.
- codeAttributeEditor.insertBeforeInstruction(instructionOffset, instruction);
- }
-
-
- /**
- * Remembers to replace the instruction at the given offset by the given
- * instruction.
- */
- private void replaceInstruction(int instructionOffset, Instruction instruction)
- {
- ensureCodeAttributeEditor();
-
- // Replace the instruction.
- codeAttributeEditor.replaceInstruction(instructionOffset, instruction);
- }
-
-
- /**
- * Remembers to place the given instruction right after the instruction
- * at the given offset.
- */
- private void insertAfterInstruction(int instructionOffset, Instruction instruction)
- {
- ensureCodeAttributeEditor();
-
- // Replace the instruction.
- codeAttributeEditor.insertAfterInstruction(instructionOffset, instruction);
- }
-
-
- /**
- * Makes sure there is a code attribute editor for the given code attribute.
- */
- private void ensureCodeAttributeEditor()
- {
- if (codeAttributeEditor == null)
- {
- codeAttributeEditor = new CodeAttributeEditor(false, true);
- codeAttributeEditor.reset(codeLength);
- }
- }
-}