feat: 使用Computed Goto优化指令分发机制和算术运算处理
This commit is contained in:
151
src/VM/VM.cpp
151
src/VM/VM.cpp
@@ -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
|
||||||
Reference in New Issue
Block a user