This commit is contained in:
wangxiang
2023-07-22 16:45:02 +08:00
parent 02fa4ffe23
commit 38e512e0ef
52 changed files with 152 additions and 281 deletions

View File

@@ -9,10 +9,10 @@ import org.apache.commons.cli.Options;
import haidnor.jvm.classloader.ClassLoader;
import haidnor.jvm.core.JavaExecutionEngine;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassMethod;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.runtime.JvmThread;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassMethod;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.JVMThread;
import haidnor.jvm.util.JavaClassUtil;
import haidnor.jvm.util.JvmThreadHolder;
import lombok.SneakyThrows;
@@ -53,11 +53,11 @@ public class Main {
if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
String className = entry.getName().replace('/', '.').substring(0, entry.getName().length() - 6);
if (className.equals(mainClass)) {
JvmThreadHolder.set(new JvmThread());
JvmThreadHolder.set(new JVMThread());
Klass mainMeteKlass = bootClassLoader.loadClass(jarFile, entry);
KlassMethod mainKlassMethod = JavaClassUtil.getMainMethod(mainMeteKlass);
Metaspace.registerJavaClass(mainMeteKlass);
JavaExecutionEngine.callMainStaticMethod(mainKlassMethod);
JavaExecutionEngine.callMainMethod(mainKlassMethod);
return;
}
}
@@ -65,14 +65,14 @@ public class Main {
}
}
if (cmd.hasOption("class")) {
JvmThreadHolder.set(new JvmThread());
JvmThreadHolder.set(new JVMThread());
String path = cmd.getOptionValue("class");
ClassLoader bootClassLoader = new ClassLoader("ApplicationClassLoader");
Klass mainMeteKlass = bootClassLoader.loadClassWithAbsolutePath(path);
KlassMethod mainKlassMethod = JavaClassUtil.getMainMethod(mainMeteKlass);
Metaspace.registerJavaClass(mainMeteKlass);
JavaExecutionEngine.callMainStaticMethod(mainKlassMethod);
JavaExecutionEngine.callMainMethod(mainKlassMethod);
}
}

View File

@@ -1,6 +1,6 @@
package haidnor.jvm.classloader;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.Klass;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;

View File

@@ -1,61 +0,0 @@
package haidnor.jvm.core;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.instruction.InstructionFactory;
import haidnor.jvm.instruction.control.RETURN;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* 字节码执行解释器
*
* @author wang xiang
*/
@Slf4j
public class Interpreter {
@SneakyThrows
public static void executeFrame(Frame frame) {
int stackSize = frame.getJvmThread().stackSize();
StringBuilder blank = new StringBuilder();
blank.append(" ".repeat(stackSize - 1));
int index = 0;
for (int i = 0; i < stackSize - 1; i++) {
blank.replace(index, index + 1, "");
index += 20;
}
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);
instructionMap.put(instruction.index(), instruction);
}
log.debug("{}├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌", blank);
// 执行方法中的字节码指令 tip:(int i, 相当于程序计数器, 记录当前执行到的字节码指令的”行号“)
for (int i = 0; i < frame.getCodeLength(); ) {
Instruction instruction = instructionMap.get(i);
log.debug("{}│ {}", blank, instruction);
instruction.execute(frame);
if (instruction instanceof RETURN) {
break;
}
i += instruction.offSet();
}
log.debug("{}└──────────────────[{}] {} | {}", blank, stackSize, frame.klass.getClassName(), frame.getMethod());
}
}

View File

@@ -1,32 +1,41 @@
package haidnor.jvm.core;
import haidnor.jvm.rtda.heap.KlassMethod;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.instruction.InstructionFactory;
import haidnor.jvm.instruction.control.RETURN;
import haidnor.jvm.rtda.KlassMethod;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.JvmThread;
import haidnor.jvm.runtime.JVMThread;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.JvmThreadHolder;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.bcel.classfile.LocalVariable;
import org.apache.bcel.classfile.LocalVariableTable;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.classfile.Utility;
import java.util.HashMap;
import java.util.Map;
/**
* JVM 执行引擎
*
* @author wang xiang
*/
@Slf4j
public class JavaExecutionEngine {
public static void callMainStaticMethod(KlassMethod klassMethod) {
JvmThread jvmThread = JvmThreadHolder.get();
// 每个栈帧中包含一个指向运行时常量池中该栈帧所属的方法的引用。包含这个引用的目的就是为了支持当前方法实现动态链接
// 有了这个引用,执行引擎就可以找到指定的方法,加载字节码指令
Frame frame = new Frame(jvmThread, klassMethod);
jvmThread.push(frame);
Interpreter.executeFrame(frame);
public static void callMainMethod(KlassMethod klassMethod) {
callMethod(null, klassMethod);
}
public static void callMethod(Frame lastFrame, KlassMethod klassMethod) {
JvmThread jvmThread = JvmThreadHolder.get();
JVMThread jvmThread = JvmThreadHolder.get();
Frame newFrame = new Frame(jvmThread, klassMethod);
// 如果有上一个栈帧, 代表需要传参
if (lastFrame != null) {
Method method = klassMethod.javaMethod;
@@ -53,7 +62,46 @@ public class JavaExecutionEngine {
}
jvmThread.push(newFrame);
Interpreter.executeFrame(newFrame);
executeFrame(newFrame);
}
@SneakyThrows
public static void executeFrame(Frame frame) {
int stackSize = frame.getJvmThread().stackSize();
StringBuilder blank = new StringBuilder();
blank.append(" ".repeat(stackSize - 1));
int index = 0;
for (int i = 0; i < stackSize - 1; i++) {
blank.replace(index, index + 1, "");
index += 20;
}
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);
instructionMap.put(instruction.index(), instruction);
}
log.debug("{}├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌", blank);
// 执行方法中的字节码指令 tip:(int i, 相当于程序计数器, 记录当前执行到的字节码指令的”行号“)
for (int i = 0; i < frame.getCodeLength(); ) {
Instruction instruction = instructionMap.get(i);
log.debug("{}│ {}", blank, instruction);
instruction.execute(frame);
if (instruction instanceof RETURN) {
break;
}
i += instruction.offSet();
}
log.debug("{}└──────────────────[{}] {} | {}", blank, stackSize, frame.klass.getClassName(), frame.getMethod());
}

View File

@@ -16,6 +16,9 @@ import haidnor.jvm.instruction.stores.*;
import haidnor.jvm.util.CodeStream;
import org.apache.bcel.Const;
/**
* @author wang xiang
*/
public abstract class InstructionFactory {
public static Instruction creatInstruction(CodeStream codeStream) {

View File

@@ -1,8 +1,8 @@
package haidnor.jvm.instruction.loads;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.heap.InstanceArray;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.rtda.InstanceArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,6 @@
package haidnor.jvm.instruction.loads;
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;

View File

@@ -1,7 +1,6 @@
package haidnor.jvm.instruction.loads;
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;

View File

@@ -1,7 +1,6 @@
package haidnor.jvm.instruction.loads;
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;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.loads;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.loads;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.loads;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.loads;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.loads;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.loads;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.loads;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,10 +1,10 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.heap.InstanceArray;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.rtda.InstanceArray;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.ArrayInstance;
import haidnor.jvm.rtda.ArrayInstance;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
import lombok.SneakyThrows;

View File

@@ -1,8 +1,8 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.heap.KlassField;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.rtda.KlassField;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.ConstantPoolUtil;

View File

@@ -1,9 +1,9 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassField;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassField;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;

View File

@@ -3,9 +3,9 @@ package haidnor.jvm.instruction.references;
import haidnor.jvm.classloader.ClassLoader;
import haidnor.jvm.core.JavaExecutionEngine;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassMethod;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassMethod;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;

View File

@@ -2,9 +2,9 @@ package haidnor.jvm.instruction.references;
import haidnor.jvm.core.JavaExecutionEngine;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassMethod;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassMethod;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;

View File

@@ -3,9 +3,9 @@ package haidnor.jvm.instruction.references;
import haidnor.jvm.classloader.ClassLoader;
import haidnor.jvm.core.JavaExecutionEngine;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassMethod;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassMethod;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,9 +1,9 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
import lombok.SneakyThrows;

View File

@@ -1,8 +1,8 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.heap.KlassField;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.rtda.KlassField;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.runtime.StackValue;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,9 +1,9 @@
package haidnor.jvm.instruction.references;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassField;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassField;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.ConstantPoolUtil;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.stack;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;
import lombok.SneakyThrows;

View File

@@ -1,8 +1,8 @@
package haidnor.jvm.instruction.stores;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.heap.InstanceArray;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.rtda.InstanceArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.stores;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.stores;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.stores;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.stores;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.stores;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.stores;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.instruction.stores;
import haidnor.jvm.instruction.Instruction;
import haidnor.jvm.rtda.heap.BasicTypeArray;
import haidnor.jvm.rtda.BasicTypeArray;
import haidnor.jvm.runtime.Frame;
import haidnor.jvm.util.CodeStream;

View File

@@ -1,4 +1,4 @@
package haidnor.jvm.rtda.heap;
package haidnor.jvm.rtda;
/**
* @author wang xiang

View File

@@ -1,4 +1,4 @@
package haidnor.jvm.rtda.heap;
package haidnor.jvm.rtda;
/**
* @author wang xiang

View File

@@ -1,4 +1,4 @@
package haidnor.jvm.rtda.heap;
package haidnor.jvm.rtda;
import java.util.ArrayList;

View File

@@ -1,4 +1,4 @@
package haidnor.jvm.rtda.heap;
package haidnor.jvm.rtda;
/**
* @author wang xiang

View File

@@ -1,8 +1,7 @@
package haidnor.jvm.rtda.heap;
package haidnor.jvm.rtda;
import haidnor.jvm.classloader.ClassLoader;
import haidnor.jvm.core.JavaExecutionEngine;
import haidnor.jvm.rtda.metaspace.Metaspace;
import lombok.SneakyThrows;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.JavaClass;

View File

@@ -1,4 +1,4 @@
package haidnor.jvm.rtda.heap;
package haidnor.jvm.rtda;
import haidnor.jvm.runtime.StackValue;
import org.apache.bcel.Const;

View File

@@ -1,4 +1,4 @@
package haidnor.jvm.rtda.heap;
package haidnor.jvm.rtda;
import org.apache.bcel.classfile.Method;

View File

@@ -1,6 +1,4 @@
package haidnor.jvm.rtda.metaspace;
import haidnor.jvm.rtda.heap.Klass;
package haidnor.jvm.rtda;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

View File

@@ -1,103 +0,0 @@
package haidnor.jvm.rtda;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.runtime.Slot;
/**
* 用于字段的联合 Slot
*/
public class UnionSlot {
private Slot high;
private Slot low;
private UnionSlot(Slot high, Slot low) {
this.high = high;
this.low = low;
}
// 初始化
public static UnionSlot of(Slot high, Slot low) {
return new UnionSlot(high, low);
}
public static UnionSlot of(Slot high) {
return new UnionSlot(high, null);
}
public static UnionSlot of(Instance instance) {
return new UnionSlot(new Slot(instance), null);
}
public static UnionSlot of(int val) {
return new UnionSlot(new Slot(val), null);
}
public static UnionSlot of(float val) {
return of(Float.floatToIntBits(val));
}
public static UnionSlot of(long val) {
int high = (int) (val >> 32); //高32位
int low = (int) (val & 0x000000ffffffffL); //低32位
return new UnionSlot(new Slot(high), new Slot(low));
}
public static UnionSlot of(double val) {
return of(Double.doubleToLongBits(val));
}
// 存
public void setRef(Instance val) {
high.ref = val;
}
public void setInt(int val) {
high.num = val;
}
public void setFloat(float val) {
setInt(Float.floatToIntBits(val));
}
public void setLong(long val) {
int highV = (int) (val >> 32); //高32位
int lowV = (int) (val & 0x000000ffffffffL); //低32位
high.num = highV;
low.num = lowV;
}
public void setDouble(double val) {
setLong(Double.doubleToLongBits(val));
}
public void set(UnionSlot neo) {
this.high = neo.high;
this.low = neo.low;
}
// 取
public Object getRef() {
return high.ref;
}
public int getInt() {
return high.num;
}
public float getFloat() {
return Float.intBitsToFloat(getInt());
}
public long getLong() {
final int high = this.high.num;
final int low = this.low.num;
long l1 = (high & 0x000000ffffffffL) << 32;
long l2 = low & 0x00000000ffffffffL;
return l1 | l2;
}
public double getDouble() {
return Double.longBitsToDouble(getLong());
}
}

View File

@@ -1,7 +0,0 @@
package haidnor.jvm.rtda.heap;
/**
* 堆空间
*/
public class Heap {
}

View File

@@ -1,14 +1,13 @@
package haidnor.jvm.runtime;
import haidnor.jvm.rtda.heap.Instance;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassMethod;
import haidnor.jvm.rtda.Instance;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassMethod;
import haidnor.jvm.util.CodeStream;
import haidnor.jvm.util.ConstantPoolUtil;
import org.apache.bcel.Const;
import org.apache.bcel.classfile.Code;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.LocalVariableTable;
import java.util.Stack;
@@ -21,7 +20,7 @@ public class Frame {
/**
* 当前栈帧所处于的 JVM 线程
*/
private final JvmThread jvmThread;
private final JVMThread jvmThread;
/**
* 栈帧所属的方法
@@ -33,6 +32,10 @@ public class Frame {
private final KlassMethod klassMethod;
/**
* 每个栈帧中包含一个指向运行时常量池中该栈帧所属的方法的引用。包含这个引用的目的就是为了支持当前方法实现动态链接
* 有了这个引用,执行引擎就可以找到指定的方法,加载字节码指令
*/
public final Klass klass;
/**
@@ -51,17 +54,12 @@ public class Frame {
*/
private final Stack<StackValue> operandStack = new Stack<>();
/**
* 局部变量表
*/
private final LocalVariableTable localVariableTable;
/**
* 槽位
*/
private final Slot[] slots;
public Frame(JvmThread jvmThread, KlassMethod klassMethod) {
public Frame(JVMThread jvmThread, KlassMethod klassMethod) {
this.jvmThread = jvmThread;
this.klass = klassMethod.aKlass;
this.klassMethod = klassMethod;
@@ -70,11 +68,10 @@ public class Frame {
this.constantPool = method.getConstantPool();
this.constantPoolUtil = new ConstantPoolUtil(constantPool);
this.codeStream = new CodeStream(method.getCode());
this.localVariableTable = code.getLocalVariableTable();
this.slots = new Slot[code.getMaxLocals()];
}
public JvmThread getJvmThread() {
public JVMThread getJvmThread() {
return jvmThread;
}

View File

@@ -7,7 +7,7 @@ import java.util.Stack;
*
* @author wang xiang
*/
public class JvmThread extends Thread {
public class JVMThread extends Thread {
/**
* JVM 线程栈

View File

@@ -1,7 +1,7 @@
package haidnor.jvm.util;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassMethod;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassMethod;
import org.apache.bcel.classfile.JavaClass;
/**

View File

@@ -1,19 +1,19 @@
package haidnor.jvm.util;
import haidnor.jvm.runtime.JvmThread;
import haidnor.jvm.runtime.JVMThread;
/**
* @author wang xiang
*/
public abstract class JvmThreadHolder {
private static final ThreadLocal<JvmThread> holder = new ThreadLocal<>();
private static final ThreadLocal<JVMThread> holder = new ThreadLocal<>();
public static void set(JvmThread thread) {
public static void set(JVMThread thread) {
holder.set(thread);
}
public static JvmThread get() {
public static JVMThread get() {
return holder.get();
}

View File

@@ -2,10 +2,10 @@ package haidnor.jvm.test;
import haidnor.jvm.classloader.ClassLoader;
import haidnor.jvm.core.JavaExecutionEngine;
import haidnor.jvm.rtda.heap.Klass;
import haidnor.jvm.rtda.heap.KlassMethod;
import haidnor.jvm.rtda.metaspace.Metaspace;
import haidnor.jvm.runtime.JvmThread;
import haidnor.jvm.rtda.Klass;
import haidnor.jvm.rtda.KlassMethod;
import haidnor.jvm.rtda.Metaspace;
import haidnor.jvm.runtime.JVMThread;
import haidnor.jvm.test.demo.*;
import haidnor.jvm.test.instruction.Array;
import haidnor.jvm.test.instruction.DO_WHILE;
@@ -28,13 +28,13 @@ public class TestJVM {
@SneakyThrows
public static void runMainClass(java.lang.Class<?> mainClass) {
JvmThreadHolder.set(new JvmThread());
JvmThreadHolder.set(new JVMThread());
ClassLoader bootClassLoader = new ClassLoader("ApplicationClassLoader");
Klass mainMeteKlass = bootClassLoader.loadClass(mainClass.getName().replace('.', '/'));
KlassMethod mainKlassMethod = JavaClassUtil.getMainMethod(mainMeteKlass);
Metaspace.registerJavaClass(mainMeteKlass);
JavaExecutionEngine.callMainStaticMethod(mainKlassMethod);
JavaExecutionEngine.callMainMethod(mainKlassMethod);
}
/**
@@ -118,7 +118,7 @@ public class TestJVM {
public void test_jar() throws Exception {
String jarFilePath = "D:/project_java/JvmDemo/target/JvmDemo-1.0-SNAPSHOT.jar";
JvmThreadHolder.set(new JvmThread());
JvmThreadHolder.set(new JVMThread());
try (JarFile jarFile = new JarFile(jarFilePath)) {
ClassLoader bootClassLoader = new ClassLoader(jarFile, "ApplicationClassLoader");
@@ -135,7 +135,7 @@ public class TestJVM {
Klass mainMeteKlass = bootClassLoader.loadClass(jarFile, entry);
KlassMethod mainKlassMethod = JavaClassUtil.getMainMethod(mainMeteKlass);
Metaspace.registerJavaClass(mainMeteKlass);
JavaExecutionEngine.callMainStaticMethod(mainKlassMethod);
JavaExecutionEngine.callMainMethod(mainKlassMethod);
break;
}
}