Make VM easily movable
This commit is contained in:
parent
ebd455c536
commit
d0be115181
2 changed files with 38 additions and 37 deletions
|
@ -19,39 +19,55 @@ namespace wren {
|
|||
void write_fn (WrenVM* wvm, const char* text) {
|
||||
auto cb = static_cast<detail::Callbacks*>(wrenGetUserData(wvm));
|
||||
assert(cb);
|
||||
assert(cb->write_fn and cb->config_obj and cb->vm);
|
||||
cb->write_fn(*cb->config_obj, cb->vm, text);
|
||||
assert(cb->write_fn and cb->config_obj and cb->owner);
|
||||
cb->write_fn(*cb->config_obj, cb->owner, text);
|
||||
}
|
||||
|
||||
void error_fn (WrenVM* wvm, WrenErrorType type, const char* module, int line, const char* message) {
|
||||
auto cb = static_cast<detail::Callbacks*>(wrenGetUserData(wvm));
|
||||
assert(cb);
|
||||
assert(cb->error_fn and cb->config_obj and cb->vm);
|
||||
cb->error_fn(*cb->config_obj, cb->vm, to_error_type(type), module, line, message);
|
||||
assert(cb->error_fn and cb->config_obj and cb->owner);
|
||||
cb->error_fn(*cb->config_obj, cb->owner, to_error_type(type), module, line, message);
|
||||
}
|
||||
|
||||
const char* resolve_module_fn (WrenVM* wvm, const char* importer, const char* name) {
|
||||
auto cb = static_cast<detail::Callbacks*>(wrenGetUserData(wvm));
|
||||
assert(cb);
|
||||
assert(cb->resolve_module_fn and cb->config_obj and cb->vm);
|
||||
return cb->resolve_module_fn(*cb->config_obj, cb->vm, importer, name);
|
||||
assert(cb->resolve_module_fn and cb->config_obj and cb->owner);
|
||||
return cb->resolve_module_fn(*cb->config_obj, cb->owner, importer, name);
|
||||
}
|
||||
|
||||
char* load_module_fn (WrenVM* wvm, const char* name) {
|
||||
auto cb = static_cast<detail::Callbacks*>(wrenGetUserData(wvm));
|
||||
assert(cb);
|
||||
assert(cb->load_module_fn and cb->config_obj and cb->vm);
|
||||
return cb->load_module_fn(*cb->config_obj, cb->vm, name);
|
||||
assert(cb->load_module_fn and cb->config_obj and cb->owner);
|
||||
return cb->load_module_fn(*cb->config_obj, cb->owner, name);
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
struct VM::LocalData {
|
||||
explicit LocalData (const detail::Callbacks& cb) :
|
||||
callbacks(cb),
|
||||
wvm(nullptr)
|
||||
{}
|
||||
~LocalData() noexcept {
|
||||
if (wvm)
|
||||
wrenFreeVM(wvm);
|
||||
#if !defined(NDEBUG)
|
||||
wvm = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
detail::Callbacks callbacks;
|
||||
WrenVM* wvm;
|
||||
};
|
||||
|
||||
VM::VM (Configuration* conf, const detail::Callbacks& cb) :
|
||||
m_callbacks(cb),
|
||||
m_vm(nullptr)
|
||||
m_local(std::make_unique<LocalData>(cb))
|
||||
{
|
||||
WrenConfiguration wconf;
|
||||
wrenInitConfiguration(&wconf);
|
||||
wconf.userData = static_cast<void*>(&m_callbacks);
|
||||
wconf.userData = static_cast<void*>(&m_local->callbacks);
|
||||
|
||||
wconf.initialHeapSize = conf->initial_heap_size();
|
||||
wconf.minHeapSize = conf->min_heap_size();
|
||||
|
@ -72,33 +88,20 @@ namespace wren {
|
|||
if (cb.load_module_fn)
|
||||
wconf.loadModuleFn = &load_module_fn;
|
||||
|
||||
m_vm = wrenNewVM(&wconf);
|
||||
|
||||
if (not m_vm)
|
||||
m_local->wvm = wrenNewVM(&wconf);
|
||||
if (not m_local->wvm)
|
||||
throw std::runtime_error("Failed to initialize Wren VM");
|
||||
}
|
||||
|
||||
VM::VM (VM&& other) :
|
||||
m_vm(nullptr)
|
||||
{
|
||||
std::swap(m_vm, other.m_vm);
|
||||
m_callbacks = other.m_callbacks;
|
||||
wrenSetUserData(m_vm, &m_callbacks);
|
||||
}
|
||||
|
||||
VM::~VM() noexcept {
|
||||
if (m_vm)
|
||||
wrenFreeVM(m_vm);
|
||||
#if !defined(NDEBUG)
|
||||
m_vm = nullptr;
|
||||
#endif
|
||||
}
|
||||
VM::VM (VM&& other) = default;
|
||||
VM::~VM() noexcept = default;
|
||||
|
||||
void VM::interpret (const char* module_name, const char* script) {
|
||||
using std::string;
|
||||
using std::runtime_error;
|
||||
|
||||
const WrenInterpretResult res = wrenInterpret(m_vm, module_name, script);
|
||||
const WrenInterpretResult res = wrenInterpret(m_local->wvm, module_name, script);
|
||||
switch (res) {
|
||||
case WREN_RESULT_COMPILE_ERROR:
|
||||
throw runtime_error(string("Compilation of ") + module_name + " has failed");
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
#include "has_method.hpp"
|
||||
#include "error_type.hpp"
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
typedef struct WrenVM WrenVM;
|
||||
} //extern C
|
||||
#include <memory>
|
||||
|
||||
namespace wren {
|
||||
class Configuration;
|
||||
|
@ -21,7 +18,7 @@ namespace wren {
|
|||
char* (*load_module_fn)(Configuration&, VM*, const char*) {nullptr};
|
||||
|
||||
Configuration* config_obj {nullptr};
|
||||
VM* vm {nullptr};
|
||||
VM* owner {nullptr};
|
||||
};
|
||||
} //namespace detail
|
||||
|
||||
|
@ -37,13 +34,14 @@ namespace wren {
|
|||
void interpret (const std::string& module_name, const std::string& script);
|
||||
|
||||
private:
|
||||
struct LocalData;
|
||||
|
||||
VM (Configuration* conf, const detail::Callbacks&);
|
||||
|
||||
template <typename T>
|
||||
detail::Callbacks to_callbacks (T& conf);
|
||||
|
||||
detail::Callbacks m_callbacks;
|
||||
WrenVM* m_vm;
|
||||
std::unique_ptr<LocalData> m_local;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
@ -76,7 +74,7 @@ namespace wren {
|
|||
|
||||
detail::Callbacks ret;
|
||||
ret.config_obj = &conf;
|
||||
ret.vm = this;
|
||||
ret.owner = this;
|
||||
|
||||
if constexpr (detail::method_write::exists<T>::value)
|
||||
ret.write_fn = &detail::AnyFunctionWrap<T, decltype(&T::write_fn)>::template call<&T::write_fn>;
|
||||
|
|
Loading…
Reference in a new issue