diff --git a/src/wren/vm.cpp b/src/wren/vm.cpp index b460f92..4ddc27a 100644 --- a/src/wren/vm.cpp +++ b/src/wren/vm.cpp @@ -55,6 +55,19 @@ namespace wren { auto retval = reinterpret_cast(dfm->make(cb->owner, func)); return retval; } + + WrenForeignClassMethods foreign_class_fn (WrenVM* wvm, const char* module, const char* class_name) { + auto cb = static_cast(wrenGetUserData(wvm)); + assert(cb); + assert(cb->foreign_class_fn and cb->config_obj and cb->owner); + foreign_class_t funcs = cb->foreign_class_fn(*cb->config_obj, cb->owner, module, class_name); + DynafuncMaker* const dfm = cb->dynafunc; + assert(dfm); + WrenForeignClassMethods retval; + retval.allocate = reinterpret_cast(dfm->make(cb->owner, funcs.allocate)); + retval.finalize = funcs.finalize; + return retval; + } } //unnamed namespace struct VM::LocalData { @@ -106,6 +119,9 @@ namespace wren { if (cb.foreign_method_fn) wconf.bindForeignMethodFn = &foreign_method_fn; + if (cb.foreign_class_fn) + wconf.bindForeignClassFn = &foreign_class_fn; + m_local->wvm = wrenNewVM(&wconf); if (not m_local->wvm) throw std::runtime_error("Failed to initialize Wren VM"); diff --git a/src/wren/vm.hpp b/src/wren/vm.hpp index d57beab..b208aca 100644 --- a/src/wren/vm.hpp +++ b/src/wren/vm.hpp @@ -11,6 +11,12 @@ namespace wren { class DynafuncMaker; typedef void(*foreign_method_t)(VM*); + typedef void(*finalizer_t)(void*); + + struct foreign_class_t { + foreign_method_t allocate; + finalizer_t finalize; + }; namespace detail { struct Callbacks { @@ -20,6 +26,7 @@ namespace wren { const char* (*resolve_module_fn)(Configuration&, VM*, const char*, const char*) {nullptr}; char* (*load_module_fn)(Configuration&, VM*, const char*) {nullptr}; foreign_method_t (*foreign_method_fn)(Configuration&, VM*, const char*, const char*, bool, const char*); + foreign_class_t (*foreign_class_fn)(Configuration&, VM*, const char*, const char*); Configuration* config_obj {nullptr}; VM* owner {nullptr}; @@ -57,6 +64,7 @@ namespace wren { define_method_info(resolve_module_fn, resolve_module, const char*, const char*, const char*); define_method_info(load_module_fn, load_module, char*, VM*, const char*); define_method_info(foreign_method_fn, foreign_method, foreign_method_t, VM*, const char*, const char*, bool, const char*); + define_method_info(foreign_class_fn, foreign_class, foreign_class_t, VM*, const char*, const char*); template struct AnyFunctionWrap; template @@ -103,6 +111,9 @@ namespace wren { if constexpr (detail::method_foreign_method::exists::value) ret.foreign_method_fn = &detail::AnyFunctionWrap::template call<&T::foreign_method_fn>; + if constexpr (detail::method_foreign_class::exists::value) + ret.foreign_class_fn = &detail::AnyFunctionWrap::template call<&T::foreign_class_fn>; + return ret; }