⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 partialevaluator.java

📁 ProGuard 是一个免费的 Java类文件的压缩
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * ProGuard -- shrinking, optimization, obfuscation, and preverification *             of Java bytecode. * * Copyright (c) 2002-2007 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.optimize.evaluation;import proguard.classfile.*;import proguard.classfile.visitor.*;import proguard.classfile.attribute.*;import proguard.classfile.attribute.visitor.*;import proguard.classfile.instruction.*;import proguard.classfile.util.*;import proguard.evaluation.*;import proguard.evaluation.value.*;import proguard.optimize.peephole.BranchTargetFinder;/** * This AttributeVisitor performs partial evaluation on the code attributes * that it visits. * * @author Eric Lafortune */public class PartialEvaluatorextends      SimplifiedVisitorimplements   AttributeVisitor,             ExceptionInfoVisitor{    //*    private static final boolean DEBUG         = false;    private static final boolean DEBUG_RESULTS = false;    /*/    private static boolean DEBUG         = true;    private static boolean DEBUG_RESULTS = true;    //*/    private static final int MAXIMUM_EVALUATION_COUNT = 5;    public static final int NONE            = -2;    public static final int AT_METHOD_ENTRY = -1;    public static final int AT_CATCH_ENTRY  = -1;    private ValueFactory   valueFactory;    private InvocationUnit invocationUnit;    private boolean        evaluateAllCode;    private InstructionOffsetValue[] varProducerValues     = new InstructionOffsetValue[ClassConstants.TYPICAL_CODE_LENGTH];    private InstructionOffsetValue[] stackProducerValues   = new InstructionOffsetValue[ClassConstants.TYPICAL_CODE_LENGTH];    private InstructionOffsetValue[] branchOriginValues    = new InstructionOffsetValue[ClassConstants.TYPICAL_CODE_LENGTH];    private InstructionOffsetValue[] branchTargetValues    = new InstructionOffsetValue[ClassConstants.TYPICAL_CODE_LENGTH];    private TracedVariables[]        variablesBefore       = new TracedVariables[ClassConstants.TYPICAL_CODE_LENGTH];    private TracedStack[]            stacksBefore          = new TracedStack[ClassConstants.TYPICAL_CODE_LENGTH];    private TracedVariables[]        variablesAfter        = new TracedVariables[ClassConstants.TYPICAL_CODE_LENGTH];    private TracedStack[]            stacksAfter           = new TracedStack[ClassConstants.TYPICAL_CODE_LENGTH];    private boolean[]                generalizedContexts   = new boolean[ClassConstants.TYPICAL_CODE_LENGTH];    private int[]                    evaluationCounts      = new int[ClassConstants.TYPICAL_CODE_LENGTH];    private int[]                    initializedVariables  = new int[ClassConstants.TYPICAL_CODE_LENGTH];    private boolean                  evaluateExceptions;    private BasicBranchUnit    branchUnit;    private BranchTargetFinder branchTargetFinder = new BranchTargetFinder();//    private ClassCleaner       classCleaner       = new ClassCleaner();    /**     * Creates a new PartialEvaluator.     */    public PartialEvaluator()    {        this(new ValueFactory(), new BasicInvocationUnit(), true);    }    /**     * Creates a new PartialEvaluator.     * @param valueFactory    the value factory that will create all values     *                        during evaluation.     * @param invocationUnit  the invocation unit that will handle all     *                        communication with other fields and methods.     * @param evaluateAllCode a flag that specifies whether all branch targets     *                        and exception 'catch' blocks should be evaluated,     *                        even if they are unreachable.     */    public PartialEvaluator(ValueFactory   valueFactory,                            InvocationUnit invocationUnit,                            boolean        evaluateAllCode)    {        this.valueFactory    = valueFactory;        this.invocationUnit  = invocationUnit;        this.evaluateAllCode = evaluateAllCode;        this.branchUnit = evaluateAllCode ?            new BasicBranchUnit() :            new TracedBranchUnit();    }    // Implementations for AttributeVisitor.    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)    {        // TODO: Remove this when the partial evaluator has stabilized.        // Catch any unexpected exceptions from the actual visiting method.        try        {            // Process the code.            visitCodeAttribute0(clazz, method, codeAttribute);        }        catch (RuntimeException ex)        {            System.err.println("Unexpected error while performing partial evaluation:");            System.err.println("  Class       = ["+clazz.getName()+"]");            System.err.println("  Method      = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");            System.err.println("  Exception   = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");            if (DEBUG)            {                method.accept(clazz, new ClassPrinter());            }            throw ex;        }    }    public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute)    {//        DEBUG = DEBUG_RESULTS =//            clazz.getName().equals("abc/Def") &&//            method.getName(clazz).equals("abc");        // Evaluate the instructions, starting at the entry point.        if (DEBUG)        {            System.out.println();            System.out.println("Partial evaluation: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));            System.out.println("  Max locals = "+codeAttribute.u2maxLocals);            System.out.println("  Max stack  = "+codeAttribute.u2maxStack);        }        // Reuse the existing variables and stack objects, ensuring the right size.        TracedVariables variables = new TracedVariables(codeAttribute.u2maxLocals);        TracedStack     stack     = new TracedStack(codeAttribute.u2maxStack);        // Initialize the reusable arrays and variables.        initializeVariables(clazz, method, codeAttribute, variables, stack);        // Find all instruction offsets,...        codeAttribute.accept(clazz, method, branchTargetFinder);        evaluateInstructionBlock(clazz,                                 method,                                 codeAttribute,                                 variables,                                 stack,                                 0);        // Evaluate the exception catch blocks, until their entry variables        // have stabilized.        do        {            // Reset the flag to stop evaluating.            evaluateExceptions = false;            // Evaluate all relevant exception catch blocks once.            codeAttribute.exceptionsAccept(clazz, method, this);        }        while (evaluateExceptions);        int codeLength = codeAttribute.u4codeLength;        if (DEBUG_RESULTS)        {            System.out.println("Evaluation results:");            int offset = 0;            do            {                if (isBranchOrExceptionTarget(offset))                {                    System.out.println("Branch target:");                    System.out.println("  Vars:  "+variablesBefore[offset]);                    System.out.println("  Stack: "+stacksBefore[offset]);                }                Instruction instruction = InstructionFactory.create(codeAttribute.code,                                                                    offset);                System.out.println(instruction.toString(offset));                if (isTraced(offset))                {                    InstructionOffsetValue varProducerOffsets = varProducerOffsets(offset);                    if (varProducerOffsets.instructionOffsetCount() > 0)                    {                        System.out.println("     has overall been using information from instructions setting vars: "+varProducerOffsets);                    }                    InstructionOffsetValue stackProducerOffsets = stackProducerOffsets(offset);                    if (stackProducerOffsets.instructionOffsetCount() > 0)                    {                        System.out.println("     has overall been using information from instructions setting stack: "+stackProducerOffsets);                    }                    int initializationOffset = branchTargetFinder.initializationOffset(offset);                    if (initializationOffset != NONE)                    {                        System.out.println("     is to be initialized at ["+initializationOffset+"]");                    }                    InstructionOffsetValue branchTargets = branchTargets(offset);                    if (branchTargets != null)                    {                        System.out.println("     has overall been branching to "+branchTargets);                    }                    System.out.println("  Vars:  "+variablesAfter[offset]);                    System.out.println("  Stack: "+stacksAfter[offset]);                }                offset += instruction.length(offset);            }            while (offset < codeLength);        }    }    /**     * Returns whether a block of instructions is ever used.     */    public boolean isTraced(int startOffset, int endOffset)    {        for (int index = startOffset; index < endOffset; index++)        {            if (isTraced(index))            {                return true;            }        }        return false;    }    /**     * Returns whether the instruction at the given offset has ever been     * executed during the partial evaluation.     */    public boolean isTraced(int instructionOffset)    {        return evaluationCounts[instructionOffset] > 0;    }    /**     * Returns whether the instruction at the given offset is the target of a     * branch instruction or an exception.     */    public boolean isBranchOrExceptionTarget(int instructionOffset)    {        return branchTargetFinder.isBranchTarget(instructionOffset) ||               branchTargetFinder.isExceptionHandler(instructionOffset);    }    /**     * Returns whether the instruction at the given offset is part of a     * subroutine.     */    public boolean isSubroutine(int instructionOffset)    {        return branchTargetFinder.isSubroutine(instructionOffset);    }    /**     * Returns whether the subroutine at the given offset is ever returning     * by means of a regular 'ret' instruction.     */    public boolean isSubroutineReturning(int instructionOffset)    {        return branchTargetFinder.isSubroutineReturning(instructionOffset);    }    /**     * Returns the offset after the subroutine that starts at the given     * offset.     */    public int subroutineEnd(int instructionOffset)    {        return branchTargetFinder.subroutineEnd(instructionOffset);    }    /**     * Returns the instruction offset at which the object instance that is     * created at the given 'new' instruction offset is initialized, or     * <code>NONE</code> if it is not being created.     */    public int initializationOffset(int instructionOffset)    {        return branchTargetFinder.initializationOffset(instructionOffset);    }    /**     * Returns whether the method is an instance initializer.     */    public boolean isInitializer()    {        return branchTargetFinder.isInitializer();    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -