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 虚拟机核心执行引擎实现
@author PuqiAR (im@puqiar.top)
@date 2026-02-19
@@ -7,8 +7,11 @@
#include <VM/VM.hpp>
#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