From 3d68124a6019dbb3bb9cdc390f984519147fd605 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sun, 26 Apr 2020 21:25:26 +0200 Subject: [PATCH] Allow client code to provide their foreign_class_fn() implementation. --- src/wren/vm.cpp | 16 ++++++++++++++++ src/wren/vm.hpp | 11 +++++++++++ 2 files changed, 27 insertions(+) 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; }