Java Code Examples for proguard.classfile.instruction.Instruction

The following examples show how to use proguard.classfile.instruction.Instruction. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
{
    if (DEBUG)
    {
        System.out.println("  "+(reachableCodeMarker.isReachable(offset) ? "+" : "-")+" "+instruction.toString(offset));
    }

    // Is this instruction unreachable?
    if (!reachableCodeMarker.isReachable(offset))
    {
        // Then delete it.
        codeAttributeEditor.deleteInstruction(offset);

        // Visit the instruction, if required.
        if (extraInstructionVisitor != null)
        {
            instruction.accept(clazz, method, codeAttribute, offset, extraInstructionVisitor);
        }
    }
}
 
Example 2
public ConfigurationLoggingInstructionSequenceReplacer(InstructionSequenceMatcher instructionSequenceMatcher,
                                                       Constant[]                 patternConstants,
                                                       Instruction[]              patternInstructions,
                                                       Constant[]                 replacementConstants,
                                                       Instruction[]              replacementInstructions,
                                                       BranchTargetFinder         branchTargetFinder,
                                                       CodeAttributeEditor        codeAttributeEditor,
                                                       InstructionVisitor         extraInstructionVisitor    )
{
    super(instructionSequenceMatcher,
          patternConstants,
          patternInstructions,
          replacementConstants,
          replacementInstructions,
          branchTargetFinder,
          codeAttributeEditor,
          extraInstructionVisitor    );
}
 
Example 3
public ConfigurationLoggingInstructionSequenceReplacer(Constant[]          patternConstants,
                                                       Instruction[]       patternInstructions,
                                                       Constant[]          replacementConstants,
                                                       Instruction[]       replacementInstructions,
                                                       BranchTargetFinder  branchTargetFinder,
                                                       CodeAttributeEditor codeAttributeEditor,
                                                       InstructionVisitor  extraInstructionVisitor )
{
    super(patternConstants,
          patternInstructions,
          replacementConstants,
          replacementInstructions,
          branchTargetFinder,
          codeAttributeEditor,
          extraInstructionVisitor );
}
 
Example 4
/**
 * Creates an array of InstructionSequenceReplacer instances.
 * @param patternConstants        any constants referenced by the pattern
 *                                instruction.
 * @param instructionSequences    the instruction sequences to be replaced,
 *                                with subsequently the sequence pair index,
 *                                the from/to index (0 or 1), and the
 *                                instruction index in the sequence.
 * @param branchTargetFinder      a branch target finder that has been
 *                                initialized to indicate branch targets
 *                                in the visited code.
 * @param codeAttributeEditor     a code editor that can be used for
 *                                accumulating changes to the code.
 * @param extraInstructionVisitor an optional extra visitor for all deleted
 *                                load instructions.
 */
private static InstructionVisitor[] createInstructionSequenceReplacers(Constant[]          patternConstants,
                                                                       Instruction[][][]   instructionSequences,
                                                                       BranchTargetFinder  branchTargetFinder,
                                                                       CodeAttributeEditor codeAttributeEditor,
                                                                       InstructionVisitor extraInstructionVisitor)
{
    InstructionVisitor[] instructionSequenceReplacers =
        new InstructionSequenceReplacer[instructionSequences.length];

    for (int index = 0; index < instructionSequenceReplacers.length; index++)
    {
        Instruction[][] instructionSequencePair = instructionSequences[index];
        instructionSequenceReplacers[index] =
            new InstructionSequenceReplacer(patternConstants,
                                            instructionSequencePair[PATTERN_INDEX],
                                            instructionSequencePair[REPLACEMENT_INDEX],
                                            branchTargetFinder,
                                            codeAttributeEditor,
                                            extraInstructionVisitor);
    }

    return instructionSequenceReplacers;
}
 
Example 5
/**
 * Creates an array of InstructionSequenceReplacer instances.
 *
 * @param constants               any constants referenced by the pattern
 *                                instructions and replacement instructions.
 * @param instructionSequences    the instruction sequences to be replaced,
 *                                with subsequently the sequence pair index,
 *                                the from/to index (0 or 1), and the
 *                                instruction index in the sequence.
 * @param branchTargetFinder      a branch target finder that has been
 *                                initialized to indicate branch targets
 *                                in the visited code.
 * @param codeAttributeEditor     a code editor that can be used for
 *                                accumulating changes to the code.
 * @param extraInstructionVisitor an optional extra visitor for all deleted
 *                                load instructions.
 */
