From 364f34cc8a8702e52a6f0e5cbd88d6a4e3b7d393 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 25 Mar 2026 18:00:36 -0400 Subject: [PATCH] xo-interpreter2 stack: scaffold for virtual root VSM [WIP] --- .../interpreter2/VirtualSchematikaMachine.hpp | 25 +++++++-- src/interpreter2/VirtualSchematikaMachine.cpp | 55 +++++++++++++++---- 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 382dbc5d..d39db5bc 100644 --- a/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -8,9 +8,10 @@ #include "VsmConfig.hpp" #include "VsmInstr.hpp" #include "VsmFrame.hpp" -#include "DLocalEnv.hpp" -#include "DGlobalEnv.hpp" +#include "LocalEnv.hpp" +#include "GlobalEnv.hpp" #include +#include #include #include #include @@ -46,6 +47,7 @@ namespace xo { bool is_eval_error() const; const obj * value() const { return std::get_if>(&result_); } + obj & value_ref() { return std::get>(result_); } /** result of evaluating first expression encountered in input **/ std::variant, TokenizerError> result_; @@ -69,6 +71,7 @@ namespace xo { public: // will be DArenaVector> probably using Stack = void *; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; @@ -127,6 +130,18 @@ namespace xo { **/ bool execute_one(); + /** @defgroup scm-virtualschematikamachine-gcobject-facet gcobject facet **/ + ///@{ + + /** object size **/ + std::size_t shallow_size() const noexcept; + + /** forward gc-aware child pointers + **/ + std::size_t forward_children(obj gc) noexcept; + + ///@} + private: /** Require: * - expression in @ref expr_ @@ -281,18 +296,18 @@ namespace xo { /** environment pointer. Maintains bindings * for global variables. Obtained from reader **/ - DGlobalEnv * global_env_ = nullptr; + obj global_env_; /** environment pointer. Provides bindings * for surrounding lexical scope at this point * in execution **/ - DLocalEnv * local_env_ = nullptr; + obj local_env_; /** evaluated function to call **/ obj fn_; /** evaluated argument list **/ - DArray * args_; + obj args_; /** result register **/ VsmResult value_; diff --git a/src/interpreter2/VirtualSchematikaMachine.cpp b/src/interpreter2/VirtualSchematikaMachine.cpp index 37f24390..5c0430e8 100644 --- a/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/src/interpreter2/VirtualSchematikaMachine.cpp @@ -85,11 +85,20 @@ namespace xo { this->error_mm_.adopt(obj(arena)); } - this->global_env_ = reader_.global_env(); + this->global_env_ + = obj(reader_.global_env()); //this->_add_gc_roots(); } + VirtualSchematikaMachine * + VirtualSchematikaMachine::_make(obj mm, + const VsmConfig & config, + obj aux_mm) + { + xxx; + } + obj VirtualSchematikaMachine::allocator() const noexcept { @@ -308,7 +317,7 @@ namespace xo { auto def_expr = obj::from(expr_); - if (local_env_ == nullptr) { + if (local_env_) { // top-level define // .stack_ --+ @@ -411,7 +420,7 @@ namespace xo { DClosure * closure = DClosure::make(mm_.to_op(), lambda.data(), - local_env_); + local_env_.data()); this->value_ = VsmResult(obj(obj(closure))); @@ -623,7 +632,7 @@ namespace xo { DVsmApplyClosureFrame::make(mm_.to_op(), stack_, cont_, - local_env_)); + local_env_.data())); // push frame w/ saved vsm registers this->stack_ = frame; @@ -634,11 +643,11 @@ namespace xo { auto local_env = DLocalEnv::_make(mm_.to_op(), - local_env_, + local_env_.data(), lambda->local_symtab(), - args_); + args_.data()); - this->local_env_ = local_env; + this->local_env_ = obj(local_env); this->expr_ = lambda->body_expr(); this->pc_ = VsmInstr::c_eval; // cont_ already established @@ -649,7 +658,7 @@ namespace xo { { auto fn = fn_.to_facet(); - this->value_ = VsmResult(fn.apply_nocheck(rcx_.to_op(), args_)); + this->value_ = VsmResult(fn.apply_nocheck(rcx_.to_op(), args_.data())); this->pc_ = cont_; this->cont_ = VsmInstr::c_sentinel; } @@ -727,7 +736,7 @@ namespace xo { // corner case: function with 0 arguments this->fn_ = apply_frame->fn(); // = value; - this->args_ = apply_frame->args(); // empty + this->args_ = obj(apply_frame->args()); // empty this->stack_ = apply_frame->parent(); this->pc_ = VsmInstr::c_apply; @@ -765,7 +774,7 @@ namespace xo { // this->fn_ = apply_frame->fn(); - this->args_ = apply_frame->args(); + this->args_ = obj(apply_frame->args()); this->stack_ = apply_frame->parent(); this->pc_ = VsmInstr::c_apply; @@ -796,7 +805,7 @@ namespace xo { assert(frame); this->stack_ = frame->parent(); - this->local_env_ = frame->local_env(); + this->local_env_ = obj(frame->local_env()); this->pc_ = frame->cont(); this->cont_ = VsmInstr::c_sentinel; } @@ -881,6 +890,30 @@ namespace xo { } } + std::size_t + VirtualSchematikaMachine::shallow_size() const noexcept + { + return sizeof(VirtualSchematikaMachine); + } + + std::size_t + VirtualSchematikaMachine::forward_children(obj gc) noexcept + { + reader_.forward_children(gc); + + gc.forward_inplace(&stack_); + gc.forward_pivot_inplace(&expr_); + gc.forward_inplace(&global_env_); + gc.forward_inplace(&local_env_); + gc.forward_inplace(&fn_); + gc.forward_inplace(&args_); + if (value_.is_value()) { + gc.forward_inplace(&value_.value_ref()); + } + + return this->shallow_size(); + } + } /*namespace scm*/ } /*namespace xo*/