Java Code Examples for proguard.evaluation.value.InstructionOffsetValue#instructionOffset()

The following examples show how to use proguard.evaluation.value.InstructionOffsetValue#instructionOffset() . 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
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Marks the variable and its producing instructions at the given offsets.
 * @param producerOffsets the offsets of the producers to be marked.
 * @param variableIndex   the index of the variable to be marked.
 */
private void markVariableProducers(InstructionOffsetValue producerOffsets,
                                   int                    variableIndex)
{
    if (producerOffsets != null)
    {
        int offsetCount = producerOffsets.instructionOffsetCount();
        for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
        {
            // Make sure the variable and the instruction are marked
            // at the producing offset.
            int offset = producerOffsets.instructionOffset(offsetIndex);

            markVariableAfter(offset, variableIndex);
            markInstruction(offset);
        }
    }
}
 
Example 2
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Marks the stack entry and its producing instructions at the given
 * offsets.
 * @param producerOffsets the offsets of the producers to be marked.
 * @param stackIndex      the index of the stack entry to be marked
 *                        (counting from the bottom).
 */
private void markStackEntryProducers(InstructionOffsetValue producerOffsets,
                                     int                    stackIndex)
{
    if (producerOffsets != null)
    {
        int offsetCount = producerOffsets.instructionOffsetCount();
        for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
        {
            // Make sure the stack entry and the instruction are marked
            // at the producing offset.
            int offset = producerOffsets.instructionOffset(offsetIndex);

            markStackEntryAfter(offset, stackIndex);
            markInstruction(offset);
        }
    }
}
 
Example 3
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Returns whether all of the given instruction offsets (at least one)
 * are smaller than or equal to the given offset.
 */
private boolean isAllSmallerThanOrEqual(InstructionOffsetValue instructionOffsets,
                                        int                    instructionOffset)
{
    if (instructionOffsets != null)
    {
        // Loop over all instruction offsets.
        int branchCount = instructionOffsets.instructionOffsetCount();
        if (branchCount > 0)
        {
            for (int branchIndex = 0; branchIndex < branchCount; branchIndex++)
            {
                // Is the offset larger than the reference offset?
                if (instructionOffsets.instructionOffset(branchIndex) > instructionOffset)
                {
                    return false;
                }
            }

            return true;
        }
    }

    return false;
}
 
Example 4
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Returns whether any of the given instruction offsets (at least one)
 * is larger than the given offset.
 */
private boolean isAnyLargerThan(InstructionOffsetValue instructionOffsets,
                                int                    instructionOffset)
{
    if (instructionOffsets != null)
    {
        // Loop over all instruction offsets.
        int branchCount = instructionOffsets.instructionOffsetCount();
        if (branchCount > 0)
        {
            for (int branchIndex = 0; branchIndex < branchCount; branchIndex++)
            {
                // Is the offset larger than the reference offset?
                if (instructionOffsets.instructionOffset(branchIndex) > instructionOffset)
                {
                    return true;
                }
            }
        }
    }

    return false;
}
 
Example 5
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Marks the stack entries after the given offsets.
 * @param instructionOffsets the offsets of the stack entries to be marked.
 * @param stackIndex         the index of the stack entries to be marked
 *                           (counting from the bottom).
 */
private void markStackEntriesAfter(InstructionOffsetValue instructionOffsets,
                                   int                    stackIndex)
{
    if (instructionOffsets != null)
    {
        int offsetCount = instructionOffsets.instructionOffsetCount();
        for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
        {
            // Make sure the stack entry and the instruction are marked
            // at the producing offset.
            int offset = instructionOffsets.instructionOffset(offsetIndex);

            markStackEntryAfter(offset, stackIndex);
        }
    }
}
 
Example 6
Source File: LivenessAnalyzer.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the combined liveness mask of the variables right before the
 * specified instruction offsets.
 */
private long combinedLiveness(InstructionOffsetValue instructionOffsetValue)
{
    long alive = 0L;

    int count = instructionOffsetValue.instructionOffsetCount();
    for (int index = 0; index < count; index++)
    {
        alive |= isAliveBefore[instructionOffsetValue.instructionOffset(index)];
    }

    return alive;
}
 