private static InstructionVisitor[] createInstructionSequenceReplacers(Constant[]          constants,
                                                                       Instruction[][][]   instructionSequences,
                                                                       BranchTargetFinder  branchTargetFinder,
                                                                       CodeAttributeEditor codeAttributeEditor,
                                                                       InstructionVisitor  extraInstructionVisitor)
{
    InstructionVisitor[] instructionSequenceReplacers =
        new InstructionSequenceReplacer[instructionSequences.length];

    for (int index = 0; index < instructionSequenceReplacers.length; index++)
    {
        Instruction[][] instructionSequencePair = instructionSequences[index];
        instructionSequenceReplacers[index] =
            new ConfigurationLoggingInstructionSequenceReplacer(constants,
                                                                instructionSequencePair[PATTERN_INDEX],
                                                                constants,
                                                                instructionSequencePair[REPLACEMENT_INDEX],
                                                                branchTargetFinder,
                                                                codeAttributeEditor,
                                                                extraInstructionVisitor);
    }

    return instructionSequenceReplacers;
}
 
Example 6
/**
 * Replaces the instruction at a given offset by a given push instruction.
 */
private void replaceInstruction(Clazz       clazz,
                                int         offset,
                                Instruction instruction,
                                Instruction replacementInstruction)
{
    // Pop unneeded stack entries if necessary.
    int popCount =
        instruction.stackPopCount(clazz) -
        replacementInstruction.stackPopCount(clazz);

    insertPopInstructions(offset, popCount);

    if (DEBUG) System.out.println("  Replacing instruction "+instruction.toString(offset)+" -> "+replacementInstruction.toString()+(popCount == 0 ? "" : " ("+popCount+" pops)"));

    codeAttributeEditor.replaceInstruction(offset, replacementInstruction);

    // Visit the instruction, if required.
    if (extraInstructionVisitor != null)
    {
        // Note: we're not passing the right arguments for now, knowing that
        // they aren't used anyway.
        instruction.accept(clazz, null, null, offset, extraInstructionVisitor);
    }
}
 
Example 7
public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
{
    Instruction patternInstruction = patternInstructions[patternInstructionIndex];

    // Check if the instruction matches the next instruction in the sequence.
    boolean condition =
        matchingOpcodes(simpleInstruction, patternInstruction) &&
        matchingArguments(simpleInstruction.constant,
                          ((SimpleInstruction)patternInstruction).constant);

    // Check if the instruction sequence is matching now.
    checkMatch(condition,
               clazz,
               method,
               codeAttribute,
               offset,
               simpleInstruction);
}
 
Example 8
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
    Instruction patternInstruction = patternInstructions[patternInstructionIndex];

    // Check if the instruction matches the next instruction in the sequence.
    boolean condition =
        matchingOpcodes(constantInstruction, patternInstruction) &&
        matchingConstantIndices(clazz,
                                constantInstruction.constantIndex,
                                ((ConstantInstruction)patternInstruction).constantIndex) &&
        matchingArguments(constantInstruction.constant,
                          ((ConstantInstruction)patternInstruction).constant);

    // Check if the instruction sequence is matching now.
    checkMatch(condition,
               clazz,
               method,
               codeAttribute,
               offset,
               constantInstruction);
}
 
Example 9
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
{
    Instruction patternInstruction = patternInstructions[patternInstructionIndex];

    // Check if the instruction matches the next instruction in the from
    // sequence.
    boolean condition =
        matchingOpcodes(branchInstruction, patternInstruction) &&
        matchingBranchOffsets(offset,
                              branchInstruction.branchOffset,
                              ((BranchInstruction)patternInstruction).branchOffset);

    // Check if the instruction sequence is matching now.
    checkMatch(condition,
               clazz,
               method,
               codeAttribute,
               offset,
               branchInstruction);
}
 
Example 10
public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)
{
    Instruction patternInstruction = patternInstructions[patternInstructionIndex];

    // Check if the instruction matches the next instruction in the sequence.
    boolean condition =
        matchingOpcodes(tableSwitchInstruction, patternInstruction) &&
        matchingBranchOffsets(offset,
                              tableSwitchInstruction.defaultOffset,
                              ((TableSwitchInstruction)patternInstruction).defaultOffset) &&
        matchingArguments(tableSwitchInstruction.lowCase,
                          ((TableSwitchInstruction)patternInstruction).lowCase)  &&
        matchingArguments(tableSwitchInstruction.highCase,
                          ((TableSwitchInstruction)patternInstruction).highCase) &&
        matchingJumpOffsets(offset,
                            tableSwitchInstruction.jumpOffsets,
                            ((TableSwitchInstruction)patternInstruction).jumpOffsets);

    // Check if the instruction sequence is matching now.
    checkMatch(condition,
               clazz,
               method,
               codeAttribute,
               offset,
               tableSwitchInstruction);
}
 
Example 11
public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
{
    Instruction patternInstruction = patternInstructions[patternInstructionIndex];

    // Check if the instruction matches the next instruction in the sequence.
    boolean condition =
        matchingOpcodes(lookUpSwitchInstruction, patternInstruction) &&
        matchingBranchOffsets(offset,
                              lookUpSwitchInstruction.defaultOffset,
                              ((LookUpSwitchInstruction)patternInstruction).defaultOffset) &&
        matchingArguments(lookUpSwitchInstruction.cases,
                          ((LookUpSwitchInstruction)patternInstruction).cases) &&
        matchingJumpOffsets(offset,
                            lookUpSwitchInstruction.jumpOffsets,
                            ((LookUpSwitchInstruction)patternInstruction).jumpOffsets);

    // Check if the instruction sequence is matching now.
    checkMatch(condition,
               clazz,
               method,
               codeAttribute,
               offset,
               lookUpSwitchInstruction);
}
 
Example 12
Source Project: java-n-IDE-for-Android   Source File: InstructionWriter.java    License: Apache License 2.0 6 votes vote down vote up
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).shrink();

        replaceInstruction(offset, replacementInstruction);

        // Write out a dummy constant instruction for now.
        constantInstruction.constantIndex = 0;
        constantInstruction.constant      = 0;
        constantInstruction.write(codeAttribute, offset);
    }
}
 
Example 13
Source Project: java-n-IDE-for-Android   Source File: InstructionWriter.java    License: Apache License 2.0 6 votes vote down vote up
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).shrink();

        replaceInstruction(offset, replacementInstruction);

        // Write out a dummy variable instruction for now.
        variableInstruction.variableIndex = 0;
        variableInstruction.constant      = 0;
        variableInstruction.write(codeAttribute, offset);
    }
}
 
Example 14
/**
 * Replaces the given instruction by an infinite loop.
 */
private void replaceByInfiniteLoop(Clazz       clazz,
                                   int         offset,
                                   Instruction instruction)
{
    // Replace the instruction by an infinite loop.
    Instruction replacementInstruction =
        new BranchInstruction(InstructionConstants.OP_GOTO, 0);

    if (DEBUG) System.out.println("  Replacing unreachable instruction by infinite loop "+replacementInstruction.toString(offset));

    codeAttributeEditor.replaceInstruction(offset, replacementInstruction);

    // Visit the instruction, if required.
    if (extraInstructionVisitor != null)
    {
        // Note: we're not passing the right arguments for now, knowing that
        // they aren't used anyway.
        instruction.accept(clazz, null, null, offset, extraInstructionVisitor);
    }
}
 
Example 15
/**
 * Replaces the reference pushing instruction at the given offset by a
 * simpler push instruction, if possible.
 */
private void replaceReferencePushInstruction(Clazz       clazz,
                                             int         offset,
                                             Instruction instruction)
{
    Value pushedValue = partialEvaluator.getStackAfter(offset).getTop(0);
    if (pushedValue.isParticular())
    {
        // A reference value can only be specific if it is null.
        replaceConstantPushInstruction(clazz,
                                       offset,
                                       instruction,
                                       InstructionConstants.OP_ACONST_NULL,
                                       0);
    }
}
 
Example 16
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor)
{
    if (instructionVisitor != CodeAttributeEditor.this)
    {
        throw new UnsupportedOperationException("Unexpected visitor ["+instructionVisitor+"]");
    }

    for (int index = 0; index < instructions.length; index++)
    {
        Instruction instruction = instructions[index];

        instruction.accept(clazz, method, codeAttribute, offset, CodeAttributeEditor.this);

        offset += instruction.length(offset);
    }
}
 
Example 17
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
{
    if (DEBUG)
    {
        System.out.println("  "+(reachableCodeMarker.isReachable(offset) ? "+" : "-")+" "+instruction.toString(offset));
    }

    // Is this instruction unreachable?
    if (!reachableCodeMarker.isReachable(offset))
    {
        // Then delete it.
        codeAttributeEditor.deleteInstruction(offset);

        // Visit the instruction, if required.
        if (extraInstructionVisitor != null)
        {
            instruction.accept(clazz, method, codeAttribute, offset, extraInstructionVisitor);
        }
    }
}
 
Example 18
/**
 * Replaces the instruction at a given offset by a given push instruction
 * of a variable.
 */
private void replaceVariablePushInstruction(Clazz       clazz,
                                            int         offset,
                                            Instruction instruction,
                                            byte        replacementOpcode,
                                            int         variableIndex)
{
    Instruction replacementInstruction =
        new VariableInstruction(replacementOpcode, variableIndex).shrink();

    replaceInstruction(clazz, offset, instruction, replacementInstruction);
}
 
Example 19
/**
 * Creates the replacement instruction for the given index in the
 * instruction sequence.
 */
public Instruction create(int index)
{
    // Create the instruction.
    replacementInstructions[index].accept(null,
                                          null,
                                          null,
                                          instructionSequenceMatcher.matchedInstructionOffset(index),
                                          this);

    // Return it.
    return replacementInstruction.shrink();
}
 
Example 20
public ConfigurationLoggingInstructionSequenceReplacer(Constant[]          patternConstants,
                                                       Instruction[]       patternInstructions,
                                                       Constant[]          replacementConstants,
                                                       Instruction[]       replacementInstructions,
                                                       BranchTargetFinder  branchTargetFinder,
                                                       CodeAttributeEditor codeAttributeEditor     )
{
    super(patternConstants,
          patternInstructions,
          replacementConstants,
          replacementInstructions,
          branchTargetFinder,
          codeAttributeEditor     );
}
 
Example 21
MyInstructionSequenceReplacer(Constant[]          constants,
                              Instruction[][][]   insSequences,
                              BranchTargetFinder  branchTargetFinder,
                              CodeAttributeEditor codeAttributeEditor)
{
    super(createInstructionSequenceReplacers(constants, insSequences, branchTargetFinder, codeAttributeEditor));
}
 
Example 22
/**
 * Deletes the given branch instruction, or replaces it by a simpler branch
 * instruction, if possible.
 */
private void replaceBranchInstruction(Clazz       clazz,
                                      int         offset,
                                      Instruction instruction)
{
    InstructionOffsetValue branchTargets = partialEvaluator.branchTargets(offset);

    // Is there exactly one branch target (not from a goto or jsr)?
    if (branchTargets != null &&
        branchTargets.instructionOffsetCount() == 1)
    {
        // Is it branching to the next instruction?
        int branchOffset = branchTargets.instructionOffset(0) - offset;
        if (branchOffset == instruction.length(offset))
        {
            if (DEBUG) System.out.println("  Ignoring zero branch instruction at ["+offset+"]");
        }
        else
        {
            // Replace the branch instruction by a simple branch instruction.
            Instruction replacementInstruction =
                new BranchInstruction(InstructionConstants.OP_GOTO_W,
                                      branchOffset).shrink();

            replaceInstruction(clazz, offset, instruction, replacementInstruction);
        }
    }
}
 
Example 23
Source Project: java-n-IDE-for-Android   Source File: EvaluationShrinker.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Replaces the instruction at a given offset by a static invocation.
 */
private void replaceByStaticInvocation(Clazz               clazz,
                                       int                 offset,
                                       ConstantInstruction constantInstruction)
{
    // Remember the replacement instruction.
    Instruction replacementInstruction =
         new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC,
                                 constantInstruction.constantIndex).shrink();

    if (DEBUG) System.out.println("  Replacing by static invocation "+constantInstruction.toString(offset)+" -> "+replacementInstruction.toString());

    codeAttributeEditor.replaceInstruction(offset, replacementInstruction);
}
 
Example 24
Source Project: java-n-IDE-for-Android   Source File: CodeAttribute.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Applies the given instruction visitor to all instructions in the
 * specified range of offsets.
 */
public void instructionsAccept(Clazz clazz, Method method, int startOffset, int endOffset, InstructionVisitor instructionVisitor)
{
    int offset = startOffset;

    while (offset < endOffset)
    {
        // Note that the instruction is only volatile.
        Instruction instruction = InstructionFactory.create(code, offset);
        int instructionLength = instruction.length(offset);
        instruction.accept(clazz, method, this, offset, instructionVisitor);
        offset += instructionLength;
    }
}
 
Example 25
Source Project: java-n-IDE-for-Android   Source File: InstructionCounter.java    License: Apache License 2.0 5 votes vote down vote up
public void visitAnyInstruction(Clazz clazz,
                                Method        method,
                                CodeAttribute codeAttribute,
                                int           offset,
                                Instruction instruction)
{
    count++;
}
 
Example 26
/**
 * Returns whether the specified block of code may throw exceptions.
 */
private boolean mayThrowExceptions(Clazz         clazz,
                                   Method        method,
                                   CodeAttribute codeAttribute,
                                   int           startOffset,
                                   int           endOffset)
{
    byte[] code = codeAttribute.code;

    // Go over all instructions.
    int offset = startOffset;
    while (offset < endOffset)
    {
        // Get the current instruction.
        Instruction instruction = InstructionFactory.create(code, offset);

        // Check if it may be throwing exceptions.
        if (exceptionInstructionChecker.mayThrowExceptions(clazz,
                                                           method,
                                                           codeAttribute,
                                                           offset,
                                                           instruction))
        {
            return true;
        }

        // Go to the next instruction.
        offset += instruction.length(offset);
    }

    return false;
}
 
Example 27
public Instruction shrink()
{
    for (int index = 0; index < instructions.length; index++)
    {
        instructions[index] = instructions[index].shrink();
    }

    return this;
}
 
Example 28
Source Project: java-n-IDE-for-Android   Source File: GotoReturnReplacer.java    License: Apache License 2.0 5 votes vote down vote up
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
{
    // Check if the instruction is an unconditional goto instruction.
    byte opcode = branchInstruction.opcode;
    if (opcode == InstructionConstants.OP_GOTO ||
        opcode == InstructionConstants.OP_GOTO_W)
    {
        // Check if the goto instruction points to a return instruction.
        int targetOffset = offset + branchInstruction.branchOffset;

        if (!codeAttributeEditor.isModified(offset) &&
            !codeAttributeEditor.isModified(targetOffset))
        {
            Instruction targetInstruction = InstructionFactory.create(codeAttribute.code,
                                                                      targetOffset);
            switch (targetInstruction.opcode)
            {
                case InstructionConstants.OP_IRETURN:
                case InstructionConstants.OP_LRETURN:
                case InstructionConstants.OP_FRETURN:
                case InstructionConstants.OP_DRETURN:
                case InstructionConstants.OP_ARETURN:
                case InstructionConstants.OP_RETURN:
                    // Replace the goto instruction by the return instruction.
                    Instruction returnInstruction =
                         new SimpleInstruction(targetInstruction.opcode);
                    codeAttributeEditor.replaceInstruction(offset,
                                                           returnInstruction);

                    // Visit the instruction, if required.
                    if (extraInstructionVisitor != null)
                    {
                        extraInstructionVisitor.visitBranchInstruction(clazz, method, codeAttribute, offset, branchInstruction);
                    }

                    break;
            }
        }
    }
}
 
Example 29
Source Project: java-n-IDE-for-Android   Source File: InstructionWriter.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example 30
Source Project: java-n-IDE-for-Android   Source File: InstructionAdder.java    License: Apache License 2.0 5 votes vote down vote up
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
    // Create a copy of the instruction.
    Instruction newConstantInstruction =
        new ConstantInstruction(constantInstruction.opcode,
                                constantAdder.addConstant(clazz, constantInstruction.constantIndex),
                                constantInstruction.constant).shrink();

    // Add the instruction.
    codeAttributeComposer.appendInstruction(offset, newConstantInstruction);
}