diff --git a/byterun/dune b/byterun/dune index 9355f9abb..258b18920 100644 --- a/byterun/dune +++ b/byterun/dune @@ -44,4 +44,4 @@ (mode (promote (until-clean))) (action - (run g++ -Wall -Wextra -Iinclude/ -c %{src} -o %{target}))) + (run g++ -Wall -Wextra -std=c++20 -Iinclude/ -c %{src} -o %{target}))) diff --git a/byterun/src/module_manager.cpp b/byterun/src/module_manager.cpp index 27a48b9d9..58010dc2d 100644 --- a/byterun/src/module_manager.cpp +++ b/byterun/src/module_manager.cpp @@ -16,6 +16,34 @@ extern "C" { #include #include +template + requires(N == 0) +void call_func(void (*f)(), Args... args) { + s_push(((void *(*)(Args...))f)(args...)); +} + +template + requires(N != 0) +void call_func(void (*f)(), Args... args) { + void *arg = s_pop(); + call_func(f, args..., arg); + // TODO: check that arg is added on the right position +} + +template +void call_anyarg_func(void (*f)(), size_t n) { + if constexpr (do_check) { + if (n > N) { + failure("too many function arguments (not supported): %zu > %zu\n", n, N); + } + } + if (n == N) { + call_func(f); + } else if constexpr (N > 0) { + call_anyarg_func(f, n); + } +} + struct ModSymbolPos { uint32_t mod_id; size_t offset; @@ -235,40 +263,12 @@ bool run_stdlib_func(const char *name, size_t args_count) { args_count); } - // TODO: work with varargs - if (it->second.is_vararg) { - failure("vararg stdlib functions are not supported yet"); - } - if (it->second.is_args) { void *ret = ((void *(*)(aint *))it->second.ptr)((aint *)s_peek()); s_popn(it->second.args_count); s_push(ret); } else { - // TODO: check if arg order is not reversed - switch (it->second.args_count) { - case 0: { - s_push(((void *(*)())it->second.ptr)()); - } break; - case 1: { - void *arg1 = s_pop(); - s_push(((void *(*)(void *))it->second.ptr)(arg1)); - } break; - case 2: { - void *arg1 = s_pop(); - void *arg2 = s_pop(); - s_push(((void *(*)(void *, void *))it->second.ptr)(arg1, arg2)); - } break; - case 3: { - void *arg1 = s_pop(); - void *arg2 = s_pop(); - void *arg3 = s_pop(); - s_push(((void *(*)(void *, void *, void *))it->second.ptr)(arg1, arg2, - arg3)); - } break; - default: - failure("too many std function args (> 3)"); - } + call_anyarg_func<20>(it->second.ptr, args_count); } return true; } diff --git a/byterun/src/parser.cpp b/byterun/src/parser.cpp index e50827351..01ac1003a 100644 --- a/byterun/src/parser.cpp +++ b/byterun/src/parser.cpp @@ -286,8 +286,7 @@ static inline const char *read_print_val(char **ip, const Bytefile &bf, } template -static inline void read_print_seq(char **ip, const Bytefile &bf, - std::ostream &out) {} +static inline void read_print_seq(char **, const Bytefile &, std::ostream &) {} template static inline void read_print_seq(char **ip, const Bytefile &bf,