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

📄 codeattributecomposer.java

📁 ProGuard 是一个免费的 Java类文件的压缩
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        localVariableTableAttribute.u2localVariableTableLength =            removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable,                                      localVariableTableAttribute.u2localVariableTableLength,                                      codeAttribute.u2maxLocals);    }    public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)    {        // Remap all local variable table entries.        localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);        // Remove local variables with empty code blocks.        localVariableTypeTableAttribute.u2localVariableTypeTableLength =            removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,                                          localVariableTypeTableAttribute.u2localVariableTypeTableLength,                                          codeAttribute.u2maxLocals);    }    // Implementations for InstructionVisitor.    public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}    public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)    {        // Adjust the branch offset.        branchInstruction.branchOffset = remapBranchOffset(offset,                                                           branchInstruction.branchOffset);    }    public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)    {        // Adjust the default jump offset.        tableSwitchInstruction.defaultOffset = remapBranchOffset(offset,                                                                 tableSwitchInstruction.defaultOffset);        // Adjust the jump offsets.        remapJumpOffsets(offset,                         tableSwitchInstruction.jumpOffsets,                         tableSwitchInstruction.highCase -                         tableSwitchInstruction.lowCase + 1);    }    public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)    {        // Adjust the default jump offset.        lookUpSwitchInstruction.defaultOffset = remapBranchOffset(offset,                                                                  lookUpSwitchInstruction.defaultOffset);        // Adjust the jump offsets.        remapJumpOffsets(offset,                         lookUpSwitchInstruction.jumpOffsets,                         lookUpSwitchInstruction.jumpOffsetCount);    }    // Implementations for ExceptionInfoVisitor.    public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)    {        // Remap the code offsets. Note that the instruction offset map also has        // an entry for the first offset after the code, for u2endPC.        exceptionInfo.u2startPC   = remapInstructionOffset(exceptionInfo.u2startPC);        exceptionInfo.u2endPC     = remapInstructionOffset(exceptionInfo.u2endPC);        exceptionInfo.u2handlerPC = remapInstructionOffset(exceptionInfo.u2handlerPC);    }    // Implementations for StackMapFrameVisitor.    public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame)    {        // Remap the stack map frame offset.        int stackMapFrameOffset = remapInstructionOffset(offset);        int offsetDelta = stackMapFrameOffset;        // Compute the offset delta if the frame is part of a stack map frame        // table (for JDK 6.0) instead of a stack map (for Java Micro Edition).        if (expectedStackMapFrameOffset >= 0)        {            offsetDelta -= expectedStackMapFrameOffset;            expectedStackMapFrameOffset = stackMapFrameOffset + 1;        }        stackMapFrame.u2offsetDelta = offsetDelta;    }    public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)    {        // Remap the stack map frame offset.        visitAnyStackMapFrame(clazz, method, codeAttribute, offset, sameOneFrame);        // Remap the verification type offset.        sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);    }    public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)    {        // Remap the stack map frame offset.        visitAnyStackMapFrame(clazz, method, codeAttribute, offset, moreZeroFrame);        // Remap the verification type offsets.        moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);    }    public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)    {        // Remap the stack map frame offset.        visitAnyStackMapFrame(clazz, method, codeAttribute, offset, fullFrame);        // Remap the verification type offsets.        fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);        fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);    }    // Implementations for VerificationTypeVisitor.    public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {}    public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType)    {        // Remap the offset of the 'new' instruction.        uninitializedType.u2newInstructionOffset = remapInstructionOffset(uninitializedType.u2newInstructionOffset);    }    // Implementations for LineNumberInfoVisitor.    public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo)    {        // Remap the code offset.        lineNumberInfo.u2startPC = remapInstructionOffset(lineNumberInfo.u2startPC);    }    // Implementations for LocalVariableInfoVisitor.    public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)    {        // Remap the code offset and length.        // TODO: The local variable frame might not be strictly preserved.        int startPC = remapInstructionOffset(localVariableInfo.u2startPC);        int endPC   = remapInstructionOffset(localVariableInfo.u2startPC + localVariableInfo.u2length);        localVariableInfo.u2startPC = startPC;        localVariableInfo.u2length  = endPC - startPC;    }    // Implementations for LocalVariableTypeInfoVisitor.    public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)    {        // Remap the code offset and length.        // TODO: The local variable frame might not be strictly preserved.        int startPC = remapInstructionOffset(localVariableTypeInfo.u2startPC);        int endPC   = remapInstructionOffset(localVariableTypeInfo.u2startPC + localVariableTypeInfo.u2length);        localVariableTypeInfo.u2length  = startPC;        localVariableTypeInfo.u2startPC = endPC - startPC;    }    // Small utility methods.    /**     * Adjusts the given jump offsets for the instruction at the given offset.     */    private void remapJumpOffsets(int offset, int[] jumpOffsets, int length)    {        for (int index = 0; index < length; index++)        {            jumpOffsets[index] = remapBranchOffset(offset, jumpOffsets[index]);        }    }    /**     * Computes the new branch offset for the instruction at the given new offset     * with the given old branch offset.     */    private int remapBranchOffset(int newInstructionOffset, int branchOffset)    {        if (newInstructionOffset < 0 ||            newInstructionOffset > codeLength)        {            throw new IllegalArgumentException("Invalid instruction offset ["+newInstructionOffset +"] in code with length ["+codeLength+"]");        }        int oldInstructionOffset = oldInstructionOffsets[newInstructionOffset];        return remapInstructionOffset(oldInstructionOffset + branchOffset) -               remapInstructionOffset(oldInstructionOffset);    }    /**     * Computes the new instruction offset for the instruction at the given old     * offset.     */    private int remapInstructionOffset(int oldInstructionOffset)    {        if (oldInstructionOffset < 0 ||            oldInstructionOffset > codeFragmentLengths[level])        {            throw new IllegalArgumentException("Invalid instruction offset ["+oldInstructionOffset +"] in code fragment with length ["+codeFragmentLengths[level]+"]");        }        return instructionOffsetMap[level][oldInstructionOffset];    }    /**     * Returns the given list of exceptions, without the ones that have empty     * code blocks.     */    private int removeEmptyExceptions(ExceptionInfo[] exceptionInfos,                                      int             exceptionInfoCount)    {        // Overwrite all empty exceptions.        int newIndex = 0;        for (int index = 0; index < exceptionInfoCount; index++)        {            ExceptionInfo exceptionInfo = exceptionInfos[index];            if (exceptionInfo.u2startPC < exceptionInfo.u2endPC)            {                exceptionInfos[newIndex++] = exceptionInfo;            }        }        // Clear the unused array entries.        for (int index = newIndex; index < exceptionInfoCount; index++)        {            exceptionInfos[index] = null;        }        return newIndex;    }    /**     * Returns the given list of line numbers, without the ones that have empty     * code blocks or that exceed the code size.     */    private int removeEmptyLineNumbers(LineNumberInfo[] lineNumberInfos,                                       int              lineNumberInfoCount,                                       int              codeLength)    {        // Overwrite all empty line number entries.        int newIndex = 0;        for (int index = 0; index < lineNumberInfoCount; index++)        {            LineNumberInfo lineNumberInfo = lineNumberInfos[index];            int startPC = lineNumberInfo.u2startPC;            if (startPC < codeLength &&                (index == 0 || startPC > lineNumberInfos[index-1].u2startPC))            {                lineNumberInfos[newIndex++] = lineNumberInfo;            }        }        // Clear the unused array entries.        for (int index = newIndex; index < lineNumberInfoCount; index++)        {            lineNumberInfos[index] = null;        }        return newIndex;    }    /**     * Returns the given list of local variables, without the ones that have empty     * code blocks or that exceed the actual number of local variables.     */    private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos,                                          int                 localVariableInfoCount,                                          int                 maxLocals)    {        // Overwrite all empty local variable entries.        int newIndex = 0;        for (int index = 0; index < localVariableInfoCount; index++)        {            LocalVariableInfo localVariableInfo = localVariableInfos[index];            if (localVariableInfo.u2length > 0 &&                localVariableInfo.u2index < maxLocals)            {                localVariableInfos[newIndex++] = localVariableInfo;            }        }        // Clear the unused array entries.        for (int index = newIndex; index < localVariableInfoCount; index++)        {            localVariableInfos[index] = null;        }        return newIndex;    }    /**     * Returns the given list of local variable types, without the ones that     * have empty code blocks or that exceed the actual number of local variables.     */    private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,                                              int                     localVariableTypeInfoCount,                                              int                     maxLocals)    {        // Overwrite all empty local variable type entries.        int newIndex = 0;        for (int index = 0; index < localVariableTypeInfoCount; index++)        {            LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];            if (localVariableTypeInfo.u2length > 0 &&                localVariableTypeInfo.u2index < maxLocals)            {                localVariableTypeInfos[newIndex++] = localVariableTypeInfo;            }        }        // Clear the unused array entries.        for (int index = newIndex; index < localVariableTypeInfoCount; index++)        {            localVariableTypeInfos[index] = null;        }        return newIndex;    }    public static void main(String[] args)    {        CodeAttributeComposer composer = new CodeAttributeComposer();        composer.beginCodeFragment(10);        composer.appendInstruction(0, new SimpleInstruction(InstructionConstants.OP_ICONST_0));        composer.appendInstruction(1, new VariableInstruction(InstructionConstants.OP_ISTORE, 0));        composer.appendInstruction(2, new BranchInstruction(InstructionConstants.OP_GOTO, 1));        composer.beginCodeFragment(10);        composer.appendInstruction(0, new VariableInstruction(InstructionConstants.OP_IINC, 0, 1));        composer.appendInstruction(1, new VariableInstruction(InstructionConstants.OP_ILOAD, 0));        composer.appendInstruction(2, new SimpleInstruction(InstructionConstants.OP_ICONST_5));        composer.appendInstruction(3, new BranchInstruction(InstructionConstants.OP_IFICMPLT, -3));        composer.endCodeFragment();        composer.appendInstruction(3, new SimpleInstruction(InstructionConstants.OP_RETURN));        composer.endCodeFragment();    }}

⌨️ 快捷键说明

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