Example 7
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * Marks the branch instructions of straddling branches, if they straddle
 * some code that has been marked.
 * @param instructionOffset   the offset of the branch origin or branch target.
 * @param branchOffsets       the offsets of the straddling branch targets
 *                            or branch origins.
 * @param isPointingToTargets <code>true</code> if the above offsets are
 *                            branch targets, <code>false</code> if they
 *                            are branch origins.
 */
private void markStraddlingBranches(int                    instructionOffset,
                                    InstructionOffsetValue branchOffsets,
                                    boolean                isPointingToTargets)
{
    if (branchOffsets != null)
    {
        // Loop over all branch offsets.
        int branchCount = branchOffsets.instructionOffsetCount();
        for (int branchIndex = 0; branchIndex < branchCount; branchIndex++)
        {
            // Is the branch straddling forward any necessary instructions?
            int branchOffset = branchOffsets.instructionOffset(branchIndex);

            // Is the offset pointing to a branch origin or to a branch target?
            if (isPointingToTargets)
            {
                markStraddlingBranch(instructionOffset,
                                     branchOffset,
                                     instructionOffset,
                                     branchOffset);
            }
            else
            {
                markStraddlingBranch(instructionOffset,
                                     branchOffset,
                                     branchOffset,
                                     instructionOffset);
            }
        }
    }
}
 
Example 8
Source File: EvaluationSimplifier.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * 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 9
Source File: TypeArgumentFinder.java    From proguard with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void visitVariableInstruction(Clazz               clazz,
                                     Method              method,
                                     CodeAttribute       codeAttribute,
                                     int                 offset,
                                     VariableInstruction variableInstruction)
{
    if (variableInstruction.canonicalOpcode() == Instruction.OP_ALOAD)
    {
        // Find the operation that stored the loaded Type.
        LastStoreFinder lastStoreFinder = new LastStoreFinder(variableInstruction.variableIndex);
        codeAttribute.instructionsAccept(clazz, method, 0, offset, lastStoreFinder);

        if (lastStoreFinder.lastStore != null)
        {
            // Find out which instruction produced the stored Type.
            TracedStack stackBeforeStore = partialEvaluator.getStackBefore(lastStoreFinder.lastStoreOffset);
            InstructionOffsetValue instructionOffsetValue = stackBeforeStore.getTopProducerValue(0).instructionOffsetValue();

            // Derive the signature of the subclass of TypeToken from which the Type is retrieved.
            TypeTokenSignatureFinder typeTokenFinder = new TypeTokenSignatureFinder();
            for (int offsetIndex = 0; offsetIndex < instructionOffsetValue.instructionOffsetCount(); offsetIndex++)
            {
                int instructionOffset = instructionOffsetValue.instructionOffset(offsetIndex);
                codeAttribute.instructionAccept(clazz, method, instructionOffset, typeTokenFinder);
            }

            // Derive the classes from the signature of the TypeToken subclass.
            if (typeTokenFinder.typeTokenSignature != null)
            {
                typeArgumentClasses = new String[0];
                Clazz[] referencedClasses = typeTokenFinder.typeTokenSignature.referencedClasses;
                for (Clazz referencedClass : referencedClasses)
                {
                    if (referencedClass!= null &&
                        !referencedClass.getName().equals(GsonClassConstants.NAME_TYPE_TOKEN))
                    {
                        typeArgumentClasses = ArrayUtil.add(typeArgumentClasses,
                                                            typeArgumentClasses.length,
                                                            referencedClass.getName());
                    }
                }
            }
        }
    }
}
 
Example 10
Source File: CodePreverifier.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
/**
 * Creates and returns the verification type corresponding to the given
 * value. If necessary, a class constant is added to the constant pool of
 * the given class.
 */
