Switch to immutable stack frames from array-based stack
This commit is contained in:
parent
213ce07f34
commit
f16850d26c
7 changed files with 154 additions and 111 deletions
|
@ -257,15 +257,13 @@ Result<PodObject*> Arena::gc_stack(PodStackFrame* obj) {
|
|||
auto nobj = TRY(alloc<PodStackFrame>(sizeof(OffPtr<PodObject>) * obj->size));
|
||||
nobj->header.tag = Tag::StackFrame;
|
||||
nobj->parent = TRY(gc_pod(obj->parent.get()));
|
||||
nobj->fun = TRY(gc_pod(obj->fun.get()));
|
||||
nobj->parent_pc = obj->parent_pc;
|
||||
nobj->size = obj->size;
|
||||
nobj->top = obj->top;
|
||||
for (uint64_t i = 0; i < obj->top; i++) {
|
||||
for (uint64_t i = 0; i < obj->size; i++) {
|
||||
PodObject* val = obj->data[i].get();
|
||||
nobj->data[i] = TRY(gc_pod(val));
|
||||
}
|
||||
for (uint64_t i = obj->top; i < obj->size; i++) {
|
||||
nobj->data[i] = 0;
|
||||
}
|
||||
return nobj;
|
||||
}
|
||||
|
||||
|
|
|
@ -302,18 +302,15 @@ Result<short> Module::cmp(const Module& rhs) const {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<StackFrame> StackFrame::create(uint64_t size) {
|
||||
auto nil = Value(TRY(Nil::create()));
|
||||
auto pod = TRY(arena_alloc<PodStackFrame>(sizeof(OffPtr<PodObject>) * size));
|
||||
Result<StackFrame> StackFrame::create(const Value& parent, const Function& fun,
|
||||
uint64_t parent_pc) {
|
||||
auto pod = TRY(arena_alloc<PodStackFrame>());
|
||||
pod->header.tag = Tag::StackFrame;
|
||||
|
||||
pod->parent = nil.pod();
|
||||
pod->size = size;
|
||||
pod->top = 0;
|
||||
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
pod->data[i] = 0;
|
||||
}
|
||||
pod->parent = parent.pod();
|
||||
pod->fun = fun.pod();
|
||||
pod->parent_pc = parent_pc;
|
||||
pod->size = 0;
|
||||
|
||||
return StackFrame(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
@ -323,32 +320,67 @@ Result<Value> StackFrame::copy_value() const {
|
|||
}
|
||||
|
||||
Result<Value> StackFrame::get(uint64_t idx) const {
|
||||
if (idx >= _value->top) return ERROR(KeyError);
|
||||
if (idx >= _value->size) return ERROR(KeyError);
|
||||
|
||||
return Value::create(_value->data[idx].get());
|
||||
}
|
||||
|
||||
Result<void> StackFrame::set(uint64_t idx, const Value& val) {
|
||||
if (idx >= _value->size) return ERROR(KeyError);
|
||||
Result<StackFrame> StackFrame::set(uint64_t idx, const Value& val) {
|
||||
uint64_t size = std::max(_value->size, idx + 1);
|
||||
auto pod = TRY(arena_alloc<PodStackFrame>(sizeof(OffPtr<PodObject>) * size));
|
||||
pod->header.tag = Tag::StackFrame;
|
||||
|
||||
if (idx >= _value->top) {
|
||||
_value->top = idx + 1;
|
||||
pod->parent = _value->parent;
|
||||
pod->fun = _value->fun;
|
||||
pod->parent_pc = _value->parent_pc;
|
||||
pod->size = size;
|
||||
|
||||
for (uint64_t i = 0; i < _value->size; i++) {
|
||||
pod->data[i] = _value->data[i];
|
||||
}
|
||||
if (size > _value->size) {
|
||||
auto nil = Value(TRY(Nil::create()));
|
||||
for (uint64_t i = _value->size; i < size; i++) {
|
||||
pod->data[i] = nil.pod();
|
||||
}
|
||||
}
|
||||
pod->data[idx] = val.pod();
|
||||
|
||||
_value->data[idx] = val.pod();
|
||||
return Result<void>();
|
||||
return StackFrame(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<void> StackFrame::settop(uint64_t idx) {
|
||||
uint64_t top = _value->top;
|
||||
for (uint64_t i = std::min(top, idx); i < std::max(top, idx); i++) {
|
||||
_value->data[i] = 0;
|
||||
}
|
||||
_value->top = idx;
|
||||
Result<StackFrame> StackFrame::settop(uint64_t idx) {
|
||||
auto pod = TRY(arena_alloc<PodStackFrame>(sizeof(OffPtr<PodObject>) * idx));
|
||||
pod->header.tag = Tag::StackFrame;
|
||||
|
||||
return Result<void>();
|
||||
pod->parent = _value->parent;
|
||||
pod->fun = _value->fun;
|
||||
pod->parent_pc = _value->parent_pc;
|
||||
pod->size = idx;
|
||||
|
||||
auto min_idx = std::min(_value->size, idx);
|
||||
for (uint64_t i = 0; i < min_idx; i++) {
|
||||
pod->data[i] = _value->data[i];
|
||||
}
|
||||
|
||||
if (min_idx < idx) {
|
||||
auto nil = Value(TRY(Nil::create()));
|
||||
for (uint64_t i = min_idx; i < idx; i++) {
|
||||
pod->data[i] = nil.pod();
|
||||
}
|
||||
}
|
||||
|
||||
return StackFrame(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<Value> StackFrame::parent() const {
|
||||
return Value::create(_value->parent.get());
|
||||
}
|
||||
Result<Function> StackFrame::fun() const {
|
||||
return Function::create((PodFunction*)_value->fun.get());
|
||||
}
|
||||
uint64_t StackFrame::parent_pc() const { return _value->parent_pc; }
|
||||
|
||||
Result<Value> Error::copy_value() const {
|
||||
return Value(Error(TRY(_value.copy())));
|
||||
}
|
||||
|
|
|
@ -1092,6 +1092,11 @@ class StackFrame : public Object {
|
|||
StackFrame(StackFrame&& rhs) : _value(std::move(rhs._value)) {}
|
||||
StackFrame(GcRoot<PodStackFrame>&& val) : _value(std::move(val)) {}
|
||||
|
||||
StackFrame& operator=(StackFrame&& rhs) {
|
||||
_value = std::move(rhs._value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual Tag tag() const final { return Tag::StackFrame; }
|
||||
virtual PodObject* pod() const final { return _value.get(); }
|
||||
virtual Result<short> cmp(const Object& rhs) const final {
|
||||
|
@ -1109,14 +1114,18 @@ class StackFrame : public Object {
|
|||
|
||||
using Object::get;
|
||||
Result<Value> get(uint64_t idx) const;
|
||||
Result<void> set(uint64_t idx, const Value& val);
|
||||
Result<void> settop(uint64_t idx);
|
||||
uint64_t gettop() { return _value->top; }
|
||||
Result<StackFrame> set(uint64_t idx, const Value& val);
|
||||
Result<StackFrame> settop(uint64_t idx);
|
||||
Result<Value> parent() const;
|
||||
Result<Function> fun() const;
|
||||
uint64_t parent_pc() const;
|
||||
Result<uint64_t> size() const { return _value->size; }
|
||||
|
||||
static Result<StackFrame> create(uint64_t size);
|
||||
static Result<StackFrame> create(const Value& parent, const Function& fun,
|
||||
uint64_t parent_pc);
|
||||
|
||||
Result<Array> slice(uint64_t start, uint64_t end) {
|
||||
if (start > end || end > gettop()) return ERROR(IndexOutOfRange);
|
||||
if (start > end || end > _value->size) return ERROR(IndexOutOfRange);
|
||||
uint64_t res_size = end - start;
|
||||
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
|
||||
pod->header.tag = Tag::Array;
|
||||
|
|
|
@ -197,8 +197,9 @@ class PodStackFrame final : public PodObject {
|
|||
PodStackFrame() : PodObject(Tag::StackFrame) {};
|
||||
|
||||
OffPtr<PodObject> parent;
|
||||
OffPtr<PodObject> fun;
|
||||
uint64_t parent_pc;
|
||||
uint64_t size;
|
||||
uint64_t top;
|
||||
OffPtr<PodObject> data[];
|
||||
};
|
||||
|
||||
|
|
|
@ -21,9 +21,10 @@ Result<Value> run_string(const String& fname, const String& src) {
|
|||
auto compiled = TRY(compile(fname, parsed));
|
||||
Module& mod = *compiled.to<Module>();
|
||||
|
||||
auto vm = TRY(VM::create());
|
||||
Dict globals = TRY(Dict::create());
|
||||
auto vm = TRY(VM::create(mod, globals));
|
||||
|
||||
auto res = TRY(vm.run(mod));
|
||||
auto res = TRY(vm.run());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -64,8 +65,8 @@ Result<void> run_repl() {
|
|||
auto compiled = maybe_compiled.release_value();
|
||||
|
||||
Module& mod = *compiled.to<Module>();
|
||||
auto vm = TRY(VM::create());
|
||||
auto maybe_res = vm.run(mod, globals);
|
||||
auto vm = TRY(VM::create(mod, globals));
|
||||
auto maybe_res = vm.run();
|
||||
|
||||
if (maybe_res.has_value()) {
|
||||
auto res = maybe_res.release_value();
|
||||
|
|
99
src/vm.cpp
99
src/vm.cpp
|
@ -3,11 +3,10 @@
|
|||
#include "common.hpp"
|
||||
#include "stdlib.hpp"
|
||||
|
||||
Result<Value> VM::getreg(uint64_t idx) { return _stack.get(_base + idx); }
|
||||
Result<Value> VM::getreg(uint64_t idx) { return _stack.get(idx); }
|
||||
|
||||
Result<void> VM::setreg(uint64_t idx, const Value& value) {
|
||||
TRY(_stack.set(_base + idx, value));
|
||||
return Result<void>();
|
||||
Result<StackFrame> VM::setreg(uint64_t idx, const Value& value) {
|
||||
return _stack.set(idx, value);
|
||||
}
|
||||
|
||||
Result<Value> VM::getconst(uint64_t idx) { return _constants.get(idx); }
|
||||
|
@ -20,7 +19,7 @@ Result<Value> VM::get(bool is_const, uint64_t idx) {
|
|||
Result<void> VM::vm_mov(Opcode& oc) {
|
||||
uint64_t acc = (uint64_t)oc.arg1().arg;
|
||||
Value val = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
setreg(acc, val);
|
||||
_stack = TRY(setreg(acc, val));
|
||||
_pc++;
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -30,7 +29,7 @@ Result<void> VM::vm_add(Opcode& oc) {
|
|||
Value val1 = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val2 = TRY(get(oc.arg3().is_const, (uint64_t)oc.arg3().arg));
|
||||
Value res = TRY(val1.add(val2));
|
||||
setreg(acc, res);
|
||||
_stack = TRY(setreg(acc, res));
|
||||
_pc++;
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -40,7 +39,7 @@ Result<void> VM::vm_mul(Opcode& oc) {
|
|||
Value val1 = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val2 = TRY(get(oc.arg3().is_const, (uint64_t)oc.arg3().arg));
|
||||
Value res = TRY(val1.mul(val2));
|
||||
setreg(acc, res);
|
||||
_stack = TRY(setreg(acc, res));
|
||||
_pc++;
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -50,7 +49,7 @@ Result<void> VM::vm_sub(Opcode& oc) {
|
|||
Value val1 = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val2 = TRY(get(oc.arg3().is_const, (uint64_t)oc.arg3().arg));
|
||||
Value res = TRY(val1.sub(val2));
|
||||
setreg(acc, res);
|
||||
_stack = TRY(setreg(acc, res));
|
||||
_pc++;
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -60,7 +59,7 @@ Result<void> VM::vm_div(Opcode& oc) {
|
|||
Value val1 = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val2 = TRY(get(oc.arg3().is_const, (uint64_t)oc.arg3().arg));
|
||||
Value res = TRY(val1.div(val2));
|
||||
setreg(acc, res);
|
||||
_stack = TRY(setreg(acc, res));
|
||||
_pc++;
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -109,21 +108,21 @@ Result<void> VM::vm_call_lisp(Opcode& oc, Function& fun) {
|
|||
return ERROR(ArgumentCountMismatch);
|
||||
}
|
||||
|
||||
uint64_t old_base = _base;
|
||||
auto trunc_stack = TRY(_stack.settop(reg_start));
|
||||
auto new_stack =
|
||||
TRY(StackFrame::create(TRY(trunc_stack.copy_value()), fun, _pc));
|
||||
|
||||
Value fun_val = TRY(_fun.copy());
|
||||
Value oldbase_val = TRY(Int64::create(old_base));
|
||||
Value pc_val = TRY(Int64::create(_pc));
|
||||
_callstack.set(_callstack.gettop(), fun_val);
|
||||
_callstack.set(_callstack.gettop(), oldbase_val);
|
||||
_callstack.set(_callstack.gettop(), pc_val);
|
||||
for (uint64_t i = 0; i < reg_end - reg_start; i++) {
|
||||
new_stack = TRY(new_stack.set(i, TRY(_stack.get(reg_start + i))));
|
||||
}
|
||||
|
||||
_stack = std::move(new_stack);
|
||||
|
||||
_code = TRY(fun.code());
|
||||
_constants = TRY(fun.constants());
|
||||
_closure = TRY(fun.closure());
|
||||
_fun = std::move(fun);
|
||||
_pc = 0;
|
||||
_base = _base + reg_start;
|
||||
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -135,7 +134,7 @@ Result<void> VM::vm_call_stdlib(Opcode& oc, StdlibFunction& fun) {
|
|||
auto params = TRY(_stack.slice(reg_start + 1, reg_end));
|
||||
|
||||
auto res = TRY(call_stdlib_function(fun.fun_id(), params));
|
||||
setreg(oc.arg1().arg, res);
|
||||
_stack = TRY(setreg(oc.arg1().arg, res));
|
||||
|
||||
_pc++;
|
||||
return Result<void>();
|
||||
|
@ -164,47 +163,41 @@ Result<void> VM::vm_selfcall(Opcode& oc) {
|
|||
return ERROR(ArgumentCountMismatch);
|
||||
}
|
||||
|
||||
uint64_t old_base = _base;
|
||||
auto trunc_stack = TRY(_stack.settop(reg_start));
|
||||
auto new_stack =
|
||||
TRY(StackFrame::create(TRY(trunc_stack.copy_value()), _fun, _pc));
|
||||
|
||||
Value fun_val = TRY(_fun.copy());
|
||||
Value oldbase_val = TRY(Int64::create(old_base));
|
||||
Value pc_val = TRY(Int64::create(_pc));
|
||||
_callstack.set(_callstack.gettop(), fun_val);
|
||||
_callstack.set(_callstack.gettop(), oldbase_val);
|
||||
_callstack.set(_callstack.gettop(), pc_val);
|
||||
for (uint64_t i = 0; i < reg_end - reg_start; i++) {
|
||||
new_stack = TRY(new_stack.set(i, TRY(_stack.get(reg_start + i))));
|
||||
}
|
||||
|
||||
_stack = std::move(new_stack);
|
||||
_pc = 0;
|
||||
_base = _base + reg_start;
|
||||
|
||||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<void> VM::vm_ret(Opcode& oc) {
|
||||
if (_callstack.gettop() == 0) {
|
||||
auto parent = TRY(_stack.parent());
|
||||
if (parent.is<Nil>()) {
|
||||
_res = TRY(getreg((uint64_t)oc.arg1().arg));
|
||||
return ERROR(EndOfProgram);
|
||||
}
|
||||
|
||||
Value fun_val = TRY(_callstack.get(_callstack.gettop() - 3));
|
||||
Value oldbase_val = TRY(_callstack.get(_callstack.gettop() - 2));
|
||||
Value pc_val = TRY(_callstack.get(_callstack.gettop() - 1));
|
||||
auto res = TRY(getreg((uint64_t)oc.arg1().arg));
|
||||
StackFrame& parent_stack = *parent.to<StackFrame>();
|
||||
uint64_t parent_size = TRY(parent_stack.size());
|
||||
parent_stack = TRY(parent_stack.set(parent_size, res));
|
||||
|
||||
if (!oldbase_val.is<Int64>() || !pc_val.is<Int64>() ||
|
||||
!fun_val.is<Function>())
|
||||
return ERROR(TypeMismatch);
|
||||
|
||||
Function& fun = *fun_val.to<Function>();
|
||||
uint64_t oldbase = oldbase_val.to<Int64>()->value();
|
||||
uint64_t pc = pc_val.to<Int64>()->value();
|
||||
auto fun = TRY(parent_stack.fun());
|
||||
uint64_t pc = _stack.parent_pc();
|
||||
|
||||
_stack = std::move(parent_stack);
|
||||
_code = TRY(fun.code());
|
||||
_constants = TRY(fun.constants());
|
||||
_closure = TRY(fun.closure());
|
||||
_fun = std::move(fun);
|
||||
_pc = pc + 1;
|
||||
_base = oldbase;
|
||||
|
||||
TRY(_callstack.settop(_callstack.gettop() - 3));
|
||||
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -215,8 +208,8 @@ Result<void> VM::vm_jump(Opcode& oc) {
|
|||
}
|
||||
|
||||
Result<void> VM::vm_make_closure(Opcode& oc) {
|
||||
uint64_t begin = (uint64_t)_base + oc.arg1().arg + 1;
|
||||
uint64_t end = (uint64_t)_base + oc.arg2().arg;
|
||||
uint64_t begin = oc.arg1().arg + 1;
|
||||
uint64_t end = oc.arg2().arg;
|
||||
|
||||
Value fun_proto = TRY(get(oc.arg1().is_const, (uint64_t)oc.arg1().arg));
|
||||
if (!fun_proto.is<Function>()) return ERROR(TypeMismatch);
|
||||
|
@ -225,7 +218,7 @@ Result<void> VM::vm_make_closure(Opcode& oc) {
|
|||
|
||||
Value fun = TRY(Function::create(*fun_proto.to<Function>(), closure));
|
||||
|
||||
setreg(oc.arg1().arg, fun);
|
||||
_stack = TRY(setreg(oc.arg1().arg, fun));
|
||||
|
||||
_pc++;
|
||||
|
||||
|
@ -235,7 +228,7 @@ Result<void> VM::vm_make_closure(Opcode& oc) {
|
|||
Result<void> VM::vm_closure_load(Opcode& oc) {
|
||||
uint64_t acc = (uint64_t)oc.arg1().arg;
|
||||
Value val = TRY(_closure.get((uint64_t)oc.arg2().arg));
|
||||
setreg(acc, val);
|
||||
_stack = TRY(setreg(acc, val));
|
||||
_pc++;
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -244,7 +237,7 @@ Result<void> VM::vm_global_load(Opcode& oc) {
|
|||
uint64_t acc = (uint64_t)oc.arg1().arg;
|
||||
Value sym = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val = TRY(_globals.get(sym));
|
||||
setreg(acc, val);
|
||||
_stack = TRY(setreg(acc, val));
|
||||
_pc++;
|
||||
return Result<void>();
|
||||
}
|
||||
|
@ -321,17 +314,7 @@ Result<void> VM::step() {
|
|||
return Result<void>();
|
||||
}
|
||||
|
||||
// Result<Value> Int64::copy() const { return Value(Int64(TRY(_value.copy())));
|
||||
// }
|
||||
Result<Value> VM::run(const Module& mod, const Dict& globals) {
|
||||
_fun = TRY(mod.fun());
|
||||
_pc = 0;
|
||||
_base = 0;
|
||||
_code = TRY(_fun.code());
|
||||
_constants = TRY(_fun.constants());
|
||||
_closure = TRY(_fun.closure());
|
||||
_globals = TRY(globals.copy());
|
||||
|
||||
Result<Value> VM::run() {
|
||||
while (true) {
|
||||
auto rc = step();
|
||||
if (!rc.has_error()) continue;
|
||||
|
@ -343,7 +326,3 @@ Result<Value> VM::run(const Module& mod, const Dict& globals) {
|
|||
}
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
|
||||
Result<Value> VM::run(const Module& mod) {
|
||||
return run(mod, TRY(Dict::create()));
|
||||
}
|
||||
|
|
47
src/vm.hpp
47
src/vm.hpp
|
@ -5,20 +5,45 @@
|
|||
class VM {
|
||||
public:
|
||||
VM() {}
|
||||
VM(StackFrame&& stack, StackFrame&& callstack)
|
||||
: _stack(std::move(stack)), _callstack(std::move(callstack)) {}
|
||||
VM(StackFrame&& stack, Function&& fun, Array&& code, Array&& constants,
|
||||
Array&& closure, Dict&& globals, uint64_t pc, Value&& res)
|
||||
: _stack(std::move(stack)),
|
||||
_fun(std::move(fun)),
|
||||
_code(std::move(code)),
|
||||
_constants(std::move(constants)),
|
||||
_closure(std::move(closure)),
|
||||
_globals(std::move(globals)),
|
||||
_pc(pc),
|
||||
_res(std::move(res)) {}
|
||||
VM(VM&& vm)
|
||||
: _stack(std::move(vm._stack)), _callstack(std::move(vm._callstack)) {}
|
||||
: _stack(std::move(vm._stack)),
|
||||
_fun(std::move(vm._fun)),
|
||||
_code(std::move(vm._code)),
|
||||
_constants(std::move(vm._constants)),
|
||||
_closure(std::move(vm._closure)),
|
||||
_globals(std::move(vm._globals)),
|
||||
_pc(vm._pc),
|
||||
_res(std::move(vm._res)) {}
|
||||
|
||||
VM(const VM&) = delete;
|
||||
|
||||
static Result<VM> create() {
|
||||
auto stack = TRY(StackFrame::create(16 * 1024));
|
||||
auto callstack = TRY(StackFrame::create(16 * 1024));
|
||||
return VM(std::move(stack), std::move(callstack));
|
||||
static Result<VM> create(const Module& mod, const Dict& globals) {
|
||||
auto fun = TRY(mod.fun());
|
||||
auto nil = Value(TRY(Nil::create()));
|
||||
auto stack = TRY(StackFrame::create(nil, fun, 0));
|
||||
|
||||
uint64_t pc = 0;
|
||||
auto code = TRY(fun.code());
|
||||
auto constants = TRY(fun.constants());
|
||||
auto closure = TRY(fun.closure());
|
||||
auto globals_copy = TRY(globals.copy());
|
||||
|
||||
return VM(std::move(stack), std::move(fun), std::move(code),
|
||||
std::move(constants), std::move(closure), std::move(globals_copy),
|
||||
pc, std::move(nil));
|
||||
}
|
||||
|
||||
Result<Value> run(const Module& mod);
|
||||
Result<Value> run(const Module& mod, const Dict& globals);
|
||||
Result<Value> run();
|
||||
|
||||
Result<void> step();
|
||||
Result<void> vm_mov(Opcode& oc);
|
||||
|
@ -46,19 +71,17 @@ class VM {
|
|||
Result<Value> get(bool is_const, uint64_t idx);
|
||||
Result<Value> getconst(uint64_t idx);
|
||||
Result<Value> getreg(uint64_t idx);
|
||||
Result<void> setreg(uint64_t idx, const Value& value);
|
||||
Result<StackFrame> setreg(uint64_t idx, const Value& value);
|
||||
|
||||
Result<Dict> globals() { return _globals.copy(); }
|
||||
|
||||
private:
|
||||
StackFrame _stack;
|
||||
StackFrame _callstack;
|
||||
Function _fun;
|
||||
Array _code;
|
||||
Array _constants;
|
||||
Array _closure;
|
||||
Dict _globals;
|
||||
uint64_t _pc;
|
||||
uint64_t _base;
|
||||
Value _res;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue