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 "seters_getters.hpp"
|
||||
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||
# include "guess_class_name.hpp"
|
||||
#endif
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
namespace wren {
|
||||
namespace detail {
|
||||
|
@ -34,12 +38,17 @@ namespace wren {
|
|||
new(memory) T{get<Args>(vm, Indices + 1)...};
|
||||
}
|
||||
|
||||
struct ConstructResult {
|
||||
std::uint16_t parameter_count;
|
||||
bool success;
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
struct ForeignClassHelper;
|
||||
|
||||
template <typename T, template <typename...> class Pack, typename... PackArgs, typename... 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;
|
||||
|
||||
//search by number of parameters.
|
||||
|
@ -48,7 +57,7 @@ namespace wren {
|
|||
constexpr int pack_size = static_cast<int>(sizeof...(PackArgs));
|
||||
if (pack_size == cardinality) {
|
||||
construct_single<T, PackArgs...>(make_integer_sequence<int, pack_size>{}, vm, memory);
|
||||
return true;
|
||||
return ConstructResult{pack_size, true};
|
||||
}
|
||||
else {
|
||||
return ForeignClassHelper<T, Args...>::construct(vm, cardinality, memory);
|
||||
|
@ -58,12 +67,12 @@ namespace wren {
|
|||
|
||||
template <typename T, typename LoneArg, typename... 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;
|
||||
|
||||
if (1 == cardinality) {
|
||||
construct_single<T, LoneArg>(make_integer_sequence<int, 1>{}, vm, memory);
|
||||
return true;
|
||||
return ConstructResult{1, true};
|
||||
}
|
||||
else {
|
||||
return ForeignClassHelper<T, Args...>::construct(vm, cardinality, memory);
|
||||
|
@ -83,29 +92,19 @@ namespace wren {
|
|||
|
||||
template <typename 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;
|
||||
|
||||
assert(cardinality == 0);
|
||||
construct_single<T>(make_integer_sequence<int, 0>{}, vm, memory);
|
||||
return true;
|
||||
if (cardinality == 0) {
|
||||
construct_single<T>(make_integer_sequence<int, 0>{}, vm, memory);
|
||||
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>
|
||||
struct AssertIfDuplicateValues {
|
||||
static_assert(sizeof...(Values) == 0, "Code bug?");
|
||||
|
@ -134,11 +133,17 @@ namespace wren {
|
|||
ret.allocate = [](VM& vm) {
|
||||
void* const mem = vm.set_slot_new_foreign(0, 0, sizeof(T));
|
||||
|
||||
detail::find_params_and_construct_foreign_class<T, Args...>(
|
||||
std::make_integer_sequence<int, sizeof...(Args)>{},
|
||||
vm,
|
||||
mem
|
||||
);
|
||||
const auto result = detail::ForeignClassHelper<T, Args...>::construct(vm, vm.slot_count() - 1, mem);
|
||||
if (not result.success) {
|
||||
set(vm, 1, std::string{"No registered c++ constructor "} +
|
||||
#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) {
|
||||
const auto cale = static_cast<T*>(mem);
|
||||
|
|
|
@ -103,6 +103,8 @@ namespace wren {
|
|||
bool has_module (const char* module) 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;
|
||||
void reset (Configuration* conf);
|
||||
|
||||
|
|
|
@ -280,6 +280,10 @@ namespace wren {
|
|||
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 {
|
||||
return m_local->dynafunc.total_memory();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue