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

View File

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

View File

@@ -26,6 +26,9 @@ public class JVMThread extends Thread {
this.stack.pop();
}
/**
* 获取 JVM 线程栈的栈帧数量
*/
public int stackSize() {
return this.stack.size();
}