📄 processor.java
字号:
case InstructionConstants.OP_FLOAD: case InstructionConstants.OP_FLOAD_0: case InstructionConstants.OP_FLOAD_1: case InstructionConstants.OP_FLOAD_2: case InstructionConstants.OP_FLOAD_3: stack.push(variables.fload(variableIndex)); break; case InstructionConstants.OP_DLOAD: case InstructionConstants.OP_DLOAD_0: case InstructionConstants.OP_DLOAD_1: case InstructionConstants.OP_DLOAD_2: case InstructionConstants.OP_DLOAD_3: stack.push(variables.dload(variableIndex)); break; case InstructionConstants.OP_ALOAD: case InstructionConstants.OP_ALOAD_0: case InstructionConstants.OP_ALOAD_1: case InstructionConstants.OP_ALOAD_2: case InstructionConstants.OP_ALOAD_3: stack.push(variables.aload(variableIndex)); break; case InstructionConstants.OP_ISTORE: case InstructionConstants.OP_ISTORE_0: case InstructionConstants.OP_ISTORE_1: case InstructionConstants.OP_ISTORE_2: case InstructionConstants.OP_ISTORE_3: variables.store(variableIndex, stack.ipop()); break; case InstructionConstants.OP_LSTORE: case InstructionConstants.OP_LSTORE_0: case InstructionConstants.OP_LSTORE_1: case InstructionConstants.OP_LSTORE_2: case InstructionConstants.OP_LSTORE_3: variables.store(variableIndex, stack.lpop()); break; case InstructionConstants.OP_FSTORE: case InstructionConstants.OP_FSTORE_0: case InstructionConstants.OP_FSTORE_1: case InstructionConstants.OP_FSTORE_2: case InstructionConstants.OP_FSTORE_3: variables.store(variableIndex, stack.fpop()); break; case InstructionConstants.OP_DSTORE: case InstructionConstants.OP_DSTORE_0: case InstructionConstants.OP_DSTORE_1: case InstructionConstants.OP_DSTORE_2: case InstructionConstants.OP_DSTORE_3: variables.store(variableIndex, stack.dpop()); break; case InstructionConstants.OP_ASTORE: case InstructionConstants.OP_ASTORE_0: case InstructionConstants.OP_ASTORE_1: case InstructionConstants.OP_ASTORE_2: case InstructionConstants.OP_ASTORE_3: // The operand on the stack can be a reference or a return // address, so we'll relax the pop operation. //variables.store(variableIndex, stack.apop()); variables.store(variableIndex, stack.pop()); break; case InstructionConstants.OP_IINC: variables.store(variableIndex, variables.iload(variableIndex).add( valueFactory.createIntegerValue(variableInstruction.constant))); break; case InstructionConstants.OP_RET: // The return address should be in the last offset of the // given instruction offset variable (even though there may // be other offsets). InstructionOffsetValue instructionOffsetValue = variables.oload(variableIndex); branchUnit.branch(clazz, codeAttribute, offset, instructionOffsetValue.instructionOffset(instructionOffsetValue.instructionOffsetCount()-1)); break; default: throw new IllegalArgumentException("Unknown variable instruction ["+variableInstruction.opcode+"]"); } } public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) { int branchTarget = offset + branchInstruction.branchOffset; switch (branchInstruction.opcode) { case InstructionConstants.OP_IFEQ: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().equal(valueFactory.createIntegerValue(0))); break; case InstructionConstants.OP_IFNE: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().notEqual(valueFactory.createIntegerValue(0))); break; case InstructionConstants.OP_IFLT: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().lessThan(valueFactory.createIntegerValue(0))); break; case InstructionConstants.OP_IFGE: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().greaterThanOrEqual(valueFactory.createIntegerValue(0))); break; case InstructionConstants.OP_IFGT: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().greaterThan(valueFactory.createIntegerValue(0))); break; case InstructionConstants.OP_IFLE: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().lessThanOrEqual(valueFactory.createIntegerValue(0))); break; case InstructionConstants.OP_IFICMPEQ: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().equal(stack.ipop())); break; case InstructionConstants.OP_IFICMPNE: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().notEqual(stack.ipop())); break; case InstructionConstants.OP_IFICMPLT: // Note that the stack entries are popped in reverse order. branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().greaterThan(stack.ipop())); break; case InstructionConstants.OP_IFICMPGE: // Note that the stack entries are popped in reverse order. branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().lessThanOrEqual(stack.ipop())); break; case InstructionConstants.OP_IFICMPGT: // Note that the stack entries are popped in reverse order. branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().lessThan(stack.ipop())); break; case InstructionConstants.OP_IFICMPLE: // Note that the stack entries are popped in reverse order. branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.ipop().greaterThanOrEqual(stack.ipop())); break; case InstructionConstants.OP_IFACMPEQ: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.apop().equal(stack.apop())); break; case InstructionConstants.OP_IFACMPNE: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.apop().notEqual(stack.apop())); break; case InstructionConstants.OP_GOTO: case InstructionConstants.OP_GOTO_W: branchUnit.branch(clazz, codeAttribute, offset, branchTarget); break; case InstructionConstants.OP_JSR: case InstructionConstants.OP_JSR_W: stack.push(new InstructionOffsetValue(offset + branchInstruction.length(offset))); branchUnit.branch(clazz, codeAttribute, offset, branchTarget); break; case InstructionConstants.OP_IFNULL: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.apop().isNull()); break; case InstructionConstants.OP_IFNONNULL: branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget, stack.apop().isNotNull()); break; default: throw new IllegalArgumentException("Unknown branch instruction ["+branchInstruction.opcode+"]"); } } public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction) { IntegerValue indexValue = stack.ipop(); // If there is no definite branch in any of the cases below, // branch to the default offset. branchUnit.branch(clazz, codeAttribute, offset, offset + tableSwitchInstruction.defaultOffset); for (int index = 0; index < tableSwitchInstruction.jumpOffsetCount; index++) { int conditional = indexValue.equal(valueFactory.createIntegerValue( tableSwitchInstruction.lowCase + index)); branchUnit.branchConditionally(clazz, codeAttribute, offset, offset + tableSwitchInstruction.jumpOffsets[index], conditional); // If this branch is always taken, we can skip the rest. if (conditional == Value.ALWAYS) { break; } } } public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) { IntegerValue indexValue = stack.ipop(); // If there is no definite branch in any of the cases below, // branch to the default offset. branchUnit.branch(clazz, codeAttribute, offset, offset + lookUpSwitchInstruction.defaultOffset); for (int index = 0; index < lookUpSwitchInstruction.jumpOffsetCount; index++) { int conditional = indexValue.equal(valueFactory.createIntegerValue( lookUpSwitchInstruction.cases[index])); branchUnit.branchConditionally(clazz, codeAttribute, offset, offset + lookUpSwitchInstruction.jumpOffsets[index], conditional); // If this branch is always taken, we can skip the rest. if (conditional == Value.ALWAYS) { break; } } } // Implementations for ConstantVisitor. public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) { cpValue = valueFactory.createIntegerValue(integerConstant.getValue()); } public void visitLongConstant(Clazz clazz, LongConstant longConstant) { cpValue = valueFactory.createLongValue(longConstant.getValue()); } public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) { cpValue = valueFactory.createFloatValue(floatConstant.getValue()); } public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) { cpValue = valueFactory.createDoubleValue(doubleConstant.getValue()); } public void visitStringConstant(Clazz clazz, StringConstant stringConstant) { cpValue = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING, null, false); } public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { cpValue = handleClassConstantAsClassValue ? valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS, null, false) : valueFactory.createReferenceValue(classConstant.getName(clazz), classConstant.referencedClass, false); } // Small utility methods. /** * Returns the Value of the constant pool element at the given index. */ private Value cpValue(Clazz clazz, int constantIndex) { return cpValue(clazz, constantIndex, false); } /** * Returns the Value of the constant pool element at the given index. */ private Value cpValue(Clazz clazz, int constantIndex, boolean handleClassConstantAsClassValue) { this.handleClassConstantAsClassValue = handleClassConstantAsClassValue; // Visit the constant pool entry to get its return value. clazz.constantPoolEntryAccept(constantIndex, this); return cpValue; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -