xo-interpreter CVector for StackFrame reflection + OSX imgui edits

This commit is contained in:
Roland Conybeare 2025-11-17 10:41:35 -05:00
commit d58a8532d4
11 changed files with 98 additions and 63 deletions

View file

@ -61,7 +61,9 @@ namespace xo {
void assign_ptr(T * x) { ptr_ = x; }
gc_ptr & operator=(const gc_ptr & x) { ptr_ = x.ptr(); return *this; }
T * operator->() const { return ptr_; }
T & operator*() const { return *ptr_; }
private:
T * ptr_ = nullptr;

View file

@ -98,7 +98,7 @@ void
AppState::generate_random_mutation() {
if (rng_() % 1000 > (5 * 1000) / 7) {
/* p=16% integer */
gc_root_v_[next_root_++] = Integer::make(next_int_);
gc_root_v_[next_root_++] = Integer::make(gc_.get(), next_int_);
} else if (rng_() % 1000 > (3 * 1000) / 7) {
/* p=16% cons */
gp<Object> random_car = gc_root_v_.at(rng_() % gc_root_v_.size());

View file

@ -691,9 +691,9 @@ VulkanApp::wait_not_minimized()
{
int width = 0;
int height = 0;
SDL_GetWindowSize(window_, &width, &height);
SDL_Vulkan_GetDrawableSize(window_, &width, &height);
while (width == 0 || height == 0) {
SDL_GetWindowSize(window_, &width, &height);
SDL_Vulkan_GetDrawableSize(window_, &width, &height);
SDL_WaitEvent(nullptr);
}
}

View file

@ -2,10 +2,41 @@
#include "xo/alloc/IAlloc.hpp"
#include "xo/alloc/Object.hpp"
#include <cstddef>
#include <cstdint>
namespace xo {
namespace scm {
/** gc-only vector
**/
template <typename ElementType>
class CVector {
public:
using value_type = ElementType;
public:
CVector(gc::IAlloc * mm, std::size_t n)
: n_{n}, v_{nullptr}
{
if (n_ > 0) {
std::byte * mem = mm->alloc(n_ * sizeof(ElementType));
this->v_ = new (mem) ElementType[n];
}
}
std::size_t size() const { return n_; }
ElementType operator[](std::size_t i) const { return v_[i]; }
ElementType & operator[](std::size_t i) { return v_[i]; }
friend class StackFrame;
private:
/** number of elements in @ref v_ **/
std::size_t n_ = 0;
/** contiguous array of pointers **/
ElementType * v_ = nullptr;
};
/** @class StackFrame
* @brief Represent a single runtime stack frame for a Schematika function
*
@ -15,26 +46,26 @@ namespace xo {
*
* memory layout:
*
* +------------+
* | vtable |
* +------------+
* | .n_ |
* +------------+
* | .v_ +------\
* +------------+ <--/
* | .v_[0] |
* +------------+
* . .. .
* +------------+
* | .v_[.n_-1] |
* +------------+
* +-----------------------+
* | vtable |
* +------------+----------+
* | .slot_v_ | .n_ |
* | +----------+
* | | .v_ +------\
* +------------+----------+ <--/
* | .v_[0] |
* +-----------------------+
* . .. .
* +-----------------------+
* | .v_[.n_-1] |
* +-----------------------+
**/
class StackFrame : public Object {
public:
using TaggedPtr = xo::reflect::TaggedPtr;
public:
StackFrame(gc::IAlloc * mm, std::size_t n_slot);
StackFrame(gc::IAlloc * mm, std::size_t n) : slot_v_{mm, n} {}
/** create frame using allocator @p mm,
* with exactly @p n_slot object pointers
@ -44,12 +75,10 @@ namespace xo {
/** reflect StackFrame object representation **/
static void reflect_self();
std::size_t n_slot() const { return n_slot_; }
gp<Object> lookup(std::size_t i) const { return v_[i]; }
gp<Object> & lookup(std::size_t i) { return v_[i]; }
std::size_t size() const { return slot_v_.size(); }
gp<Object> operator[](std::size_t i) const { return lookup(i); }
gp<Object> & operator[](std::size_t i) { return lookup(i); }
gp<Object> operator[](std::size_t i) const { return slot_v_[i]; }
gp<Object> & operator[](std::size_t i) { return slot_v_[i]; }
// inherited from Object..
virtual TaggedPtr self_tp() const final override;
@ -59,10 +88,8 @@ namespace xo {
virtual std::size_t _forward_children() final override;
private:
/** number of elements in frame **/
std::size_t n_slot_ = 0;
/** contiguous array of object pointers: v[0] .. v[n-1] **/
gp<Object> * v_ = nullptr;
/** stack frame contents **/
CVector<gp<Object>> slot_v_;
};
} /*namespace scm*/
} /*namespace xo*/

View file

@ -20,7 +20,7 @@ namespace xo {
private:
std::string_view name_;
ActionFn action_;
//ActionFn action_;
};
}
}

View file

@ -8,7 +8,11 @@
namespace xo {
using xo::reflect::Reflect;
using xo::reflect::StructReflector;
using xo::reflect::TypeDescrW;
using xo::reflect::TaggedPtr;
using xo::reflect::TypeDescrExtra;
using xo::reflect::EstablishTypeDescr;
using xo::reflect::StlVectorTdx;
using xo::print::quot;
namespace scm {
@ -19,20 +23,10 @@ namespace xo {
}
}
StackFrame::StackFrame(gc::IAlloc * mm, std::size_t n_slot)
: n_slot_{n_slot}, v_{nullptr}
{
if (n_slot > 0) {
std::byte * mem = mm->alloc(slot_array_size(n_slot));
this->v_ = new (mem) gp<Object>[n_slot];
}
}
gp<StackFrame>
StackFrame::make(gc::IAlloc * mm, std::size_t n_slot)
StackFrame::make(gc::IAlloc * mm, std::size_t n)
{
return new (MMPtr(mm)) StackFrame(mm, n_slot);
return new (MMPtr(mm)) StackFrame(mm, n);
}
TaggedPtr
@ -45,7 +39,7 @@ namespace xo {
StackFrame::display(std::ostream & os) const
{
os << "<stack-frame"
<< xtag("n_slot", n_slot_);
<< xtag("n", slot_v_.size());
#ifdef NOT_YET
for (std::size_t i = 0, n = n_slot(); i < n; ++i) {
@ -64,7 +58,7 @@ namespace xo {
{
std::size_t retval = sizeof(StackFrame);
retval += gc::IAlloc::with_padding(slot_array_size(n_slot_));
retval += gc::IAlloc::with_padding(slot_array_size(slot_v_.size()));
return retval;
}
@ -74,12 +68,14 @@ namespace xo {
{
Cpof cpof(Object::mm, this);
StackFrame * copy = new (cpof) StackFrame(cpof.mm_, n_slot_);
size_t z = size();
void * v_dest = copy->v_;
StackFrame * copy = new (cpof) StackFrame(cpof.mm_, z);
if (v_) {
::memcpy(v_dest, v_, slot_array_size(n_slot_));
void * v_dest = copy->slot_v_.v_;
if (slot_v_.v_) {
::memcpy(v_dest, slot_v_.v_, slot_array_size(z));
}
#ifdef OBSOLETE
@ -94,8 +90,8 @@ namespace xo {
std::size_t
StackFrame::_forward_children()
{
for (std::size_t i = 0, n = n_slot_; i < n; ++i) {
Object::_forward_inplace(lookup(i));
for (std::size_t i = 0, n = slot_v_.size(); i < n; ++i) {
Object::_forward_inplace((*this)[i]);
}
return _shallow_size();
@ -107,11 +103,24 @@ namespace xo {
StructReflector<StackFrame> sr;
if (sr.is_incomplete()) {
REFLECT_MEMBER(sr, n_slot);
/* reflect CVector<gp<Object>>
*
* note: placement here works b/c CVector<T> not used anywhere else
*/
using VectorType = CVector<gp<Object>>;
// non-trivial to reflect frame members,
// effectively need separate reflection for each cardinality;
// or: reflect .v_[] as nested element
/* custom reflection for array of Object pointers.
* Can use StlVectorTdx here, treating CVector<T> as a vector
* via .size() and .operator[] members
*/
std::unique_ptr<TypeDescrExtra> tdx1
= std::make_unique<StlVectorTdx<VectorType>>();
TypeDescrW td1
= EstablishTypeDescr::establish<VectorType>();
td1->assign_tdextra(Reflect::get_final_invoker<VectorType>(),
std::move(tdx1));
REFLECT_MEMBER(sr, slot_v);
}
}
} /*namespace scm*/

View file

@ -101,7 +101,7 @@ namespace xo {
REQUIRE(gc->tospace_generation_of(frame.ptr()) == generation_result::nursery);
for (std::size_t i = 0; i < n; ++i)
frame->lookup(i) = Integer::make(mm, tc.contents_.at(i));
(*frame)[i] = Integer::make(mm, tc.contents_.at(i));
std::size_t expected_alloc_z = frame->_shallow_size();
REQUIRE(expected_alloc_z >= sizeof(StackFrame) + n * sizeof(gp<Object>));
@ -116,7 +116,7 @@ namespace xo {
/* verify StackFrame preserved across gc */
REQUIRE(gc->tospace_generation_of(frame.ptr()) == generation_result::nursery);
REQUIRE(frame->n_slot() == n);
REQUIRE(frame->size() == n);
for (std::size_t i = 0; i < n; ++i) {
//REQUIRE(Integer::from(frame->lookup(i)).ptr());
//REQUIRE(Integer::from(frame->lookup(i))->value() == tc.contents_.at(i));

View file

@ -11,7 +11,6 @@
/* stuff from kaleidoscope.cpp */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
# include "llvm/ADT/APFloat.h"
# include "llvm/ADT/STLExtras.h"
# include "llvm/IR/BasicBlock.h"

View file

@ -254,15 +254,12 @@ namespace xo {
template<typename T>
static TaggedRcptr make_rctp(T * x) { return TaggedPtrMaker<T>::make_rctp(x); }
private:
template <typename T>
static detail::InvokerAux<T> * get_final_invoker() {
static detail::InvokerAux<T> s_final_invoker;
return &s_final_invoker;
}
}; /*Reflect*/
// ----- MakeTagged -----

View file

@ -61,8 +61,9 @@ namespace xo {
using Memptr = MemberT OwnerT::*;
public:
GeneralStructMemberAccessor(Memptr memptr) : member_td_{EstablishTypeDescr::establish<MemberT>()},
memptr_{memptr} {}
GeneralStructMemberAccessor(Memptr memptr)
: member_td_{EstablishTypeDescr::establish<MemberT>()},
memptr_{memptr} {}
GeneralStructMemberAccessor(GeneralStructMemberAccessor const & x) = default;
virtual ~GeneralStructMemberAccessor() = default;
@ -214,8 +215,8 @@ namespace xo {
} /*for_descendant*/
StructMember & operator=(StructMember && x) {
member_name_ = std::move(x.member_name_);
accessor_ = std::move(x.accessor_);
this->member_name_ = std::move(x.member_name_);
this->accessor_ = std::move(x.accessor_);
return *this;
}

View file

@ -17,7 +17,7 @@ namespace xo {
/* named ctor idiom. create new instance for a vector type */
//static std::unique_ptr<VectorTdx> make();
/** @brief true if array elements are stored at regularly-spaced offsetts **/
/** @brief true if array elements are stored at regularly-spaced offsets **/
virtual bool has_contiguous_storage() const = 0;
// ----- Inherited from TypeDescrExtra -----