📄 processor.java
字号:
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( IntegerValueFactory.create(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(classFile, codeAttrInfo, offset, instructionOffsetValue.instructionOffset(instructionOffsetValue.instructionOffsetCount()-1)); break; default: throw new IllegalArgumentException("Unknown variable instruction ["+variableInstruction.opcode+"]"); } } public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction) { int branchTarget = offset + branchInstruction.branchOffset; switch (branchInstruction.opcode) { case InstructionConstants.OP_IFEQ: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.ipop().equal(IntegerValueFactory.create(0))); break; case InstructionConstants.OP_IFNE: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.ipop().notEqual(IntegerValueFactory.create(0))); break; case InstructionConstants.OP_IFLT: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.ipop().lessThan(IntegerValueFactory.create(0))); break; case InstructionConstants.OP_IFGE: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.ipop().greaterThanOrEqual(IntegerValueFactory.create(0))); break; case InstructionConstants.OP_IFGT: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.ipop().greaterThan(IntegerValueFactory.create(0))); break; case InstructionConstants.OP_IFLE: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.ipop().lessThanOrEqual(IntegerValueFactory.create(0))); break; case InstructionConstants.OP_IFICMPEQ: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.ipop().equal(stack.ipop())); break; case InstructionConstants.OP_IFICMPNE: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.ipop().notEqual(stack.ipop())); break; case InstructionConstants.OP_IFICMPLT: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, -stack.ipop().lessThan(stack.ipop())); break; case InstructionConstants.OP_IFICMPGE: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, -stack.ipop().greaterThanOrEqual(stack.ipop())); break; case InstructionConstants.OP_IFICMPGT: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, -stack.ipop().greaterThan(stack.ipop())); break; case InstructionConstants.OP_IFICMPLE: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, -stack.ipop().lessThanOrEqual(stack.ipop())); break; case InstructionConstants.OP_IFACMPEQ: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.apop().equal(stack.apop())); break; case InstructionConstants.OP_IFACMPNE: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.apop().notEqual(stack.apop())); break; case InstructionConstants.OP_GOTO: case InstructionConstants.OP_GOTO_W: branchUnit.branch(classFile, codeAttrInfo, offset, branchTarget); break; case InstructionConstants.OP_JSR: case InstructionConstants.OP_JSR_W: stack.push(InstructionOffsetValueFactory.create(offset + branchInstruction.length(offset))); branchUnit.branch(classFile, codeAttrInfo, offset, branchTarget); break; case InstructionConstants.OP_IFNULL: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.apop().isNull()); break; case InstructionConstants.OP_IFNONNULL: branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget, stack.apop().isNotNull()); break; default: throw new IllegalArgumentException("Unknown branch instruction ["+branchInstruction.opcode+"]"); } } public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, 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(classFile, codeAttrInfo, offset, offset + tableSwitchInstruction.defaultOffset); for (int index = 0; index < tableSwitchInstruction.jumpOffsetCount; index++) { int conditional = indexValue.equal(IntegerValueFactory.create( tableSwitchInstruction.lowCase + index)); branchUnit.branchConditionally(classFile, codeAttrInfo, 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(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, 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(classFile, codeAttrInfo, offset, offset + lookUpSwitchInstruction.defaultOffset); for (int index = 0; index < lookUpSwitchInstruction.jumpOffsetCount; index++) { int conditional = indexValue.equal(IntegerValueFactory.create( lookUpSwitchInstruction.cases[index])); branchUnit.branchConditionally(classFile, codeAttrInfo, offset, offset + lookUpSwitchInstruction.jumpOffsets[index], conditional); // If this branch is always taken, we can skip the rest. if (conditional == Value.ALWAYS) { break; } } } // Implementations for CpInfoVisitor. public void visitUtf8CpInfo(ClassFile classFile, Utf8CpInfo utf8CpInfo) {} public void visitNameAndTypeCpInfo(ClassFile classFile, NameAndTypeCpInfo nameAndTypeCpInfo) {} public void visitIntegerCpInfo(ClassFile classFile, IntegerCpInfo integerCpInfo) { cpValue = IntegerValueFactory.create(integerCpInfo.getValue()); } public void visitLongCpInfo(ClassFile classFile, LongCpInfo longCpInfo) { cpValue = LongValueFactory.create(longCpInfo.getValue()); } public void visitFloatCpInfo(ClassFile classFile, FloatCpInfo floatCpInfo) { cpValue = FloatValueFactory.create(floatCpInfo.getValue()); } public void visitDoubleCpInfo(ClassFile classFile, DoubleCpInfo doubleCpInfo) { cpValue = DoubleValueFactory.create(doubleCpInfo.getValue()); } public void visitStringCpInfo(ClassFile classFile, StringCpInfo stringCpInfo) { cpValue = ReferenceValueFactory.create(false); } public void visitFieldrefCpInfo(ClassFile classFile, FieldrefCpInfo fieldrefCpInfo) { cpValue = ValueFactory.create(fieldrefCpInfo.getType(classFile)); } public void visitInterfaceMethodrefCpInfo(ClassFile classFile, InterfaceMethodrefCpInfo interfaceMethodrefCpInfo) { visitRefCpInfo(classFile, interfaceMethodrefCpInfo); } public void visitMethodrefCpInfo(ClassFile classFile, MethodrefCpInfo methodrefCpInfo) { visitRefCpInfo(classFile, methodrefCpInfo); } private void visitRefCpInfo(ClassFile classFile, RefCpInfo methodrefCpInfo) { String type = methodrefCpInfo.getType(classFile); parameterCount = ClassUtil.internalMethodParameterCount(type); cpValue = ValueFactory.create(ClassUtil.internalMethodReturnType(type)); } public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo) { String className = classCpInfo.getName(classFile); referencedClassFile = classCpInfo.referencedClassFile; referencedTypeDimensionCount = ClassUtil.internalArrayTypeDimensionCount(className); cpValue = ReferenceValueFactory.create(referencedClassFile, referencedTypeDimensionCount, false); } // Small utility methods. /** * Returns the Value of the constant pool element at the given index. * The element can be a constant, a field, a method,... */ private Value cpValue(ClassFile classFile, int cpIndex) { // Visit the constant pool entry to get its return value. classFile.constantPoolEntryAccept(cpIndex, this); return cpValue; } /** * Returns the class file referenced by the class constant pool entry at the * given index. */ private ClassFile referencedClassFile(ClassFile classFile, int cpIndex) { // Visit the constant pool entry to get its referenced class file. classFile.constantPoolEntryAccept(cpIndex, this); return referencedClassFile; } /** * Returns the dimensionality of the class constant pool entry at the given * index. */ private int referencedTypeDimensionCount(ClassFile classFile, int cpIndex) { // Visit the constant pool entry to get its referenced class file. //classFile.constantPoolEntryAccept(this, cpIndex); // We'll return the value that was just computed. return referencedTypeDimensionCount; } /** * Returns the number of parameters of the method reference at the given * constant pool index. This method must be invoked right after the * cpValue(ClassFile,int) method. */ private int parameterCount(ClassFile classFile, int methodRefCpIndex) { // Visit the method ref constant pool entry to get its parameter count. //classFile.constantPoolEntryAccept(this, methodRefCpIndex); // We'll return the value that was just computed. return parameterCount; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -