From 93c50b58826aff8c5111e55363d7474fe7e0a18c Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Thu, 2 Jan 2020 00:20:38 +0200 Subject: [PATCH] Remove native C bindings. Validate args for Raw calls. Cleanup --- source/m3.h | 39 +--- source/m3_api_defs.h | 8 +- source/m3_api_libc.c | 101 +++++----- source/m3_api_wasi.c | 40 ++-- source/m3_bind.c | 324 ++------------------------------- test/run-wasi-test.py | 2 +- test/wasi/test_native_vs_raw.c | 8 + test/wasi/wasm_api.h | 3 - test/wasi/wasm_api.syms | 1 - 9 files changed, 103 insertions(+), 423 deletions(-) diff --git a/source/m3.h b/source/m3.h index 83d4ba0..c081807 100644 --- a/source/m3.h +++ b/source/m3.h @@ -163,15 +163,11 @@ d_m3ErrorConst (trapIntegerConversion, "[trap] invalid conversion to in d_m3ErrorConst (trapIndirectCallTypeMismatch, "[trap] indirect call type mismatch") d_m3ErrorConst (trapTableIndexOutOfRange, "[trap] undefined element") d_m3ErrorConst (trapExit, "[trap] program called exit") +d_m3ErrorConst (trapAbort, "[trap] program called abort") d_m3ErrorConst (trapUnreachable, "[trap] unreachable executed") d_m3ErrorConst (trapStackOverflow, "[trap] stack overflow") -typedef void (* M3Free) (const void * i_data, void * i_ref); -typedef void (* M3Importer) (IM3ImportInfo io_import, IM3Module io_module, void * i_ref); -typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref); - - //------------------------------------------------------------------------------------------------------------------------------- // configuration (found in m3_core.h) //------------------------------------------------------------------------------------------------------------------------------- @@ -200,18 +196,8 @@ typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref); uint32_t i_stackSizeInBytes, M3StackInfo * i_nativeStackInfo); // i_nativeStackInfo can be NULL - - M3Result m3_RegisterFunction (IM3Runtime io_runtime, - const char * const i_functionName, - const char * const i_signature, - const void * const i_function /* , const void * const i_ref */); - - void m3_FreeRuntime (IM3Runtime i_runtime); -// void m3_SetImporter (IM3Runtime i_runtime, M3Importer i_importHandler); -// void m3_SetTimeoutHandler (IM3Runtime i_runtime, float i_periodInSeconds, M3Callback i_callback); - //-------------------------------------------------------------------------------------------------------------------------------------------- // modules //-------------------------------------------------------------------------------------------------------------------------------------------- @@ -230,9 +216,6 @@ typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref); void m3_FreeModule (IM3Module i_module); // Only unloaded modules need to be freed. - -// M3Result m3_EnableOptimizer (IM3Module io_module, bool i_enable); - M3Result m3_LoadModule (IM3Runtime io_runtime, IM3Module io_module); // LoadModule transfers ownership of a module to the runtime. Do not free modules once successfully imported into the runtime. @@ -243,19 +226,8 @@ typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref); M3Result m3_LinkRawFunction (IM3Module io_module, const char * const i_moduleName, const char * const i_functionName, - M3RawCall i_function); // void (u64 * _sp, u8 * _mem) - - - - M3Result m3_LinkCFunction (IM3Module io_module, - const char * const i_moduleName, - const char * const i_functionName, - const char * const i_signature, // signature is null terminated - const void * const i_function /* , const void * const i_ref */); - - - -// M3Result m3_SetGlobal + const char * const i_signature, + M3RawCall i_function); //-------------------------------------------------------------------------------------------------------------------------------------------- // functions @@ -265,15 +237,10 @@ typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref); IM3Runtime i_runtime, const char * const i_functionName); -// M3Result m3_GetCFunction (void ** o_cFunction, IM3Runtime i_runtime, -// const char * const i_functionName, const char * const i_signature); - M3Result m3_Call (IM3Function i_function); M3Result m3_CallWithArgs (IM3Function i_function, uint32_t i_argc, const char * const * i_argv); // M3Result m3_CallMain (IM3Function i_function, uint32_t i_argc, const char * const * i_argv); -// void * /* return */ m3_Call (IM3Function i_function, M3Result * o_result); - // IM3Functions are valid during the lifetime of the originating runtime M3ErrorInfo m3_GetErrorInfo (IM3Runtime i_runtime); diff --git a/source/m3_api_defs.h b/source/m3_api_defs.h index aa43632..ba29993 100644 --- a/source/m3_api_defs.h +++ b/source/m3_api_defs.h @@ -10,12 +10,16 @@ #include "m3_core.h" +// TODO: perform bounds checks +#define m3ApiOffsetToPtr(offset) (void*)((u8*)_mem + (u32)(offset)) +#define m3ApiPtrToOffset(ptr) (u32)((u8*)ptr - (u8*)_mem) + #define m3ApiReturnType(TYPE) TYPE* raw_return = ((TYPE*) (_sp)); #define m3ApiGetArg(TYPE, NAME) TYPE NAME = * ((TYPE *) (_sp++)); -#define m3ApiGetArgMem(TYPE, NAME) TYPE NAME = (TYPE)(void*)((u8*)_mem + * (u32 *) _sp++); +#define m3ApiGetArgMem(TYPE, NAME) TYPE NAME = (TYPE)m3ApiOffsetToPtr(* ((u32 *) (_sp++))); #define m3ApiRawFunction(NAME) const void * NAME (IM3Runtime runtime, uint64_t * _sp, void * _mem) -#define m3ApiReturn(VALUE) { *raw_return = (VALUE); return NULL; } +#define m3ApiReturn(VALUE) { *raw_return = (VALUE); return c_m3Err_none; } #define m3ApiTrap(VALUE) { return VALUE; } #endif /* m3_api_defs_h */ diff --git a/source/m3_api_libc.c b/source/m3_api_libc.c index 57b7991..0069d97 100644 --- a/source/m3_api_libc.c +++ b/source/m3_api_libc.c @@ -19,58 +19,50 @@ #include -#if defined(WIN32) - -#include - -int clock_gettime(int clk_id, struct timespec *spec) +m3ApiRawFunction(m3_libc_abort) { - __int64 wintime; - GetSystemTimeAsFileTime((FILETIME*)&wintime); - wintime -=116444736000000000i64; //1jan1601 to 1jan1970 - spec->tv_sec =wintime / 10000000i64; //seconds - spec->tv_nsec =wintime % 10000000i64 *100; //nano-seconds - return 0; + m3ApiTrap(c_m3Err_trapAbort); } -#endif - - -// TODO: return trap -void m3_libc_abort() +m3ApiRawFunction(m3_libc_exit) { - abort (); + m3ApiGetArg (int32_t, code) + + m3ApiTrap(c_m3Err_trapExit); } -m3ret_t m3_libc_exit (i32 i_code) + +m3ApiRawFunction(m3_libc_memset) { - printf ("exit (%d)\n", i_code); + m3ApiReturnType (int32_t) - return c_m3Err_trapExit; -} + m3ApiGetArgMem (void*, i_ptr) + m3ApiGetArg (int32_t, i_value) + m3ApiGetArg (int32_t, i_size) -void* m3_libc_memset(void * i_ptr, i32 i_value, i32 i_size) -{ - memset (i_ptr, i_value, i_size); - return i_ptr; + u32 result = m3ApiPtrToOffset(memset (i_ptr, i_value, i_size)); + m3ApiReturn(result); } -void* m3_libc_memcpy(void * o_dst, void * i_src, i32 i_size) +m3ApiRawFunction(m3_libc_memmove) { - return memcpy (o_dst, i_src, i_size); -} + m3ApiReturnType (int32_t) -uint32_t m3_libc_clock() -{ - return clock(); + m3ApiGetArgMem (void*, o_dst) + m3ApiGetArgMem (void*, i_src) + m3ApiGetArg (int32_t, i_size) + + u32 result = m3ApiPtrToOffset(memmove (o_dst, i_src, i_size)); + m3ApiReturn(result); } -uint32_t m3_libc_clock_gettime(uint32_t clk_id, struct timespec* tp) +m3ApiRawFunction(m3_libc_clock) { - return clock_gettime(clk_id, tp); -} + m3ApiReturnType (uint32_t) + m3ApiReturn(clock()); +} static M3Result SuppressLookupFailure (M3Result i_result) @@ -99,10 +91,12 @@ m3ApiRawFunction(m3_wasm3_raw_sum) return c_m3Err_none; } +/* TODO: implement direct native function calls (using libffi?) i64 m3_wasm3_native_sum(i32 val1, i32 val2, i32 val3, i32 val4) { return val1 + val2 + val3 + val4; } +*/ M3Result m3_LinkSpecTest (IM3Module module) @@ -110,19 +104,19 @@ M3Result m3_LinkSpecTest (IM3Module module) M3Result result = c_m3Err_none; const char* spectest = "spectest"; + const char* wasm3 = "wasm3"; -_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print", &m3_spectest_dummy))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i32", &m3_spectest_dummy))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i64", &m3_spectest_dummy))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_f32", &m3_spectest_dummy))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_f64", &m3_spectest_dummy))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i32_f32", &m3_spectest_dummy))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i64_f64", &m3_spectest_dummy))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print", "v()", &m3_spectest_dummy))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i32", "v(i)", &m3_spectest_dummy))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i64", "v(I)", &m3_spectest_dummy))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_f32", "v(f)", &m3_spectest_dummy))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_f64", "v(F)", &m3_spectest_dummy))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i32_f32", "v(if)", &m3_spectest_dummy))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i64_f64", "v(IF)", &m3_spectest_dummy))); - const char* wasm3 = "wasm3"; -_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasm3, "raw_sum", &m3_wasm3_raw_sum))); -_ (SuppressLookupFailure (m3_LinkCFunction (module, wasm3, "native_sum", "I(iiii)", &m3_wasm3_native_sum))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasm3, "raw_sum", "I(iiii)", &m3_wasm3_raw_sum))); +//_ (SuppressLookupFailure (m3_LinkCFunction (module, wasm3, "native_sum", "I(iiii)", &m3_wasm3_native_sum))); _catch: return result; @@ -133,19 +127,14 @@ M3Result m3_LinkLibC (IM3Module module) { M3Result result = c_m3Err_none; - const char* namespace = "env"; - -//_ (SuppressLookupFailure (m3_LinkFunction (module, "_printf", "v(**)", &m3_libc_printf))); -//_ (SuppressLookupFailure (m3_LinkFunction (module, "g$_stderr", "i(M)", &m3_libc_get_stderr))); - -_ (SuppressLookupFailure (m3_LinkCFunction (module, namespace, "_memset", "*(*ii)", &m3_libc_memset))); -_ (SuppressLookupFailure (m3_LinkCFunction (module, namespace, "_memcpy", "*(**i)", &m3_libc_memcpy))); -_ (SuppressLookupFailure (m3_LinkCFunction (module, namespace, "_exit", "Tv(i)", &m3_libc_exit))); -_ (SuppressLookupFailure (m3_LinkCFunction (module, namespace, "_perror", "v(*)", &perror))); - -_ (SuppressLookupFailure (m3_LinkCFunction (module, namespace, "_clock", "i()", &m3_libc_clock))); -_ (SuppressLookupFailure (m3_LinkCFunction (module, namespace, "_clock_gettime", "i(i*)", &m3_libc_clock_gettime))); + const char* env = "env"; +_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memset", "*(*ii)", &m3_libc_memset))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memmove", "*(**i)", &m3_libc_memmove))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memcpy", "*(**i)", &m3_libc_memmove))); // just alias of memmove +_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_abort", "v()", &m3_libc_abort))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_exit", "v(i)", &m3_libc_exit))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_clock", "i()", &m3_libc_clock))); _catch: return result; diff --git a/source/m3_api_wasi.c b/source/m3_api_wasi.c index c917865..82a162f 100644 --- a/source/m3_api_wasi.c +++ b/source/m3_api_wasi.c @@ -627,7 +627,7 @@ M3Result m3_LinkWASI (IM3Module module) { M3Result result = c_m3Err_none; - const char* namespace = "wasi_unstable"; + const char* wasi = "wasi_unstable"; #ifdef _WIN32 setmode(fileno(stdin), O_BINARY); @@ -640,31 +640,31 @@ M3Result m3_LinkWASI (IM3Module module) preopen[i].fd = open(preopen[i].path, O_RDONLY); } #endif -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "args_sizes_get", &m3_wasi_unstable_args_sizes_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "environ_sizes_get", &m3_wasi_unstable_environ_sizes_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "args_get", &m3_wasi_unstable_args_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "environ_get", &m3_wasi_unstable_environ_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_sizes_get", "i(**)", &m3_wasi_unstable_args_sizes_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_sizes_get", "i(**)", &m3_wasi_unstable_environ_sizes_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_get", "i(**)", &m3_wasi_unstable_args_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_get", "i(**)", &m3_wasi_unstable_environ_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "fd_prestat_dir_name", &m3_wasi_unstable_fd_prestat_dir_name))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "fd_prestat_get", &m3_wasi_unstable_fd_prestat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_prestat_dir_name", "i(i*i)", &m3_wasi_unstable_fd_prestat_dir_name))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_prestat_get", "i(i*)", &m3_wasi_unstable_fd_prestat_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "path_open", &m3_wasi_unstable_path_open))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_open", "i(ii*iiiii*)", &m3_wasi_unstable_path_open))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "fd_fdstat_get", &m3_wasi_unstable_fd_fdstat_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "fd_write", &m3_wasi_unstable_fd_write))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "fd_read", &m3_wasi_unstable_fd_read))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "fd_seek", &m3_wasi_unstable_fd_seek))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "fd_datasync", &m3_wasi_unstable_fd_datasync))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "fd_close", &m3_wasi_unstable_fd_close))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_get", "i(i*)", &m3_wasi_unstable_fd_fdstat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_write", "i(iii*)", &m3_wasi_unstable_fd_write))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_read", "i(iii*)", &m3_wasi_unstable_fd_read))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_seek", "i(iii*)", &m3_wasi_unstable_fd_seek))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_datasync", "i(i)", &m3_wasi_unstable_fd_datasync))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_close", "i(i)", &m3_wasi_unstable_fd_close))); -//_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "sock_send", &...))); -//_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "sock_recv", &...))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_send", "i()", &...))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_recv", "i()", &...))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "random_get", &m3_wasi_unstable_random_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "random_get", "i(*i)", &m3_wasi_unstable_random_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "clock_res_get", &m3_wasi_unstable_clock_res_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "clock_time_get", &m3_wasi_unstable_clock_time_get))); -_ (SuppressLookupFailure (m3_LinkRawFunction (module, namespace, "proc_exit", &m3_wasi_unstable_proc_exit))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_res_get", "i(i*)", &m3_wasi_unstable_clock_res_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_time_get", "i(ii*)", &m3_wasi_unstable_clock_time_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_exit", "i(i)", &m3_wasi_unstable_proc_exit))); _catch: return result; diff --git a/source/m3_bind.c b/source/m3_bind.c index 2b6ea81..8658f10 100644 --- a/source/m3_bind.c +++ b/source/m3_bind.c @@ -10,191 +10,30 @@ #include "m3_env.h" #include "m3_exception.h" - -typedef struct M3State -{ - pc_t pc; - m3stack_t sp; - u8 * mem; -} -M3State; - - -// TODO: This binding code only work'n for System V AMD64 ABI calling convention (macOS & Linux) -// Needs work for MS cdecl - -#define d_m3BindingArgList i64 _i0, i64 _i1, i64 _i2, i64 _i3, i64 _i4, i64 _i5, \ - f64 _f0, f64 _f1, f64 _f2, f64 _f3, f64 _f4 -#define d_m3BindingArgs _i0, _i1, _i2, _i3, _i4, _i5, \ - _f0, _f1, _f2, _f3, _f4 -#define d_m3BindingDefaultArgs 0,0,0,0,0,0, \ - 0.,0.,0.,0.,0. - -typedef m3ret_t (* M3ArgPusher) (d_m3BindingArgList, M3State * i_state); -typedef f64 (* M3ArgPusherFpReturn) (d_m3BindingArgList, M3State * i_state); - - -m3ret_t PushArg_runtime (d_m3BindingArgList, M3State * _state) -{ - M3MemoryHeader * info = (M3MemoryHeader *) _state->mem - 1; - _i0 = (i64) info->runtime; - M3ArgPusher pusher = (M3ArgPusher)(* _state->pc++); - return pusher (d_m3BindingArgs, _state); -} - - -#define d_argPusherPointer(INDEX) \ -m3ret_t PushArg_p##INDEX (d_m3BindingArgList, M3State * _state) \ -{ \ - i32 offset = (u32) * (_state->sp++); \ - _i##INDEX = (i64) (_state->mem + offset); \ - M3ArgPusher pusher = (M3ArgPusher)(* _state->pc++); \ - return pusher (d_m3BindingArgs, _state); \ -} -//printf ("push ptr: r%d off: %d\n", INDEX, offset); - -//printf ("push [%d]: %" PRId64 "\n", INDEX, _i##INDEX); -#define d_argPusherInt(INDEX) \ -m3ret_t PushArg_i##INDEX (d_m3BindingArgList, M3State * _state) \ -{ \ - _i##INDEX = * (_state->sp++); \ - M3ArgPusher pusher = (M3ArgPusher)(* _state->pc++); \ - return pusher (d_m3BindingArgs, _state); \ -} - -//printf ("push [%d]: %lf\n", INDEX, * (TYPE *) (_state->sp)); - -#define d_argPusherFloat(INDEX,TYPE) \ -m3ret_t PushArg_##TYPE##_##INDEX (d_m3BindingArgList, M3State * _state) \ -{ \ - _f##INDEX = * (TYPE *) (_state->sp++); \ - M3ArgPusher pusher = (M3ArgPusher)(* _state->pc++); \ - return pusher (d_m3BindingArgs, _state); \ -} - - - - -d_argPusherPointer (0) d_argPusherPointer (1) d_argPusherPointer (2) d_argPusherPointer (3) -d_argPusherInt (0) d_argPusherInt (1) d_argPusherInt (2) d_argPusherInt (3) -d_argPusherFloat (0, f32) d_argPusherFloat (1, f32) d_argPusherFloat (2, f32) d_argPusherFloat (3, f32) -d_argPusherFloat (0, f64) d_argPusherFloat (1, f64) d_argPusherFloat (2, f64) d_argPusherFloat (3, f64) - -d_argPusherPointer (4) d_argPusherPointer (5) -d_argPusherInt (4) d_argPusherInt (5) -d_argPusherFloat (4, f32) -d_argPusherFloat (4, f64) - -M3ArgPusher c_m3PointerPushers [] = { PushArg_p0, PushArg_p1, PushArg_p2, PushArg_p3, PushArg_p4, PushArg_p5, NULL }; // one dummy is required -M3ArgPusher c_m3IntPushers [] = { PushArg_i0, PushArg_i1, PushArg_i2, PushArg_i3, PushArg_i4, PushArg_i5, NULL }; -M3ArgPusher c_m3Float32Pushers [] = { PushArg_f32_0, PushArg_f32_1, PushArg_f32_2, PushArg_f32_3, PushArg_f32_4, NULL }; -M3ArgPusher c_m3Float64Pushers [] = { PushArg_f64_0, PushArg_f64_1, PushArg_f64_2, PushArg_f64_3, PushArg_f64_4, NULL }; - - - -d_m3RetSig CallTrappingCFunction_void (d_m3OpSig) -{ - M3ArgPusher pusher = (M3ArgPusher) (* _pc++); - M3State state = { _pc, _sp, m3MemData(_mem) }; - - m3ret_t r = (m3ret_t) pusher (d_m3BindingDefaultArgs, & state); - - return r; -} - - -d_m3RetSig CallCFunction_i64 (d_m3OpSig) -{ - M3ArgPusher pusher = (M3ArgPusher) (* _pc++); - M3State state = { _pc, _sp, m3MemData(_mem) }; - - i64 r = (i64) pusher (d_m3BindingDefaultArgs, & state); - * _sp = r; - - return 0; -} - - -d_m3RetSig CallCFunction_f64 (d_m3OpSig) -{ - M3ArgPusherFpReturn pusher = (M3ArgPusherFpReturn) (* _pc++); - M3State state = { _pc, _sp, m3MemData(_mem) }; - - f64 r = (f64) pusher (d_m3BindingDefaultArgs, & state); - * (f64 *) (_sp) = r; - - return 0; -} - - -d_m3RetSig CallCFunction_f32 (d_m3OpSig) -{ - M3ArgPusherFpReturn pusher = (M3ArgPusherFpReturn) (* _pc++); - M3State state = { _pc, _sp, m3MemData(_mem) }; - - f32 r = (f32) pusher (d_m3BindingDefaultArgs, & state); - * (f32 *) (_sp) = r; - - return 0; -} - - -d_m3RetSig CallCFunction_ptr (d_m3OpSig) -{ - M3ArgPusher pusher = (M3ArgPusher) (* _pc++); - M3State state = { _pc, _sp, m3MemData(_mem) }; - - const u8 * r = (const u8*) pusher (d_m3BindingDefaultArgs, & state); - - size_t offset = r - m3MemData(_mem); - - * (i32 *) (_sp) = (i32) offset; - - return 0; -} - - - +static u8 ConvertTypeCharToTypeId (char i_code) { - u8 type = 0; - -// if (i_code > c_m3Type_ptr) - { - if (i_code == 'v') type = c_m3Type_void; - else if (i_code == '*') type = c_m3Type_ptr; - else if (i_code == 'T') type = c_m3Type_trap; - else if (i_code == '8') type = c_m3Type_i32; - else if (i_code == 'f') type = c_m3Type_f32; - else if (i_code == 'F') type = c_m3Type_f64; - else if (i_code == 'i') type = c_m3Type_i32; - else if (i_code == 'I') type = c_m3Type_i64; - else if (i_code == 'R') type = c_m3Type_runtime; + switch (i_code) { + case 'v': return c_m3Type_void; + case 'i': return c_m3Type_i32; + case 'I': return c_m3Type_i64; + case 'f': return c_m3Type_f32; + case 'F': return c_m3Type_f64; + case '*': return c_m3Type_ptr; } - - return type; + return c_m3Type_none; } - -M3Result ValidateSignature (IM3Function i_function, bool * o_traps, u8 * o_normalizedSignature, ccstr_t i_linkingSignature) +static +M3Result ValidateSignature (IM3Function i_function, ccstr_t i_linkingSignature) { M3Result result = c_m3Err_none; - * o_traps = false; - cstr_t sig = i_linkingSignature; bool hasReturn = false; u32 numArgs = 0; - // check for trap flag - u8 type = ConvertTypeCharToTypeId (* sig); - if (type == c_m3Type_trap) - { - * o_traps = true; - ++sig; - } - bool parsingArgs = false; while (* sig) { @@ -216,15 +55,10 @@ M3Result ValidateSignature (IM3Function i_function, bool * o_traps, u8 * o_nor else if (typeChar == ')') break; - type = ConvertTypeCharToTypeId (typeChar); + u8 type = ConvertTypeCharToTypeId (typeChar); if (type) { - * o_normalizedSignature++ = type; - - if (type == c_m3Type_trap) - _throw ("malformed function signature"); - if (not parsingArgs) { if (hasReturn) @@ -247,118 +81,8 @@ M3Result ValidateSignature (IM3Function i_function, bool * o_traps, u8 * o_nor _catch: return result; } - -M3Result m3_RegisterFunction (IM3Runtime io_runtime, const char * const i_functionName, const char * const i_signature, const void * const i_function /* , const void * const i_ref */) -{ - M3Result result = c_m3Err_none; - - - return result; -} - - typedef M3Result (* M3Linker) (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function); - - -M3Result LinkCFunction (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function) -{ - M3Result result = c_m3Err_none; - - M3ArgPusher pushers [c_m3MaxNumFunctionArgs + 1]; - u8 signature [1 /* return */ + c_m3MaxNumFunctionArgs + 2]; - - M3_INIT(pushers); - M3_INIT(signature); - - bool trappingFunction = false; - - result = ValidateSignature (io_function, & trappingFunction, signature, i_signature); - - if (not result) - { - u8 returnType = signature [0]; - u8 * sig = & signature [1]; - - u32 intIndex = 0; - u32 floatIndex = 0; - - u32 i = 0; - while (* sig) - { - M3ArgPusher * pusher = & pushers [i]; - u8 type = * sig; - - if (type == c_m3Type_ptr) * pusher = c_m3PointerPushers [intIndex++]; - else if (IsIntType (type)) * pusher = c_m3IntPushers [intIndex++]; - else if (type == c_m3Type_f32) * pusher = c_m3Float32Pushers [floatIndex++]; - else if (type == c_m3Type_f64) * pusher = c_m3Float64Pushers [floatIndex++]; - else if (type == c_m3Type_runtime) - { - * pusher = PushArg_runtime; - d_m3Assert (i == 0); // can only push to arg0 - ++intIndex; - } - else - { - result = "FIX"; - m3NotImplemented(); - } - - if (* pusher == NULL) - _throw ("too many arguments in C binding"); - - ++i; ++sig; - } - - if (not result) - { - IM3CodePage page = AcquireCodePageWithCapacity (io_module->runtime, /*setup-func:*/ 1 + /*arg pushers:*/ i + /*target c-function:*/ 1); - - if (page) - { - io_function->compiled = GetPagePC (page); - io_function->module = io_module; - - IM3Operation callerOp; - - if (trappingFunction) - { - // TODO: returned types not implemented! - d_m3Assert (returnType == c_m3Type_void); - - callerOp = CallTrappingCFunction_void; - } - else - { - callerOp = CallCFunction_i64; - - if (returnType == c_m3Type_f64) - callerOp = CallCFunction_f64; - else if (returnType == c_m3Type_f32) - callerOp = CallCFunction_f32; - else if (returnType == c_m3Type_ptr) - callerOp = CallCFunction_ptr; - } - - EmitWord (page, callerOp); - - for (u32 j = 0; j < i; ++j) - EmitWord (page, pushers [j]); - - EmitWord (page, i_function); - - ReleaseCodePage (io_module->runtime, page); - } - else result = c_m3Err_mallocFailedCodePage; - } - } - - _catch: - return result; -} - - M3Result FindAndLinkFunction (IM3Module io_module, ccstr_t i_moduleName, ccstr_t i_functionName, @@ -386,25 +110,15 @@ M3Result FindAndLinkFunction (IM3Module io_module, return result; } - - -M3Result m3_LinkCFunction (IM3Module io_module, - const char * const i_moduleName, - const char * const i_functionName, - const char * const i_signature, - const void * i_function) -{ - return FindAndLinkFunction (io_module, i_moduleName, i_functionName, i_signature, i_function, LinkCFunction); -} - - // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -// TODO: validate signature as well? M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, ccstr_t signature, const void * i_function) { M3Result result = c_m3Err_none; d_m3Assert (io_module->runtime); - + +_try { +_ (ValidateSignature (io_function, signature)); + IM3CodePage page = AcquireCodePageWithCapacity (io_module->runtime, 2); if (page) @@ -417,8 +131,9 @@ M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, ccstr ReleaseCodePage (io_module->runtime, page); } - else result = c_m3Err_mallocFailedCodePage; + else _throw(c_m3Err_mallocFailedCodePage); +} _catch: return result; } @@ -426,9 +141,10 @@ M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, ccstr M3Result m3_LinkRawFunction (IM3Module io_module, const char * const i_moduleName, const char * const i_functionName, + const char * const i_signature, M3RawCall i_function) { - return FindAndLinkFunction (io_module, i_moduleName, i_functionName, NULL, i_function, LinkRawFunction); + return FindAndLinkFunction (io_module, i_moduleName, i_functionName, i_signature, i_function, LinkRawFunction); } diff --git a/test/run-wasi-test.py b/test/run-wasi-test.py index d1e6162..3658c85 100755 --- a/test/run-wasi-test.py +++ b/test/run-wasi-test.py @@ -42,7 +42,7 @@ commands = [ "args": ["cat", "./wasi/0.txt"], "expect_pattern": "Hello world*Constructor OK*Args: *; cat; ./wasi/0.txt;*fib(20) = 6765*[* ms]*48 65 6c 6c 6f 20 77 6f 72 6c 64*=== done ===*" }, { - "skip": True, # TODO: Native calls fail on all 32-bit targets + "skip": True, # Direct native calls were removed from wasm3 "name": "Raw/Native funcs benchmark", "wasm": "./wasi/test_native_vs_raw.wasm", "expect_pattern": "Validation...*Native/Raw: *" diff --git a/test/wasi/test_native_vs_raw.c b/test/wasi/test_native_vs_raw.c index 30c6c0d..8cd00a5 100644 --- a/test/wasi/test_native_vs_raw.c +++ b/test/wasi/test_native_vs_raw.c @@ -4,6 +4,14 @@ #include "wasm_api.h" +/* + * Result: "Raw" calls are ~2x faster than native arg "pushers". + * + * WARNING: this benchmark no longer works. + * Native calls were removed along with wasm3_native_sum. + * It may be useful in future when we implement libffi calls, etc. + */ + static inline double get_time() { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); diff --git a/test/wasi/wasm_api.h b/test/wasi/wasm_api.h index bcd476c..8a26137 100644 --- a/test/wasi/wasm_api.h +++ b/test/wasi/wasm_api.h @@ -12,7 +12,4 @@ WASM_IMPORT("wasm3", "raw_sum") int64_t wasm3_raw_sum (int32_t val1, int32_t val2, int32_t val3, int32_t val4); -WASM_IMPORT("wasm3", "native_sum") -int64_t wasm3_native_sum (int32_t val1, int32_t val2, int32_t val3, int32_t val4); - #endif diff --git a/test/wasi/wasm_api.syms b/test/wasi/wasm_api.syms index fe46e53..06ac8d4 100644 --- a/test/wasi/wasm_api.syms +++ b/test/wasi/wasm_api.syms @@ -1,2 +1 @@ wasm3_raw_sum -wasm3_native_sum