#pragma once #include "common.hpp" class VM { public: VM() {} VM(StackFrame&& stack, Dict&& globals, Value&& res) : _stack(std::move(stack)), _globals(std::move(globals)), _res(std::move(res)) {} VM(VM&& vm) : _stack(std::move(vm._stack)), _globals(std::move(vm._globals)), _res(std::move(vm._res)) {} VM(const VM&) = delete; static Result create(const Module& mod, const Dict& globals) { auto fun = Value(TRY(mod.fun())); auto nil = Value(TRY(Nil::create())); auto stack = TRY(StackFrame::create(nil, fun)); auto globals_copy = TRY(globals.copy()); /* 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(globals_copy), std::move(nil)); } Result run(); Result step(); Result step_bytecode(); Result step_native(); Result vm_mov(Opcode& oc); Result vm_add(Opcode& oc); Result vm_mul(Opcode& oc); Result vm_sub(Opcode& oc); Result vm_div(Opcode& oc); Result vm_call(Opcode& oc); Result vm_selfcall(Opcode& oc); Result vm_call_lisp(Opcode& oc, Function& fun); Result vm_call_stdlib(Opcode& oc, StdlibFunction& fun); Result vm_ret(Opcode& oc); Result vm_equal(Opcode& oc); Result vm_less(Opcode& oc); Result vm_less_equal(Opcode& oc); Result vm_jump(Opcode& oc); Result vm_make_closure(Opcode& oc); Result vm_closure_load(Opcode& oc); Result vm_global_load(Opcode& oc); Result vm_global_store(Opcode& oc); Result handle_raise(const Continuation& cont); Result get(bool is_const, uint64_t idx); Result getconst(uint64_t idx); Result getreg(uint64_t idx); Result setreg(uint64_t idx, const Value& value); Result globals() { return _globals.copy(); } Result code() { auto fun = TRY(_stack.fun()); if (!fun.is()) return ERROR(TypeMismatch); return fun.to()->code(); } Result constants() { auto fun = TRY(_stack.fun()); if (!fun.is()) return ERROR(TypeMismatch); return fun.to()->constants(); } Result closure() { auto fun = TRY(_stack.fun()); if (!fun.is()) return ERROR(TypeMismatch); return fun.to()->closure(); } Result backtrace(uint64_t indent = 0) { return _stack.backtrace(indent); } private: StackFrame _stack; Dict _globals; Value _res; };