update JavaExecutionEngine.java

This commit is contained in:
wangxiang
2023-07-30 00:57:53 +08:00
parent f8504c3255
commit 3f049c9393
3 changed files with 29 additions and 10 deletions

View File

@@ -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();

View File

@@ -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() {

View File

@@ -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();
} }