feat: 重构编译器以支持函数定义和调用,添加新的字节码以支持函数调用
另外,我很高兴地宣布,fib(40) 递归法 在我的平台, i5-13490f,只需要 6600ms, fib(30) 56ms 这是历史性的一刻!
This commit is contained in:
177
src/VM/VM.cpp
177
src/VM/VM.cpp
@@ -7,79 +7,85 @@
|
||||
|
||||
#include <VM/VM.hpp>
|
||||
|
||||
#define BINARY_ARITHMETIC_OP(opCode, op) \
|
||||
case OpCode::opCode: { \
|
||||
std::uint8_t b = decodeB(inst); \
|
||||
std::uint8_t c = decodeC(inst); \
|
||||
Value lhs = registers[b]; \
|
||||
Value rhs = registers[c]; \
|
||||
if (lhs.IsInt() && rhs.IsInt()) [[likely]] \
|
||||
{ \
|
||||
registers[a] = Value::FromInt(lhs.AsInt() op rhs.AsInt()); \
|
||||
} \
|
||||
else if (lhs.IsDouble() && rhs.IsDouble()) [[likely]] \
|
||||
{ \
|
||||
registers[a] = Value::FromDouble(lhs.AsDouble() op rhs.AsDouble()); \
|
||||
} \
|
||||
/* 隐式类型提升:Int 与 Double 混合运算 */ \
|
||||
else if (lhs.IsInt() && rhs.IsDouble()) [[likely]] \
|
||||
{ \
|
||||
registers[a] = Value::FromDouble(lhs.AsInt() op rhs.AsDouble()); \
|
||||
} \
|
||||
else if (lhs.IsDouble() && rhs.IsInt()) [[likely]] \
|
||||
{ \
|
||||
registers[a] = Value::FromDouble(lhs.AsDouble() op rhs.AsInt()); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
assert(false && "VM Runtime Error: Unsupported types for arithmetic operation"); \
|
||||
} \
|
||||
break; \
|
||||
#define BINARY_ARITHMETIC_OP(opCode, op) \
|
||||
case OpCode::opCode: { \
|
||||
std::uint8_t b = decodeB(inst); \
|
||||
std::uint8_t c = decodeC(inst); \
|
||||
Value lhs = currentFrame->registerBase[b]; \
|
||||
Value rhs = currentFrame->registerBase[c]; \
|
||||
if (lhs.IsInt() && rhs.IsInt()) [[likely]] \
|
||||
{ \
|
||||
currentFrame->registerBase[a] = Value::FromInt(lhs.AsInt() op rhs.AsInt()); \
|
||||
} \
|
||||
else if (lhs.IsDouble() && rhs.IsDouble()) [[likely]] \
|
||||
{ \
|
||||
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()); \
|
||||
} \
|
||||
else if (lhs.IsDouble() && rhs.IsInt()) [[likely]] \
|
||||
{ \
|
||||
currentFrame->registerBase[a] = Value::FromDouble(lhs.AsDouble() op rhs.AsInt()); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
assert(false && "VM Runtime Error: Unsupported types for arithmetic operation"); \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define BINARY_COMPARE_OP(opCode, op) \
|
||||
case OpCode::opCode: { \
|
||||
std::uint8_t b = decodeB(inst); \
|
||||
std::uint8_t c = decodeC(inst); \
|
||||
Value lhs = registers[b]; \
|
||||
Value rhs = registers[c]; \
|
||||
if (lhs.IsInt() && rhs.IsInt()) [[likely]] \
|
||||
{ \
|
||||
registers[a] = (lhs.AsInt() op rhs.AsInt()) ? Value::GetTrueInstance() : Value::GetFalseInstance(); \
|
||||
} \
|
||||
else if (lhs.IsDouble() && rhs.IsDouble()) [[likely]] \
|
||||
{ \
|
||||
registers[a] = (lhs.AsDouble() op rhs.AsDouble()) ? Value::GetTrueInstance() : Value::GetFalseInstance(); \
|
||||
} \
|
||||
else if (lhs.IsInt() && rhs.IsDouble()) [[likely]] \
|
||||
{ \
|
||||
registers[a] = (lhs.AsInt() op rhs.AsDouble()) ? Value::GetTrueInstance() : Value::GetFalseInstance(); \
|
||||
} \
|
||||
else if (lhs.IsDouble() && rhs.IsInt()) [[likely]] \
|
||||
{ \
|
||||
registers[a] = (lhs.AsDouble() op rhs.AsInt()) ? Value::GetTrueInstance() : Value::GetFalseInstance(); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* TODO: 非数字比较 */ \
|
||||
assert(false && "VM Runtime Error: Unsupported types for comparison"); \
|
||||
} \
|
||||
break; \
|
||||
#define BINARY_COMPARE_OP(opCode, op) \
|
||||
case OpCode::opCode: { \
|
||||
std::uint8_t b = decodeB(inst); \
|
||||
std::uint8_t c = decodeC(inst); \
|
||||
Value lhs = currentFrame->registerBase[b]; \
|
||||
Value rhs = currentFrame->registerBase[c]; \
|
||||
if (lhs.IsInt() && rhs.IsInt()) [[likely]] \
|
||||
{ \
|
||||
currentFrame->registerBase[a] = (lhs.AsInt() op rhs.AsInt()) ? \
|
||||
Value::GetTrueInstance() : \
|
||||
Value::GetFalseInstance(); \
|
||||
} \
|
||||
else if (lhs.IsDouble() && rhs.IsDouble()) [[likely]] \
|
||||
{ \
|
||||
currentFrame->registerBase[a] = (lhs.AsDouble() op rhs.AsDouble()) ? \
|
||||
Value::GetTrueInstance() : \
|
||||
Value::GetFalseInstance(); \
|
||||
} \
|
||||
else if (lhs.IsInt() && rhs.IsDouble()) [[likely]] \
|
||||
{ \
|
||||
currentFrame->registerBase[a] = (lhs.AsInt() op rhs.AsDouble()) ? \
|
||||
Value::GetTrueInstance() : \
|
||||
Value::GetFalseInstance(); \
|
||||
} \
|
||||
else if (lhs.IsDouble() && rhs.IsInt()) [[likely]] \
|
||||
{ \
|
||||
currentFrame->registerBase[a] = (lhs.AsDouble() op rhs.AsInt()) ? \
|
||||
Value::GetTrueInstance() : \
|
||||
Value::GetFalseInstance(); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* TODO: 非数字比较 */ \
|
||||
assert(false && "VM Runtime Error: Unsupported types for comparison"); \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
Result<Value, Error> VM::Execute(Proto *proto)
|
||||
Result<Value, Error> VM::Execute(CompiledModule *compiledModule)
|
||||
{
|
||||
// 指令指针 (Instruction Pointer / PC) 和 常量池指针
|
||||
const Instruction *ip = proto->code.data();
|
||||
const Value *k = proto->constants.data();
|
||||
Proto *entry = compiledModule->protos[0];
|
||||
pushFrame(entry, registers);
|
||||
|
||||
// 核心解释器循环 (The Dispatch Loop)
|
||||
while (true)
|
||||
{
|
||||
// 取指并递增指针
|
||||
Instruction inst = *ip++;
|
||||
Instruction inst = *(currentFrame->ip++);
|
||||
|
||||
// 解码 OpCode 和 A 操作数
|
||||
OpCode op = decodeOpCode(inst);
|
||||
@@ -92,34 +98,63 @@ namespace Fig
|
||||
|
||||
case OpCode::LoadK: {
|
||||
std::uint16_t bx = decodeBx(inst);
|
||||
registers[a] = k[bx]; // constants
|
||||
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: {
|
||||
return registers[a];
|
||||
*currentFrame->registerBase = currentFrame->registerBase[a];
|
||||
popFrame();
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::Jmp: {
|
||||
std::int16_t sbx = decodeSBx(inst);
|
||||
ip += sbx;
|
||||
currentFrame->ip += sbx;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::JmpIfFalse: {
|
||||
Value &v = registers[a];
|
||||
Value &v = currentFrame->registerBase[a];
|
||||
bool cond = v.AsBool(); // 条件类型 Compiler检查
|
||||
if (!cond)
|
||||
{
|
||||
std::int16_t sbx = decodeSBx(inst);
|
||||
ip += sbx;
|
||||
currentFrame->ip += sbx;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::Mov: {
|
||||
std::uint16_t bx = decodeBx(inst);
|
||||
registers[a] = registers[bx];
|
||||
currentFrame->registerBase[a] = currentFrame->registerBase[bx];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -136,9 +171,9 @@ namespace Fig
|
||||
BINARY_COMPARE_OP(LessEqual, <=);
|
||||
|
||||
|
||||
default: {
|
||||
assert(false && "VM: Unknown OpCode encountered!");
|
||||
}
|
||||
// default: {
|
||||
// assert(false && "VM: Unknown OpCode encountered!");
|
||||
// }
|
||||
}
|
||||
}
|
||||
return Value::GetNullInstance();
|
||||
|
||||
Reference in New Issue
Block a user