private VerificationType correspondingVerificationType(ProgramClass  programClass,
                                                       ProgramMethod programMethod,
                                                       CodeAttribute codeAttribute,
                                                       int           offset,
                                                       boolean       isVariable0,
                                                       Value value,
                                                       Value producerValue)
{
    if (value == null)
    {
        return VerificationTypeFactory.createTopType();
    }

    int type = value.computationalType();

    switch (type)
    {
        case Value.TYPE_INSTRUCTION_OFFSET:
        case Value.TYPE_INTEGER:   return VerificationTypeFactory.createIntegerType();
        case Value.TYPE_LONG:      return VerificationTypeFactory.createLongType();
        case Value.TYPE_FLOAT:     return VerificationTypeFactory.createFloatType();
        case Value.TYPE_DOUBLE:    return VerificationTypeFactory.createDoubleType();
        case Value.TYPE_TOP:       return VerificationTypeFactory.createTopType();
        case Value.TYPE_REFERENCE:
            // Is it a Null type?
            ReferenceValue referenceValue = value.referenceValue();
            if (referenceValue.isNull() == Value.ALWAYS)
            {
                return VerificationTypeFactory.createNullType();
            }

            // Does the reference type have a single producer?
            if (offset != PartialEvaluator.AT_METHOD_ENTRY)
            {
                InstructionOffsetValue producers = producerValue.instructionOffsetValue();
                if (producers.instructionOffsetCount() == 1)
                {
                    int producerOffset = producers.instructionOffset(0);

                    // Follow any dup or swap instructions.
                    while (producerOffset != PartialEvaluator.AT_METHOD_ENTRY &&
                           isDupOrSwap(codeAttribute.code[producerOffset]))
                    {
                        producers      = partialEvaluator.getStackBefore(producerOffset).getTopProducerValue(0).instructionOffsetValue();
                        producerOffset = producers.instructionOffset(0);
                    }

                    // Are we in an instance initialization method,
                    // before the super initialization, loading "this"?
                    if (partialEvaluator.isInitializer()                       &&
                        offset <= partialEvaluator.superInitializationOffset() &&
                        (isVariable0 ||
                         producerOffset > PartialEvaluator.AT_METHOD_ENTRY &&
                         codeAttribute.code[producerOffset] == InstructionConstants.OP_ALOAD_0))
                    {
                        // It's an UninitializedThis type.
                        return VerificationTypeFactory.createUninitializedThisType();
                    }

                    // Is the reference type newly created and still
                    // uninitialized?
                    if (producerOffset > PartialEvaluator.AT_METHOD_ENTRY &&
                        offset <= partialEvaluator.initializationOffset(producerOffset))
                    {
                        // It's an Uninitialized type.
                        return VerificationTypeFactory.createUninitializedType(producerOffset);
                    }
                }
            }

            // It's an ordinary Object type.
            return VerificationTypeFactory.createObjectType(createClassConstant(programClass, referenceValue));
    }

    throw new IllegalArgumentException("Unknown computational type ["+type+"]");
}
 
Example 11
Source File: EvaluationSimplifier.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
/**
 * Makes sure all branch targets of the given switch instruction are valid.
 */
private void replaceSwitchInstruction(Clazz             clazz,
                                      int               offset,
                                      SwitchInstruction switchInstruction)
{
    // Get the actual branch targets.
    InstructionOffsetValue branchTargets = partialEvaluator.branchTargets(offset);

    // Get an offset that can serve as a valid default offset.
    int defaultOffset =
        branchTargets.instructionOffset(branchTargets.instructionOffsetCount()-1) -
        offset;

    Instruction replacementInstruction = null;

    // Check the jump offsets.
    int[] jumpOffsets = switchInstruction.jumpOffsets;
    for (int index = 0; index < jumpOffsets.length; index++)
    {
        if (!branchTargets.contains(offset + jumpOffsets[index]))
        {
            // Replace the unused offset.
            jumpOffsets[index] = defaultOffset;

            // Remember to replace the instruction.
            replacementInstruction = switchInstruction;
        }
    }

    // Check the default offset.
    if (!branchTargets.contains(offset + switchInstruction.defaultOffset))
    {
        // Replace the unused offset.
        switchInstruction.defaultOffset = defaultOffset;

        // Remember to replace the instruction.
        replacementInstruction = switchInstruction;
    }

    if (replacementInstruction != null)
    {
        replaceInstruction(clazz, offset, switchInstruction, replacementInstruction);
    }
}