/** @file DGlobalSymtab.cpp * * @author Roland Conybeare, Jan 2026 **/ #include "DGlobalSymtab.hpp" #include "DUniqueString.hpp" #include #include #include #include #include #include namespace xo { using xo::map::DArenaHashMap; using xo::mm::AGCObject; namespace scm { DGlobalSymtab::DGlobalSymtab(dp map, DArray * vars) : map_{std::move(map)}, vars_{vars} { } dp DGlobalSymtab::make(obj mm, obj aux_mm, const ArenaHashMapConfig & cfg) { auto map = dp::make(aux_mm, cfg); assert(map); /* choosing same capacity for hash, vars */ DArray * vars = DArray::empty(mm, map->capacity()); assert(vars); auto symtab = dp::make(mm, std::move(map), vars); assert(symtab); return symtab; } void DGlobalSymtab::visit_pools(const MemorySizeVisitor & visitor) const { if (map_) map_->visit_pools(visitor); } DVariable * DGlobalSymtab::lookup_variable(const DUniqueString * sym) const noexcept { Binding existing = this->lookup_binding(sym); if (existing.is_null()) return nullptr; auto var_gco = obj::from((*vars_)[existing.j_slot()]); auto var = var_gco.to_facet(); assert(var.data()); return var.data(); } DVariable * DGlobalSymtab::establish_variable(obj mm, const DUniqueString * sym, TypeRef typeref) { DVariable * var = this->lookup_variable(sym); if (!var) { assert(vars_); DArray::size_type n = vars_->size(); // NOTE: expansion here is moot at present (Feb 2026). // Not implemented in ArenaHashMap /** make sure vars_ has room **/ if (n == vars_->capacity()) { // reallocate with more capacity DArray * vars_2x = DArray::copy(mm, vars_, vars_->capacity() * 2); assert(vars_2x); this->vars_ = vars_2x; } /** create new variable **/ Binding binding = Binding::global(n); var = DVariable::make(mm, sym, typeref, binding); if (!var) { // something terribly wrong assert(false); return var; } assert(map_->size() < map_->capacity()); (*map_)[sym] = binding.j_slot(); bool ok = vars_->push_back(obj(var)); if (!ok) assert(false); } return var; } Binding DGlobalSymtab::lookup_binding(const DUniqueString * sym) const noexcept { assert(sym); scope log(XO_DEBUG(true), "stub"); log && log(xtag("sym", std::string_view(*sym))); auto ix = map_->find(sym); if (ix == map_->end()) return Binding::null(); return Binding::global(ix->second); } // ----- gcobject facet ----- std::size_t DGlobalSymtab::shallow_size() const noexcept { return sizeof(DGlobalSymtab); } DGlobalSymtab * DGlobalSymtab::shallow_copy(obj mm) const noexcept { /** can't use std_copy_for because of non-copyable dp * * TODO: rename to shallow_move() throughout, and have std_copy_for() * -> std_move_for() * **/ void * copy_mem = mm.alloc_copy_for(this); if (copy_mem) { DGlobalSymtab * self = const_cast(this); return new (copy_mem) DGlobalSymtab(std::move(self->map_), vars_); } return nullptr; } std::size_t DGlobalSymtab::forward_children(obj gc) noexcept { // map_ doesn't contain any gc-owned data, can skip gc.forward_inplace(&vars_); return this->shallow_size(); } } /*namespace scm*/ } /*namespace xo*/ /* end DGlobalSymtab.cpp */