#pragma once #include "common.hpp" class VM { public: VM() {} VM(Stack&& stack, Stack&& callstack) : _stack(std::move(stack)), _callstack(std::move(callstack)) {} VM(VM&& vm) : _stack(std::move(vm._stack)), _callstack(std::move(vm._callstack)) {} VM(const VM&) = delete; static Result create() { auto stack = TRY(Stack::create(16 * 1024)); auto callstack = TRY(Stack::create(16 * 1024)); return VM(std::move(stack), std::move(callstack)); } Result run(const Module& mod); Result run(const Module& mod, const Dict& globals); Result step(); 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 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(); } private: Stack _stack; Stack _callstack; Function _fun; Array _code; Array _constants; Array _closure; Dict _globals; uint64_t _pc; uint64_t _base; Value _res; };