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

📄 evaluationsimplifier.java

📁 ProGuard 是一个免费的 Java类文件的压缩
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                        newOpcode = InstructionConstants.OP_DUP;                    }                }                break;            }            case InstructionConstants.OP_DUP_X1:            {                boolean stackEntryPresent0 = isStackEntryNecessaryAfter(dupOffset, 0, false);                boolean stackEntryPresent1 = isStackEntryNecessaryAfter(dupOffset, 1, false);                boolean stackEntryPresent2 = isStackEntryNecessaryAfter(dupOffset, 2, false);                // Should either the original element or the copy be present?                if (stackEntryPresent0 ||                    stackEntryPresent2)                {                    present = true;                    // Should the copy be present?                    if (stackEntryPresent2)                    {                        // Compute the number of elements to be skipped.                        int skipCount = stackEntryPresent1 ? 1 : 0;                        // Should the original element be present?                        if (stackEntryPresent0)                        {                            // Copy the original element.                            newOpcode = (byte)(InstructionConstants.OP_DUP + skipCount);                        }                        else if (skipCount == 1)                        {                            // Move the original element.                            newOpcode = InstructionConstants.OP_SWAP;                        }                    }                }                break;            }            case InstructionConstants.OP_DUP_X2:            {                boolean stackEntryPresent0 = isStackEntryNecessaryAfter(dupOffset, 0, false);                boolean stackEntryPresent1 = isStackEntryNecessaryAfter(dupOffset, 1, false);                boolean stackEntryPresent2 = isStackEntryNecessaryAfter(dupOffset, 2, false);                boolean stackEntryPresent3 = isStackEntryNecessaryAfter(dupOffset, 3, false);                // Should either the original element or the copy be present?                if (stackEntryPresent0 ||                    stackEntryPresent3)                {                    present = true;                    // Should the copy be present?                    if (stackEntryPresent3)                    {                        int skipCount = (stackEntryPresent1 ? 1 : 0) +                                        (stackEntryPresent2 ? 1 : 0);                        // Should the original element be present?                        if (stackEntryPresent0)                        {                            // Copy the original element.                            newOpcode = (byte)(InstructionConstants.OP_DUP + skipCount);                        }                        else if (skipCount == 1)                        {                            // Move the original element.                            newOpcode = InstructionConstants.OP_SWAP;                        }                        else if (skipCount == 2)                        {                            // We can't easily move the original element.                            throw new IllegalArgumentException("Can't handle dup_x2 instruction moving original element across two elements at ["+dupOffset +"]");                        }                    }                }                break;            }            case InstructionConstants.OP_DUP2:            {                boolean stackEntriesPresent01 = isStackEntriesNecessaryAfter(dupOffset, 0, 1, false);                boolean stackEntriesPresent23 = isStackEntriesNecessaryAfter(dupOffset, 2, 3, false);                // Should either the original element or the copy be present?                if (stackEntriesPresent01 ||                    stackEntriesPresent23)                {                    present = true;                    // Should both the original element and the copy be present?                    if (stackEntriesPresent01 &&                        stackEntriesPresent23)                    {                        newOpcode = InstructionConstants.OP_DUP2;                    }                }                break;            }            case InstructionConstants.OP_DUP2_X1:            {                boolean stackEntriesPresent01 = isStackEntriesNecessaryAfter(dupOffset, 0, 1, false);                boolean stackEntryPresent2    = isStackEntryNecessaryAfter(dupOffset, 2, false);                boolean stackEntriesPresent34 = isStackEntriesNecessaryAfter(dupOffset, 3, 4, false);                // Should either the original element or the copy be present?                if (stackEntriesPresent01 ||                    stackEntriesPresent34)                {                    present = true;                    // Should the copy be present?                    if (stackEntriesPresent34)                    {                        int skipCount = stackEntryPresent2 ? 1 : 0;                        // Should the original element be present?                        if (stackEntriesPresent01)                        {                            // Copy the original element.                            newOpcode = (byte)(InstructionConstants.OP_DUP2 + skipCount);                        }                        else if (skipCount > 0)                        {                            // We can't easily move the original element.                            throw new IllegalArgumentException("Can't handle dup2_x1 instruction moving original element across "+skipCount+" elements at ["+dupOffset +"]");                        }                    }                }                break;            }            case InstructionConstants.OP_DUP2_X2:            {                boolean stackEntriesPresent01 = isStackEntriesNecessaryAfter(dupOffset, 0, 1, false);                boolean stackEntryPresent2    = isStackEntryNecessaryAfter(dupOffset, 2, false);                boolean stackEntryPresent3    = isStackEntryNecessaryAfter(dupOffset, 3, false);                boolean stackEntriesPresent45 = isStackEntriesNecessaryAfter(dupOffset, 4, 5, false);                // Should either the original element or the copy be present?                if (stackEntriesPresent01 ||                    stackEntriesPresent45)                {                    present = true;                    // Should the copy be present?                    if (stackEntriesPresent45)                    {                        int skipCount = (stackEntryPresent2 ? 1 : 0) +                                        (stackEntryPresent3 ? 1 : 0);                        // Should the original element be present?                        if (stackEntriesPresent01)                        {                            // Copy the original element.                            newOpcode = (byte)(InstructionConstants.OP_DUP2 + skipCount);                        }                        else if (skipCount > 0)                        {                            // We can't easily move the original element.                            throw new IllegalArgumentException("Can't handle dup2_x2 instruction moving original element across "+skipCount+" elements at ["+dupOffset +"]");                        }                    }                }                break;            }            case InstructionConstants.OP_SWAP:            {                boolean stackEntryPresent0 = isStackEntryNecessaryAfter(dupOffset, 0, false);                boolean stackEntryPresent1 = isStackEntryNecessaryAfter(dupOffset, 1, false);                // Will either element be present?                if (stackEntryPresent0 ||                    stackEntryPresent1)                {                    present = true;                    // Will both elements be present?                    if (stackEntryPresent0 &&                        stackEntryPresent1)                    {                        newOpcode = InstructionConstants.OP_SWAP;                    }                }                break;            }        }        boolean updated = false;        // Actually replace the instruction with the new opcode, if any.        if (present)        {            // If this is the first pass, note that the instruction is updated.            if (!isNecessary[dupOffset])            {                updated = true;                // Mark that the instruction is necessary.                isNecessary[dupOffset]  = true;            }            if      (newOpcode == 0)            {                // Delete the instruction.                codeAttributeEditor.deleteInstruction(dupOffset);                if (DEBUG_ANALYSIS) System.out.println("  Marking but deleting instruction "+instruction.toString(dupOffset));            }            else if (newOpcode == oldOpcode)            {                // Leave the instruction unchanged.                codeAttributeEditor.undeleteInstruction(dupOffset);                if (DEBUG_ANALYSIS) System.out.println("  Marking unchanged instruction "+instruction.toString(dupOffset));            }            else            {                // Replace the instruction.                Instruction replacementInstruction = new SimpleInstruction(newOpcode);                codeAttributeEditor.replaceInstruction(dupOffset,                                                      replacementInstruction);                if (DEBUG_ANALYSIS) System.out.println("  Replacing instruction "+instruction.toString(dupOffset)+" by "+replacementInstruction.toString());            }        }        return updated;    }    /**     * Pops the stack after the given necessary instruction, if it pushes an     * entry that is not used at all.     * @param clazz          the class that is being checked.     * @param codeAttribute  the code that is being checked.     * @param producerOffset the offset of the producer instruction.     * @param instruction    the producer instruction.     */    private void fixPushInstruction(Clazz         clazz,                                    CodeAttribute codeAttribute,                                    int           producerOffset,                                    Instruction   instruction)    {        int pushCount = instruction.stackPushCount(clazz);        if (pushCount > 0)        {            boolean stackEntryPresent0 = isStackEntryNecessaryAfter(producerOffset, 0, false);            if (!stackEntryPresent0)            {                if (instruction.opcode != InstructionConstants.OP_JSR &&                    instruction.opcode != InstructionConstants.OP_JSR_W)                {                    // Make sure the pushed value is popped again,                    // right after this instruction.                    decreaseStackSize(producerOffset, pushCount, false, false);                    if (DEBUG_ANALYSIS) System.out.println("  Popping unused value right after "+instruction.toString(producerOffset));                }            }        }    }    /**     * Pops the stack before the given unnecessary instruction, if the stack     * contains an entry that it would have popped.     * @param clazz          the class that is being checked.     * @param codeAttribute  the code that is being checked.     * @param consumerOffset the offset of the consumer instruction.     * @param instruction    the consumer instruction.     */    private void fixPopInstruction(Clazz         clazz,                                   CodeAttribute codeAttribute,                                   int           consumerOffset,                                   Instruction   instruction)    {        int popCount = instruction.stackPopCount(clazz);        if (popCount > 0)        {            if (partialEvaluator.stackProducerOffsets(consumerOffset).contains(PartialEvaluator.AT_CATCH_ENTRY) ||                (isStackEntryNecessaryBefore(consumerOffset, 0, false) &&                 !isStackEntryNecessaryBefore(consumerOffset, 0, true)))            {                // Is the consumer a simple pop or pop2 instruction?                byte popOpcode = instruction.opcode;                if (popOpcode == InstructionConstants.OP_POP ||                    popOpcode == InstructionConstants.OP_POP2)                {                    if (DEBUG_ANALYSIS) System.out.println("  Popping value again at "+instruction.toString(consumerOffset));                    // Simply mark the pop or pop2 instruction.                    isNecessary[consumerOffset] = true;                }                else                {                    if (DEBUG_ANALYSIS) System.out.println("  Popping value instead of "+instruction.toString(consumerOffset));                    // Make sure the pushed value is popped again,                    // right before this instruction.                    decreaseStackSize(consumerOffset, popCount, true, true);                }            }        }    }    /**     * Puts the required push instruction before the given index. The     * instruction is marked as necessary.     * @param offset            the offset of the instruction.     * @param computationalType the computational type on the stack, for     *                          push instructions.

⌨️ 快捷键说明

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