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

📄 branchtargetfinder.java

📁 ProGuard 是一个免费的 Java类文件的压缩
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        codeAttribute.instructionsAccept(clazz, method, this);        // Mark branch targets in the exception table.        codeAttribute.exceptionsAccept(clazz, method, this);        // Fill out the subroutine flags and ends, working backward.        boolean isSubroutine          = false;        boolean isSubroutineReturning = false;        int     subroutineEnd         = codeLength;        for (int index = codeLength - 1; index >= 0; index--)        {            if (isInstruction(index))            {                // Did we hit a marked subroutine instruction?                if (isSubroutine(index))                {                    // Remember that we're inside a subroutine.                    isSubroutine = true;                    // Remember if the subroutine is returning.                    if (isSubroutineReturning(index))                    {                        isSubroutineReturning = true;                    }                    // Have we reached the start of the subroutine?                    if (isSubroutineStart(index))                    {                        // Mark all subroutine instructions.                        int flags = isSubroutineReturning ?                            SUBROUTINE | SUBROUTINE_RETURNING :                            SUBROUTINE;                        for (int subroutineIndex = index;                             subroutineIndex < subroutineEnd;                             subroutineIndex++)                        {                            if (isInstruction(subroutineIndex))                            {                                // Set the subroutine flags.                                instructionMarks[subroutineIndex] |= flags;                                // Fill out the subroutine start and end.                                subroutineStarts[subroutineIndex] = index;                                subroutineEnds[subroutineIndex]   = subroutineEnd;                            }                        }                        // Reset the subroutine flags.                        isSubroutine          = false;                        isSubroutineReturning = false;                    }                }                // Are we not inside a subroutine?                if (!isSubroutine)                {                    // Reset the potential subroutine end.                    subroutineEnd = index;                }            }        }        // Fill out the unreachable flags.        boolean unreachable = false;        for (int index = 0; index < codeLength; index++)        {            if (isInstruction(index))            {                // Should we stop or start marking unreachable code?                if (isBranchTarget(index) ||                    isExceptionHandler(index))                {                    unreachable = false;                }                else if (isAfterBranch(index))                {                    unreachable = true;                }                if (unreachable)                {                    // Set the unreachable flag.                    instructionMarks[index] |= UNREACHABLE;                }            }        }    }    // Implementations for InstructionVisitor.    public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)    {        // Mark the instruction.        instructionMarks[offset] |= INSTRUCTION;        // Check if this is the first instruction of a subroutine.        checkSubroutineStart(offset);        byte opcode = simpleInstruction.opcode;        if (opcode == InstructionConstants.OP_IRETURN ||            opcode == InstructionConstants.OP_LRETURN ||            opcode == InstructionConstants.OP_FRETURN ||            opcode == InstructionConstants.OP_DRETURN ||            opcode == InstructionConstants.OP_ARETURN ||            opcode == InstructionConstants.OP_ATHROW)        {            // Mark the branch origin.            markBranchOrigin(offset);            // Mark the next instruction.            markAfterBranchOrigin(offset + simpleInstruction.length(offset));        }    }    public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)    {        // Mark the instruction.        instructionMarks[offset] |= INSTRUCTION;        // Check if this is the first instruction of a subroutine.        checkSubroutineStart(offset);        // Check if the instruction is a 'new' instruction.        if (constantInstruction.opcode == InstructionConstants.OP_NEW)        {            // Push the 'new' instruction offset on the stack.            recentCreationOffsets[recentCreationOffsetIndex++] = offset;        }        else        {            // Check if the instruction is an initializer invocation.            isInitializer = false;            clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);            if (isInitializer)            {                // Pop the 'new' instruction offset from the stack.                int recentCreationOffset = recentCreationOffsets[--recentCreationOffsetIndex];                // Fill it out in the creation offsets.                creationOffsets[offset] = recentCreationOffset;                // Fill out the initialization offsets.                if (recentCreationOffset == AT_METHOD_ENTRY)                {                    superInitializationOffset = offset;                }                else                {                    initializationOffsets[recentCreationOffset] = offset;                }            }        }    }    public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)    {        // Mark the instruction.        instructionMarks[offset] |= INSTRUCTION;        // Check if this is the first instruction of a subroutine.        checkSubroutineStart(offset);        if (variableInstruction.opcode == InstructionConstants.OP_RET)        {            // Mark the branch origin.            markBranchOrigin(offset);            // Mark the regular subroutine return.            instructionMarks[offset] |= SUBROUTINE | SUBROUTINE_RETURNING;            // Mark the next instruction.            markAfterBranchOrigin(offset + variableInstruction.length(offset));        }    }    public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)    {        // Mark the branch origin.        markBranchOrigin(offset);        // Check if this is the first instruction of a subroutine.        checkSubroutineStart(offset);        // Mark the branch target.        markBranchTarget(offset + branchInstruction.branchOffset);        byte opcode = branchInstruction.opcode;        if (opcode == InstructionConstants.OP_JSR ||            opcode == InstructionConstants.OP_JSR_W)        {            // Mark the subroutine invocation.            instructionMarks[offset] |= SUBROUTINE_INVOCATION;            // Mark the subroutine start.            instructionMarks[offset + branchInstruction.branchOffset] |=                SUBROUTINE | SUBROUTINE_START;        }        else if (opcode == InstructionConstants.OP_GOTO ||                 opcode == InstructionConstants.OP_GOTO_W)        {            // Mark the next instruction.            markAfterBranchOrigin(offset + branchInstruction.length(offset));        }    }    public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)    {        // Mark the branch origin.        markBranchOrigin(offset);        // Check if this is the first instruction of a subroutine.        checkSubroutineStart(offset);        // Mark the branch targets of the default jump offset.        markBranchTarget(offset + tableSwitchInstruction.defaultOffset);        // Mark the branch targets of the jump offsets.        markBranchTargets(offset,                          tableSwitchInstruction.jumpOffsets,                          tableSwitchInstruction.highCase -                          tableSwitchInstruction.lowCase + 1);        // Mark the next instruction.        markAfterBranchOrigin(offset + tableSwitchInstruction.length(offset));    }    public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)    {        // Mark the branch origin.        markBranchOrigin(offset);        // Check if this is the first instruction of a subroutine.        checkSubroutineStart(offset);        // Mark the branch targets of the default jump offset.        markBranchTarget(offset + lookUpSwitchInstruction.defaultOffset);        // Mark the branch targets of the jump offsets.        markBranchTargets(offset,                          lookUpSwitchInstruction.jumpOffsets,                          lookUpSwitchInstruction.jumpOffsetCount);        // Mark the next instruction.        markAfterBranchOrigin(offset + lookUpSwitchInstruction.length(offset));    }    // Implementations for ConstantVisitor.    public void visitAnyConstant(Clazz clazz, Constant constant) {}    public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)    {        isInitializer = methodrefConstant.getName(clazz).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT);    }    // Implementations for ExceptionInfoVisitor.    public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)    {        // Remap the code offsets. Note that the branch target array also has        // an entry for the first offset after the code, for u2endPC.        instructionMarks[exceptionInfo.u2startPC]   |= EXCEPTION_START;        instructionMarks[exceptionInfo.u2endPC]     |= EXCEPTION_END;        instructionMarks[exceptionInfo.u2handlerPC] |= EXCEPTION_HANDLER;    }    // Small utility methods.    /**     * Marks the branch targets of the given jump offsets for the instruction     * at the given offset.     */    private void markBranchTargets(int offset, int[] jumpOffsets, int length)    {        for (int index = 0; index < length; index++)        {            markBranchTarget(offset + jumpOffsets[index]);        }    }    /**     * Marks the branch origin at the given offset.     */    private void markBranchOrigin(int offset)    {        instructionMarks[offset] |= INSTRUCTION | BRANCH_ORIGIN;        // Remember the minimum offset of the end of the current subroutine.        if (minimumSubroutineEnd < offset)        {            minimumSubroutineEnd = offset;            instructionMarks[offset] |= SUBROUTINE;        }    }    /**     * Marks the branch target at the given offset.     */    private void markBranchTarget(int offset)    {        instructionMarks[offset] |= BRANCH_TARGET;        // Remember the minimum offset of the end of the current subroutine.        if (minimumSubroutineEnd < offset)        {            minimumSubroutineEnd = offset;            instructionMarks[offset] |= SUBROUTINE;        }    }    /**     * Marks the instruction at the given offset, after a branch.     */    private void markAfterBranchOrigin(int nextOffset)    {        instructionMarks[nextOffset] |= AFTER_BRANCH;        // Check if this is a backward branch that marks the end of a subroutine.        if (minimumSubroutineEnd < nextOffset && !isSubroutine(nextOffset))        {            minimumSubroutineEnd = Integer.MAX_VALUE;        }    }    /**     * Checks if the specified instruction is a subroutine end.     */    private void checkSubroutineStart(int offset)    {        // Start looking for a subroutine end if this is a subroutine start.        if (isSubroutineStart(offset))        {            minimumSubroutineEnd = offset;        }    }}

⌨️ 快捷键说明

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