diff --git a/meson.build b/meson.build index c10a6b3..b20adb8 100644 --- a/meson.build +++ b/meson.build @@ -45,6 +45,7 @@ executable(meson.project_name(), 'src/wren/dynafunc_maker.cpp', 'src/dynafunc_' + arch + '_' + os + '.S', 'src/wren/handle.cpp', + 'src/wren/vm_fun.cpp', dependencies: [wren_dep], install: true, ) diff --git a/src/main.cpp b/src/main.cpp index c14e3ea..7f3a57d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#include "wren/vm.hpp" +#include "wren/vm_fun.hpp" #include "wren/def_configuration.hpp" #include #include diff --git a/src/wren/handle.cpp b/src/wren/handle.cpp index eb09d6a..97d09a7 100644 --- a/src/wren/handle.cpp +++ b/src/wren/handle.cpp @@ -9,6 +9,6 @@ namespace wren { void Handle::release() noexcept { assert(m_vm); - m_vm->release(*this); + m_vm->release_handle(*this); } } //namespace wren diff --git a/src/wren/vm.cpp b/src/wren/vm.cpp index 03f3db8..900e836 100644 --- a/src/wren/vm.cpp +++ b/src/wren/vm.cpp @@ -4,7 +4,6 @@ #include #include #include -#include namespace wren { namespace { @@ -150,80 +149,51 @@ namespace wren { } } - void VM::interpret (const std::string& module_name, const std::string& script) { - return interpret(module_name.c_str(), script.c_str()); - } - - void VM::release (Handle& handle) noexcept { + void VM::release_handle (Handle& handle) noexcept { if (handle) wrenReleaseHandle(m_local->wvm, handle); } - template <> bool VM::slot (int slot_num) { + bool VM::slot_bool (int slot_num) { assert(SlotType::Bool == slot_type(slot_num)); return wrenGetSlotBool(m_local->wvm, slot_num); } - template <> std::string VM::slot (int slot_num) { + const char* VM::slot_string (int slot_num) { assert(SlotType::String == slot_type(slot_num)); return wrenGetSlotString(m_local->wvm, slot_num); } - template <> double VM::slot (int slot_num) { + double VM::slot_double (int slot_num) { assert(SlotType::Num == slot_type(slot_num)); return wrenGetSlotDouble(m_local->wvm, slot_num); } - template <> std::vector VM::slot (int slot_num) { + std::pair VM::slot_bytes (int slot_num) { assert(SlotType::String == slot_type(slot_num)); int length; const char* const data = wrenGetSlotBytes(m_local->wvm, slot_num, &length); - return std::vector{data, data + length}; + return {data, length}; } - template <> - int VM::slot (int slot_num) { - assert(SlotType::Num == slot_type(slot_num)); - return static_cast(slot(slot_num)); - } - - std::string_view VM::slot_string_view (int slot_num) { - assert(SlotType::String == slot_type(slot_num)); - int length; - const char* const data = wrenGetSlotBytes(m_local->wvm, slot_num, &length); - return {data, static_cast(length)}; - } - - void VM::set (int slot_num, const std::string& value) { - wrenSetSlotString(m_local->wvm, slot_num, value.c_str()); - } - - void VM::set (int slot_num, const char* value) { + void VM::set_slot_string (int slot_num, const char* value) { wrenSetSlotString(m_local->wvm, slot_num, value); } - void VM::set (int slot_num, std::string_view value) { - wrenSetSlotBytes(m_local->wvm, slot_num, value.data(), value.size()); - } - - void VM::set (int slot_num, const char* beg, const char* end) { - wrenSetSlotBytes(m_local->wvm, slot_num, beg, std::distance(beg, end)); - } - - void VM::set (int slot_num, double value) { + void VM::set_slot_double (int slot_num, double value) { wrenSetSlotDouble(m_local->wvm, slot_num, value); } - void VM::set (int slot_num, bool value) { + void VM::set_slot_bool (int slot_num, bool value) { wrenSetSlotBool(m_local->wvm, slot_num, value); } - void VM::set (int slot_num, const std::vector& value) { - wrenSetSlotBytes(m_local->wvm, slot_num, value.data(), value.size()); + void VM::set_slot_null (int slot_num) { + wrenSetSlotNull(m_local->wvm, slot_num); } - void VM::set (int slot_num, std::nullptr_t) { - wrenSetSlotNull(m_local->wvm, slot_num); + void VM::set_slot_bytes (int slot_num, const char* bytes, std::size_t length) { + wrenSetSlotBytes(m_local->wvm, slot_num, bytes, length); } void VM::ensure_slots (int num_slots) { @@ -238,11 +208,7 @@ namespace wren { wrenGetVariable(m_local->wvm, module, name, slot); } - void VM::variable(const ModuleAndName& mod_and_name, int slot) { - this->variable(std::get<0>(mod_and_name), std::get<1>(mod_and_name), slot); - } - - void VM::variable (const Handle& handle, int slot) { + void VM::set_slot_handle (const Handle& handle, int slot) { wrenSetSlotHandle(m_local->wvm, slot, handle); } diff --git a/src/wren/vm.hpp b/src/wren/vm.hpp index 80151d2..63aecde 100644 --- a/src/wren/vm.hpp +++ b/src/wren/vm.hpp @@ -3,15 +3,12 @@ #include "has_method.hpp" #include "error_type.hpp" #include "handle.hpp" -#include #include #include #include #if __cpp_concepts >= 201907 # include #endif -#include -#include namespace wren { class Configuration; @@ -20,7 +17,6 @@ namespace wren { typedef void(*foreign_method_t)(VM*); typedef void(*finalizer_t)(void*); - typedef std::tuple ModuleAndName; struct foreign_class_t { foreign_method_t allocate; @@ -45,14 +41,6 @@ namespace wren { VM* owner {nullptr}; DynafuncMaker* dynafunc {nullptr}; }; - -#if __cpp_concepts >= 201907 - template - concept ConstCharTuple = requires { - std::same_as, Handle> or - std::same_as, ModuleAndName>; - }; -#endif } //namespace detail class VM { @@ -64,27 +52,29 @@ namespace wren { ~VM() noexcept; void interpret (const char* module_name, const char* script); - void interpret (const std::string& module_name, const std::string& script); - void release (Handle& handle) noexcept; - template T slot (int slot_num); - std::string_view slot_string_view (int slot_num); - void set (int slot_num, const std::string& value); - void set (int slot_num, const char* value); - void set (int slot_num, std::string_view value); - void set (int slot_num, const char* beg, const char* end); - void set (int slot_num, double value); - void set (int slot_num, bool value); - void set (int slot_num, const std::vector& value); - void set (int slot_num, std::nullptr_t); + void call (Handle& method); + void release_handle (Handle& handle) noexcept; void ensure_slots(int num_slots); int slot_count(); void variable(const char* module, const char* name, int slot); - void variable(const ModuleAndName& mod_and_name, int slot); - void variable(const Handle& handle, int slot); + void set_slot_handle(const Handle& handle, int slot); SlotType slot_type(int slot_num); Handle slot_handle(int slot_num); Handle make_call_handle(const char* signature); + //slot setters + void set_slot_string (int slot_num, const char* value); + void set_slot_double (int slot_num, double value); + void set_slot_bool (int slot_num, bool value); + void set_slot_null (int slot_num); + void set_slot_bytes (int slot_num, const char* bytes, std::size_t length); + + //slot getters + const char* slot_string (int slot_num); + double slot_double (int slot_num); + bool slot_bool (int slot_num); + std::pair slot_bytes (int slot_num); + private: struct LocalData; @@ -121,29 +111,6 @@ namespace wren { return (*M)(args...); } }; - -#if __cpp_concepts >= 201907 - template -#else - template -#endif - inline std::tuple variables_impl ( - VM& vm, - std::integer_sequence, - Params&&... modules_names - ) { - if constexpr (sizeof...(Outs) == 0) { - return {}; - } - else { - static_assert(sizeof...(Params) == sizeof...(Outs), "Expected a module/name pair per requested output"); - static_assert(sizeof...(Outs) == sizeof...(Indices), "Mismatching index count"); - - vm.ensure_slots(sizeof...(Outs)); - (vm.variable(modules_names, Indices), ...); - return std::tuple(vm.slot(Indices)...); - } - } } //namespace detail template @@ -185,13 +152,4 @@ namespace wren { VM(static_cast(conf), to_callbacks(*conf)) { } - -#if __cpp_concepts >= 201907 - template -#else - template -#endif - std::tuple variables(VM& vm, Params&&... modules_names) { - return detail::variables_impl(vm, std::make_integer_sequence(), std::forward(modules_names)...); - } } //namespace wren diff --git a/src/wren/vm_fun.cpp b/src/wren/vm_fun.cpp new file mode 100644 index 0000000..9ef347e --- /dev/null +++ b/src/wren/vm_fun.cpp @@ -0,0 +1,54 @@ +#include "vm_fun.hpp" +#include +#include +#include + +namespace wren { + void set (VM& vm, int slot_num, const char* beg, const char* end) { + vm.set_slot_bytes(slot_num, beg, std::distance(beg, end)); + } + + std::string_view slot_string_view (VM& vm, int slot_num) { + assert(SlotType::String == vm.slot_type(slot_num)); + auto ptr = vm.slot_bytes(slot_num); + return {ptr.first, static_cast(ptr.second)}; + } + + template<> std::string get (VM& vm, int slot_num) { + return {vm.slot_string(slot_num)}; + } + + template <> double get (VM& vm, int slot_num) { + return vm.slot_double(slot_num); + } + + template <> bool get (VM& vm, int slot_num) { + return vm.slot_bool(slot_num); + } + + template <> std::pair get (VM& vm, int slot_num) { + return vm.slot_bytes(slot_num); + } + + template<> int get (VM& vm, int slot_num) { + return static_cast(vm.slot_double(slot_num)); + } + + template <> std::string_view get (VM& vm, int slot_num) { + auto arr = get>(vm, slot_num); + return std::string_view{arr.first, static_cast(arr.second)}; + } + + template <> std::vector get (VM& vm, int slot_num) { + auto arr = get>(vm, slot_num); + return std::vector{arr.first, arr.first + arr.second}; + } + + void variable(VM& vm, const ModuleAndName& mod_and_name, int slot) { + vm.variable(std::get<0>(mod_and_name), std::get<1>(mod_and_name), slot); + } + + void variable (VM& vm, const Handle& handle, int slot) { + vm.set_slot_handle(handle, slot); + } +} //namespace wren diff --git a/src/wren/vm_fun.hpp b/src/wren/vm_fun.hpp new file mode 100644 index 0000000..5e64cca --- /dev/null +++ b/src/wren/vm_fun.hpp @@ -0,0 +1,86 @@ +#pragma once + +#include "vm.hpp" +#include +#include +#include + +namespace wren { + typedef std::tuple ModuleAndName; + + namespace detail { +#if __cpp_concepts >= 201907 + template + concept ConstCharTuple = requires { + std::same_as, Handle> or + std::same_as, ModuleAndName>; + }; +#endif + } //namespace detail + +#if __cpp_concepts >= 201907 + template +#else + template +#endif + std::tuple variables(VM& vm, Params&&... modules_names); + void interpret (VM& vm, const std::string& module_name, const std::string& script); + void set (VM& vm, int slot_num, const std::string& value); + void set (VM& vm, int slot_num, std::string_view value); + void set (VM& vm, int slot_num, const std::vector& value); + void set (VM& vm, int slot_num, const char* beg, const char* end); + std::string_view slot_string_view (VM& vm, int slot_num); + template T get (VM& vm, int slot_num); + void variable(VM& vm, const ModuleAndName& mod_and_name, int slot); + void variable(VM& vm, const Handle& handle, int slot); + + namespace detail { +#if __cpp_concepts >= 201907 + template +#else + template +#endif + inline std::tuple variables_impl ( + VM& vm, + std::integer_sequence, + Params&&... modules_names + ) { + if constexpr (sizeof...(Outs) == 0) { + return {}; + } + else { + static_assert(sizeof...(Params) == sizeof...(Outs), "Expected a module/name pair per requested output"); + static_assert(sizeof...(Outs) == sizeof...(Indices), "Mismatching index count"); + + vm.ensure_slots(sizeof...(Outs)); + (variable(vm, modules_names, Indices), ...); + return std::tuple(get(vm, Indices)...); + } + } + } //namespace detail + +#if __cpp_concepts >= 201907 + template +#else + template +#endif + inline std::tuple variables(VM& vm, Params&&... modules_names) { + return detail::variables_impl(vm, std::make_integer_sequence(), std::forward(modules_names)...); + } + + inline void interpret (VM& vm, const std::string& module_name, const std::string& script) { + return vm.interpret(module_name.c_str(), script.c_str()); + } + + inline void set (VM& vm, int slot_num, const std::string& value) { + vm.set_slot_string(slot_num, value.c_str()); + } + + inline void set (VM& vm, int slot_num, std::string_view value) { + vm.set_slot_bytes(slot_num, value.data(), value.size()); + } + + inline void set (VM& vm, int slot_num, const std::vector& value) { + vm.set_slot_bytes(slot_num, value.data(), value.size()); + } +} //namespace wren