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