Move public headers to a separate directory, make a library

This commit is contained in:
King_DuckZ 2020-04-30 22:50:46 +02:00
commit 0f0d149ad2
15 changed files with 22 additions and 11 deletions

View file

@ -1,5 +1,5 @@
#include "wren/vm_fun.hpp"
#include "wren/def_configuration.hpp"
#include "wrenpp/vm_fun.hpp"
#include "wrenpp/def_configuration.hpp"
#include <iostream>
#include <chrono>
#include <thread>

View file

@ -1,4 +1,4 @@
#include "configuration.hpp"
#include "wrenpp/configuration.hpp"
#include <wren.hpp>
namespace wren {

View file

@ -1,25 +0,0 @@
#pragma once
#include <cstddef>
namespace wren {
class Configuration {
public:
Configuration();
~Configuration() noexcept = default;
std::size_t initial_heap_size() const { return m_initial_heap_size; }
void set_initial_heap_size(std::size_t v) { m_initial_heap_size = v; }
std::size_t min_heap_size() const { return m_min_heap_size; }
void set_min_heap_size(std::size_t v) { m_min_heap_size = v; }
std::size_t heap_growth_percent() const { return m_heap_growth_percent; }
void set_heap_growth_percent(std::size_t v) { m_heap_growth_percent = v; }
private:
std::size_t m_initial_heap_size;
std::size_t m_min_heap_size;
std::size_t m_heap_growth_percent;
};
} //namespace wren

View file

@ -1,4 +1,4 @@
#include "def_configuration.hpp"
#include "wrenpp/def_configuration.hpp"
#include <iostream>
namespace wren {

View file

@ -1,17 +0,0 @@
#pragma once
#include "configuration.hpp"
#include "error_type.hpp"
namespace wren {
class VM;
typedef void(*foreign_method_t)(VM*);
class DefConfiguration : public Configuration {
public:
static void write_fn (VM*, const char* text);
static void error_fn (VM*, ErrorType, const char* module, int line, const char* msg);
foreign_method_t foreign_method_fn (VM* vm, const char* module, const char* class_name, bool is_static, const char* signature);
};
} //namespace wren

View file

@ -1,14 +0,0 @@
#pragma once
namespace wren {
enum class ErrorType {
// A syntax or resolution error detected at compile time.
Compile,
// The error message for a runtime error.
Runtime,
// One entry of a runtime error's stack trace.
StackTrace
};
} //namespace wren

View file

@ -1,5 +1,5 @@
#include "handle.hpp"
#include "vm.hpp"
#include "wrenpp/handle.hpp"
#include "wrenpp/vm.hpp"
#include <cassert>
namespace wren {

View file

@ -1,60 +0,0 @@
#pragma once
typedef struct WrenHandle WrenHandle;
namespace wren {
class VM;
class Handle {
public:
Handle() noexcept;
Handle (const Handle&) = delete;
Handle (Handle&& other) noexcept;
Handle (VM* vm, WrenHandle* handle) noexcept :
m_handle(handle),
m_vm(vm)
{
}
Handle& operator= (const Handle&) = delete;
Handle& operator= (Handle&& other) noexcept;
~Handle() noexcept;
void release() noexcept;
operator WrenHandle*() const { return m_handle; }
operator bool() const { return nullptr != m_handle; }
private:
WrenHandle* m_handle;
VM* m_vm;
};
inline Handle::Handle() noexcept :
m_handle(nullptr),
m_vm(nullptr)
{
}
inline Handle::Handle (Handle&& other) noexcept :
m_handle(other.m_handle),
m_vm(other.m_vm)
{
other.m_handle = nullptr;
other.m_vm = nullptr;
}
inline Handle& Handle::operator= (Handle&& other) noexcept {
{
auto tmp = other.m_handle;
other.m_handle = m_handle;
m_handle = tmp;
}
{
auto tmp = other.m_vm;
other.m_vm = m_vm;
m_vm = tmp;
}
return *this;
}
} //namespace wren

View file

@ -1,53 +0,0 @@
#pragma once
#include <type_traits>
//see https://stackoverflow.com/a/10707822
#define define_method_info(method_name, pretty_name, ret_type, ...) \
class method_ ## pretty_name { \
typedef std::integral_constant<int, 0> no_method_t; \
typedef std::integral_constant<int, 1> has_method_t; \
typedef std::integral_constant<int, 2> has_static_method_t; \
template<typename A, typename... Args> \
static has_method_t test(ret_type (A::*)(Args...)) { \
return {}; \
} \
template <typename A, typename... Args> \
static has_static_method_t test(ret_type (*)(Args...)) { \
return {}; \
} \
template <typename A, typename... Args> \
static auto test(decltype(std::declval<A>().method_name(std::declval<Args>()...))*,void *) { \
typedef decltype(test<A, Args...>(&A::method_name)) return_type; \
return return_type{}; \
} \
template<typename A, typename... Args> \
static no_method_t test(...) { \
return {}; \
} \
public: \
template< typename T> \
class exists { \
typedef decltype(test<T, __VA_ARGS__>(0,0)) found_t; \
public: \
static const constexpr bool value = (found_t::value != no_method_t::value); \
}; \
template <typename T> \
class is_static { \
typedef decltype(test<T, __VA_ARGS__>(0,0)) found_t; \
public: \
static const constexpr bool value = (found_t::value == has_static_method_t::value); \
}; \
template <typename T> struct static_ptr { \
typedef ret_type (*type)(__VA_ARGS__); \
}; \
template <typename T> struct nonstatic_ptr { \
typedef ret_type (T::*type)(__VA_ARGS__); \
}; \
template <typename T> struct ptr { \
typedef typename std::conditional<is_static<T>::value, typename static_ptr<T>::type, typename std::conditional<exists<T>::value, typename nonstatic_ptr<T>::type, void>::type>::type type; \
}; \
}
namespace wren {
} //namespace wren

View file

@ -1,135 +0,0 @@
/* Copyright 2016-2018 Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id170B0E6C34D14EBA9B92A35977BDBFB3
#define id170B0E6C34D14EBA9B92A35977BDBFB3
#include <utility>
#include <cstddef>
#include <iostream>
#include <stdexcept>
namespace dhandy {
namespace bt {
template <std::size_t S, typename Ch=char>
class string;
template <std::size_t S, typename Ch>
std::basic_ostream<Ch>& operator<< ( std::basic_ostream<Ch>& parStream, const string<S, Ch>& parString );
namespace implem {
template <std::size_t S, typename Ch> constexpr bool eq (const string<S, Ch>& l, const string<S, Ch>& r);
} //namespace implem
template <std::size_t S, typename Ch>
class string {
friend std::ostream& operator<< <>( std::ostream& parStream, const string<S>& parString );
friend constexpr bool implem::eq<S, Ch> (const string<S, Ch>&, const string<S, Ch>&);
public:
using value_type = Ch;
constexpr string ( const value_type* parString );
constexpr std::size_t size ( void ) const { return S - 1; }
template <std::size_t S2>
constexpr string<S + S2 - 1, Ch> operator+ ( const string<S2, Ch>& parOther ) const;
constexpr value_type operator[] ( std::size_t parIndex ) const;
constexpr bool operator== (const string<S, Ch>& other) const;
template <std::size_t Start, std::size_t Len=S-1> constexpr auto substr() const;
template <std::size_t S2> constexpr bool operator== (const string<S2, Ch>&) const { return false; }
template <typename... Args>
constexpr string ( Args... );
constexpr const value_type (&data_arr() const)[S] { return m_data; }
constexpr const value_type* data() const { return m_data; }
private:
template <std::size_t... I>
constexpr string ( std::index_sequence<I...>, const value_type* parString );
const value_type m_data[S];
};
namespace implem {
template <std::size_t S, std::size_t S2, std::size_t... I>
constexpr string<S + S2 - 1> concat ( std::index_sequence<I...>, const string<S>& parLeft, const string<S2>& parRight ) {
return string<S + S2 - 1>(
(I < S - 1 ? parLeft[I] : (I < S + S2 - 2 ? parRight[I - (S - 1)] : '\0'))...
);
}
template <> constexpr inline bool eq (const string<1>& l, const string<1>& r) { return l[0] == r[0]; }
template <std::size_t S, typename Ch>
constexpr inline bool eq (const string<S, Ch>& l, const string<S, Ch>& r) { return l[0] == r[0] and eq(string<S-1>(l.m_data+1), string<S-1>(r.m_data+1)); }
} //namespace implem
template <std::size_t S, typename Ch>
template <std::size_t... I>
constexpr string<S, Ch>::string (std::index_sequence<I...>, const value_type* parString) :
m_data{parString[I]...}
{
}
template <std::size_t S, typename Ch>
inline constexpr string<S, Ch>::string (const value_type* parString) :
string(std::make_index_sequence<S>(), parString)
{
}
template <std::size_t S, typename Ch>
template <typename... Args>
inline constexpr string<S, Ch>::string (Args... parArgs) :
m_data{parArgs...}
{
}
template <std::size_t S, typename Ch>
template <std::size_t S2>
constexpr inline string<S + S2 - 1, Ch> string<S, Ch>::operator+ (const string<S2, Ch>& parOther) const {
return implem::concat(std::make_index_sequence<S + S2 - 1>(), string<S>(m_data), parOther);
}
template <std::size_t S, typename Ch>
inline std::ostream& operator<< (std::ostream& parStream, const string<S, Ch>& parString) {
parStream << parString.m_data;
return parStream;
}
template <std::size_t S, typename Ch>
constexpr auto string<S, Ch>::operator[] (std::size_t parIndex) const -> value_type {
return (parIndex < S ? m_data[parIndex] : throw std::out_of_range(""));
}
template <std::size_t S, typename Ch>
constexpr string<S, Ch> make_string (const Ch (&parData)[S]) {
return string<S>(parData);
}
template <std::size_t S, typename Ch>
constexpr bool string<S, Ch>::operator== (const string<S, Ch>& other) const {
return implem::eq(*this, other);
}
template <std::size_t S, typename Ch>
template <std::size_t Start, std::size_t Len>
constexpr auto string<S, Ch>::substr() const {
return string<std::min(S - 1 - std::min(Start, S - 1), Len) + 1, Ch>(m_data + std::min(Start, S - 1)) + make_string("");
}
} //namespace bt
} //namespace dhandy
#endif

View file

@ -1,5 +1,5 @@
#include "vm.hpp"
#include "configuration.hpp"
#include "wrenpp/vm.hpp"
#include "wrenpp/configuration.hpp"
#include "dynafunc_maker.hpp"
#include <wren.hpp>
#include <cassert>

View file

@ -1,157 +0,0 @@
#pragma once
#include "has_method.hpp"
#include "error_type.hpp"
#include "handle.hpp"
#include <memory>
#include <tuple>
#include <utility>
#if __cpp_concepts >= 201907
# include <concepts>
#endif
namespace wren {
class Configuration;
class VM;
class DynafuncMaker;
typedef void(*foreign_method_t)(VM*);
typedef void(*finalizer_t)(void*);
struct foreign_class_t {
foreign_method_t allocate;
finalizer_t finalize;
};
enum class SlotType {
Bool, Num, Foreign, List, Null, String, Unknown
};
namespace detail {
struct Callbacks {
void (*write_fn)(Configuration&, VM*, const char*) {nullptr};
void (*error_fn)(Configuration&, VM*, ErrorType, const char*, int, const char*) {nullptr};
void* (*reallocate_fn)(void*, std::size_t) {nullptr};
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};
DynafuncMaker* dynafunc {nullptr};
};
} //namespace detail
class VM {
public:
template <typename T>
VM (T* conf);
VM (const VM&) = delete;
VM (VM&& other) = default;
~VM() noexcept;
void interpret (const char* module_name, const char* script);
void call (const 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 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);
void* set_slot_new_foreign (int slot_num, int class_slot, std::size_t size);
//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);
void* slot_foreign (int slot_num);
private:
struct LocalData;
VM (Configuration* conf, const detail::Callbacks&);
DynafuncMaker* dynafunc_maker();
template <typename T>
detail::Callbacks to_callbacks (T& conf);
std::unique_ptr<LocalData> m_local;
};
namespace detail {
define_method_info(write_fn, write, void, VM*, const char*);
define_method_info(error_fn, error, void, VM*, ErrorType, const char*, int, const char*);
define_method_info(reallocate_fn, reallocate, void*, void*, std::size_t);
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 <typename T, typename F> struct AnyFunctionWrap;
template <typename T, typename R, typename... Args>
struct AnyFunctionWrap<T, R(T::*)(Args...)> {
template <R(T::*M)(Args...)>
inline static R call(Configuration& obj, Args... args) {
return (reinterpret_cast<T&>(obj).*M)(args...);
}
};
template <typename T, typename R, typename... Args>
struct AnyFunctionWrap<T, R(*)(Args...)> {
template <R(*M)(Args...)>
inline static R call(Configuration&, Args... args) {
return (*M)(args...);
}
};
} //namespace detail
template <typename T>
inline detail::Callbacks VM::to_callbacks (T& conf) {
using detail::method_reallocate;
detail::Callbacks ret;
ret.config_obj = &conf;
ret.owner = this;
ret.dynafunc = nullptr;
if constexpr (detail::method_write::exists<T>::value)
ret.write_fn = &detail::AnyFunctionWrap<T, decltype(&T::write_fn)>::template call<&T::write_fn>;
if constexpr (detail::method_error::exists<T>::value)
ret.error_fn = &detail::AnyFunctionWrap<T, decltype(&T::error_fn)>::template call<&T::error_fn>;
if constexpr (method_reallocate::exists<T>::value and method_reallocate::is_static<T>::value)
ret.reallocate_fn = &T::reallocate_fn;
static_assert(not method_reallocate::exists<T>::value or method_reallocate::is_static<T>::value, "Realloc function must be a static function");
if constexpr (detail::method_resolve_module::exists<T>::value)
ret.resolve_module_fn = &detail::AnyFunctionWrap<T, decltype(&T::resolve_module_fn)>::template call<&T::resolve_module_fn>;
if constexpr (detail::method_load_module::exists<T>::value)
ret.load_module_fn = &detail::AnyFunctionWrap<T, decltype(&T::load_module_fn)>::template call<&T::load_module_fn>;
if constexpr (detail::method_foreign_method::exists<T>::value)
ret.foreign_method_fn = &detail::AnyFunctionWrap<T, decltype(&T::foreign_method_fn)>::template call<&T::foreign_method_fn>;
if constexpr (detail::method_foreign_class::exists<T>::value)
ret.foreign_class_fn = &detail::AnyFunctionWrap<T, decltype(&T::foreign_class_fn)>::template call<&T::foreign_class_fn>;
return ret;
}
template <typename T>
inline VM::VM (T* conf) :
VM(static_cast<Configuration*>(conf), to_callbacks(*conf))
{
}
} //namespace wren

View file

@ -1,4 +1,4 @@
#include "vm_fun.hpp"
#include "wrenpp/vm_fun.hpp"
#include <cassert>
#include <iterator>
#include <utility>

View file

@ -1,180 +0,0 @@
#pragma once
#include "vm.hpp"
#include "string_bt.hpp"
#include <string>
#include <string_view>
#include <vector>
#include <type_traits>
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);
template <typename R, typename... Args>
R call (VM& vm, const Handle& object, const Handle& method, const Args&... args);
template <typename R, typename... Args>
R call (VM& vm, const ModuleAndName& object, const Handle& method, const Args&... args);
template <typename R, std::size_t N, typename... Args>
R call (VM& vm, const ModuleAndName& object, const char (&method)[N], const Args&... args);
void interpret (VM& vm, const std::string& module_name, const std::string& script);
void set (VM& vm, int slot_num, const char* value);
void set (VM& vm, int slot_num, double value);
void set (VM& vm, int slot_num, bool value);
void set (VM& vm, int slot_num, std::nullptr_t);
void set (VM& vm, int slot_num, const char* bytes, std::size_t length);
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);
void set (VM& vm, int slot_num, int value);
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...(Params));
(variable(vm, modules_names, Indices), ...);
return std::tuple<Outs...>(get<Outs>(vm, Indices)...);
}
}
template <typename T>
inline void set_single_for_call (VM& vm, int slot, const T& value) {
set(vm, slot, value);
}
template <>
inline void set_single_for_call (VM& vm, int slot_num, const Handle& handle) {
vm.set_slot_handle(handle, slot_num);
}
template <>
inline void set_single_for_call (VM& vm, int slot_num, const ModuleAndName& name) {
variable(vm, name, slot_num);
}
template <typename... Args, int... Indices>
inline void set_for_call (std::integer_sequence<int, Indices...>, VM& vm, const Args&... args) {
vm.ensure_slots(sizeof...(Args));
(set_single_for_call(vm, Indices + 1, args), ...);
}
} //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 char* value) {
vm.set_slot_string(slot_num, value);
}
inline void set (VM& vm, int slot_num, double value) {
vm.set_slot_double(slot_num, value);
}
inline void set (VM& vm, int slot_num, bool value) {
vm.set_slot_bool(slot_num, value);
}
inline void set (VM& vm, int slot_num, std::nullptr_t) {
vm.set_slot_null(slot_num);
}
inline void set (VM& vm, int slot_num, const char* bytes, std::size_t length) {
vm.set_slot_bytes(slot_num, bytes, length);
}
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());
}
inline void set (VM& vm, int slot_num, int value) {
vm.set_slot_double(slot_num, static_cast<double>(value));
}
template <typename R, typename... Args>
inline R call (VM& vm, const Handle& object, const Handle& method, const Args&... args) {
detail::set_for_call<Args...>(std::make_integer_sequence<int, sizeof...(Args)>(), vm, args...);
vm.call(method);
if constexpr (not std::is_same<void, R>::value) {
return get<R>(vm, 0);
}
}
template <typename R, typename... Args>
inline R call (VM& vm, const ModuleAndName& object, const Handle& method, const Args&... args) {
vm.ensure_slots(sizeof...(args) + 1);
variable(vm, object, 0);
Handle obj_handle = vm.slot_handle(0);
return call<R, Args...>(vm, obj_handle, method, args...);
}
template <typename R, std::size_t N, typename... Args>
inline R call (VM& vm, const ModuleAndName& object, const char (&method)[N], const Args&... args) {
const constexpr char dummy_name_buff[N] = {0};
const constexpr auto params = dhandy::bt::string<N, char>(dummy_name_buff) +
dhandy::bt::make_string("(") +
((static_cast<void>(args), dhandy::bt::make_string(",_")) + ...).template substr<1>() +
dhandy::bt::make_string(")");
;
char cat_buff[params.size() + 1];
std::copy(method, method + N - 1, cat_buff);
std::copy(params.data() + N - 1, params.data() + params.size() + 1, cat_buff + N - 1);
return call<R, Args...>(vm, object, vm.make_call_handle(cat_buff), args...);
}
} //namespace wren