/** @file DGlobalEnv.cpp * * @author Roland Conybeare, Feb 2026 **/ #include "GlobalEnv.hpp" #include #include namespace xo { using xo::mm::AAllocator; using xo::mm::AGCObject; namespace scm { DGlobalEnv::DGlobalEnv(DGlobalSymtab * symtab, DArray * values) : symtab_{symtab}, values_{values} {} DGlobalEnv * DGlobalEnv::_make(obj mm, DGlobalSymtab * symtab) { DArray * values = DArray::empty(mm, symtab->var_capacity()); void * mem = mm.alloc_for(); return new (mem) DGlobalEnv(symtab, values); } obj DGlobalEnv::lookup_value(Binding ix) const noexcept { if (!ix.is_global()) { assert(false); return obj(); } if (ix.j_slot() >= static_cast(values_->size())) { assert(false); return obj(); } return (*values_)[ix.j_slot()]; } void DGlobalEnv::assign_value(obj mm, Binding ix, obj x) { scope log(XO_DEBUG(false), xtag("ix.j_slot", ix.j_slot()), xtag("values.cap", values_->capacity())); assert(ix.is_global()); if (ix.j_slot() >= static_cast(values_->size())) { // Control will come here in interpreter as new definitions are introduced. // After seeing // def foo = 1.2345; // introducing new symbol foo: // GlobalSymtab extends to include foo without this GlobalEnv // knowing about it. if (ix.j_slot() + 1 > static_cast(values_->capacity())) { // realloc global array for more size size_t cap_2x = 2 * values_->capacity(); while (cap_2x < static_cast(ix.j_slot() + 1)) cap_2x = 2 * cap_2x; DArray * values_2x = DArray::copy(mm, values_, cap_2x); assert(values_2x); if (values_2x) { log && log("STUB: need write barrier for GC (also in GlobalSymtab!)"); this->values_ = values_2x; } else { return; } } /** expand size sot that j_slot is valid **/ values_->resize(ix.j_slot() + 1); } log && log("STUB: need write barrier for GC here"); (*values_)[ix.j_slot()] = x; } DVariable * DGlobalEnv::_upsert_value(obj mm, const DUniqueString * sym, TypeDescr td, obj value) { DVariable * var = DVariable::make(mm, sym, TypeRef::resolved(td)); assert(var); symtab_->upsert_variable(mm, var); this->assign_value(mm, var->path(), value); return var; } // ----- AGCObject facet ----- std::size_t DGlobalEnv::shallow_size() const noexcept { return sizeof(*this); } DGlobalEnv * DGlobalEnv::shallow_move(obj mm) noexcept { return mm.std_copy_for(this); } std::size_t DGlobalEnv::forward_children(obj gc) noexcept { gc.forward_inplace(&symtab_); gc.forward_inplace(&values_); return this->shallow_size(); } // ----- APrintable facet ----- bool DGlobalEnv::pretty(const ppindentinfo & ppii) const { return ppii.pps()->pretty_struct (ppii, "DGlobalEnv", refrtag("n_vars", symtab_->n_vars())); } } /*namespace scm*/ } /*namespace xo*/ /* end DGlobalEnv.cpp */