Improve error reporting

This commit is contained in:
King_DuckZ 2022-05-15 20:17:07 +02:00
parent 0e3e0ed506
commit ce7be396d2
3 changed files with 38 additions and 27 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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();
}