evaluationsimplifier.java
来自「proguard 一个java的混淆器」· Java 代码 · 共 1,560 行 · 第 1/5 页
JAVA
1,560 行
// Is the consumer a simple pop or pop2 instruction? if (isPop(instruction)) { 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); } } } } /** * Marks pop and pop2 instructions that pop stack entries produced by the * given instruction. * @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 producerInstruction the producer instruction. */ private void markConsumingPopInstructions(Clazz clazz, CodeAttribute codeAttribute, int producerOffset, Instruction producerInstruction) { // Loop over all pushed stack entries. int pushCount = producerInstruction.stackPushCount(clazz); for (int stackIndex = 0; stackIndex < pushCount; stackIndex++) { // Loop over all consumers of this entry. InstructionOffsetValue consumerOffsets = partialEvaluator.getStackAfter(producerOffset).getTopConsumerValue(stackIndex).instructionOffsetValue(); int consumerCount = consumerOffsets.instructionOffsetCount(); for (int consumerIndex = 0; consumerIndex < consumerCount; consumerIndex++) { int consumerOffset = consumerOffsets.instructionOffset(consumerIndex); // Is the consumer not necessary yet? if (!isNecessary[consumerOffset]) { Instruction consumerInstruction = InstructionFactory.create(codeAttribute.code, consumerOffset); // Is the consumer a simple pop or pop2 instruction? if (isPop(consumerInstruction)) { // Mark it. isNecessary[consumerOffset] = true; if (DEBUG_ANALYSIS) System.out.println(" Marking "+consumerInstruction.toString(consumerOffset)+" due to "+producerInstruction.toString(producerOffset)); } } } } } /** * 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. * @param delete specifies whether the instruction should be * deleted. */ private void increaseStackSize(int offset, int computationalType, boolean delete) { // Mark this instruction. isNecessary[offset] = true; // Create a simple push instrucion. byte replacementOpcode = computationalType == Value.TYPE_INTEGER ? InstructionConstants.OP_ICONST_0 : computationalType == Value.TYPE_LONG ? InstructionConstants.OP_LCONST_0 : computationalType == Value.TYPE_FLOAT ? InstructionConstants.OP_FCONST_0 : computationalType == Value.TYPE_DOUBLE ? InstructionConstants.OP_DCONST_0 : computationalType == Value.TYPE_REFERENCE ? InstructionConstants.OP_ACONST_NULL : InstructionConstants.OP_NOP; Instruction replacementInstruction = new SimpleInstruction(replacementOpcode); // Insert the pop or push instruction. codeAttributeEditor.insertBeforeInstruction(offset, replacementInstruction); if (extraAddedInstructionVisitor != null) { replacementInstruction.accept(null, null, null, offset, extraAddedInstructionVisitor); } // Delete the original instruction if necessary. if (delete) { codeAttributeEditor.deleteInstruction(offset); if (extraDeletedInstructionVisitor != null) { extraDeletedInstructionVisitor.visitSimpleInstruction(null, null, null, offset, null); } } } /** * Puts the required pop instruction at the given index. The * instruction is marked as necessary. * @param offset the offset of the instruction. * @param popCount the required reduction of the stack size. * @param before specifies whether the pop instruction should be inserted * before or after the present instruction. * @param delete specifies whether the instruction should be deleted. */ private void decreaseStackSize(int offset, int popCount, boolean before, boolean delete) { // Mark this instruction. isNecessary[offset] = true; boolean after = !before; int remainingPopCount = popCount; if (delete) { // Replace the original instruction. int count = remainingPopCount == 1 ? 1 : 2; // Create a simple pop instrucion. byte replacementOpcode = count == 1 ? InstructionConstants.OP_POP : InstructionConstants.OP_POP2; Instruction replacementInstruction = new SimpleInstruction(replacementOpcode); // Insert the pop instruction. codeAttributeEditor.replaceInstruction(offset, replacementInstruction); remainingPopCount -= count; // We may insert other pop instructions before and after this one. before = true; after = true; } if (before && remainingPopCount > 0) { // Insert before the original instruction. int count = remainingPopCount == 1 ? 1 : 2; // Create a simple pop instrucion. byte replacementOpcode = count == 1 ? InstructionConstants.OP_POP : InstructionConstants.OP_POP2; Instruction replacementInstruction = new SimpleInstruction(replacementOpcode); // Insert the pop instruction. codeAttributeEditor.insertBeforeInstruction(offset, replacementInstruction); remainingPopCount -= count; if (extraAddedInstructionVisitor != null) { replacementInstruction.accept(null, null, null, offset, extraAddedInstructionVisitor); } } if (after && remainingPopCount > 0) { // Insert after the original instruction. int count = remainingPopCount == 1 ? 1 : 2; // Create a simple pop instrucion. byte replacementOpcode = count == 1 ? InstructionConstants.OP_POP : InstructionConstants.OP_POP2; Instruction replacementInstruction = new SimpleInstruction(replacementOpcode); // Insert the pop instruction. codeAttributeEditor.insertAfterInstruction(offset, replacementInstruction); remainingPopCount -= count; if (extraAddedInstructionVisitor != null) { replacementInstruction.accept(null, null, null, offset, extraAddedInstructionVisitor); } } if (remainingPopCount > 0) { throw new IllegalArgumentException("Unsupported stack size reduction ["+popCount+"]"); } } // Implementations for InstructionVisitor. public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction) { if (partialEvaluator.isTraced(offset)) { switch (simpleInstruction.opcode) { case InstructionConstants.OP_IALOAD: case InstructionConstants.OP_BALOAD: case InstructionConstants.OP_CALOAD: case InstructionConstants.OP_SALOAD: case InstructionConstants.OP_IADD: case InstructionConstants.OP_ISUB: case InstructionConstants.OP_IMUL: case InstructionConstants.OP_IDIV: case InstructionConstants.OP_IREM: case InstructionConstants.OP_INEG: case InstructionConstants.OP_ISHL: case InstructionConstants.OP_ISHR: case InstructionConstants.OP_IUSHR: case InstructionConstants.OP_IAND: case InstructionConstants.OP_IOR: case InstructionConstants.OP_IXOR: case InstructionConstants.OP_L2I: case InstructionConstants.OP_F2I: case InstructionConstants.OP_D2I: case InstructionConstants.OP_I2B: case InstructionConstants.OP_I2C: case InstructionConstants.OP_I2S: replaceIntegerPushInstruction(offset); break; case InstructionConstants.OP_LALOAD: case InstructionConstants.OP_LADD: case InstructionConstants.OP_LSUB: case InstructionConstants.OP_LMUL: case InstructionConstants.OP_LDIV: case InstructionConstants.OP_LREM: case InstructionConstants.OP_LNEG: case InstructionConstants.OP_LSHL: case InstructionConstants.OP_LSHR: case InstructionConstants.OP_LUSHR: case InstructionConstants.OP_LAND: case InstructionConstants.OP_LOR: case InstructionConstants.OP_LXOR: case InstructionConstants.OP_I2L: case InstructionConstants.OP_F2L: case InstructionConstants.OP_D2L: replaceLongPushInstruction(offset); break; case InstructionConstants.OP_FALOAD: case InstructionConstants.OP_FADD: case InstructionConstants.OP_FSUB: case InstructionConstants.OP_FMUL: case InstructionConstants.OP_FDIV: case InstructionConstants.OP_FREM: case InstructionConstants.OP_FNEG: case InstructionConstants.OP_I2F: case InstructionConstants.OP_L2F: case InstructionConstants.OP_D2F: replaceFloatPushInstruction(offset); break; case InstructionConstants.OP_DALOAD: case InstructionConstants.OP_DADD: case InstructionConstants.OP_DSUB: case InstructionConstants.OP_DMUL: case InstructionConstants.OP_DDIV: case InstructionConstants.OP_DREM: case InstructionConstants.OP_DNEG: case InstructionConstants.OP_I2D: case InstructionConstants.OP_L2D: case InstructionConstants.OP_F2D: replaceDoublePushInstruction(offset); break; case InstructionConstants.OP_AALOAD: replaceReferencePushInstruction(offset); break; } } } public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { if (partialEvaluator.isTraced(offset)) { switch (variableInstruction.opcode) { case InstructionConstants.OP_ILOAD: case InstructionConstants.OP_ILOAD_0: case InstructionConstants.OP_ILOAD_1: case InstructionConstants.OP_ILOAD_2: case InstructionConstants.OP_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?