Refactoring.
VM now aims to only wrap Wren's c functions as closely as possible. All the fun stuff should be put into vm_fun.hpp.
This commit is contained in:
parent
36f2b4393c
commit
2755371792
7 changed files with 173 additions and 108 deletions
|
@ -45,6 +45,7 @@ executable(meson.project_name(),
|
||||||
'src/wren/dynafunc_maker.cpp',
|
'src/wren/dynafunc_maker.cpp',
|
||||||
'src/dynafunc_' + arch + '_' + os + '.S',
|
'src/dynafunc_' + arch + '_' + os + '.S',
|
||||||
'src/wren/handle.cpp',
|
'src/wren/handle.cpp',
|
||||||
|
'src/wren/vm_fun.cpp',
|
||||||
dependencies: [wren_dep],
|
dependencies: [wren_dep],
|
||||||
install: true,
|
install: true,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "wren/vm.hpp"
|
#include "wren/vm_fun.hpp"
|
||||||
#include "wren/def_configuration.hpp"
|
#include "wren/def_configuration.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
|
@ -9,6 +9,6 @@ namespace wren {
|
||||||
|
|
||||||
void Handle::release() noexcept {
|
void Handle::release() noexcept {
|
||||||
assert(m_vm);
|
assert(m_vm);
|
||||||
m_vm->release(*this);
|
m_vm->release_handle(*this);
|
||||||
}
|
}
|
||||||
} //namespace wren
|
} //namespace wren
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <wren.hpp>
|
#include <wren.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
namespace wren {
|
namespace wren {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -150,80 +149,51 @@ namespace wren {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::interpret (const std::string& module_name, const std::string& script) {
|
void VM::release_handle (Handle& handle) noexcept {
|
||||||
return interpret(module_name.c_str(), script.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void VM::release (Handle& handle) noexcept {
|
|
||||||
if (handle)
|
if (handle)
|
||||||
wrenReleaseHandle(m_local->wvm, 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));
|
assert(SlotType::Bool == slot_type(slot_num));
|
||||||
return wrenGetSlotBool(m_local->wvm, 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));
|
assert(SlotType::String == slot_type(slot_num));
|
||||||
return wrenGetSlotString(m_local->wvm, 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));
|
assert(SlotType::Num == slot_type(slot_num));
|
||||||
return wrenGetSlotDouble(m_local->wvm, slot_num);
|
return wrenGetSlotDouble(m_local->wvm, slot_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> std::vector<char> VM::slot (int slot_num) {
|
std::pair<const char*, int> VM::slot_bytes (int slot_num) {
|
||||||
assert(SlotType::String == slot_type(slot_num));
|
assert(SlotType::String == slot_type(slot_num));
|
||||||
int length;
|
int length;
|
||||||
const char* const data = wrenGetSlotBytes(m_local->wvm, slot_num, &length);
|
const char* const data = wrenGetSlotBytes(m_local->wvm, slot_num, &length);
|
||||||
return std::vector<char>{data, data + length};
|
return {data, length};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
void VM::set_slot_string (int slot_num, const char* value) {
|
||||||
int VM::slot (int slot_num) {
|
|
||||||
assert(SlotType::Num == slot_type(slot_num));
|
|
||||||
return static_cast<int>(slot<double>(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<std::size_t>(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) {
|
|
||||||
wrenSetSlotString(m_local->wvm, slot_num, value);
|
wrenSetSlotString(m_local->wvm, slot_num, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::set (int slot_num, std::string_view value) {
|
void VM::set_slot_double (int slot_num, double 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) {
|
|
||||||
wrenSetSlotDouble(m_local->wvm, slot_num, 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);
|
wrenSetSlotBool(m_local->wvm, slot_num, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::set (int slot_num, const std::vector<char>& value) {
|
void VM::set_slot_null (int slot_num) {
|
||||||
wrenSetSlotBytes(m_local->wvm, slot_num, value.data(), value.size());
|
wrenSetSlotNull(m_local->wvm, slot_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::set (int slot_num, std::nullptr_t) {
|
void VM::set_slot_bytes (int slot_num, const char* bytes, std::size_t length) {
|
||||||
wrenSetSlotNull(m_local->wvm, slot_num);
|
wrenSetSlotBytes(m_local->wvm, slot_num, bytes, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::ensure_slots (int num_slots) {
|
void VM::ensure_slots (int num_slots) {
|
||||||
|
@ -238,11 +208,7 @@ namespace wren {
|
||||||
wrenGetVariable(m_local->wvm, module, name, slot);
|
wrenGetVariable(m_local->wvm, module, name, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::variable(const ModuleAndName& mod_and_name, int slot) {
|
void VM::set_slot_handle (const Handle& handle, 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) {
|
|
||||||
wrenSetSlotHandle(m_local->wvm, slot, handle);
|
wrenSetSlotHandle(m_local->wvm, slot, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,12 @@
|
||||||
#include "has_method.hpp"
|
#include "has_method.hpp"
|
||||||
#include "error_type.hpp"
|
#include "error_type.hpp"
|
||||||
#include "handle.hpp"
|
#include "handle.hpp"
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#if __cpp_concepts >= 201907
|
#if __cpp_concepts >= 201907
|
||||||
# include <concepts>
|
# include <concepts>
|
||||||
#endif
|
#endif
|
||||||
#include <vector>
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
namespace wren {
|
namespace wren {
|
||||||
class Configuration;
|
class Configuration;
|
||||||
|
@ -20,7 +17,6 @@ namespace wren {
|
||||||
|
|
||||||
typedef void(*foreign_method_t)(VM*);
|
typedef void(*foreign_method_t)(VM*);
|
||||||
typedef void(*finalizer_t)(void*);
|
typedef void(*finalizer_t)(void*);
|
||||||
typedef std::tuple<const char*, const char*> ModuleAndName;
|
|
||||||
|
|
||||||
struct foreign_class_t {
|
struct foreign_class_t {
|
||||||
foreign_method_t allocate;
|
foreign_method_t allocate;
|
||||||
|
@ -45,14 +41,6 @@ namespace wren {
|
||||||
VM* owner {nullptr};
|
VM* owner {nullptr};
|
||||||
DynafuncMaker* dynafunc {nullptr};
|
DynafuncMaker* dynafunc {nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
|
||||||
template <typename T>
|
|
||||||
concept ConstCharTuple = requires {
|
|
||||||
std::same_as<std::remove_cv_t<T>, Handle> or
|
|
||||||
std::same_as<std::remove_cv_t<T>, ModuleAndName>;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
} //namespace detail
|
} //namespace detail
|
||||||
|
|
||||||
class VM {
|
class VM {
|
||||||
|
@ -64,27 +52,29 @@ namespace wren {
|
||||||
~VM() noexcept;
|
~VM() noexcept;
|
||||||
|
|
||||||
void interpret (const char* module_name, const char* script);
|
void interpret (const char* module_name, const char* script);
|
||||||
void interpret (const std::string& module_name, const std::string& script);
|
void call (Handle& method);
|
||||||
void release (Handle& handle) noexcept;
|
void release_handle (Handle& handle) noexcept;
|
||||||
template <typename T> 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<char>& value);
|
|
||||||
void set (int slot_num, std::nullptr_t);
|
|
||||||
void ensure_slots(int num_slots);
|
void ensure_slots(int num_slots);
|
||||||
int slot_count();
|
int slot_count();
|
||||||
void variable(const char* module, const char* name, int slot);
|
void variable(const char* module, const char* name, int slot);
|
||||||
void variable(const ModuleAndName& mod_and_name, int slot);
|
void set_slot_handle(const Handle& handle, int slot);
|
||||||
void variable(const Handle& handle, int slot);
|
|
||||||
SlotType slot_type(int slot_num);
|
SlotType slot_type(int slot_num);
|
||||||
Handle slot_handle(int slot_num);
|
Handle slot_handle(int slot_num);
|
||||||
Handle make_call_handle(const char* signature);
|
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<const char*, int> slot_bytes (int slot_num);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct LocalData;
|
struct LocalData;
|
||||||
|
|
||||||
|
@ -121,29 +111,6 @@ namespace wren {
|
||||||
return (*M)(args...);
|
return (*M)(args...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
|
||||||
template <typename... Outs, int... Indices, ConstCharTuple... Params>
|
|
||||||
#else
|
|
||||||
template <typename... Outs, int... Indices, typename... Params>
|
|
||||||
#endif
|
|
||||||
inline std::tuple<Outs...> variables_impl (
|
|
||||||
VM& vm,
|
|
||||||
std::integer_sequence<int, Indices...>,
|
|
||||||
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<Outs...>(vm.slot<Outs>(Indices)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} //namespace detail
|
} //namespace detail
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -185,13 +152,4 @@ namespace wren {
|
||||||
VM(static_cast<Configuration*>(conf), to_callbacks(*conf))
|
VM(static_cast<Configuration*>(conf), to_callbacks(*conf))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
|
||||||
template <typename... Outs, detail::ConstCharTuple... Params>
|
|
||||||
#else
|
|
||||||
template <typename... Outs, typename... Params>
|
|
||||||
#endif
|
|
||||||
std::tuple<Outs...> variables(VM& vm, Params&&... modules_names) {
|
|
||||||
return detail::variables_impl<Outs...>(vm, std::make_integer_sequence<int, sizeof...(Outs)>(), std::forward<Params>(modules_names)...);
|
|
||||||
}
|
|
||||||
} //namespace wren
|
} //namespace wren
|
||||||
|
|
54
src/wren/vm_fun.cpp
Normal file
54
src/wren/vm_fun.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "vm_fun.hpp"
|
||||||
|
#include <cassert>
|
||||||
|
#include <iterator>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
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<std::size_t>(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<const char*, int> get (VM& vm, int slot_num) {
|
||||||
|
return vm.slot_bytes(slot_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> int get (VM& vm, int slot_num) {
|
||||||
|
return static_cast<int>(vm.slot_double(slot_num));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> std::string_view get (VM& vm, int slot_num) {
|
||||||
|
auto arr = get<std::pair<const char*, int>>(vm, slot_num);
|
||||||
|
return std::string_view{arr.first, static_cast<std::size_t>(arr.second)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> std::vector<char> get (VM& vm, int slot_num) {
|
||||||
|
auto arr = get<std::pair<const char*, int>>(vm, slot_num);
|
||||||
|
return std::vector<char>{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
|
86
src/wren/vm_fun.hpp
Normal file
86
src/wren/vm_fun.hpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "vm.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace wren {
|
||||||
|
typedef std::tuple<const char*, const char*> ModuleAndName;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
#if __cpp_concepts >= 201907
|
||||||
|
template <typename T>
|
||||||
|
concept ConstCharTuple = requires {
|
||||||
|
std::same_as<std::remove_cv_t<T>, Handle> or
|
||||||
|
std::same_as<std::remove_cv_t<T>, ModuleAndName>;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
|
#if __cpp_concepts >= 201907
|
||||||
|
template <typename... Outs, detail::ConstCharTuple... Params>
|
||||||
|
#else
|
||||||
|
template <typename... Outs, typename... Params>
|
||||||
|
#endif
|
||||||
|
std::tuple<Outs...> 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<char>& 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 <typename T> 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 <typename... Outs, int... Indices, ConstCharTuple... Params>
|
||||||
|
#else
|
||||||
|
template <typename... Outs, int... Indices, typename... Params>
|
||||||
|
#endif
|
||||||
|
inline std::tuple<Outs...> variables_impl (
|
||||||
|
VM& vm,
|
||||||
|
std::integer_sequence<int, Indices...>,
|
||||||
|
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<Outs...>(get<Outs>(vm, Indices)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
|
#if __cpp_concepts >= 201907
|
||||||
|
template <typename... Outs, detail::ConstCharTuple... Params>
|
||||||
|
#else
|
||||||
|
template <typename... Outs, typename... Params>
|
||||||
|
#endif
|
||||||
|
inline std::tuple<Outs...> variables(VM& vm, Params&&... modules_names) {
|
||||||
|
return detail::variables_impl<Outs...>(vm, std::make_integer_sequence<int, sizeof...(Outs)>(), std::forward<Params>(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<char>& value) {
|
||||||
|
vm.set_slot_bytes(slot_num, value.data(), value.size());
|
||||||
|
}
|
||||||
|
} //namespace wren
|
Loading…
Reference in a new issue