refactor: 引入 Arena 内存池并优化指令分发,为类型系统重构做准备
This commit is contained in:
@@ -21,6 +21,7 @@ namespace Fig
|
||||
enum class OpCode : std::uint8_t
|
||||
{
|
||||
Exit, // 结束运行
|
||||
|
||||
LoadK, // iABx 模式: R[A] = Constants[Bx]
|
||||
LoadTrue, // iABC: R[A] = true
|
||||
LoadFalse, // iABC: R[A] = false
|
||||
@@ -35,7 +36,8 @@ namespace Fig
|
||||
Jmp, // iAsBx: ip += sBx 无条件跳转
|
||||
JmpIfFalse, // iAsBx: 如果 R[A] 为假, ip += sBx
|
||||
|
||||
Mov, // iABx: R[A] = R[Bx]
|
||||
Mov, // iABx: R[A] = R[Bx]
|
||||
|
||||
Add, // iABC: R[A] = R[B] + R[C]
|
||||
Sub, // iABC: R[A] = R[B] - R[C]
|
||||
Mul, // iABC: R[A] = R[B] * R[C]
|
||||
@@ -43,6 +45,11 @@ namespace Fig
|
||||
Mod, // iABC: R[A] = R[B] % R[C]
|
||||
BitXor, // iABC: R[A] = R[B] ^ R[C]
|
||||
|
||||
IntFastAdd, // iABC: R[A] (Int) = R[B] (Int) + R[C] (Int)
|
||||
IntFastSub, // iABC: R[A] (Int) = R[B] (Int) - R[C] (Int)
|
||||
IntFastMul, // iABC: R[A] (Int) = R[B] (Int) * R[C] (Int)
|
||||
IntFastDiv, // iABC: R[A] (Double) = R[B] (Int) / R[C] (Int)
|
||||
|
||||
Equal, // iABC: R[A] = R[B] == R[C]
|
||||
NotEqual, // iABC: R[A] = R[B] != R[C]
|
||||
Greater, // iABC: R[A] = R[B] > R[C]
|
||||
|
||||
@@ -346,7 +346,13 @@ namespace Fig
|
||||
case OpCode::Sub:
|
||||
case OpCode::Mul:
|
||||
case OpCode::Div:
|
||||
case OpCode::Mod: {
|
||||
case OpCode::Mod:
|
||||
|
||||
case OpCode::IntFastAdd:
|
||||
case OpCode::IntFastSub:
|
||||
case OpCode::IntFastMul:
|
||||
case OpCode::IntFastDiv:
|
||||
{
|
||||
// iABC 模式:解析 B (16~23 位) 和 C (24~31 位)
|
||||
std::uint8_t b = (inst >> 16) & 0xFF;
|
||||
std::uint8_t c = (inst >> 24) & 0xFF;
|
||||
|
||||
@@ -139,13 +139,16 @@ namespace Fig
|
||||
return compileAssignment(infix);
|
||||
}
|
||||
|
||||
const auto &_lhsReg = compileExpr(infix->left);
|
||||
Expr *left = infix->left;
|
||||
Expr *right = infix->right;
|
||||
|
||||
const auto &_lhsReg = compileExpr(left);
|
||||
if (!_lhsReg)
|
||||
{
|
||||
return _lhsReg;
|
||||
}
|
||||
std::uint8_t lhsReg = *_lhsReg;
|
||||
const auto &_rhsReg = compileExpr(infix->right);
|
||||
const auto &_rhsReg = compileExpr(right);
|
||||
if (!_rhsReg)
|
||||
{
|
||||
return _rhsReg;
|
||||
@@ -156,25 +159,58 @@ namespace Fig
|
||||
FreeReg(lhsReg);
|
||||
|
||||
std::uint8_t resultReg = AllocReg();
|
||||
|
||||
switch (infix->op)
|
||||
{
|
||||
case BinaryOperator::Add: {
|
||||
Emit(Op::iABC(OpCode::Add, resultReg, lhsReg, rhsReg));
|
||||
if (left->resolvedType == right->resolvedType && left->resolvedType->isInt())
|
||||
{
|
||||
// Int + Int
|
||||
Emit(Op::iABC(OpCode::IntFastAdd, resultReg, lhsReg, rhsReg));
|
||||
}
|
||||
else
|
||||
{
|
||||
Emit(Op::iABC(OpCode::Add, resultReg, lhsReg, rhsReg));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BinaryOperator::Subtract: {
|
||||
Emit(Op::iABC(OpCode::Sub, resultReg, lhsReg, rhsReg));
|
||||
if (left->resolvedType == right->resolvedType && left->resolvedType->isInt())
|
||||
{
|
||||
// Int - Int
|
||||
Emit(Op::iABC(OpCode::IntFastSub, resultReg, lhsReg, rhsReg));
|
||||
}
|
||||
else
|
||||
{
|
||||
Emit(Op::iABC(OpCode::Sub, resultReg, lhsReg, rhsReg));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BinaryOperator::Multiply: {
|
||||
Emit(Op::iABC(OpCode::Mul, resultReg, lhsReg, rhsReg));
|
||||
if (left->resolvedType == right->resolvedType && left->resolvedType->isInt())
|
||||
{
|
||||
// Int * Int
|
||||
Emit(Op::iABC(OpCode::IntFastMul, resultReg, lhsReg, rhsReg));
|
||||
}
|
||||
else
|
||||
{
|
||||
Emit(Op::iABC(OpCode::Mul, resultReg, lhsReg, rhsReg));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BinaryOperator::Divide: {
|
||||
Emit(Op::iABC(OpCode::Div, resultReg, lhsReg, rhsReg));
|
||||
if (left->resolvedType == right->resolvedType && left->resolvedType->isInt())
|
||||
{
|
||||
// Int / Int
|
||||
Emit(Op::iABC(OpCode::IntFastDiv, resultReg, lhsReg, rhsReg));
|
||||
}
|
||||
else
|
||||
{
|
||||
Emit(Op::iABC(OpCode::Div, resultReg, lhsReg, rhsReg));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -267,7 +303,7 @@ namespace Fig
|
||||
for (size_t i = 0; i < expr->args.size(); ++i)
|
||||
{
|
||||
std::uint8_t argTarget = AllocReg();
|
||||
auto argRes = compileExpr(expr->args.args[i]);
|
||||
auto argRes = compileExpr(expr->args.args[i]);
|
||||
if (!argRes)
|
||||
{
|
||||
return argRes;
|
||||
|
||||
@@ -41,7 +41,9 @@ namespace Fig::CoreIO
|
||||
|
||||
void InitConsoleIO()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleCP(CP_UTF8);
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include <Object/ObjectBase.hpp>
|
||||
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
// 运行时闭包对象 (24字节 Base + 8字节 Proto指针 = 32 bytes)
|
||||
@@ -17,7 +16,9 @@ namespace Fig
|
||||
struct Proto;
|
||||
struct FunctionObject final : public Object
|
||||
{
|
||||
String name; // 调试使用
|
||||
Proto *proto; // 指向编译器生成的只读字节码与常量池
|
||||
std::uint8_t paraCount;
|
||||
|
||||
// TODO: 实现闭包时 加一个 Upvalue 指针数组
|
||||
// Value* upvalues;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Fig
|
||||
StateProtector p(this, {State::ParsingLiteralExpr});
|
||||
|
||||
const Token &literal_token = consumeToken();
|
||||
LiteralExpr *node = new LiteralExpr(literal_token, makeSourceLocation(literal_token));
|
||||
LiteralExpr *node = arena.Allocate<LiteralExpr>(literal_token, makeSourceLocation(literal_token));
|
||||
return node;
|
||||
}
|
||||
Result<IdentiExpr *, Error> Parser::parseIdentiExpr() // 当前token为Identifier调用
|
||||
@@ -22,7 +22,7 @@ namespace Fig
|
||||
StateProtector p(this, {State::ParsingIdentiExpr});
|
||||
|
||||
const Token &identifier = consumeToken();
|
||||
IdentiExpr *node = new IdentiExpr(
|
||||
IdentiExpr *node = arena.Allocate<IdentiExpr>(
|
||||
srcManager.GetSub(identifier.index, identifier.length), makeSourceLocation(identifier));
|
||||
return node;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ namespace Fig
|
||||
}
|
||||
Expr *rhs = *rhs_result;
|
||||
|
||||
InfixExpr *node = new InfixExpr(lhs, op, rhs);
|
||||
InfixExpr *node = arena.Allocate<InfixExpr>(lhs, op, rhs);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Fig
|
||||
}
|
||||
|
||||
Expr *rhs = *rhs_result;
|
||||
PrefixExpr *node = new PrefixExpr(op, rhs);
|
||||
PrefixExpr *node = arena.Allocate<PrefixExpr>(op, rhs);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Fig
|
||||
}
|
||||
consumeToken(); // consume `]`
|
||||
|
||||
IndexExpr *indexExpr = new IndexExpr(base, *index_result);
|
||||
IndexExpr *indexExpr = arena.Allocate<IndexExpr>(base, *index_result);
|
||||
return indexExpr;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Fig
|
||||
if (currentToken().type == TokenType::RightParen)
|
||||
{
|
||||
consumeToken(); // consume `)`
|
||||
return new CallExpr(callee, callArgs);
|
||||
return arena.Allocate<CallExpr>(callee, callArgs);
|
||||
}
|
||||
|
||||
while (true)
|
||||
@@ -140,7 +140,7 @@ namespace Fig
|
||||
consumeToken(); // consume `,`
|
||||
}
|
||||
|
||||
return new CallExpr(callee, callArgs);
|
||||
return arena.Allocate<CallExpr>(callee, callArgs);
|
||||
}
|
||||
|
||||
Result<Expr *, Error> Parser::parseExpression(BindingPower rbp)
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Fig
|
||||
{
|
||||
Result<Program *, Error> Parser::Parse()
|
||||
{
|
||||
Program *program = new Program;
|
||||
Program *program = arena.Allocate<Program>();
|
||||
while (!isEOF)
|
||||
{
|
||||
auto result = parseStatement();
|
||||
@@ -27,5 +27,6 @@ namespace Fig
|
||||
program->nodes.push_back(stmt);
|
||||
}
|
||||
return program;
|
||||
|
||||
}
|
||||
}; // namespace Fig
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <Error/Error.hpp>
|
||||
#include <Lexer/Lexer.hpp>
|
||||
#include <Token/Token.hpp>
|
||||
#include <Utils/Arena.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
@@ -24,6 +25,7 @@ namespace Fig
|
||||
class Parser
|
||||
{
|
||||
private:
|
||||
Arena arena;
|
||||
Lexer &lexer;
|
||||
SourceManager &srcManager;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Fig
|
||||
Result<BlockStmt *, Error> Parser::parseBlockStmt() // 当前token为 {
|
||||
{
|
||||
SourceLocation location = makeSourceLocation(consumeToken()); // consume `{`
|
||||
BlockStmt *stmt = new BlockStmt();
|
||||
BlockStmt *stmt = arena.Allocate<BlockStmt>();
|
||||
while (true)
|
||||
{
|
||||
if (isEOF)
|
||||
@@ -94,7 +94,7 @@ namespace Fig
|
||||
{
|
||||
return std::unexpected(makeExpectSemicolonError());
|
||||
}
|
||||
VarDecl *varDecl = new VarDecl(isPublic, name, typeSpeicifer, isInfer, initExpr, location);
|
||||
VarDecl *varDecl = arena.Allocate<VarDecl>(isPublic, name, typeSpeicifer, isInfer, initExpr, location);
|
||||
return varDecl;
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace Fig
|
||||
return std::unexpected(result.error());
|
||||
}
|
||||
BlockStmt *consequent = *result;
|
||||
ElseIfStmt *elif = new ElseIfStmt(cond, consequent, elseLocation);
|
||||
ElseIfStmt *elif = arena.Allocate<ElseIfStmt>(cond, consequent, elseLocation);
|
||||
elifs.push_back(elif);
|
||||
}
|
||||
else
|
||||
@@ -233,7 +233,7 @@ namespace Fig
|
||||
alternate = *result;
|
||||
}
|
||||
}
|
||||
IfStmt *ifStmt = new IfStmt(cond, consequent, elifs, alternate, location);
|
||||
IfStmt *ifStmt = arena.Allocate<IfStmt>(cond, consequent, elifs, alternate, location);
|
||||
return ifStmt;
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace Fig
|
||||
}
|
||||
BlockStmt *body = *result;
|
||||
|
||||
WhileStmt *whileStmt = new WhileStmt(cond, body, location);
|
||||
WhileStmt *whileStmt = arena.Allocate<WhileStmt>(cond, body, location);
|
||||
return whileStmt;
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ namespace Fig
|
||||
defaultValue = *result;
|
||||
}
|
||||
|
||||
PosParam *posParam = new PosParam(name, type, defaultValue, location);
|
||||
PosParam *posParam = arena.Allocate<PosParam>(name, type, defaultValue, location);
|
||||
params.push_back(posParam);
|
||||
|
||||
if (match(TokenType::Comma))
|
||||
@@ -423,7 +423,7 @@ namespace Fig
|
||||
}
|
||||
body = *bodyResult;
|
||||
|
||||
FnDefStmt *fnDef = new FnDefStmt(isPublic, name, params, returnType, body, location);
|
||||
FnDefStmt *fnDef = arena.Allocate<FnDefStmt>(isPublic, name, params, returnType, body, location);
|
||||
return fnDef;
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ namespace Fig
|
||||
}
|
||||
|
||||
Expr *value = *result;
|
||||
ReturnStmt *returnStmt = new ReturnStmt(value, location);
|
||||
ReturnStmt *returnStmt = arena.Allocate<ReturnStmt>(value, location);
|
||||
|
||||
if (!match(TokenType::Semicolon))
|
||||
{
|
||||
@@ -507,7 +507,7 @@ namespace Fig
|
||||
{
|
||||
return std::unexpected(makeExpectSemicolonError());
|
||||
}
|
||||
BreakStmt *breakStmt = new BreakStmt(location);
|
||||
BreakStmt *breakStmt = arena.Allocate<BreakStmt>(location);
|
||||
return breakStmt;
|
||||
}
|
||||
|
||||
@@ -518,7 +518,7 @@ namespace Fig
|
||||
{
|
||||
return std::unexpected(makeExpectSemicolonError());
|
||||
}
|
||||
ContinueStmt *continueStmt = new ContinueStmt(location);
|
||||
ContinueStmt *continueStmt = arena.Allocate<ContinueStmt>(location);
|
||||
return continueStmt;
|
||||
}
|
||||
|
||||
@@ -532,7 +532,7 @@ namespace Fig
|
||||
{
|
||||
return std::unexpected(expr_result.error());
|
||||
}
|
||||
ExprStmt *exprStmt = new ExprStmt(*expr_result);
|
||||
ExprStmt *exprStmt = arena.Allocate<ExprStmt>(*expr_result);
|
||||
if (!match(TokenType::Semicolon))
|
||||
{
|
||||
return std::unexpected(makeExpectSemicolonError());
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
@date 2026-02-25
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Parser/Parser.hpp>
|
||||
|
||||
namespace Fig
|
||||
@@ -37,7 +35,7 @@ namespace Fig
|
||||
break;
|
||||
}
|
||||
}
|
||||
NamedTypeExpr *namedTypeExpr = new NamedTypeExpr(path, location);
|
||||
NamedTypeExpr *namedTypeExpr = arena.Allocate<NamedTypeExpr>(path, location);
|
||||
return namedTypeExpr;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,41 @@ namespace Fig
|
||||
{
|
||||
return tag == TypeTag::Any;
|
||||
}
|
||||
|
||||
bool isNull() const
|
||||
{
|
||||
return tag == TypeTag::Null;
|
||||
}
|
||||
|
||||
bool isInt() const
|
||||
{
|
||||
return tag == TypeTag::Int;
|
||||
}
|
||||
|
||||
bool isDouble() const
|
||||
{
|
||||
return tag == TypeTag::Double;
|
||||
}
|
||||
|
||||
bool isBool() const
|
||||
{
|
||||
return tag == TypeTag::Bool;
|
||||
}
|
||||
|
||||
bool isString() const
|
||||
{
|
||||
return tag == TypeTag::String;
|
||||
}
|
||||
|
||||
bool isFunction() const
|
||||
{
|
||||
return tag == TypeTag::Function;
|
||||
}
|
||||
|
||||
bool isStruct() const
|
||||
{
|
||||
return tag == TypeTag::Struct;
|
||||
}
|
||||
};
|
||||
|
||||
// 全局唯一类型驻留池
|
||||
|
||||
115
src/Utils/Arena.hpp
Normal file
115
src/Utils/Arena.hpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*!
|
||||
@file src/Utils/Arena.hpp
|
||||
@brief 线性分配内存池,支持非平凡析构对象的自动清理
|
||||
@author PuqiAR (im@puqiar.top)
|
||||
@date 2026-03-08
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
class Arena
|
||||
{
|
||||
private:
|
||||
struct DestructorNode
|
||||
{
|
||||
void (*destructor)(void *);
|
||||
void *object;
|
||||
DestructorNode *next;
|
||||
};
|
||||
|
||||
static constexpr std::size_t CHUNK_SIZE = 64 * 1024; // 64KB 块大小
|
||||
|
||||
std::vector<char *> chunks;
|
||||
char *currentPtr = nullptr;
|
||||
std::size_t remaining = 0;
|
||||
DestructorNode *destructorHead = nullptr;
|
||||
|
||||
public:
|
||||
Arena() = default;
|
||||
|
||||
~Arena()
|
||||
{
|
||||
// 1. 逆序调用析构函数
|
||||
DestructorNode *node = destructorHead;
|
||||
while (node)
|
||||
{
|
||||
node->destructor(node->object);
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
// 2. 释放所有分配的内存块
|
||||
for (char *chunk : chunks)
|
||||
{
|
||||
delete[] chunk;
|
||||
}
|
||||
}
|
||||
|
||||
// 禁止拷贝和移动,防止内存所有权混乱
|
||||
Arena(const Arena &) = delete;
|
||||
Arena &operator=(const Arena &) = delete;
|
||||
|
||||
template <typename T, typename... Args>
|
||||
T *Allocate(Args &&...args)
|
||||
{
|
||||
std::size_t size = sizeof(T);
|
||||
std::size_t alignment = alignof(T);
|
||||
|
||||
// 在当前块中尝试对齐并分配
|
||||
void *ptr = allocateRaw(size, alignment);
|
||||
|
||||
// 在分配的内存上构造对象
|
||||
T *obj = new (ptr) T(std::forward<Args>(args)...);
|
||||
|
||||
// 如果 T 需要析构(如包含 String),注册到销毁链表
|
||||
if constexpr (!std::is_trivially_destructible_v<T>)
|
||||
{
|
||||
// 注意: DestructorNode 本身是 POD,直接在 Arena 里分配,不需要注册析构
|
||||
void *nodeRaw = allocateRaw(sizeof(DestructorNode), alignof(DestructorNode));
|
||||
DestructorNode *node = new (nodeRaw) DestructorNode();
|
||||
|
||||
node->object = obj;
|
||||
node->destructor = [](void *p) { static_cast<T *>(p)->~T(); };
|
||||
node->next = destructorHead;
|
||||
destructorHead = node;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
void *allocateRaw(std::size_t size, std::size_t alignment)
|
||||
{
|
||||
// 对齐计算
|
||||
std::size_t adjustment = 0;
|
||||
std::size_t currentAddr = reinterpret_cast<std::size_t>(currentPtr);
|
||||
if (alignment > 0 && (currentAddr % alignment) != 0)
|
||||
{
|
||||
adjustment = alignment - (currentAddr % alignment);
|
||||
}
|
||||
|
||||
if (remaining < (size + adjustment))
|
||||
{
|
||||
// 当前块空间不足,分配新块
|
||||
std::size_t nextChunkSize = (size > CHUNK_SIZE) ? size : CHUNK_SIZE;
|
||||
currentPtr = new char[nextChunkSize];
|
||||
chunks.push_back(currentPtr);
|
||||
remaining = nextChunkSize;
|
||||
adjustment = 0; // 新分配的块通常是最大对齐的
|
||||
}
|
||||
|
||||
currentPtr += adjustment;
|
||||
void *res = currentPtr;
|
||||
currentPtr += size;
|
||||
remaining -= (size + adjustment);
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
} // namespace Fig
|
||||
@@ -86,24 +86,37 @@ namespace Fig
|
||||
pushFrame(entry, registers);
|
||||
|
||||
// 🔥 必须与 Bytecode.hpp 中的 OpCode 枚举严格一一对应!
|
||||
static const void *dispatchTable[] = {&&do_Exit,
|
||||
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_IntFastAdd,
|
||||
&&do_IntFastSub,
|
||||
&&do_IntFastMul,
|
||||
&&do_IntFastDiv,
|
||||
|
||||
&&do_Equal,
|
||||
&&do_NotEqual,
|
||||
&&do_Greater,
|
||||
@@ -114,7 +127,7 @@ namespace Fig
|
||||
|
||||
Instruction inst;
|
||||
|
||||
// 🔥 核心分发引擎:取指 -> 直接查表并 Jump
|
||||
// 取指 -> 直接查表并 Jump
|
||||
#define DISPATCH() \
|
||||
do \
|
||||
{ \
|
||||
@@ -122,7 +135,7 @@ namespace Fig
|
||||
goto *dispatchTable[inst & 0xFF]; \
|
||||
} while (0)
|
||||
|
||||
// 引擎点火!
|
||||
// 引擎点火!! :3
|
||||
DISPATCH();
|
||||
|
||||
do_Exit: {
|
||||
@@ -215,6 +228,54 @@ namespace Fig
|
||||
assert(false && "VM: Mod and BitXor not fully implemented yet!");
|
||||
DISPATCH();
|
||||
|
||||
do_IntFastAdd: {
|
||||
std::uint8_t a = decodeA(inst);
|
||||
std::uint8_t b = decodeB(inst);
|
||||
std::uint8_t c = decodeC(inst);
|
||||
|
||||
Value l = currentFrame->registerBase[b];
|
||||
Value r = currentFrame->registerBase[c];
|
||||
|
||||
currentFrame->registerBase[a] = Value::FromInt(l.AsInt() + r.AsInt());
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
do_IntFastSub: {
|
||||
std::uint8_t a = decodeA(inst);
|
||||
std::uint8_t b = decodeB(inst);
|
||||
std::uint8_t c = decodeC(inst);
|
||||
|
||||
Value l = currentFrame->registerBase[b];
|
||||
Value r = currentFrame->registerBase[c];
|
||||
|
||||
currentFrame->registerBase[a] = Value::FromInt(l.AsInt() - r.AsInt());
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
do_IntFastMul: {
|
||||
std::uint8_t a = decodeA(inst);
|
||||
std::uint8_t b = decodeB(inst);
|
||||
std::uint8_t c = decodeC(inst);
|
||||
|
||||
Value l = currentFrame->registerBase[b];
|
||||
Value r = currentFrame->registerBase[c];
|
||||
|
||||
currentFrame->registerBase[a] = Value::FromInt(l.AsInt() * r.AsInt());
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
do_IntFastDiv: {
|
||||
std::uint8_t a = decodeA(inst);
|
||||
std::uint8_t b = decodeB(inst);
|
||||
std::uint8_t c = decodeC(inst);
|
||||
|
||||
Value l = currentFrame->registerBase[b];
|
||||
Value r = currentFrame->registerBase[c];
|
||||
|
||||
currentFrame->registerBase[a] = Value::FromDouble(l.AsInt() + r.AsInt());
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
BINARY_COMPARE_OP(Equal, ==);
|
||||
BINARY_COMPARE_OP(NotEqual, !=);
|
||||
BINARY_COMPARE_OP(Greater, >);
|
||||
@@ -226,5 +287,6 @@ namespace Fig
|
||||
assert(false && "Hit Count sentinel!");
|
||||
return Value::GetNullInstance();
|
||||
}
|
||||
|
||||
}
|
||||
}; // namespace Fig
|
||||
Reference in New Issue
Block a user