diff --git a/platforms/cpp/README.md b/platforms/cpp/README.md index 1e3d4c7..7751ff3 100644 --- a/platforms/cpp/README.md +++ b/platforms/cpp/README.md @@ -52,9 +52,30 @@ If the module doesn't reference an imported function named `func`, an exception `function` object can be obtained from a `runtime`, looking up the function by name. Function objects are used to call WebAssembly functions. -`template Ret function::call()` — call a WebAssembly function which doesn't take any arguments. The return value of the function is automatically converted to the type `Ret`. Note that you need to specify the return type when using this template function, and the type has to match the type returned by the WebAssembly function. +`template Ret function::call(Args...)` — calls a WebAssembly function with or without arguments and a return value.
+The return value of the function, if not `void`, is automatically converted to the type `Ret`.
+Note that you always need to specify the matching return type when using this template with a non-void function.
+Examples: +```cpp +// WASM signature: [] → [] +func.call(); -`template Ret function::call(Args...)` — same as above, but also allows passing arguments to the WebAssembly function. +// WASM signature: [i32, i32] → [] +func.call(42, 43); // implicit argument types + +// WASM signature: [i32, i64] → [] +func.call(42, 43); // explicit argument types require the return type + +// WASM signature: [] → [i32] +auto result = func.call(); + +// WASM signature: [i32, i32] → [i64] +auto result = func.call(42, 43); // implicit argument types + +// WASM signature: [i32, i64] → [i64] +auto result = func.call(42, 43); // explicit argument types + +``` `template Ret function::call_argv(Args...)` — same as above, except that this function takes arguments as C strings (`const char*`). diff --git a/platforms/cpp/main.cpp b/platforms/cpp/main.cpp index 25f8ba8..93b4dcb 100644 --- a/platforms/cpp/main.cpp +++ b/platforms/cpp/main.cpp @@ -56,6 +56,29 @@ int main(void) auto res = memcpy_test_fn.call(); std::cout << "result: 0x" << std::hex << res << std::dec << std::endl; } + + /** + * Calling functions that modify an internal state, with mixed argument / return types + */ + { + wasm3::function counter_get_fn = runtime.find_function("test_counter_get"); + wasm3::function counter_inc_fn = runtime.find_function("test_counter_inc"); + wasm3::function counter_add_fn = runtime.find_function("test_counter_add"); + + // call with no arguments and a return value + auto value = counter_get_fn.call(); + std::cout << "counter: " << value << std::endl; + + // call with no arguments and no return value + counter_inc_fn.call(); + value = counter_get_fn.call(); + std::cout << "counter after increment: " << value << std::endl; + + // call with one argument and no return value + counter_add_fn.call(42); + value = counter_get_fn.call(); + std::cout << "counter after adding value: " << value << std::endl; + } } catch(wasm3::error &e) { std::cerr << "WASM3 error: " << e.what() << std::endl; diff --git a/platforms/cpp/wasm/test_prog.c b/platforms/cpp/wasm/test_prog.c index a2250c8..c11c8d9 100644 --- a/platforms/cpp/wasm/test_prog.c +++ b/platforms/cpp/wasm/test_prog.c @@ -4,6 +4,8 @@ extern int sum(int, int); extern int ext_memcpy(void*, const void*, size_t); +int32_t counter = 0; + #define WASM_EXPORT __attribute__((used)) __attribute__((visibility ("default"))) int WASM_EXPORT test(int32_t arg1, int32_t arg2) @@ -22,3 +24,18 @@ int64_t WASM_EXPORT test_memcpy(void) ext_memcpy(((uint8_t*)&x) + 4, &high, 4); return x; } + +int32_t WASM_EXPORT test_counter_get() +{ + return counter; +} + +void WASM_EXPORT test_counter_inc() +{ + ++counter; +} + +void WASM_EXPORT test_counter_add(int32_t inc_value) +{ + counter += inc_value; +} diff --git a/platforms/cpp/wasm/test_prog.wasm b/platforms/cpp/wasm/test_prog.wasm old mode 100644 new mode 100755 index eeb49b0..345d441 Binary files a/platforms/cpp/wasm/test_prog.wasm and b/platforms/cpp/wasm/test_prog.wasm differ diff --git a/platforms/cpp/wasm/test_prog.wasm.h b/platforms/cpp/wasm/test_prog.wasm.h index cfc8003..d54e08c 100644 --- a/platforms/cpp/wasm/test_prog.wasm.h +++ b/platforms/cpp/wasm/test_prog.wasm.h @@ -1,25 +1,68 @@ unsigned char test_prog_wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x15, 0x04, 0x60, - 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x03, 0x7f, 0x7f, - 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x01, 0x7e, 0x02, 0x1c, 0x02, 0x03, 0x65, + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x22, 0x07, 0x60, + 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, + 0x00, 0x01, 0x7e, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x02, 0x94, 0x01, 0x06, + 0x03, 0x65, 0x6e, 0x76, 0x03, 0x73, 0x75, 0x6d, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x65, 0x78, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x63, 0x70, - 0x79, 0x00, 0x02, 0x03, 0x65, 0x6e, 0x76, 0x03, 0x73, 0x75, 0x6d, 0x00, - 0x00, 0x03, 0x04, 0x03, 0x01, 0x03, 0x00, 0x05, 0x06, 0x01, 0x01, 0x80, - 0x02, 0x80, 0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x8c, 0xc0, - 0x02, 0x0b, 0x07, 0x28, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, - 0x02, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x00, 0x04, 0x0b, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x63, 0x70, 0x79, 0x00, 0x03, 0x06, - 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x02, 0x0a, 0x71, 0x03, 0x03, - 0x00, 0x01, 0x0b, 0x59, 0x02, 0x01, 0x7f, 0x01, 0x7e, 0x23, 0x00, 0x41, - 0x10, 0x6b, 0x22, 0x00, 0x24, 0x00, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, - 0x08, 0x20, 0x00, 0x41, 0xe7, 0x8a, 0x8d, 0x09, 0x36, 0x02, 0x04, 0x20, - 0x00, 0x41, 0xef, 0x9b, 0xaf, 0xcd, 0x78, 0x36, 0x02, 0x00, 0x20, 0x00, - 0x41, 0x08, 0x6a, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x41, 0x04, 0x10, 0x00, - 0x1a, 0x20, 0x00, 0x41, 0x08, 0x6a, 0x41, 0x04, 0x72, 0x20, 0x00, 0x41, - 0x04, 0x10, 0x00, 0x1a, 0x20, 0x00, 0x29, 0x03, 0x08, 0x21, 0x01, 0x20, - 0x00, 0x41, 0x10, 0x6a, 0x24, 0x00, 0x20, 0x01, 0x0b, 0x11, 0x00, 0x20, - 0x00, 0x20, 0x01, 0x6a, 0x20, 0x00, 0x20, 0x01, 0x6b, 0x10, 0x01, 0x41, - 0x02, 0x6d, 0x0b, 0x0b, 0x0a, 0x01, 0x00, 0x41, 0x80, 0x0c, 0x0b, 0x03, - 0xa0, 0x06, 0x50 + 0x79, 0x00, 0x04, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x31, 0x0e, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x73, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77, 0x61, 0x73, 0x69, + 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x08, 0x61, 0x72, 0x67, 0x73, 0x5f, + 0x67, 0x65, 0x74, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x04, 0x6d, 0x61, + 0x69, 0x6e, 0x00, 0x00, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, + 0x65, 0x77, 0x31, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, + 0x74, 0x00, 0x01, 0x03, 0x0c, 0x0b, 0x02, 0x00, 0x05, 0x03, 0x02, 0x01, + 0x02, 0x03, 0x01, 0x06, 0x03, 0x04, 0x05, 0x01, 0x70, 0x01, 0x02, 0x02, + 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80, 0x02, 0x06, 0x09, 0x01, 0x7f, + 0x01, 0x41, 0x90, 0x88, 0xc0, 0x02, 0x0b, 0x07, 0xb8, 0x01, 0x0c, 0x06, + 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x04, 0x74, 0x65, 0x73, + 0x74, 0x00, 0x07, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, + 0x63, 0x70, 0x79, 0x00, 0x08, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x09, + 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x5f, 0x69, 0x6e, 0x63, 0x00, 0x0a, 0x10, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, + 0x00, 0x0b, 0x19, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x01, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x00, 0x0c, 0x10, 0x5f, 0x5f, 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x10, 0x09, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x53, 0x61, 0x76, 0x65, 0x00, 0x0d, 0x0c, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x00, + 0x0e, 0x0a, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x41, 0x6c, 0x6c, 0x6f, 0x63, + 0x00, 0x0f, 0x09, 0x07, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x01, 0x06, 0x0a, + 0xd1, 0x02, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, + 0x01, 0x6a, 0x20, 0x00, 0x20, 0x01, 0x6b, 0x10, 0x00, 0x41, 0x02, 0x6d, + 0x0b, 0x58, 0x02, 0x02, 0x7f, 0x01, 0x7e, 0x23, 0x00, 0x41, 0x10, 0x6b, + 0x22, 0x00, 0x24, 0x00, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x08, 0x20, + 0x00, 0x41, 0xe7, 0x8a, 0x8d, 0x09, 0x36, 0x02, 0x04, 0x20, 0x00, 0x41, + 0xef, 0x9b, 0xaf, 0xcd, 0x78, 0x36, 0x02, 0x00, 0x20, 0x00, 0x41, 0x08, + 0x6a, 0x22, 0x01, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x41, 0x04, 0x10, 0x01, + 0x1a, 0x20, 0x01, 0x41, 0x04, 0x72, 0x20, 0x00, 0x41, 0x04, 0x10, 0x01, + 0x1a, 0x20, 0x00, 0x29, 0x03, 0x08, 0x21, 0x02, 0x20, 0x00, 0x41, 0x10, + 0x6a, 0x24, 0x00, 0x20, 0x02, 0x0b, 0x08, 0x00, 0x41, 0x80, 0x08, 0x28, + 0x02, 0x00, 0x0b, 0x11, 0x00, 0x41, 0x80, 0x08, 0x41, 0x80, 0x08, 0x28, + 0x02, 0x00, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x00, 0x0b, 0x11, 0x00, 0x41, + 0x80, 0x08, 0x41, 0x80, 0x08, 0x28, 0x02, 0x00, 0x20, 0x00, 0x6a, 0x36, + 0x02, 0x00, 0x0b, 0x8f, 0x01, 0x01, 0x04, 0x7f, 0x02, 0x7f, 0x23, 0x00, + 0x41, 0x10, 0x6b, 0x22, 0x00, 0x24, 0x00, 0x02, 0x40, 0x20, 0x00, 0x22, + 0x01, 0x41, 0x0c, 0x6a, 0x20, 0x00, 0x41, 0x08, 0x6a, 0x10, 0x02, 0x45, + 0x04, 0x40, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x22, 0x02, 0x04, 0x7f, 0x20, + 0x00, 0x20, 0x02, 0x41, 0x02, 0x74, 0x22, 0x03, 0x41, 0x13, 0x6a, 0x41, + 0x70, 0x71, 0x6b, 0x22, 0x00, 0x24, 0x00, 0x20, 0x00, 0x20, 0x01, 0x28, + 0x02, 0x08, 0x41, 0x0f, 0x6a, 0x41, 0x70, 0x71, 0x6b, 0x22, 0x02, 0x24, + 0x00, 0x20, 0x00, 0x20, 0x03, 0x6a, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, + 0x00, 0x20, 0x02, 0x10, 0x03, 0x0d, 0x02, 0x20, 0x01, 0x28, 0x02, 0x0c, + 0x05, 0x41, 0x00, 0x0b, 0x20, 0x00, 0x10, 0x04, 0x21, 0x00, 0x20, 0x01, + 0x41, 0x10, 0x6a, 0x24, 0x00, 0x20, 0x00, 0x0c, 0x02, 0x0b, 0x41, 0xc7, + 0x00, 0x10, 0x05, 0x00, 0x0b, 0x41, 0xc7, 0x00, 0x10, 0x05, 0x00, 0x0b, + 0x10, 0x05, 0x00, 0x0b, 0x04, 0x00, 0x23, 0x00, 0x0b, 0x06, 0x00, 0x20, + 0x00, 0x24, 0x00, 0x0b, 0x10, 0x00, 0x23, 0x00, 0x20, 0x00, 0x6b, 0x41, + 0x70, 0x71, 0x22, 0x00, 0x24, 0x00, 0x20, 0x00, 0x0b, 0x05, 0x00, 0x41, + 0x84, 0x08, 0x0b }; -unsigned int test_prog_wasm_len = 255; +unsigned int test_prog_wasm_len = 771; diff --git a/platforms/cpp/wasm3_cpp/include/wasm3_cpp.h b/platforms/cpp/wasm3_cpp/include/wasm3_cpp.h index f33f4fa..c12a127 100644 --- a/platforms/cpp/wasm3_cpp/include/wasm3_cpp.h +++ b/platforms/cpp/wasm3_cpp/include/wasm3_cpp.h @@ -344,25 +344,21 @@ namespace wasm3 { * * Note that the type of the return value must be explicitly specified as a template argument. * - * @return the return value of the function. + * @return the return value of the function or void. */ - template + template Ret call(Args... args) { const void *arg_ptrs[] = { reinterpret_cast(&args)... }; M3Result res = m3_Call(m_func, sizeof...(args), arg_ptrs); detail::check_error(res); - Ret ret; - const void* ret_ptrs[] = { &ret }; - res = m3_GetResults(m_func, 1, ret_ptrs); - detail::check_error(res); - return ret; - } - template - void call(Args... args) { - const void *arg_ptrs[] = { reinterpret_cast(&args)... }; - M3Result res = m3_Call(m_func, sizeof...(args), arg_ptrs); - detail::check_error(res); + if constexpr (!std::is_void::value) { + Ret ret; + const void* ret_ptrs[] = { &ret }; + res = m3_GetResults(m_func, 1, ret_ptrs); + detail::check_error(res); + return ret; + } } protected: