mirror of
https://github.com/FranzHaidnor/haidnorJVM.git
synced 2026-03-13 21:43:42 +08:00
add Instruction
This commit is contained in:
@@ -19,30 +19,30 @@ import java.util.Map;
|
||||
@Slf4j
|
||||
public class Interpreter {
|
||||
|
||||
private static int frameCount = -1;
|
||||
|
||||
@SneakyThrows
|
||||
public static void executeFrame(Frame frame) {
|
||||
frameCount++;
|
||||
int stackSize = frame.getJvmThread().stackSize();
|
||||
|
||||
StringBuilder blank = new StringBuilder();
|
||||
blank.append(" ".repeat(Math.max(0, frameCount)));
|
||||
blank.append(" ".repeat(stackSize - 1));
|
||||
int index = 0;
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
for (int i = 0; i < stackSize - 1; i++) {
|
||||
blank.replace(index, index + 1, "│");
|
||||
index += 20;
|
||||
}
|
||||
|
||||
log.debug("{}┌──────────────────[{}] {} | {} ", blank, frameCount + 1, frame.aKlass.getClassName(), frame.getMethod());
|
||||
Map<Integer, Instruction> instructionMap = new HashMap<>();
|
||||
log.debug("{}┌──────────────────[{}] {} | {}", blank, stackSize, frame.klass.getClassName(), frame.getMethod());
|
||||
|
||||
// 解析方法中的字节码指令
|
||||
Map<Integer, Instruction> instructionMap = new HashMap<>();
|
||||
CodeStream codeStream = frame.getCodeStream();
|
||||
while (codeStream.available() > 0) {
|
||||
Instruction instruction = InstructionFactory.creatInstruction(codeStream);
|
||||
// log.debug("{}│>{}", blank, instruction);
|
||||
log.debug("{}│> {}", blank, instruction);
|
||||
instructionMap.put(instruction.index(), instruction);
|
||||
}
|
||||
// log.debug("{}├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌", blank);
|
||||
|
||||
log.debug("{}├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌", blank);
|
||||
|
||||
// 执行方法中的字节码指令 tip:(int i, 相当于程序计数器, 记录当前执行到的字节码指令的”行号“)
|
||||
for (int i = 0; i < frame.getCodeLength(); ) {
|
||||
@@ -54,8 +54,8 @@ public class Interpreter {
|
||||
}
|
||||
i += instruction.offSet();
|
||||
}
|
||||
log.debug("{}└──────────────────[{}] {} | {} ", blank, frameCount + 1, frame.aKlass.getClassName(), frame.getMethod());
|
||||
frameCount--;
|
||||
|
||||
log.debug("{}└──────────────────[{}] {} | {}", blank, stackSize, frame.klass.getClassName(), frame.getMethod());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package haidnor.jvm.instruction;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
|
||||
/**
|
||||
* @author wang xiang
|
||||
*/
|
||||
public abstract class Instruction {
|
||||
/**
|
||||
* 指令坐在 code 数组中的索引下标
|
||||
@@ -10,7 +13,7 @@ public abstract class Instruction {
|
||||
private final int index;
|
||||
|
||||
/**
|
||||
* 执行下一个执行的偏移量
|
||||
* 执行下一个指令的偏移量
|
||||
*/
|
||||
private int offSet = 1;
|
||||
|
||||
|
||||
@@ -598,7 +598,7 @@ public abstract class InstructionFactory {
|
||||
return new CHECKCAST(codeStream);
|
||||
}
|
||||
case Const.INSTANCEOF -> {
|
||||
throw new Error("Not support JavaVM opcode INSTANCEOF");
|
||||
return new INSTANCEOF(codeStream);
|
||||
}
|
||||
case Const.MONITORENTER -> {
|
||||
throw new Error("Not support JavaVM opcode MONITORENTER");
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package haidnor.jvm.instruction.references;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.heap.Instance;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.runtime.StackValue;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
import haidnor.jvm.util.ConstantPoolUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.bcel.Const;
|
||||
import org.apache.bcel.classfile.ConstantClass;
|
||||
import org.apache.bcel.classfile.ConstantPool;
|
||||
import org.apache.bcel.classfile.Utility;
|
||||
|
||||
/**
|
||||
* @author wang xiang
|
||||
*/
|
||||
public class INSTANCEOF extends Instruction {
|
||||
|
||||
private final int constantClassIndex;
|
||||
|
||||
public INSTANCEOF(CodeStream codeStream) {
|
||||
super(codeStream);
|
||||
this.constantClassIndex = codeStream.readUnsignedShort(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void execute(Frame frame) {
|
||||
ConstantPool constantPool = frame.getConstantPool();
|
||||
ConstantPoolUtil constantPoolUtil = frame.getConstantPoolUtil();
|
||||
ConstantClass constantClass = constantPool.getConstant(constantClassIndex);
|
||||
String className = constantPoolUtil.getClassName(constantClass);
|
||||
className = Utility.compactClassName(className);
|
||||
|
||||
StackValue stackValue = frame.pop();
|
||||
Object obj = stackValue.getValue();
|
||||
Class<?> objClass = obj.getClass();
|
||||
|
||||
if (obj instanceof Instance instance) {
|
||||
String instanceClassName = instance.klass.getClassName();
|
||||
if (instanceClassName.equals(className)) {
|
||||
frame.push(new StackValue(Const.T_INT, 1));
|
||||
} else {
|
||||
frame.push(new StackValue(Const.T_INT, 0));
|
||||
}
|
||||
} else {
|
||||
if (objClass.getName().equals(className)) {
|
||||
frame.push(new StackValue(Const.T_INT, 1));
|
||||
} else {
|
||||
frame.push(new StackValue(Const.T_INT, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package haidnor.jvm.instruction.stores;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.heap.Instance;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.runtime.StackValue;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
@@ -18,7 +17,7 @@ public class ASTORE extends Instruction {
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
StackValue value = frame.pop();
|
||||
frame.slotSetRef(index, (Instance) value.getValue());
|
||||
frame.slotSetRef(index, value.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package haidnor.jvm.instruction.stores;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.heap.Instance;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.runtime.StackValue;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
@@ -15,7 +14,7 @@ public class ASTORE_0 extends Instruction {
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
StackValue value = frame.pop();
|
||||
frame.slotSetRef(0, (Instance) value.getValue());
|
||||
frame.slotSetRef(0, value.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package haidnor.jvm.instruction.stores;
|
||||
|
||||
import haidnor.jvm.instruction.Instruction;
|
||||
import haidnor.jvm.rtda.heap.Instance;
|
||||
import haidnor.jvm.runtime.Frame;
|
||||
import haidnor.jvm.runtime.StackValue;
|
||||
import haidnor.jvm.util.CodeStream;
|
||||
@@ -15,7 +14,7 @@ public class ASTORE_3 extends Instruction {
|
||||
@Override
|
||||
public void execute(Frame frame) {
|
||||
StackValue value = frame.pop();
|
||||
frame.slotSetRef(3, (Instance) value.getValue());
|
||||
frame.slotSetRef(3, value.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class Frame {
|
||||
|
||||
private final KlassMethod klassMethod;
|
||||
|
||||
public final Klass aKlass;
|
||||
public final Klass klass;
|
||||
|
||||
/**
|
||||
* 栈帧所属的方法代码对象
|
||||
@@ -63,7 +63,7 @@ public class Frame {
|
||||
|
||||
public Frame(JvmThread jvmThread, KlassMethod klassMethod) {
|
||||
this.jvmThread = jvmThread;
|
||||
this.aKlass = klassMethod.aKlass;
|
||||
this.klass = klassMethod.aKlass;
|
||||
this.klassMethod = klassMethod;
|
||||
this.method = klassMethod.javaMethod;
|
||||
this.code = method.getCode();
|
||||
@@ -103,7 +103,7 @@ public class Frame {
|
||||
}
|
||||
|
||||
public Klass getMetaClass() {
|
||||
return aKlass;
|
||||
return klass;
|
||||
}
|
||||
|
||||
/* 操作数栈操作 --------------------------------------------------------------------------------------------------- */
|
||||
|
||||
@@ -59,6 +59,11 @@ public class TestJVM {
|
||||
runMainClass(Demo5.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_6() throws Exception {
|
||||
runMainClass(Demo6.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_NEW() throws Exception {
|
||||
runMainClass(NEW.class);
|
||||
|
||||
@@ -11,7 +11,7 @@ public class Demo3 {
|
||||
Student sut2 = new Student();
|
||||
|
||||
HashMap<Student, String> hashMap = new HashMap<>();
|
||||
hashMap.put(sut1, "张三");
|
||||
hashMap.put(sut1, "张三123");
|
||||
hashMap.put(sut2, "张三");
|
||||
|
||||
System.out.println(hashMap.get(sut1)); // 1
|
||||
|
||||
15
src/test/java/haidnor/jvm/test/demo/Demo6.java
Normal file
15
src/test/java/haidnor/jvm/test/demo/Demo6.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package haidnor.jvm.test.demo;
|
||||
|
||||
|
||||
import haidnor.jvm.test.clazz.Student;
|
||||
|
||||
public class Demo6 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Student student = new Student();
|
||||
if (student instanceof Student) {
|
||||
System.out.println("instanceof");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user