feat: 使用Computed Goto优化指令分发机制和算术运算处理

This commit is contained in:
2026-03-07 21:33:55 +08:00
parent 6dbecbbdc0
commit 91e4eb734e

View File

@@ -1,5 +1,5 @@
/*! /*!
@file src/VM/VM.hpp @file src/VM/VM.cpp
@brief 虚拟机核心执行引擎实现 @brief 虚拟机核心执行引擎实现
@author PuqiAR (im@puqiar.top) @author PuqiAR (im@puqiar.top)
@date 2026-02-19 @date 2026-02-19
@@ -7,8 +7,11 @@
#include <VM/VM.hpp> #include <VM/VM.hpp>
#define BINARY_ARITHMETIC_OP(opCode, op) \ // Computed GOTO!!!
case OpCode::opCode: { \ #define BINARY_ARITHMETIC_OP(opName, op) \
do_##opName: \
{ \
std::uint8_t a = decodeA(inst); \
std::uint8_t b = decodeB(inst); \ std::uint8_t b = decodeB(inst); \
std::uint8_t c = decodeC(inst); \ std::uint8_t c = decodeC(inst); \
Value lhs = currentFrame->registerBase[b]; \ Value lhs = currentFrame->registerBase[b]; \
@@ -21,7 +24,6 @@
{ \ { \
currentFrame->registerBase[a] = Value::FromDouble(lhs.AsDouble() op rhs.AsDouble()); \ currentFrame->registerBase[a] = Value::FromDouble(lhs.AsDouble() op rhs.AsDouble()); \
} \ } \
/* 隐式类型提升Int 与 Double 混合运算 */ \
else if (lhs.IsInt() && rhs.IsDouble()) [[likely]] \ else if (lhs.IsInt() && rhs.IsDouble()) [[likely]] \
{ \ { \
currentFrame->registerBase[a] = Value::FromDouble(lhs.AsInt() op rhs.AsDouble()); \ currentFrame->registerBase[a] = Value::FromDouble(lhs.AsInt() op rhs.AsDouble()); \
@@ -34,11 +36,13 @@
{ \ { \
assert(false && "VM Runtime Error: Unsupported types for arithmetic operation"); \ assert(false && "VM Runtime Error: Unsupported types for arithmetic operation"); \
} \ } \
break; \ DISPATCH(); \
} }
#define BINARY_COMPARE_OP(opCode, op) \ #define BINARY_COMPARE_OP(opName, op) \
case OpCode::opCode: { \ do_##opName: \
{ \
std::uint8_t a = decodeA(inst); \
std::uint8_t b = decodeB(inst); \ std::uint8_t b = decodeB(inst); \
std::uint8_t c = decodeC(inst); \ std::uint8_t c = decodeC(inst); \
Value lhs = currentFrame->registerBase[b]; \ Value lhs = currentFrame->registerBase[b]; \
@@ -69,10 +73,9 @@
} \ } \
else \ else \
{ \ { \
/* TODO: 非数字比较 */ \
assert(false && "VM Runtime Error: Unsupported types for comparison"); \ assert(false && "VM Runtime Error: Unsupported types for comparison"); \
} \ } \
break; \ DISPATCH(); \
} }
namespace Fig namespace Fig
@@ -82,80 +85,124 @@ namespace Fig
Proto *entry = compiledModule->protos[0]; Proto *entry = compiledModule->protos[0];
pushFrame(entry, registers); pushFrame(entry, registers);
while (true) // 🔥 必须与 Bytecode.hpp 中的 OpCode 枚举严格一一对应!
{ static const void *dispatchTable[] = {&&do_Exit,
// 取指并递增指针 &&do_LoadK,
Instruction inst = *(currentFrame->ip++); &&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};
// 解码 OpCode 和 A 操作数 Instruction inst;
OpCode op = decodeOpCode(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::uint8_t a = decodeA(inst);
switch (op)
{
case OpCode::Exit: { [[unlikely]]
return Value::GetNullInstance();
}
case OpCode::LoadK: {
std::uint16_t bx = decodeBx(inst); std::uint16_t bx = decodeBx(inst);
currentFrame->registerBase[a] = currentFrame->getConstant(bx); // constants currentFrame->registerBase[a] = currentFrame->getConstant(bx);
break; DISPATCH();
} }
case OpCode::LoadTrue: { do_LoadTrue: {
std::uint8_t a = decodeA(inst);
currentFrame->registerBase[a] = Value::GetTrueInstance(); currentFrame->registerBase[a] = Value::GetTrueInstance();
break; DISPATCH();
} }
case OpCode::LoadFalse: { do_LoadFalse: {
std::uint8_t a = decodeA(inst);
currentFrame->registerBase[a] = Value::GetFalseInstance(); currentFrame->registerBase[a] = Value::GetFalseInstance();
break; DISPATCH();
} }
case OpCode::LoadNull: { do_LoadNull: {
std::uint8_t a = decodeA(inst);
currentFrame->registerBase[a] = Value::GetNullInstance(); currentFrame->registerBase[a] = Value::GetNullInstance();
break; DISPATCH();
} }
case OpCode::FastCall: { do_FastCall: {
std::uint8_t a = decodeA(inst);
Proto *proto = compiledModule->protos[a]; Proto *proto = compiledModule->protos[a];
std::uint8_t baseReg = decodeB(inst); std::uint8_t baseReg = decodeB(inst);
pushFrame(proto, currentFrame->registerBase + baseReg); pushFrame(proto, currentFrame->registerBase + baseReg);
break; DISPATCH();
} }
case OpCode::Call: { do_Call: {
break; // TODO: FunctionObject 动态解包
DISPATCH();
} }
case OpCode::Return: { do_Return: {
std::uint8_t a = decodeA(inst);
*currentFrame->registerBase = currentFrame->registerBase[a]; *currentFrame->registerBase = currentFrame->registerBase[a];
popFrame(); popFrame();
break; DISPATCH();
} }
case OpCode::Jmp: { 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); std::int16_t sbx = decodeSBx(inst);
currentFrame->ip += sbx; currentFrame->ip += sbx;
break; DISPATCH();
} }
case OpCode::JmpIfFalse: { do_JmpIfFalse: {
std::uint8_t a = decodeA(inst);
Value &v = currentFrame->registerBase[a]; Value &v = currentFrame->registerBase[a];
bool cond = v.AsBool(); // 条件类型 Compiler检查 if (!v.AsBool())
if (!cond)
{ {
std::int16_t sbx = decodeSBx(inst); std::int16_t sbx = decodeSBx(inst);
currentFrame->ip += sbx; currentFrame->ip += sbx;
} }
break; DISPATCH();
} }
case OpCode::Mov: { do_Mov: {
std::uint8_t a = decodeA(inst);
std::uint16_t bx = decodeBx(inst); std::uint16_t bx = decodeBx(inst);
currentFrame->registerBase[a] = currentFrame->registerBase[bx]; currentFrame->registerBase[a] = currentFrame->registerBase[bx];
break; DISPATCH();
} }
BINARY_ARITHMETIC_OP(Add, +); BINARY_ARITHMETIC_OP(Add, +);
@@ -163,6 +210,11 @@ namespace Fig
BINARY_ARITHMETIC_OP(Mul, *); BINARY_ARITHMETIC_OP(Mul, *);
BINARY_ARITHMETIC_OP(Div, /); 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(Equal, ==);
BINARY_COMPARE_OP(NotEqual, !=); BINARY_COMPARE_OP(NotEqual, !=);
BINARY_COMPARE_OP(Greater, >); BINARY_COMPARE_OP(Greater, >);
@@ -170,12 +222,9 @@ namespace Fig
BINARY_COMPARE_OP(GreaterEqual, >=); BINARY_COMPARE_OP(GreaterEqual, >=);
BINARY_COMPARE_OP(LessEqual, <=); BINARY_COMPARE_OP(LessEqual, <=);
do_Count: {
// default: { assert(false && "Hit Count sentinel!");
// assert(false && "VM: Unknown OpCode encountered!");
// }
}
}
return Value::GetNullInstance(); return Value::GetNullInstance();
} }
}
}; // namespace Fig }; // namespace Fig