mirror of
https://github.com/FranzHaidnor/haidnorJVM.git
synced 2026-04-08 09:07:31 +00:00
update JavaExecutionEngine.java
This commit is contained in:
@@ -26,10 +26,19 @@ import java.util.Map;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class JavaExecutionEngine {
|
public class JavaExecutionEngine {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行 public static void main(String[] args) 方法
|
||||||
|
*/
|
||||||
public static void callMainMethod(KlassMethod klassMethod) {
|
public static void callMainMethod(KlassMethod klassMethod) {
|
||||||
callMethod(null, klassMethod);
|
callMethod(null, klassMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行普通方法
|
||||||
|
*
|
||||||
|
* @param lastFrame 方法调用者的栈帧
|
||||||
|
* @param klassMethod 方法元信息
|
||||||
|
*/
|
||||||
public static void callMethod(Frame lastFrame, KlassMethod klassMethod) {
|
public static void callMethod(Frame lastFrame, KlassMethod klassMethod) {
|
||||||
JVMThread jvmThread = JvmThreadHolder.get();
|
JVMThread jvmThread = JvmThreadHolder.get();
|
||||||
Frame newFrame = new Frame(jvmThread, klassMethod);
|
Frame newFrame = new Frame(jvmThread, klassMethod);
|
||||||
@@ -80,26 +89,28 @@ public class JavaExecutionEngine {
|
|||||||
CodeStream codeStream = frame.getCodeStream();
|
CodeStream codeStream = frame.getCodeStream();
|
||||||
while (codeStream.available() > 0) {
|
while (codeStream.available() > 0) {
|
||||||
Instruction instruction = InstructionFactory.creatInstruction(codeStream);
|
Instruction instruction = InstructionFactory.creatInstruction(codeStream);
|
||||||
log.debug("{}│> {}", blank, instruction);
|
|
||||||
instructionMap.put(instruction.index(), instruction);
|
instructionMap.put(instruction.index(), instruction);
|
||||||
|
log.debug("{}│> {}", blank, instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("{}├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌", blank);
|
log.debug("{}├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌", blank);
|
||||||
|
|
||||||
// 执行方法中的字节码指令 tip:(int pc, 相当于程序计数器, 记录当前执行到的字节码指令的”行号“)
|
// 执行方法中的字节码指令
|
||||||
|
// 提示: 变量 pc 相当于程序计数器, 记录当前执行到的字节码指令的"行号"
|
||||||
for (int pc = 0; pc < frame.getCodeLength(); ) {
|
for (int pc = 0; pc < frame.getCodeLength(); ) {
|
||||||
Instruction instruction = instructionMap.get(pc);
|
Instruction instruction = instructionMap.get(pc);
|
||||||
log.debug("{}│ {}", blank, instruction);
|
log.debug("{}│ {}", blank, instruction);
|
||||||
try {
|
try {
|
||||||
// 执行栈帧
|
// 执行字节码指令
|
||||||
instruction.execute(frame);
|
instruction.execute(frame);
|
||||||
|
// 若为 return 系列指令则结束当前栈帧
|
||||||
if (instruction instanceof RETURN || instruction instanceof ARETURN || instruction instanceof DRETURN || instruction instanceof FRETURN || instruction instanceof IRETURN) {
|
if (instruction instanceof RETURN || instruction instanceof ARETURN || instruction instanceof DRETURN || instruction instanceof FRETURN || instruction instanceof IRETURN) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 程序计数器值增加. 指向下一次执行的字节码行号
|
// 程序计数器值增加. 指向下一次执行的字节码行号
|
||||||
pc += instruction.offSet();
|
pc += instruction.offSet();
|
||||||
}
|
}
|
||||||
// 捕获执行栈帧运行抛出的异常
|
// 捕获执行字节码指令抛出的异常
|
||||||
catch (Exception exception) {
|
catch (Exception exception) {
|
||||||
// 从类元信息中获取异常表
|
// 从类元信息中获取异常表
|
||||||
CodeException[] exceptionTable = frame.getMethod().getCode().getExceptionTable();
|
CodeException[] exceptionTable = frame.getMethod().getCode().getExceptionTable();
|
||||||
@@ -107,9 +118,9 @@ public class JavaExecutionEngine {
|
|||||||
// handlerPC 是从异常表中获取的处理异常的字节码行号 (如果查询不到就会一直为 null. 代表方法无异常处理代码)
|
// handlerPC 是从异常表中获取的处理异常的字节码行号 (如果查询不到就会一直为 null. 代表方法无异常处理代码)
|
||||||
Integer handlerPC = null;
|
Integer handlerPC = null;
|
||||||
for (CodeException codeException : exceptionTable) {
|
for (CodeException codeException : exceptionTable) {
|
||||||
if (codeException.getStartPC() <= pc & pc <= codeException.getEndPC()) {
|
if (codeException.getStartPC() <= pc && pc <= codeException.getEndPC()) {
|
||||||
|
// 异常类型 (0 代表捕获所有类型的异常)
|
||||||
int catchType = codeException.getCatchType();
|
int catchType = codeException.getCatchType();
|
||||||
// catchType == 0 代表捕获所有类型的异常
|
|
||||||
if (catchType == 0) {
|
if (catchType == 0) {
|
||||||
frame.push(new StackValue(Const.T_OBJECT, exception));
|
frame.push(new StackValue(Const.T_OBJECT, exception));
|
||||||
handlerPC = codeException.getHandlerPC();
|
handlerPC = codeException.getHandlerPC();
|
||||||
@@ -128,7 +139,7 @@ public class JavaExecutionEngine {
|
|||||||
// 将程序计数器跳转到处理异常的字节码指令上
|
// 将程序计数器跳转到处理异常的字节码指令上
|
||||||
pc = handlerPC;
|
pc = handlerPC;
|
||||||
} else {
|
} else {
|
||||||
// 方法无异常处理. 异常退出.结束栈帧
|
// 方法无异常处理,结束栈帧. 将异常抛给调用者处理
|
||||||
log.debug("{}└──────────────────[{}] No Exception Handler Return!", blank, stackSize);
|
log.debug("{}└──────────────────[{}] No Exception Handler Return!", blank, stackSize);
|
||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
@@ -141,9 +152,9 @@ public class JavaExecutionEngine {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算绘画 jvm 线程栈 debug 日志信息的空格
|
* 计算绘画 jvm 线程栈 debug 日志信息的空格
|
||||||
* 用于表现栈的调用关系.
|
* 用于表现栈的调用关系
|
||||||
*
|
*
|
||||||
* @param stackSize 当前 JVM 栈的深度
|
* @param stackSize 当前 JVM 线程栈的栈帧数量
|
||||||
*/
|
*/
|
||||||
private static String getDebugStackInfoBlank(int stackSize) {
|
private static String getDebugStackInfoBlank(int stackSize) {
|
||||||
StringBuilder blank = new StringBuilder();
|
StringBuilder blank = new StringBuilder();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import haidnor.jvm.util.CodeStream;
|
|||||||
*/
|
*/
|
||||||
public abstract class Instruction {
|
public abstract class Instruction {
|
||||||
/**
|
/**
|
||||||
* 指令坐在 code 数组中的索引下标
|
* 指令在字节码 code 数组中的索引下标 (可以理解为指令的行号)
|
||||||
*/
|
*/
|
||||||
private final int index;
|
private final int index;
|
||||||
|
|
||||||
@@ -21,6 +21,11 @@ public abstract class Instruction {
|
|||||||
this.index = codeStream.index();
|
this.index = codeStream.index();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行执行
|
||||||
|
*
|
||||||
|
* @param frame 当前 JVM 线程栈的栈帧
|
||||||
|
*/
|
||||||
public abstract void execute(Frame frame);
|
public abstract void execute(Frame frame);
|
||||||
|
|
||||||
public int index() {
|
public int index() {
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ public class JVMThread extends Thread {
|
|||||||
this.stack.pop();
|
this.stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 JVM 线程栈的栈帧数量
|
||||||
|
*/
|
||||||
public int stackSize() {
|
public int stackSize() {
|
||||||
return this.stack.size();
|
return this.stack.size();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user