From 91e4eb734e17a272e5c88bc087cf28e876315403 Mon Sep 17 00:00:00 2001 From: PuqiAR Date: Sat, 7 Mar 2026 21:33:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8Computed=20Goto?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8C=87=E4=BB=A4=E5=88=86=E5=8F=91=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E5=92=8C=E7=AE=97=E6=9C=AF=E8=BF=90=E7=AE=97=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/VM/VM.cpp | 251 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 150 insertions(+), 101 deletions(-) diff --git a/src/VM/VM.cpp b/src/VM/VM.cpp index d51001d..b9a16be 100644 --- a/src/VM/VM.cpp +++ b/src/VM/VM.cpp @@ -1,5 +1,5 @@ /*! - @file src/VM/VM.hpp + @file src/VM/VM.cpp @brief 虚拟机核心执行引擎实现 @author PuqiAR (im@puqiar.top) @date 2026-02-19 @@ -7,8 +7,11 @@ #include -#define BINARY_ARITHMETIC_OP(opCode, op) \ - case OpCode::opCode: { \ +// Computed GOTO!!! +#define BINARY_ARITHMETIC_OP(opName, op) \ + do_##opName: \ + { \ + std::uint8_t a = decodeA(inst); \ std::uint8_t b = decodeB(inst); \ std::uint8_t c = decodeC(inst); \ Value lhs = currentFrame->registerBase[b]; \ @@ -21,7 +24,6 @@ { \ currentFrame->registerBase[a] = Value::FromDouble(lhs.AsDouble() op rhs.AsDouble()); \ } \ - /* 隐式类型提升:Int 与 Double 混合运算 */ \ else if (lhs.IsInt() && rhs.IsDouble()) [[likely]] \ { \ currentFrame->registerBase[a] = Value::FromDouble(lhs.AsInt() op rhs.AsDouble()); \ @@ -34,11 +36,13 @@ { \ assert(false && "VM Runtime Error: Unsupported types for arithmetic operation"); \ } \ - break; \ + DISPATCH(); \ } -#define BINARY_COMPARE_OP(opCode, op) \ - case OpCode::opCode: { \ +#define BINARY_COMPARE_OP(opName, op) \ + do_##opName: \ + { \ + std::uint8_t a = decodeA(inst); \ std::uint8_t b = decodeB(inst); \ std::uint8_t c = decodeC(inst); \ Value lhs = currentFrame->registerBase[b]; \ @@ -69,10 +73,9 @@ } \ else \ { \ - /* TODO: 非数字比较 */ \ assert(false && "VM Runtime Error: Unsupported types for comparison"); \ } \ - break; \ + DISPATCH(); \ } namespace Fig @@ -82,100 +85,146 @@ namespace Fig Proto *entry = compiledModule->protos[0]; pushFrame(entry, registers); - while (true) + // 🔥 必须与 Bytecode.hpp 中的 OpCode 枚举严格一一对应! + static const void *dispatchTable[] = {&&do_Exit, + &&do_LoadK, + &&do_LoadTrue, + &&do_LoadFalse, + &&do_LoadNull, + &&do_FastCall, + &&do_Call, + &&do_Return, + &&do_LoadFn, + &&do_Jmp, + &&do_JmpIfFalse, + &&do_Mov, + &&do_Add, + &&do_Sub, + &&do_Mul, + &&do_Div, + &&do_Mod, + &&do_BitXor, + &&do_Equal, + &&do_NotEqual, + &&do_Greater, + &&do_Less, + &&do_GreaterEqual, + &&do_LessEqual, + &&do_Count}; + + Instruction inst; + +// 🔥 核心分发引擎:取指 -> 直接查表并 Jump +#define DISPATCH() \ + do \ + { \ + inst = *(currentFrame->ip++); \ + goto *dispatchTable[inst & 0xFF]; \ + } while (0) + + // 引擎点火! + DISPATCH(); + + do_Exit: { + [[unlikely]] return Value::GetNullInstance(); + } + + do_LoadK: { + std::uint8_t a = decodeA(inst); + std::uint16_t bx = decodeBx(inst); + currentFrame->registerBase[a] = currentFrame->getConstant(bx); + DISPATCH(); + } + + do_LoadTrue: { + std::uint8_t a = decodeA(inst); + currentFrame->registerBase[a] = Value::GetTrueInstance(); + DISPATCH(); + } + + do_LoadFalse: { + std::uint8_t a = decodeA(inst); + currentFrame->registerBase[a] = Value::GetFalseInstance(); + DISPATCH(); + } + + do_LoadNull: { + std::uint8_t a = decodeA(inst); + currentFrame->registerBase[a] = Value::GetNullInstance(); + DISPATCH(); + } + + do_FastCall: { + std::uint8_t a = decodeA(inst); + Proto *proto = compiledModule->protos[a]; + std::uint8_t baseReg = decodeB(inst); + pushFrame(proto, currentFrame->registerBase + baseReg); + DISPATCH(); + } + + do_Call: { + // TODO: FunctionObject 动态解包 + DISPATCH(); + } + + do_Return: { + std::uint8_t a = decodeA(inst); + *currentFrame->registerBase = currentFrame->registerBase[a]; + popFrame(); + DISPATCH(); + } + + do_LoadFn: { + // std::uint8_t a = decodeA(inst); + // std::uint16_t bx = decodeBx(inst); + // TODO: R[a] = new FunctionObject(compiledModule->protos[bx]) + DISPATCH(); + } + + do_Jmp: { + std::int16_t sbx = decodeSBx(inst); + currentFrame->ip += sbx; + DISPATCH(); + } + + do_JmpIfFalse: { + std::uint8_t a = decodeA(inst); + Value &v = currentFrame->registerBase[a]; + if (!v.AsBool()) { - // 取指并递增指针 - Instruction inst = *(currentFrame->ip++); - - // 解码 OpCode 和 A 操作数 - OpCode op = decodeOpCode(inst); - std::uint8_t a = decodeA(inst); - switch (op) - { - case OpCode::Exit: { [[unlikely]] - return Value::GetNullInstance(); - } - - case OpCode::LoadK: { - std::uint16_t bx = decodeBx(inst); - currentFrame->registerBase[a] = currentFrame->getConstant(bx); // constants - break; - } - - case OpCode::LoadTrue: { - currentFrame->registerBase[a] = Value::GetTrueInstance(); - break; - } - - case OpCode::LoadFalse: { - currentFrame->registerBase[a] = Value::GetFalseInstance(); - break; - } - - case OpCode::LoadNull: { - currentFrame->registerBase[a] = Value::GetNullInstance(); - break; - } - - case OpCode::FastCall: { - Proto *proto = compiledModule->protos[a]; - std::uint8_t baseReg = decodeB(inst); - - pushFrame(proto, currentFrame->registerBase + baseReg); - break; - } - - case OpCode::Call: { - break; - } - - case OpCode::Return: { - *currentFrame->registerBase = currentFrame->registerBase[a]; - popFrame(); - break; - } - - case OpCode::Jmp: { - std::int16_t sbx = decodeSBx(inst); - currentFrame->ip += sbx; - break; - } - - case OpCode::JmpIfFalse: { - Value &v = currentFrame->registerBase[a]; - bool cond = v.AsBool(); // 条件类型 Compiler检查 - if (!cond) - { - std::int16_t sbx = decodeSBx(inst); - currentFrame->ip += sbx; - } - break; - } - - case OpCode::Mov: { - std::uint16_t bx = decodeBx(inst); - currentFrame->registerBase[a] = currentFrame->registerBase[bx]; - break; - } - - BINARY_ARITHMETIC_OP(Add, +); - BINARY_ARITHMETIC_OP(Sub, -); - BINARY_ARITHMETIC_OP(Mul, *); - BINARY_ARITHMETIC_OP(Div, /); - - BINARY_COMPARE_OP(Equal, ==); - BINARY_COMPARE_OP(NotEqual, !=); - BINARY_COMPARE_OP(Greater, >); - BINARY_COMPARE_OP(Less, <); - BINARY_COMPARE_OP(GreaterEqual, >=); - BINARY_COMPARE_OP(LessEqual, <=); - - - // default: { - // assert(false && "VM: Unknown OpCode encountered!"); - // } - } + std::int16_t sbx = decodeSBx(inst); + currentFrame->ip += sbx; } + DISPATCH(); + } + + do_Mov: { + std::uint8_t a = decodeA(inst); + std::uint16_t bx = decodeBx(inst); + currentFrame->registerBase[a] = currentFrame->registerBase[bx]; + DISPATCH(); + } + + BINARY_ARITHMETIC_OP(Add, +); + BINARY_ARITHMETIC_OP(Sub, -); + BINARY_ARITHMETIC_OP(Mul, *); + BINARY_ARITHMETIC_OP(Div, /); + + do_Mod: + do_BitXor: + assert(false && "VM: Mod and BitXor not fully implemented yet!"); + DISPATCH(); + + BINARY_COMPARE_OP(Equal, ==); + BINARY_COMPARE_OP(NotEqual, !=); + BINARY_COMPARE_OP(Greater, >); + BINARY_COMPARE_OP(Less, <); + BINARY_COMPARE_OP(GreaterEqual, >=); + BINARY_COMPARE_OP(LessEqual, <=); + + do_Count: { + assert(false && "Hit Count sentinel!"); return Value::GetNullInstance(); } + } }; // namespace Fig \ No newline at end of file