Improve error reporting
This commit is contained in:
parent
0e3e0ed506
commit
ce7be396d2
3 changed files with 38 additions and 27 deletions
|
@ -19,9 +19,13 @@
|
||||||
|
|
||||||
#include "wrenpp/vm.hpp"
|
#include "wrenpp/vm.hpp"
|
||||||
#include "seters_getters.hpp"
|
#include "seters_getters.hpp"
|
||||||
|
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||||
|
# include "guess_class_name.hpp"
|
||||||
|
#endif
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace wren {
|
namespace wren {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -34,12 +38,17 @@ namespace wren {
|
||||||
new(memory) T{get<Args>(vm, Indices + 1)...};
|
new(memory) T{get<Args>(vm, Indices + 1)...};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ConstructResult {
|
||||||
|
std::uint16_t parameter_count;
|
||||||
|
bool success;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
struct ForeignClassHelper;
|
struct ForeignClassHelper;
|
||||||
|
|
||||||
template <typename T, template <typename...> class Pack, typename... PackArgs, typename... Args>
|
template <typename T, template <typename...> class Pack, typename... PackArgs, typename... Args>
|
||||||
struct ForeignClassHelper<T, Pack<PackArgs...>, Args...> {
|
struct ForeignClassHelper<T, Pack<PackArgs...>, Args...> {
|
||||||
static bool construct (VM& vm, int cardinality, void* memory) {
|
static ConstructResult construct (VM& vm, int cardinality, void* memory) {
|
||||||
using std::make_integer_sequence;
|
using std::make_integer_sequence;
|
||||||
|
|
||||||
//search by number of parameters.
|
//search by number of parameters.
|
||||||
|
@ -48,7 +57,7 @@ namespace wren {
|
||||||
constexpr int pack_size = static_cast<int>(sizeof...(PackArgs));
|
constexpr int pack_size = static_cast<int>(sizeof...(PackArgs));
|
||||||
if (pack_size == cardinality) {
|
if (pack_size == cardinality) {
|
||||||
construct_single<T, PackArgs...>(make_integer_sequence<int, pack_size>{}, vm, memory);
|
construct_single<T, PackArgs...>(make_integer_sequence<int, pack_size>{}, vm, memory);
|
||||||
return true;
|
return ConstructResult{pack_size, true};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return ForeignClassHelper<T, Args...>::construct(vm, cardinality, memory);
|
return ForeignClassHelper<T, Args...>::construct(vm, cardinality, memory);
|
||||||
|
@ -58,12 +67,12 @@ namespace wren {
|
||||||
|
|
||||||
template <typename T, typename LoneArg, typename... Args>
|
template <typename T, typename LoneArg, typename... Args>
|
||||||
struct ForeignClassHelper<T, LoneArg, Args...> {
|
struct ForeignClassHelper<T, LoneArg, Args...> {
|
||||||
static bool construct (VM& vm, int cardinality, void* memory) {
|
static ConstructResult construct (VM& vm, int cardinality, void* memory) {
|
||||||
using std::make_integer_sequence;
|
using std::make_integer_sequence;
|
||||||
|
|
||||||
if (1 == cardinality) {
|
if (1 == cardinality) {
|
||||||
construct_single<T, LoneArg>(make_integer_sequence<int, 1>{}, vm, memory);
|
construct_single<T, LoneArg>(make_integer_sequence<int, 1>{}, vm, memory);
|
||||||
return true;
|
return ConstructResult{1, true};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return ForeignClassHelper<T, Args...>::construct(vm, cardinality, memory);
|
return ForeignClassHelper<T, Args...>::construct(vm, cardinality, memory);
|
||||||
|
@ -83,29 +92,19 @@ namespace wren {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ForeignClassHelper<T> {
|
struct ForeignClassHelper<T> {
|
||||||
static bool construct (VM& vm, int cardinality, void* memory) {
|
static ConstructResult construct (VM& vm, int cardinality, void* memory) {
|
||||||
using std::make_integer_sequence;
|
using std::make_integer_sequence;
|
||||||
|
|
||||||
assert(cardinality == 0);
|
if (cardinality == 0) {
|
||||||
construct_single<T>(make_integer_sequence<int, 0>{}, vm, memory);
|
construct_single<T>(make_integer_sequence<int, 0>{}, vm, memory);
|
||||||
return true;
|
return ConstructResult{0, true};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ConstructResult{static_cast<std::uint16_t>(cardinality), false};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Args, int... Indices>
|
|
||||||
inline void find_params_and_construct_foreign_class (
|
|
||||||
std::integer_sequence<int, Indices...> seq,
|
|
||||||
VM& vm,
|
|
||||||
void* memory
|
|
||||||
) {
|
|
||||||
if constexpr (sizeof...(Args) == 0) {
|
|
||||||
construct_single<T>(seq, vm, memory);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ForeignClassHelper<T, Args...>::construct(vm, vm.slot_count() - 1, memory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t Search, std::size_t... Values>
|
template <std::size_t Search, std::size_t... Values>
|
||||||
struct AssertIfDuplicateValues {
|
struct AssertIfDuplicateValues {
|
||||||
static_assert(sizeof...(Values) == 0, "Code bug?");
|
static_assert(sizeof...(Values) == 0, "Code bug?");
|
||||||
|
@ -134,11 +133,17 @@ namespace wren {
|
||||||
ret.allocate = [](VM& vm) {
|
ret.allocate = [](VM& vm) {
|
||||||
void* const mem = vm.set_slot_new_foreign(0, 0, sizeof(T));
|
void* const mem = vm.set_slot_new_foreign(0, 0, sizeof(T));
|
||||||
|
|
||||||
detail::find_params_and_construct_foreign_class<T, Args...>(
|
const auto result = detail::ForeignClassHelper<T, Args...>::construct(vm, vm.slot_count() - 1, mem);
|
||||||
std::make_integer_sequence<int, sizeof...(Args)>{},
|
if (not result.success) {
|
||||||
vm,
|
set(vm, 1, std::string{"No registered c++ constructor "} +
|
||||||
mem
|
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||||
);
|
"for class " + guess_class_name<T>() + " " +
|
||||||
|
#endif
|
||||||
|
"takes " + std::to_string(result.parameter_count) +
|
||||||
|
" parameter" + (result.parameter_count == 1 ? "" : "s")
|
||||||
|
);
|
||||||
|
vm.abort_fiber(1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ret.finalize = [](void* mem) {
|
ret.finalize = [](void* mem) {
|
||||||
const auto cale = static_cast<T*>(mem);
|
const auto cale = static_cast<T*>(mem);
|
||||||
|
|
|
@ -103,6 +103,8 @@ namespace wren {
|
||||||
bool has_module (const char* module) const noexcept;
|
bool has_module (const char* module) const noexcept;
|
||||||
bool has_variable (const char* module, const char* name) const noexcept;
|
bool has_variable (const char* module, const char* name) const noexcept;
|
||||||
|
|
||||||
|
void abort_fiber(int slot_num);
|
||||||
|
|
||||||
std::size_t dynafunc_byte_size() const;
|
std::size_t dynafunc_byte_size() const;
|
||||||
void reset (Configuration* conf);
|
void reset (Configuration* conf);
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,10 @@ namespace wren {
|
||||||
return wrenHasVariable(m_local->wvm, module, name);
|
return wrenHasVariable(m_local->wvm, module, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VM::abort_fiber(int slot_num) {
|
||||||
|
wrenAbortFiber(m_local->wvm, slot_num);
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t VM::dynafunc_byte_size() const {
|
std::size_t VM::dynafunc_byte_size() const {
|
||||||
return m_local->dynafunc.total_memory();
|
return m_local->dynafunc.total_memory();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue