From 18729709bf31eb3bce0a520730198dea826af62d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 9 Oct 2020 14:37:07 +0200 Subject: [PATCH 01/25] feat(c-api) Update `wasm-c-api` repository. This change is important because `wasm.h` contains new functions, like `wasm_name_new_from_string_nt`, which are useful for the Go implementation. --- .../tests/wasm_c_api/wasm-c-api/README.md | 1 + .../wasm_c_api/wasm-c-api/example/callback.c | 33 +++++----- .../wasm_c_api/wasm-c-api/example/callback.cc | 11 ++-- .../wasm_c_api/wasm-c-api/example/finalize.c | 5 +- .../wasm_c_api/wasm-c-api/example/finalize.cc | 3 +- .../wasm_c_api/wasm-c-api/example/global.c | 52 ++++++++------- .../wasm_c_api/wasm-c-api/example/global.cc | 14 +++-- .../wasm_c_api/wasm-c-api/example/hello.c | 13 ++-- .../wasm_c_api/wasm-c-api/example/hello.cc | 8 ++- .../wasm_c_api/wasm-c-api/example/hostref.c | 63 ++++++++++--------- .../wasm_c_api/wasm-c-api/example/hostref.cc | 28 +++++---- .../wasm_c_api/wasm-c-api/example/memory.c | 59 +++++++++-------- .../wasm_c_api/wasm-c-api/example/memory.cc | 17 ++--- .../wasm_c_api/wasm-c-api/example/multi.c | 57 +++++++++-------- .../wasm_c_api/wasm-c-api/example/multi.cc | 10 +-- .../wasm_c_api/wasm-c-api/example/reflect.c | 6 +- .../wasm_c_api/wasm-c-api/example/reflect.cc | 3 +- .../wasm_c_api/wasm-c-api/example/serialize.c | 14 +++-- .../wasm-c-api/example/serialize.cc | 8 ++- .../wasm_c_api/wasm-c-api/example/start.c | 5 +- .../wasm_c_api/wasm-c-api/example/start.cc | 3 +- .../wasm_c_api/wasm-c-api/example/table.c | 33 +++++----- .../wasm_c_api/wasm-c-api/example/table.cc | 13 ++-- .../wasm_c_api/wasm-c-api/example/threads.c | 18 +++--- .../wasm_c_api/wasm-c-api/example/threads.cc | 7 ++- .../wasm_c_api/wasm-c-api/example/trap.c | 15 +++-- .../wasm_c_api/wasm-c-api/example/trap.cc | 10 +-- .../wasm_c_api/wasm-c-api/include/wasm.h | 29 +++++++-- .../wasm_c_api/wasm-c-api/include/wasm.hh | 24 ++++--- .../tests/wasm_c_api/wasm-c-api/src/wasm-c.cc | 35 +++++++---- .../wasm_c_api/wasm-c-api/src/wasm-v8.cc | 15 ++--- 31 files changed, 348 insertions(+), 264 deletions(-) diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/README.md b/lib/c-api/tests/wasm_c_api/wasm-c-api/README.md index 6ba4799e8d2..1dbcbda9783 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/README.md +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/README.md @@ -94,6 +94,7 @@ Currently, known implementations of this API are included in * V8 natively (both C and C++) * Wabt (only C?) * Wasmtime (only C?) +* [Wasmer](https://github.com/wasmerio/wasmer/tree/master/lib/c-api) (only C, C++ coming soon) ### TODO diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/callback.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/callback.c index e17429bdd24..2fddb1634ff 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/callback.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/callback.c @@ -35,27 +35,27 @@ void wasm_val_print(wasm_val_t val) { // A function to be called from Wasm code. own wasm_trap_t* print_callback( - const wasm_val_t args[], wasm_val_t results[] + const wasm_val_vec_t* args, wasm_val_vec_t* results ) { printf("Calling back...\n> "); - wasm_val_print(args[0]); + wasm_val_print(args->data[0]); printf("\n"); - wasm_val_copy(&results[0], &args[0]); + wasm_val_copy(&results->data[0], &args->data[0]); return NULL; } // A function closure. own wasm_trap_t* closure_callback( - void* env, const wasm_val_t args[], wasm_val_t results[] + void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results ) { int i = *(int*)env; printf("Calling back closure...\n"); printf("> %d\n", i); - results[0].kind = WASM_I32; - results[0].of.i32 = (int32_t)i; + results->data[0].kind = WASM_I32; + results->data[0].of.i32 = (int32_t)i; return NULL; } @@ -68,7 +68,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("callback.wasm", "r"); + FILE* file = fopen("callback.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -108,11 +108,12 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { + wasm_extern_t* externs[] = { wasm_func_as_extern(print_func), wasm_func_as_extern(closure_func) }; + wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -140,13 +141,11 @@ int main(int argc, const char* argv[]) { // Call. printf("Calling export...\n"); - wasm_val_t args[2]; - args[0].kind = WASM_I32; - args[0].of.i32 = 3; - args[1].kind = WASM_I32; - args[1].of.i32 = 4; - wasm_val_t results[1]; - if (wasm_func_call(run_func, args, results)) { + wasm_val_t as[2] = { WASM_I32_VAL(3), WASM_I32_VAL(4) }; + wasm_val_t rs[1] = { WASM_INIT_VAL }; + wasm_val_vec_t args = WASM_ARRAY_VEC(as); + wasm_val_vec_t results = WASM_ARRAY_VEC(rs); + if (wasm_func_call(run_func, &args, &results)) { printf("> Error calling function!\n"); return 1; } @@ -155,7 +154,7 @@ int main(int argc, const char* argv[]) { // Print result. printf("Printing result...\n"); - printf("> %u\n", results[0].of.i32); + printf("> %u\n", rs[0].of.i32); // Shut down. printf("Shutting down...\n"); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/callback.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/callback.cc index 41a388ca981..957629cabc8 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/callback.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/callback.cc @@ -35,7 +35,7 @@ auto operator<<(std::ostream& out, const wasm::Val& val) -> std::ostream& { // A function to be called from Wasm code. auto print_callback( - const wasm::Val args[], wasm::Val results[] + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl << "> " << args[0] << std::endl; results[0] = args[0].copy(); @@ -45,7 +45,7 @@ auto print_callback( // A function closure. auto closure_callback( - void* env, const wasm::Val args[], wasm::Val results[] + void* env, const wasm::vec& args, wasm::vec& results ) -> wasm::own { auto i = *reinterpret_cast(env); std::cout << "Calling back closure..." << std::endl; @@ -103,7 +103,8 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - wasm::Extern* imports[] = {print_func.get(), closure_func.get()}; + auto imports = wasm::vec::make( + print_func.get(), closure_func.get()); auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; @@ -121,8 +122,8 @@ void run() { // Call. std::cout << "Calling export..." << std::endl; - wasm::Val args[] = {wasm::Val::i32(3), wasm::Val::i32(4)}; - wasm::Val results[1]; + auto args = wasm::vec::make(wasm::Val::i32(3), wasm::Val::i32(4)); + auto results = wasm::vec::make_uninitialized(1); if (run_func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/finalize.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/finalize.c index 247368f28eb..502fc60b2c7 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/finalize.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/finalize.c @@ -20,7 +20,7 @@ void finalize(void* data) { void run_in_store(wasm_store_t* store) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("finalize.wasm", "r"); + FILE* file = fopen("finalize.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); exit(1); @@ -50,8 +50,9 @@ void run_in_store(wasm_store_t* store) { printf("Instantiating modules...\n"); for (int i = 0; i <= iterations; ++i) { if (i % (iterations / 10) == 0) printf("%d\n", i); + wasm_extern_vec_t imports = WASM_EMPTY_VEC; own wasm_instance_t* instance = - wasm_instance_new(store, module, NULL, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module %d!\n", i); exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/finalize.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/finalize.cc index 64e134b8d87..ce7e972bc06 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/finalize.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/finalize.cc @@ -46,7 +46,8 @@ void run_in_store(wasm::Store* store) { std::cout << "Instantiating modules..." << std::endl; for (int i = 0; i <= iterations; ++i) { if (i % (iterations / 10) == 0) std::cout << i << std::endl; - auto instance = wasm::Instance::make(store, module.get(), nullptr); + auto imports = wasm::vec::make(); + auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module " << i << "!" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/global.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/global.c index 5fe357cd4c1..5bd403369c3 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/global.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/global.c @@ -39,9 +39,11 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) { #define check_call(func, type, expected) \ { \ - wasm_val_t results[1]; \ - wasm_func_call(func, NULL, results); \ - check(results[0], type, expected); \ + wasm_val_t vs[1]; \ + wasm_val_vec_t args = WASM_EMPTY_VEC; \ + wasm_val_vec_t results = WASM_ARRAY_VEC(vs); \ + wasm_func_call(func, &args, &results); \ + check(vs[0], type, expected); \ } @@ -53,7 +55,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("global.wasm", "r"); + FILE* file = fopen("global.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -90,16 +92,16 @@ int main(int argc, const char* argv[]) { own wasm_globaltype_t* var_i64_type = wasm_globaltype_new( wasm_valtype_new(WASM_I64), WASM_VAR); - wasm_val_t val_f32_1 = {.kind = WASM_F32, .of = {.f32 = 1}}; + wasm_val_t val_f32_1 = WASM_F32_VAL(1); own wasm_global_t* const_f32_import = wasm_global_new(store, const_f32_type, &val_f32_1); - wasm_val_t val_i64_2 = {.kind = WASM_I64, .of = {.i64 = 2}}; + wasm_val_t val_i64_2 = WASM_I64_VAL(2); own wasm_global_t* const_i64_import = wasm_global_new(store, const_i64_type, &val_i64_2); - wasm_val_t val_f32_3 = {.kind = WASM_F32, .of = {.f32 = 3}}; + wasm_val_t val_f32_3 = WASM_F32_VAL(3); own wasm_global_t* var_f32_import = wasm_global_new(store, var_f32_type, &val_f32_3); - wasm_val_t val_i64_4 = {.kind = WASM_I64, .of = {.i64 = 4}}; + wasm_val_t val_i64_4 = WASM_I64_VAL(4); own wasm_global_t* var_i64_import = wasm_global_new(store, var_i64_type, &val_i64_4); @@ -110,14 +112,15 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { + wasm_extern_t* externs[] = { wasm_global_as_extern(const_f32_import), wasm_global_as_extern(const_i64_import), wasm_global_as_extern(var_f32_import), wasm_global_as_extern(var_i64_import) }; + wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -175,13 +178,13 @@ int main(int argc, const char* argv[]) { check_call(get_var_i64_export, i64, 8); // Modify variables through API and check again. - wasm_val_t val33 = {.kind = WASM_F32, .of = {.f32 = 33}}; + wasm_val_t val33 = WASM_F32_VAL(33); wasm_global_set(var_f32_import, &val33); - wasm_val_t val34 = {.kind = WASM_I64, .of = {.i64 = 34}}; + wasm_val_t val34 = WASM_I64_VAL(34); wasm_global_set(var_i64_import, &val34); - wasm_val_t val37 = {.kind = WASM_F32, .of = {.f32 = 37}}; + wasm_val_t val37 = WASM_F32_VAL(37); wasm_global_set(var_f32_export, &val37); - wasm_val_t val38 = {.kind = WASM_I64, .of = {.i64 = 38}}; + wasm_val_t val38 = WASM_I64_VAL(38); wasm_global_set(var_i64_export, &val38); check_global(var_f32_import, f32, 33); @@ -195,14 +198,19 @@ int main(int argc, const char* argv[]) { check_call(get_var_i64_export, i64, 38); // Modify variables through calls and check again. - wasm_val_t args73[] = { {.kind = WASM_F32, .of = {.f32 = 73}} }; - wasm_func_call(set_var_f32_import, args73, NULL); - wasm_val_t args74[] = { {.kind = WASM_I64, .of = {.i64 = 74}} }; - wasm_func_call(set_var_i64_import, args74, NULL); - wasm_val_t args77[] = { {.kind = WASM_F32, .of = {.f32 = 77}} }; - wasm_func_call(set_var_f32_export, args77, NULL); - wasm_val_t args78[] = { {.kind = WASM_I64, .of = {.i64 = 78}} }; - wasm_func_call(set_var_i64_export, args78, NULL); + wasm_val_vec_t res = WASM_EMPTY_VEC; + wasm_val_t vs73[] = { WASM_F32_VAL(73) }; + wasm_val_vec_t args73 = WASM_ARRAY_VEC(vs73); + wasm_func_call(set_var_f32_import, &args73, &res); + wasm_val_t vs74[] = { WASM_I64_VAL(74) }; + wasm_val_vec_t args74 = WASM_ARRAY_VEC(vs74); + wasm_func_call(set_var_i64_import, &args74, &res); + wasm_val_t vs77[] = { WASM_F32_VAL(77) }; + wasm_val_vec_t args77 = WASM_ARRAY_VEC(vs77); + wasm_func_call(set_var_f32_export, &args77, &res); + wasm_val_t vs78[] = { WASM_I64_VAL(78) }; + wasm_val_vec_t args78 = WASM_ARRAY_VEC(vs78); + wasm_func_call(set_var_i64_export, &args78, &res); check_global(var_f32_import, f32, 73); check_global(var_i64_import, i64, 74); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/global.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/global.cc index efe90f05c46..178eb61f8b7 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/global.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/global.cc @@ -32,8 +32,9 @@ void check(T actual, U expected) { } auto call(const wasm::Func* func) -> wasm::Val { - wasm::Val results[1]; - if (func->call(nullptr, results)) { + auto args = wasm::vec::make(); + auto results = wasm::vec::make_uninitialized(1); + if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); } @@ -41,8 +42,9 @@ auto call(const wasm::Func* func) -> wasm::Val { } void call(const wasm::Func* func, wasm::Val&& arg) { - wasm::Val args[1] = {std::move(arg)}; - if (func->call(args)) { + auto args = wasm::vec::make(std::move(arg)); + auto results = wasm::vec::make(); + if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); } @@ -95,10 +97,10 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - wasm::Extern* imports[] = { + auto imports = wasm::vec::make( const_f32_import.get(), const_i64_import.get(), var_f32_import.get(), var_i64_import.get() - }; + ); auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hello.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hello.c index e4ef9837ffc..740f099699f 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hello.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hello.c @@ -9,7 +9,7 @@ // A function to be called from Wasm code. own wasm_trap_t* hello_callback( - const wasm_val_t args[], wasm_val_t results[] + const wasm_val_vec_t* args, wasm_val_vec_t* results ) { printf("Calling back...\n"); printf("> Hello World!\n"); @@ -25,7 +25,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("hello.wasm", "r"); + FILE* file = fopen("hello.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -61,9 +61,10 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) }; + wasm_extern_t* externs[] = { wasm_func_as_extern(hello_func) }; + wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -90,7 +91,9 @@ int main(int argc, const char* argv[]) { // Call. printf("Calling export...\n"); - if (wasm_func_call(run_func, NULL, NULL)) { + wasm_val_vec_t args = WASM_EMPTY_VEC; + wasm_val_vec_t results = WASM_EMPTY_VEC; + if (wasm_func_call(run_func, &args, &results)) { printf("> Error calling function!\n"); return 1; } diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hello.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hello.cc index a6bbe28acb5..94eb567b8c8 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hello.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hello.cc @@ -9,7 +9,7 @@ // A function to be called from Wasm code. auto hello_callback( - const wasm::Val args[], wasm::Val results[] + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> Hello world!" << std::endl; @@ -55,7 +55,7 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - wasm::Extern* imports[] = {hello_func.get()}; + auto imports = wasm::vec::make(hello_func.get()); auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; @@ -73,7 +73,9 @@ void run() { // Call. std::cout << "Calling export..." << std::endl; - if (run_func->call()) { + auto args = wasm::vec::make(); + auto results = wasm::vec::make(); + if (run_func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); } diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hostref.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hostref.c index b70218e6105..1e787ab1902 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hostref.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hostref.c @@ -10,12 +10,12 @@ // A function to be called from Wasm code. own wasm_trap_t* callback( - const wasm_val_t args[], wasm_val_t results[] + const wasm_val_vec_t* args, wasm_val_vec_t* results ) { printf("Calling back...\n> "); printf("> %p\n", - args[0].of.ref ? wasm_ref_get_host_info(args[0].of.ref) : NULL); - wasm_val_copy(&results[0], &args[0]); + args->data[0].of.ref ? wasm_ref_get_host_info(args->data[0].of.ref) : NULL); + wasm_val_copy(&results->data[0], &args->data[0]); return NULL; } @@ -47,21 +47,23 @@ wasm_table_t* get_export_table(const wasm_extern_vec_t* exports, size_t i) { own wasm_ref_t* call_v_r(const wasm_func_t* func) { printf("call_v_r... "); fflush(stdout); - wasm_val_t results[1]; - if (wasm_func_call(func, NULL, results)) { + wasm_val_t rs[] = { WASM_INIT_VAL }; + wasm_val_vec_t args = WASM_EMPTY_VEC; + wasm_val_vec_t results = WASM_ARRAY_VEC(rs); + if (wasm_func_call(func, &args, &results)) { printf("> Error calling function!\n"); exit(1); } printf("okay\n"); - return results[0].of.ref; + return rs[0].of.ref; } void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) { printf("call_r_v... "); fflush(stdout); - wasm_val_t args[1]; - args[0].kind = WASM_ANYREF; - args[0].of.ref = ref; - if (wasm_func_call(func, args, NULL)) { + wasm_val_t vs[1] = { WASM_REF_VAL(ref) }; + wasm_val_vec_t args = WASM_ARRAY_VEC(vs); + wasm_val_vec_t results = WASM_EMPTY_VEC; + if (wasm_func_call(func, &args, &results)) { printf("> Error calling function!\n"); exit(1); } @@ -70,26 +72,24 @@ void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) { own wasm_ref_t* call_r_r(const wasm_func_t* func, wasm_ref_t* ref) { printf("call_r_r... "); fflush(stdout); - wasm_val_t args[1]; - args[0].kind = WASM_ANYREF; - args[0].of.ref = ref; - wasm_val_t results[1]; - if (wasm_func_call(func, args, results)) { + wasm_val_t vs[1] = { WASM_REF_VAL(ref) }; + wasm_val_t rs[1] = { WASM_INIT_VAL }; + wasm_val_vec_t args = WASM_ARRAY_VEC(vs); + wasm_val_vec_t results = WASM_ARRAY_VEC(rs); + if (wasm_func_call(func, &args, &results)) { printf("> Error calling function!\n"); exit(1); } printf("okay\n"); - return results[0].of.ref; + return rs[0].of.ref; } void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) { printf("call_ir_v... "); fflush(stdout); - wasm_val_t args[2]; - args[0].kind = WASM_I32; - args[0].of.i32 = i; - args[1].kind = WASM_ANYREF; - args[1].of.ref = ref; - if (wasm_func_call(func, args, NULL)) { + wasm_val_t vs[2] = { WASM_I32_VAL(i), WASM_REF_VAL(ref) }; + wasm_val_vec_t args = WASM_ARRAY_VEC(vs); + wasm_val_vec_t results = WASM_EMPTY_VEC; + if (wasm_func_call(func, &args, &results)) { printf("> Error calling function!\n"); exit(1); } @@ -98,16 +98,16 @@ void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) { own wasm_ref_t* call_i_r(const wasm_func_t* func, int32_t i) { printf("call_i_r... "); fflush(stdout); - wasm_val_t args[1]; - args[0].kind = WASM_I32; - args[0].of.i32 = i; - wasm_val_t results[1]; - if (wasm_func_call(func, args, results)) { + wasm_val_t vs[1] = { WASM_I32_VAL(i) }; + wasm_val_t rs[1] = { WASM_INIT_VAL }; + wasm_val_vec_t args = WASM_ARRAY_VEC(vs); + wasm_val_vec_t results = WASM_ARRAY_VEC(rs); + if (wasm_func_call(func, &args, &results)) { printf("> Error calling function!\n"); exit(1); } printf("okay\n"); - return results[0].of.ref; + return rs[0].of.ref; } void check(own wasm_ref_t* actual, const wasm_ref_t* expected) { @@ -130,7 +130,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("hostref.wasm", "r"); + FILE* file = fopen("hostref.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -167,9 +167,10 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(callback_func) }; + wasm_extern_t* externs[] = { wasm_func_as_extern(callback_func) }; + wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hostref.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hostref.cc index c94c8f59627..09c239e0c91 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hostref.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/hostref.cc @@ -9,7 +9,7 @@ // A function to be called from Wasm code. auto callback( - const wasm::Val args[], wasm::Val results[] + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> " << (args[0].ref() ? args[0].ref()->get_host_info() : nullptr) << std::endl; @@ -45,8 +45,9 @@ auto get_export_table(wasm::ownvec& exports, size_t i) -> wasm::Ta void call_r_v(const wasm::Func* func, const wasm::Ref* ref) { std::cout << "call_r_v... " << std::flush; - wasm::Val args[1] = {wasm::Val::ref(ref ? ref->copy() : wasm::own())}; - if (func->call(args, nullptr)) { + auto args = wasm::vec::make(wasm::Val::ref(ref ? ref->copy() : wasm::own())); + auto results = wasm::vec::make(); + if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); } @@ -55,8 +56,9 @@ void call_r_v(const wasm::Func* func, const wasm::Ref* ref) { auto call_v_r(const wasm::Func* func) -> wasm::own { std::cout << "call_v_r... " << std::flush; - wasm::Val results[1]; - if (func->call(nullptr, results)) { + auto args = wasm::vec::make(); + auto results = wasm::vec::make_uninitialized(1); + if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); } @@ -66,8 +68,8 @@ auto call_v_r(const wasm::Func* func) -> wasm::own { auto call_r_r(const wasm::Func* func, const wasm::Ref* ref) -> wasm::own { std::cout << "call_r_r... " << std::flush; - wasm::Val args[1] = {wasm::Val::ref(ref ? ref->copy() : wasm::own())}; - wasm::Val results[1]; + auto args = wasm::vec::make(wasm::Val::ref(ref ? ref->copy() : wasm::own())); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -78,8 +80,10 @@ auto call_r_r(const wasm::Func* func, const wasm::Ref* ref) -> wasm::owncopy() : wasm::own())}; - if (func->call(args, nullptr)) { + auto args = wasm::vec::make( + wasm::Val::i32(i), wasm::Val::ref(ref ? ref->copy() : wasm::own())); + auto results = wasm::vec::make(); + if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); } @@ -88,8 +92,8 @@ void call_ir_v(const wasm::Func* func, int32_t i, const wasm::Ref* ref) { auto call_i_r(const wasm::Func* func, int32_t i) -> wasm::own { std::cout << "call_i_r... " << std::flush; - wasm::Val args[1] = {wasm::Val::i32(i)}; - wasm::Val results[1]; + auto args = wasm::vec::make(wasm::Val::i32(i)); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -147,7 +151,7 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - wasm::Extern* imports[] = {callback_func.get()}; + auto imports = wasm::vec::make(callback_func.get()); auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/memory.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/memory.c index af2b9414d38..edd4ebadd0b 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/memory.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/memory.c @@ -32,49 +32,49 @@ void check(bool success) { } } -void check_call(wasm_func_t* func, wasm_val_t args[], int32_t expected) { - wasm_val_t results[1]; - if (wasm_func_call(func, args, results) || results[0].of.i32 != expected) { +void check_call(wasm_func_t* func, int i, wasm_val_t args[], int32_t expected) { + wasm_val_t r = WASM_INIT_VAL; + wasm_val_vec_t args_ = {i, args}; + wasm_val_vec_t results = {1, &r}; + if (wasm_func_call(func, &args_, &results) || r.of.i32 != expected) { printf("> Error on result\n"); exit(1); } } void check_call0(wasm_func_t* func, int32_t expected) { - check_call(func, NULL, expected); + check_call(func, 0, NULL, expected); } void check_call1(wasm_func_t* func, int32_t arg, int32_t expected) { - wasm_val_t args[] = { {.kind = WASM_I32, .of = {.i32 = arg}} }; - check_call(func, args, expected); + wasm_val_t args[] = { WASM_I32_VAL(arg) }; + check_call(func, 1, args, expected); } void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; - check_call(func, args, expected); + wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) }; + check_call(func, 2, args, expected); } -void check_ok(wasm_func_t* func, wasm_val_t args[]) { - if (wasm_func_call(func, args, NULL)) { +void check_ok(wasm_func_t* func, int i, wasm_val_t args[]) { + wasm_val_vec_t args_ = {i, args}; + wasm_val_vec_t results = {0, NULL}; + if (wasm_func_call(func, &args_, &results)) { printf("> Error on result, expected empty\n"); exit(1); } } void check_ok2(wasm_func_t* func, int32_t arg1, int32_t arg2) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; - check_ok(func, args); + wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) }; + check_ok(func, 2, args); } -void check_trap(wasm_func_t* func, wasm_val_t args[]) { - wasm_val_t results[1]; - own wasm_trap_t* trap = wasm_func_call(func, args, results); +void check_trap(wasm_func_t* func, int i, wasm_val_t args[]) { + wasm_val_t r = WASM_INIT_VAL; + wasm_val_vec_t args_ = {i, args}; + wasm_val_vec_t results = {1, &r}; + own wasm_trap_t* trap = wasm_func_call(func, &args_, &results); if (! trap) { printf("> Error on result, expected trap\n"); exit(1); @@ -83,16 +83,13 @@ void check_trap(wasm_func_t* func, wasm_val_t args[]) { } void check_trap1(wasm_func_t* func, int32_t arg) { - wasm_val_t args[1] = { {.kind = WASM_I32, .of = {.i32 = arg}} }; - check_trap(func, args); + wasm_val_t args[] = { WASM_I32_VAL(arg) }; + check_trap(func, 1, args); } void check_trap2(wasm_func_t* func, int32_t arg1, int32_t arg2) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; - check_trap(func, args); + wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) }; + check_trap(func, 2, args); } @@ -104,7 +101,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("memory.wasm", "r"); + FILE* file = fopen("memory.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -132,7 +129,9 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - own wasm_instance_t* instance = wasm_instance_new(store, module, NULL, NULL); + wasm_extern_vec_t imports = WASM_EMPTY_VEC; + own wasm_instance_t* instance = + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/memory.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/memory.cc index 4094accd8d0..6cc36192a85 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/memory.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/memory.cc @@ -33,8 +33,9 @@ void check(T actual, U expected) { template void check_ok(const wasm::Func* func, Args... xs) { - wasm::Val args[] = {wasm::Val::i32(xs)...}; - if (func->call(args)) { + auto args = wasm::vec::make(wasm::Val::i32(xs)...); + auto results = wasm::vec::make(); + if (func->call(args, results)) { std::cout << "> Error on result, expected return" << std::endl; exit(1); } @@ -42,8 +43,9 @@ void check_ok(const wasm::Func* func, Args... xs) { template void check_trap(const wasm::Func* func, Args... xs) { - wasm::Val args[] = {wasm::Val::i32(xs)...}; - if (! func->call(args)) { + auto args = wasm::vec::make(wasm::Val::i32(xs)...); + auto results = wasm::vec::make(); + if (! func->call(args, results)) { std::cout << "> Error on result, expected trap" << std::endl; exit(1); } @@ -51,8 +53,8 @@ void check_trap(const wasm::Func* func, Args... xs) { template auto call(const wasm::Func* func, Args... xs) -> int32_t { - wasm::Val args[] = {wasm::Val::i32(xs)...}; - wasm::Val results[1]; + auto args = wasm::vec::make(wasm::Val::i32(xs)...); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error on result, expected return" << std::endl; exit(1); @@ -92,7 +94,8 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - auto instance = wasm::Instance::make(store, module.get(), nullptr); + auto imports = wasm::vec::make(); + auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/multi.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/multi.c index 3859401c081..846c6ec92af 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/multi.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/multi.c @@ -9,31 +9,32 @@ // A function to be called from Wasm code. own wasm_trap_t* callback( - const wasm_val_t args[], wasm_val_t results[] + const wasm_val_vec_t* args, wasm_val_vec_t* results ) { printf("Calling back...\n> "); printf("> %"PRIu32" %"PRIu64" %"PRIu64" %"PRIu32"\n", - args[0].of.i32, args[1].of.i64, args[2].of.i64, args[3].of.i32); + args->data[0].of.i32, args->data[1].of.i64, + args->data[2].of.i64, args->data[3].of.i32); printf("\n"); - wasm_val_copy(&results[0], &args[3]); - wasm_val_copy(&results[1], &args[1]); - wasm_val_copy(&results[2], &args[2]); - wasm_val_copy(&results[3], &args[0]); + wasm_val_copy(&results->data[0], &args->data[3]); + wasm_val_copy(&results->data[1], &args->data[1]); + wasm_val_copy(&results->data[2], &args->data[2]); + wasm_val_copy(&results->data[3], &args->data[0]); return NULL; } // A function closure. own wasm_trap_t* closure_callback( - void* env, const wasm_val_t args[], wasm_val_t results[] + void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results ) { int i = *(int*)env; printf("Calling back closure...\n"); printf("> %d\n", i); - results[0].kind = WASM_I32; - results[0].of.i32 = (int32_t)i; + results->data[0].kind = WASM_I32; + results->data[0].of.i32 = (int32_t)i; return NULL; } @@ -46,7 +47,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("multi.wasm", "r"); + FILE* file = fopen("multi.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -89,9 +90,10 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = {wasm_func_as_extern(callback_func)}; + wasm_extern_t* externs[] = { wasm_func_as_extern(callback_func) }; + wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -118,17 +120,15 @@ int main(int argc, const char* argv[]) { // Call. printf("Calling export...\n"); - wasm_val_t args[4]; - args[0].kind = WASM_I32; - args[0].of.i32 = 1; - args[1].kind = WASM_I64; - args[1].of.i64 = 2; - args[2].kind = WASM_I64; - args[2].of.i64 = 3; - args[3].kind = WASM_I32; - args[3].of.i32 = 4; - wasm_val_t results[4]; - if (wasm_func_call(run_func, args, results)) { + wasm_val_t vals[4] = { + WASM_I32_VAL(1), WASM_I32_VAL(2), WASM_I32_VAL(3), WASM_I32_VAL(4) + }; + wasm_val_t res[4] = { + WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL + }; + wasm_val_vec_t args = WASM_ARRAY_VEC(vals); + wasm_val_vec_t results = WASM_ARRAY_VEC(res); + if (wasm_func_call(run_func, &args, &results)) { printf("> Error calling function!\n"); return 1; } @@ -138,13 +138,12 @@ int main(int argc, const char* argv[]) { // Print result. printf("Printing result...\n"); printf("> %"PRIu32" %"PRIu64" %"PRIu64" %"PRIu32"\n", - results[0].of.i32, results[1].of.i64, - results[2].of.i64, results[3].of.i32); + res[0].of.i32, res[1].of.i64, res[2].of.i64, res[3].of.i32); - assert(results[0].of.i32 == 4); - assert(results[1].of.i64 == 3); - assert(results[2].of.i64 == 2); - assert(results[3].of.i32 == 1); + assert(res[0].of.i32 == 4); + assert(res[1].of.i64 == 3); + assert(res[2].of.i64 == 2); + assert(res[3].of.i32 == 1); // Shut down. printf("Shutting down...\n"); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/multi.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/multi.cc index 8f7a555cd37..6d083557114 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/multi.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/multi.cc @@ -8,7 +8,7 @@ // A function to be called from Wasm code. auto callback( - const wasm::Val args[], wasm::Val results[] + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> " << args[0].i32(); @@ -66,7 +66,7 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - wasm::Extern* imports[] = {callback_func.get()}; + auto imports = wasm::vec::make(callback_func.get()); auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; @@ -84,10 +84,10 @@ void run() { // Call. std::cout << "Calling export..." << std::endl; - wasm::Val args[] = { + auto args = wasm::vec::make( wasm::Val::i32(1), wasm::Val::i64(2), wasm::Val::i64(3), wasm::Val::i32(4) - }; - wasm::Val results[4]; + ); + auto results = wasm::vec::make_uninitialized(4); if (wasm::own trap = run_func->call(args, results)) { std::cout << "> Error calling function! " << trap->message().get() << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/reflect.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/reflect.c index 15e0165d191..d4383185ff0 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/reflect.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/reflect.c @@ -90,7 +90,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("reflect.wasm", "r"); + FILE* file = fopen("reflect.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -118,7 +118,9 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - own wasm_instance_t* instance = wasm_instance_new(store, module, NULL, NULL); + wasm_extern_vec_t imports = WASM_EMPTY_VEC; + own wasm_instance_t* instance = + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/reflect.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/reflect.cc index 704ae478f13..9820d814383 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/reflect.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/reflect.cc @@ -101,7 +101,8 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - auto instance = wasm::Instance::make(store, module.get(), nullptr); + auto imports = wasm::vec::make(); + auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/serialize.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/serialize.c index 4522c00dff5..8ea1a379af6 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/serialize.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/serialize.c @@ -8,7 +8,9 @@ #define own // A function to be called from Wasm code. -own wasm_trap_t* hello_callback(const wasm_val_t args[], wasm_val_t results[]) { +own wasm_trap_t* hello_callback( + const wasm_val_vec_t* args, wasm_val_vec_t* results +) { printf("Calling back...\n"); printf("> Hello World!\n"); return NULL; @@ -23,7 +25,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("serialize.wasm", "r"); + FILE* file = fopen("serialize.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -76,9 +78,10 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating deserialized module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) }; + wasm_extern_t* externs[] = { wasm_func_as_extern(hello_func) }; + wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, deserialized, imports, NULL); + wasm_instance_new(store, deserialized, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -105,7 +108,8 @@ int main(int argc, const char* argv[]) { // Call. printf("Calling export...\n"); - if (wasm_func_call(run_func, NULL, NULL)) { + wasm_val_vec_t empty = WASM_EMPTY_VEC; + if (wasm_func_call(run_func, &empty, &empty)) { printf("> Error calling function!\n"); return 1; } diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/serialize.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/serialize.cc index 3a059b5a1fe..f63baebf89f 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/serialize.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/serialize.cc @@ -9,7 +9,7 @@ // A function to be called from Wasm code. auto hello_callback( - const wasm::Val args[], wasm::Val results[] + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> Hello world!" << std::endl; @@ -67,7 +67,7 @@ void run() { // Instantiate. std::cout << "Instantiating deserialized module..." << std::endl; - wasm::Extern* imports[] = {hello_func.get()}; + auto imports = wasm::vec::make(hello_func.get()); auto instance = wasm::Instance::make(store, deserialized.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; @@ -85,7 +85,9 @@ void run() { // Call. std::cout << "Calling export..." << std::endl; - if (run_func->call()) { + auto args = wasm::vec::make(); + auto results = wasm::vec::make(); + if (run_func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); } diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/start.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/start.c index 42fa317490b..f60c03c6468 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/start.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/start.c @@ -26,7 +26,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("start.wasm", "r"); + FILE* file = fopen("start.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -54,9 +54,10 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); + wasm_extern_vec_t imports = WASM_EMPTY_VEC; own wasm_trap_t* trap = NULL; own wasm_instance_t* instance = - wasm_instance_new(store, module, NULL, &trap); + wasm_instance_new(store, module, &imports, &trap); if (instance || !trap) { printf("> Error instantiating module, expected trap!\n"); return 1; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/start.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/start.cc index 71d6fd25add..1643b9f7727 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/start.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/start.cc @@ -47,7 +47,8 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; wasm::own trap; - auto instance = wasm::Instance::make(store, module.get(), nullptr, &trap); + auto imports = wasm::vec::make(); + auto instance = wasm::Instance::make(store, module.get(), imports, &trap); if (instance || !trap) { std::cout << "> Error instantiating module, expected trap!" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/table.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/table.c index 9b3beeb6328..5e91a34a45d 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/table.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/table.c @@ -9,11 +9,11 @@ // A function to be called from Wasm code. own wasm_trap_t* neg_callback( - const wasm_val_t args[], wasm_val_t results[] + const wasm_val_vec_t* args, wasm_val_vec_t* results ) { printf("Calling back...\n"); - results[0].kind = WASM_I32; - results[0].of.i32 = -args[0].of.i32; + results->data[0].kind = WASM_I32; + results->data[0].of.i32 = -args->data[0].of.i32; return NULL; } @@ -49,23 +49,22 @@ void check_table(wasm_table_t* table, int32_t i, bool expect_set) { } void check_call(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; - wasm_val_t results[1]; - if (wasm_func_call(func, args, results) || results[0].of.i32 != expected) { + wasm_val_t vs[2] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) }; + wasm_val_t r[1] = { WASM_INIT_VAL }; + wasm_val_vec_t args = WASM_ARRAY_VEC(vs); + wasm_val_vec_t results = WASM_ARRAY_VEC(r); + if (wasm_func_call(func, &args, &results) || r[0].of.i32 != expected) { printf("> Error on result\n"); exit(1); } } void check_trap(wasm_func_t* func, int32_t arg1, int32_t arg2) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; - own wasm_trap_t* trap = wasm_func_call(func, args, NULL); + wasm_val_t vs[2] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) }; + wasm_val_t r[1] = { WASM_INIT_VAL }; + wasm_val_vec_t args = WASM_ARRAY_VEC(vs); + wasm_val_vec_t results = WASM_ARRAY_VEC(r); + own wasm_trap_t* trap = wasm_func_call(func, &args, &results); if (! trap) { printf("> Error on result, expected trap\n"); exit(1); @@ -82,7 +81,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("table.wasm", "r"); + FILE* file = fopen("table.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -110,7 +109,9 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - own wasm_instance_t* instance = wasm_instance_new(store, module, NULL, NULL); + wasm_extern_vec_t imports = WASM_EMPTY_VEC; + own wasm_instance_t* instance = + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/table.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/table.cc index 6890ae7e26e..9ddf1d902bf 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/table.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/table.cc @@ -9,7 +9,7 @@ // A function to be called from Wasm code. auto neg_callback( - const wasm::Val args[], wasm::Val results[] + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; results[0] = wasm::Val(-args[0].i32()); @@ -51,8 +51,8 @@ void check(bool success) { auto call( const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2 ) -> wasm::Val { - wasm::Val args[2] = {std::move(arg1), std::move(arg2)}; - wasm::Val results[1]; + auto args = wasm::vec::make(std::move(arg1), std::move(arg2)); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error on result, expected return" << std::endl; exit(1); @@ -61,8 +61,8 @@ auto call( } void check_trap(const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2) { - wasm::Val args[2] = {std::move(arg1), std::move(arg2)}; - wasm::Val results[1]; + auto args = wasm::vec::make(std::move(arg1), std::move(arg2)); + auto results = wasm::vec::make_uninitialized(1); if (! func->call(args, results)) { std::cout << "> Error on result, expected trap" << std::endl; exit(1); @@ -100,7 +100,8 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - auto instance = wasm::Instance::make(store, module.get(), nullptr); + auto imports = wasm::vec::make(); + auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/threads.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/threads.c index 9f9d5894a66..d70bd1ae55c 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/threads.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/threads.c @@ -13,9 +13,9 @@ const int N_THREADS = 10; const int N_REPS = 3; // A function to be called from Wasm code. -own wasm_trap_t* callback(const wasm_val_t args[], wasm_val_t results[]) { - assert(args[0].kind == WASM_I32); - printf("> Thread %d running\n", args[0].of.i32); +own wasm_trap_t* callback(const wasm_val_vec_t* args, wasm_val_vec_t* results) { + assert(args->data[0].kind == WASM_I32); + printf("> Thread %d running\n", args->data[0].of.i32); return NULL; } @@ -42,18 +42,19 @@ void* run(void* args_abs) { own wasm_func_t* func = wasm_func_new(store, func_type, callback); wasm_functype_delete(func_type); - wasm_val_t val = {.kind = WASM_I32, .of = {.i32 = (int32_t)args->id}}; + wasm_val_t val = WASM_I32_VAL((int32_t)args->id); own wasm_globaltype_t* global_type = wasm_globaltype_new(wasm_valtype_new_i32(), WASM_CONST); own wasm_global_t* global = wasm_global_new(store, global_type, &val); wasm_globaltype_delete(global_type); // Instantiate. - const wasm_extern_t* imports[] = { + wasm_extern_t* externs[] = { wasm_func_as_extern(func), wasm_global_as_extern(global), }; + wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return NULL; @@ -78,7 +79,8 @@ void* run(void* args_abs) { wasm_instance_delete(instance); // Call. - if (wasm_func_call(run_func, NULL, NULL)) { + wasm_val_vec_t empty = WASM_EMPTY_VEC; + if (wasm_func_call(run_func, &empty, &empty)) { printf("> Error calling function!\n"); return NULL; } @@ -99,7 +101,7 @@ int main(int argc, const char *argv[]) { wasm_engine_t* engine = wasm_engine_new(); // Load binary. - FILE* file = fopen("threads.wasm", "r"); + FILE* file = fopen("threads.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/threads.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/threads.cc index 6148be655b3..e130717a0cf 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/threads.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/threads.cc @@ -10,7 +10,7 @@ const int N_REPS = 3; // A function to be called from Wasm code. auto callback( - void* env, const wasm::Val args[], wasm::Val results[] + void* env, const wasm::vec& args, wasm::vec& results ) -> wasm::own { assert(args[0].kind() == wasm::ValKind::I32); std::lock_guard lock(*reinterpret_cast(env)); @@ -53,7 +53,7 @@ void run( store, global_type.get(), wasm::Val::i32(i)); // Instantiate. - wasm::Extern* imports[] = {func.get(), global.get()}; + auto imports = wasm::vec::make(func.get(), global.get()); auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::lock_guard lock(*mutex); @@ -71,7 +71,8 @@ void run( auto run_func = exports[0]->func(); // Call. - run_func->call(); + auto empty = wasm::vec::make(); + run_func->call(empty, empty); } } diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/trap.c b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/trap.c index 975d6f8599f..1146f69e621 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/trap.c +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/trap.c @@ -9,11 +9,11 @@ // A function to be called from Wasm code. own wasm_trap_t* fail_callback( - void* env, const wasm_val_t args[], wasm_val_t results[] + void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results ) { printf("Calling back...\n"); own wasm_name_t message; - wasm_name_new_from_string(&message, "callback abort"); + wasm_name_new_from_string_nt(&message, "callback abort"); own wasm_trap_t* trap = wasm_trap_new((wasm_store_t*)env, &message); wasm_name_delete(&message); return trap; @@ -38,7 +38,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); - FILE* file = fopen("trap.wasm", "r"); + FILE* file = fopen("trap.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); return 1; @@ -75,9 +75,10 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(fail_func) }; + wasm_extern_t* externs[] = { wasm_func_as_extern(fail_func) }; + wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -106,7 +107,9 @@ int main(int argc, const char* argv[]) { } printf("Calling export %d...\n", i); - own wasm_trap_t* trap = wasm_func_call(func, NULL, NULL); + wasm_val_vec_t args = WASM_EMPTY_VEC; + wasm_val_vec_t results = WASM_EMPTY_VEC; + own wasm_trap_t* trap = wasm_func_call(func, &args, &results); if (!trap) { printf("> Error calling function, expected trap!\n"); return 1; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/trap.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/trap.cc index 9cfcf50168c..2e70c76dec6 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/example/trap.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/example/trap.cc @@ -8,11 +8,11 @@ // A function to be called from Wasm code. auto fail_callback( - void* env, const wasm::Val args[], wasm::Val results[] + void* env, const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; auto store = reinterpret_cast(env); - auto message = wasm::Name::make(std::string("callback abort")); + auto message = wasm::Name::make_nt(std::string("callback abort")); return wasm::Trap::make(store, message); } @@ -65,7 +65,7 @@ void run() { // Instantiate. std::cout << "Instantiating module..." << std::endl; - wasm::Extern* imports[] = {fail_func.get()}; + auto imports = wasm::vec::make(fail_func.get()); auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; @@ -85,7 +85,9 @@ void run() { // Call. for (size_t i = 0; i < 2; ++i) { std::cout << "Calling export " << i << "..." << std::endl; - auto trap = exports[i]->func()->call(); + auto args = wasm::vec::make(); + auto results = wasm::vec::make(); + auto trap = exports[i]->func()->call(args, results); if (!trap) { std::cout << "> Error calling function, expected trap!" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/include/wasm.h b/lib/c-api/tests/wasm_c_api/wasm-c-api/include/wasm.h index 46e75cacb5b..25e0453a3ab 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/include/wasm.h +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/include/wasm.h @@ -105,7 +105,13 @@ typedef wasm_byte_vec_t wasm_name_t; #define wasm_name_delete wasm_byte_vec_delete static inline void wasm_name_new_from_string( - own wasm_name_t* out, const char* s + own wasm_name_t* out, own const char* s +) { + wasm_name_new(out, strlen(s), s); +} + +static inline void wasm_name_new_from_string_nt( + own wasm_name_t* out, own const char* s ) { wasm_name_new(out, strlen(s) + 1, s); } @@ -408,9 +414,9 @@ WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const WASM_DECLARE_REF(func) typedef own wasm_trap_t* (*wasm_func_callback_t)( - const wasm_val_t args[], wasm_val_t results[]); + const wasm_val_vec_t* args, own wasm_val_vec_t* results); typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)( - void* env, const wasm_val_t args[], wasm_val_t results[]); + void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results); WASM_API_EXTERN own wasm_func_t* wasm_func_new( wasm_store_t*, const wasm_functype_t*, wasm_func_callback_t); @@ -423,7 +429,7 @@ WASM_API_EXTERN size_t wasm_func_param_arity(const wasm_func_t*); WASM_API_EXTERN size_t wasm_func_result_arity(const wasm_func_t*); WASM_API_EXTERN own wasm_trap_t* wasm_func_call( - const wasm_func_t*, const wasm_val_t args[], wasm_val_t results[]); + const wasm_func_t*, const wasm_val_vec_t* args, wasm_val_vec_t* results); // Global Instances @@ -510,7 +516,7 @@ WASM_API_EXTERN const wasm_memory_t* wasm_extern_as_memory_const(const wasm_exte WASM_DECLARE_REF(instance) WASM_API_EXTERN own wasm_instance_t* wasm_instance_new( - wasm_store_t*, const wasm_module_t*, const wasm_extern_t* const imports[], + wasm_store_t*, const wasm_module_t*, const wasm_extern_vec_t* imports, own wasm_trap_t** ); @@ -520,6 +526,12 @@ WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_exte /////////////////////////////////////////////////////////////////////////////// // Convenience +// Vectors + +#define WASM_EMPTY_VEC {0, NULL} +#define WASM_ARRAY_VEC(array) {sizeof(array)/sizeof(*(array)), array} + + // Value Type construction short-hands static inline own wasm_valtype_t* wasm_valtype_new_i32() { @@ -692,6 +704,13 @@ static inline void* wasm_val_ptr(const wasm_val_t* val) { #endif } +#define WASM_I32_VAL(i) {.kind = WASM_I32, .of = {.i32 = i}} +#define WASM_I64_VAL(i) {.kind = WASM_I64, .of = {.i64 = i}} +#define WASM_F32_VAL(z) {.kind = WASM_F32, .of = {.f32 = z}} +#define WASM_F64_VAL(z) {.kind = WASM_F64, .of = {.f64 = z}} +#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .of = {.ref = r}} +#define WASM_INIT_VAL {.kind = WASM_ANYREF, .of = {.ref = NULL}} + /////////////////////////////////////////////////////////////////////////////// diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/include/wasm.hh b/lib/c-api/tests/wasm_c_api/wasm-c-api/include/wasm.hh index 29b3798e35c..597c10f4d8c 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/include/wasm.hh +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/include/wasm.hh @@ -146,6 +146,12 @@ public: } static auto make(std::string s) -> vec { + auto v = vec(s.length()); + if (v) std::strncpy(v.get(), s.data(), s.length()); + return v; + } + + static auto make_nt(std::string s) -> vec { auto v = vec(s.length() + 1); if (v) std::strcpy(v.get(), s.data()); return v; @@ -431,11 +437,11 @@ class Val { public: Val() : kind_(ValKind::ANYREF) { impl_.ref = nullptr; } - Val(int32_t i) : kind_(ValKind::I32) { impl_.i32 = i; } - Val(int64_t i) : kind_(ValKind::I64) { impl_.i64 = i; } - Val(float32_t z) : kind_(ValKind::F32) { impl_.f32 = z; } - Val(float64_t z) : kind_(ValKind::F64) { impl_.f64 = z; } - Val(own&& r) : kind_(ValKind::ANYREF) { impl_.ref = r.release(); } + explicit Val(int32_t i) : kind_(ValKind::I32) { impl_.i32 = i; } + explicit Val(int64_t i) : kind_(ValKind::I64) { impl_.i64 = i; } + explicit Val(float32_t z) : kind_(ValKind::F32) { impl_.f32 = z; } + explicit Val(float64_t z) : kind_(ValKind::F64) { impl_.f64 = z; } + explicit Val(own&& r) : kind_(ValKind::ANYREF) { impl_.ref = r.release(); } Val(Val&& that) : kind_(that.kind_), impl_(that.impl_) { if (is_ref()) that.impl_.ref = nullptr; @@ -648,8 +654,8 @@ public: Func() = delete; ~Func(); - using callback = auto (*)(const Val[], Val[]) -> own; - using callback_with_env = auto (*)(void*, const Val[], Val[]) -> own; + using callback = auto (*)(const vec&, vec&) -> own; + using callback_with_env = auto (*)(void*, const vec&, vec&) -> own; static auto make(Store*, const FuncType*, callback) -> own; static auto make(Store*, const FuncType*, callback_with_env, @@ -660,7 +666,7 @@ public: auto param_arity() const -> size_t; auto result_arity() const -> size_t; - auto call(const Val[] = nullptr, Val[] = nullptr) const -> own; + auto call(const vec&, vec&) const -> own; }; @@ -731,7 +737,7 @@ public: ~Instance(); static auto make( - Store*, const Module*, const Extern* const[], own* = nullptr + Store*, const Module*, const vec&, own* = nullptr ) -> own; auto copy() const -> own; diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/src/wasm-c.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/src/wasm-c.cc index 982cc8071cc..b4316116148 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/src/wasm-c.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/src/wasm-c.cc @@ -60,7 +60,7 @@ struct borrowed_vec { // Vectors -#define WASM_DEFINE_VEC_BASE(name, Name, vec, ptr_or_none) \ +#define WASM_DEFINE_VEC_BASE(name, Name, vec, plainvec, ptr_or_none) \ static_assert( \ sizeof(wasm_##name##_vec_t) == sizeof(vec), \ "C/C++ incompatibility" \ @@ -86,6 +86,14 @@ struct borrowed_vec { -> wasm_##name##_t ptr_or_none const* { \ return reinterpret_cast(v); \ } \ + extern "C++" inline auto reveal_##name##_vec(wasm_##name##_vec_t* v) \ + -> plainvec* { \ + return reinterpret_cast*>(v); \ + } \ + extern "C++" inline auto reveal_##name##_vec(const wasm_##name##_vec_t* v) \ + -> const plainvec* { \ + return reinterpret_cast*>(v); \ + } \ extern "C++" inline auto reveal_##name##_vec(wasm_##name##_t ptr_or_none* v) \ -> vec::elem_type* { \ return reinterpret_cast::elem_type*>(v); \ @@ -134,7 +142,7 @@ struct borrowed_vec { // Vectors with no ownership management of elements #define WASM_DEFINE_VEC_PLAIN(name, Name) \ - WASM_DEFINE_VEC_BASE(name, Name, vec, ) \ + WASM_DEFINE_VEC_BASE(name, Name, vec, vec, ) \ \ void wasm_##name##_vec_new( \ wasm_##name##_vec_t* out, \ @@ -156,7 +164,7 @@ struct borrowed_vec { // Vectors that own their elements #define WASM_DEFINE_VEC_OWN(name, Name) \ - WASM_DEFINE_VEC_BASE(name, Name, ownvec, *) \ + WASM_DEFINE_VEC_BASE(name, Name, ownvec, vec, *) \ \ void wasm_##name##_vec_new( \ wasm_##name##_vec_t* out, \ @@ -620,7 +628,7 @@ inline auto borrow_val(const wasm_val_t* v) -> borrowed_val { } // extern "C++" -WASM_DEFINE_VEC_BASE(val, Val, vec, ) +WASM_DEFINE_VEC_BASE(val, Val, vec, vec, ) void wasm_val_vec_new( wasm_val_vec_t* out, size_t size, wasm_val_t const data[] @@ -771,7 +779,9 @@ WASM_DEFINE_REF(func, Func) extern "C++" { -auto wasm_callback(void* env, const Val args[], Val results[]) -> own { +auto wasm_callback( + void* env, const vec& args, vec& results +) -> own { auto f = reinterpret_cast(env); return adopt_trap(f(hide_val_vec(args), hide_val_vec(results))); } @@ -783,7 +793,7 @@ struct wasm_callback_env_t { }; auto wasm_callback_with_env( - void* env, const Val args[], Val results[] + void* env, const vec& args, vec& results ) -> own { auto t = static_cast(env); return adopt_trap(t->callback(t->env, hide_val_vec(args), hide_val_vec(results))); @@ -826,9 +836,11 @@ size_t wasm_func_result_arity(const wasm_func_t* func) { } wasm_trap_t* wasm_func_call( - const wasm_func_t* func, const wasm_val_t args[], wasm_val_t results[] + const wasm_func_t* func, const wasm_val_vec_t* args, wasm_val_vec_t* results ) { - return release_trap(func->call(reveal_val_vec(args), reveal_val_vec(results))); + auto args_ = borrow_val_vec(args); + auto results_ = borrow_val_vec(results); + return release_trap(func->call(args_.it, results_.it)); } @@ -995,12 +1007,13 @@ WASM_DEFINE_REF(instance, Instance) wasm_instance_t* wasm_instance_new( wasm_store_t* store, const wasm_module_t* module, - const wasm_extern_t* const imports[], + const wasm_extern_vec_t* imports, wasm_trap_t** trap ) { own error; - auto instance = release_instance(Instance::make(store, module, - reinterpret_cast(imports), &error)); + auto imports_ = reveal_extern_vec(imports); + auto instance = + release_instance(Instance::make(store, module, *imports_, &error)); if (trap) *trap = hide_trap(error.release()); return instance; } diff --git a/lib/c-api/tests/wasm_c_api/wasm-c-api/src/wasm-v8.cc b/lib/c-api/tests/wasm_c_api/wasm-c-api/src/wasm-v8.cc index 75b9e6644ba..b58aaf40eea 100644 --- a/lib/c-api/tests/wasm_c_api/wasm-c-api/src/wasm-v8.cc +++ b/lib/c-api/tests/wasm_c_api/wasm-c-api/src/wasm-v8.cc @@ -229,6 +229,7 @@ DEFINE_VEC(Global, ownvec, GLOBAL) DEFINE_VEC(Table, ownvec, TABLE) DEFINE_VEC(Memory, ownvec, MEMORY) DEFINE_VEC(Extern, ownvec, EXTERN) +DEFINE_VEC(Extern*, vec, EXTERN) DEFINE_VEC(Val, vec, VAL) #endif // #ifdef WASM_API_DEBUG @@ -1257,7 +1258,7 @@ auto Trap::message() const -> Message { auto message = v8::Exception::CreateMessage(isolate, impl(this)->v8_object()); v8::String::Utf8Value string(isolate, message->Get()); - return vec::make(std::string(*string)); + return vec::make_nt(std::string(*string)); } auto Trap::origin() const -> own { @@ -1687,7 +1688,7 @@ auto Func::result_arity() const -> size_t { return wasm_v8::func_type_result_arity(impl(this)->v8_object()); } -auto Func::call(const Val args[], Val results[]) const -> own { +auto Func::call(const vec& args, vec& results) const -> own { auto func = impl(this); auto store = func->store(); auto isolate = store->isolate(); @@ -1754,17 +1755,17 @@ void FuncData::v8_callback(const v8::FunctionCallbackInfo& info) { assert(param_types.size() == info.Length()); // TODO: cache params and result arrays per thread. - auto args = std::unique_ptr(new Val[param_types.size()]); - auto results = std::unique_ptr(new Val[result_types.size()]); + auto args = vec::make_uninitialized(param_types.size()); + auto results = vec::make_uninitialized(result_types.size()); for (size_t i = 0; i < param_types.size(); ++i) { args[i] = v8_to_val(store, info[i], param_types[i].get()); } own trap; if (self->kind == CALLBACK_WITH_ENV) { - trap = self->callback_with_env(self->env, args.get(), results.get()); + trap = self->callback_with_env(self->env, args, results); } else { - trap = self->callback(args.get(), results.get()); + trap = self->callback(args, results); } if (trap) { @@ -2019,7 +2020,7 @@ auto Instance::copy() const -> own { } auto Instance::make( - Store* store_abs, const Module* module_abs, const Extern* const imports[], + Store* store_abs, const Module* module_abs, const vec& imports, own* trap ) -> own { auto store = impl(store_abs); From 8b38dd575e01dfd288d1d73e2e60459a889efc79 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 11:22:54 +0200 Subject: [PATCH 02/25] feat(c-api) Implement `wasm_val_vec_t`. --- lib/c-api/src/wasm_c_api/value.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/c-api/src/wasm_c_api/value.rs b/lib/c-api/src/wasm_c_api/value.rs index cb427e78d06..5ae7c449f5d 100644 --- a/lib/c-api/src/wasm_c_api/value.rs +++ b/lib/c-api/src/wasm_c_api/value.rs @@ -23,6 +23,8 @@ pub struct wasm_val_t { pub of: wasm_val_inner, } +wasm_declare_vec!(val); + impl Clone for wasm_val_t { fn clone(&self) -> Self { wasm_val_t { From d8dcb4133a579cdcd35bf8ada9c6dbd4cc6ef409 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 11:23:52 +0200 Subject: [PATCH 03/25] feat(c-api) Update the definitions of `wasm_func_callback*_t`. --- lib/c-api/src/wasm_c_api/externals/function.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index b64f52d87bf..7a95088c58f 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -1,7 +1,7 @@ use super::super::store::wasm_store_t; use super::super::trap::wasm_trap_t; use super::super::types::{wasm_functype_t, wasm_valkind_enum}; -use super::super::value::{wasm_val_inner, wasm_val_t}; +use super::super::value::{wasm_val_inner, wasm_val_t, wasm_val_vec_t}; use std::convert::TryInto; use std::ffi::c_void; use std::sync::Arc; @@ -15,14 +15,16 @@ pub struct wasm_func_t { } #[allow(non_camel_case_types)] -pub type wasm_func_callback_t = - unsafe extern "C" fn(args: *const wasm_val_t, results: *mut wasm_val_t) -> *mut wasm_trap_t; +pub type wasm_func_callback_t = unsafe extern "C" fn( + args: *const wasm_val_vec_t, + results: *mut wasm_val_vec_t, +) -> *mut wasm_trap_t; #[allow(non_camel_case_types)] pub type wasm_func_callback_with_env_t = unsafe extern "C" fn( *mut c_void, - args: *const wasm_val_t, - results: *mut wasm_val_t, + args: *const wasm_val_vec_t, + results: *mut wasm_val_vec_t, ) -> *mut wasm_trap_t; #[allow(non_camel_case_types)] From 5dffd976f5fc770df3aae84dbdea30ace951a452 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 11:24:30 +0200 Subject: [PATCH 04/25] feat(c-api) Update `wasm_func_new`. --- lib/c-api/src/wasm_c_api/externals/function.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index 7a95088c58f..015d38edcc2 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -40,31 +40,37 @@ pub unsafe extern "C" fn wasm_func_new( let func_sig = ft.sig(); let num_rets = func_sig.results().len(); let inner_callback = move |args: &[Val]| -> Result, RuntimeError> { - let processed_args = args + let processed_args: wasm_val_vec_t = args .into_iter() .map(TryInto::try_into) .collect::, _>>() - .expect("Argument conversion failed"); + .expect("Argument conversion failed") + .into(); - let mut results = vec![ + let mut results: wasm_val_vec_t = vec![ wasm_val_t { kind: wasm_valkind_enum::WASM_I64 as _, of: wasm_val_inner { int64_t: 0 }, }; num_rets - ]; + ] + .into(); + + let trap = callback(&processed_args, &mut results); - let trap = callback(processed_args.as_ptr(), results.as_mut_ptr()); if !trap.is_null() { let trap: Box = Box::from_raw(trap); RuntimeError::raise(Box::new(trap.inner)); } let processed_results = results + .into_slice() + .expect("Failed to convert `results` into a slice") .into_iter() .map(TryInto::try_into) .collect::, _>>() .expect("Result conversion failed"); + Ok(processed_results) }; let function = Function::new(&store.inner, &func_sig, inner_callback); From 7f098387e8174595e568ba13db6861a1790e978d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 11:24:59 +0200 Subject: [PATCH 05/25] faet(c-api) Update `wasm_func_new_with_env`. --- lib/c-api/src/wasm_c_api/externals/function.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index 015d38edcc2..74633f31669 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -94,30 +94,36 @@ pub unsafe extern "C" fn wasm_func_new_with_env( let num_rets = func_sig.results().len(); let inner_callback = move |env: &mut *mut c_void, args: &[Val]| -> Result, RuntimeError> { - let processed_args = args + let processed_args: wasm_val_vec_t = args .into_iter() .map(TryInto::try_into) .collect::, _>>() - .expect("Argument conversion failed"); + .expect("Argument conversion failed") + .into(); - let mut results = vec![ + let mut results: wasm_val_vec_t = vec![ wasm_val_t { kind: wasm_valkind_enum::WASM_I64 as _, of: wasm_val_inner { int64_t: 0 }, }; num_rets - ]; + ] + .into(); - let _traps = callback(*env, processed_args.as_ptr(), results.as_mut_ptr()); + let _traps = callback(*env, &processed_args, &mut results); // TODO: do something with `traps` let processed_results = results + .into_slice() + .expect("Failed to convert `results` into a slice") .into_iter() .map(TryInto::try_into) .collect::, _>>() .expect("Result conversion failed"); + Ok(processed_results) }; + let function = Function::new_with_env(&store.inner, &func_sig, env, inner_callback); Some(Box::new(wasm_func_t { From e9cd7105066679eea6969f32a5eb0efa0ed9674a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 11:25:17 +0200 Subject: [PATCH 06/25] feat(c-api) Update `wasm_func_call`. --- .../src/wasm_c_api/externals/function.rs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index 74633f31669..9fddd29f20e 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -138,21 +138,25 @@ pub unsafe extern "C" fn wasm_func_delete(_func: Option>) {} #[no_mangle] pub unsafe extern "C" fn wasm_func_call( func: &wasm_func_t, - args: *const wasm_val_t, - results: *mut wasm_val_t, + args: &wasm_val_vec_t, + results: &mut wasm_val_vec_t, ) -> Option> { - let num_params = func.inner.ty().params().len(); - let params: Vec = (0..num_params) - .map(|i| (&(*args.add(i))).try_into()) - .collect::>() - .ok()?; + let params = args + .into_slice()? + .into_iter() + .map(TryInto::try_into) + .collect::, _>>() + .expect("Argument conversion failed"); match func.inner.call(¶ms) { Ok(wasm_results) => { - for (i, actual_result) in wasm_results.iter().enumerate() { - let result_loc = &mut (*results.add(i)); - *result_loc = (&*actual_result).try_into().ok()?; - } + *results = wasm_results + .into_iter() + .map(TryInto::try_into) + .collect::, _>>() + .expect("Argument conversion failed") + .into(); + None } Err(e) => Some(Box::new(e.into())), From fa7fe83bc0b19a43138454df0d716e4e2e2b774a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 11:45:31 +0200 Subject: [PATCH 07/25] feat(c-api) Update `wasm_instance_new`. The `CArrayIter` type is no longer needed. This patch removes it. --- lib/c-api/src/wasm_c_api/instance.rs | 43 +++------------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/instance.rs b/lib/c-api/src/wasm_c_api/instance.rs index a79044a4ebf..3b16e1eeffa 100644 --- a/lib/c-api/src/wasm_c_api/instance.rs +++ b/lib/c-api/src/wasm_c_api/instance.rs @@ -12,56 +12,21 @@ pub struct wasm_instance_t { pub(crate) inner: Arc, } -struct CArrayIter { - cur_entry: *const *const T, -} - -impl CArrayIter { - fn new(array: *const *const T) -> Option { - if array.is_null() { - None - } else { - Some(CArrayIter { cur_entry: array }) - } - } -} - -impl Iterator for CArrayIter { - type Item = &'static T; - - fn next(&mut self) -> Option { - let next_entry_candidate = unsafe { *self.cur_entry }; - if next_entry_candidate.is_null() { - None - } else { - self.cur_entry = unsafe { self.cur_entry.add(1) }; - Some(unsafe { &*next_entry_candidate }) - } - } -} - -// reads from null-terminated array of `wasm_extern_t`s -unsafe fn argument_import_iter( - imports: *const *const wasm_extern_t, -) -> Box> { - CArrayIter::new(imports) - .map(|it| Box::new(it) as _) - .unwrap_or_else(|| Box::new(std::iter::empty()) as _) -} - #[no_mangle] pub unsafe extern "C" fn wasm_instance_new( _store: &wasm_store_t, module: &wasm_module_t, - imports: *const *const wasm_extern_t, + imports: &wasm_extern_vec_t, // own _traps: *mut *mut wasm_trap_t, ) -> Option> { let wasm_module = &module.inner; let module_imports = wasm_module.imports(); let module_import_count = module_imports.len(); - let imports = argument_import_iter(imports); let resolver: OrderedResolver = imports + .into_slice() + .map(|imports| imports.iter()) + .unwrap_or_else(|| [].iter()) .map(|imp| &imp.inner) .take(module_import_count) .cloned() From fea156defa4fcffc60d1a808b51f8942eef9f38f Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 11:58:53 +0200 Subject: [PATCH 08/25] =?UTF-8?q?feat(c-api)=20Update=20`wasi=5Fget=5Fimpo?= =?UTF-8?q?rts`=20to=20use=20a=20`wasm=5Fextern=5Fvec=5Ft`=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … so that it matches the definition of `wasm_instance_new`, which is much simpler and consistent. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 44 ++++++++++++++++------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/wasi/mod.rs b/lib/c-api/src/wasm_c_api/wasi/mod.rs index cf0a08b73d4..2db9204d05b 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -5,7 +5,7 @@ mod capture_files; use super::{ - externals::{wasm_extern_t, wasm_func_t, wasm_memory_t}, + externals::{wasm_extern_t, wasm_extern_vec_t, wasm_func_t, wasm_memory_t}, instance::wasm_instance_t, module::wasm_module_t, store::wasm_store_t, @@ -243,7 +243,7 @@ pub unsafe extern "C" fn wasi_get_imports( store: &wasm_store_t, module: &wasm_module_t, wasi_env: &wasi_env_t, - imports: *mut *mut wasm_extern_t, + imports: &mut wasm_extern_vec_t, ) -> bool { wasi_get_imports_inner(store, module, wasi_env, imports).is_some() } @@ -253,7 +253,7 @@ unsafe fn wasi_get_imports_inner( store: &wasm_store_t, module: &wasm_module_t, wasi_env: &wasi_env_t, - imports: *mut *mut wasm_extern_t, + imports: &mut wasm_extern_vec_t, ) -> Option<()> { let store = &store.inner; @@ -265,22 +265,28 @@ unsafe fn wasi_get_imports_inner( let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version); - for (i, it) in module.inner.imports().enumerate() { - let export = c_try!(import_object - .resolve_by_name(it.module(), it.name()) - .ok_or_else(|| CApiError { - msg: format!( - "Failed to resolve import \"{}\" \"{}\"", - it.module(), - it.name() - ), - })); - let inner = Extern::from_export(store, export); - *imports.add(i) = Box::into_raw(Box::new(wasm_extern_t { - instance: None, - inner, - })); - } + *imports = module + .inner + .imports() + .map(|import_type| { + let export = c_try!(import_object + .resolve_by_name(import_type.module(), import_type.name()) + .ok_or_else(|| CApiError { + msg: format!( + "Failed to resolve import \"{}\" \"{}\"", + import_type.module(), + import_type.name() + ), + })); + let inner = Extern::from_export(store, export); + + Some(Box::new(wasm_extern_t { + instance: None, + inner, + })) + }) + .collect::>>()? + .into(); Some(()) } From 202ffe7771cbea376bd238d5108e34de328a4735 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 12:20:29 +0200 Subject: [PATCH 09/25] fix(c-api) Fix `wasm_func_call` when params are empty. `wasm_$name_vec_t.into_slice` returns `None` if the vec is empty. So an empty vec of `wasm_extern_t` given to `wasm_func_call` was raising an error. This patch fixes this. --- lib/c-api/src/wasm_c_api/externals/function.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index 9fddd29f20e..0b9ae3ff407 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -142,11 +142,15 @@ pub unsafe extern "C" fn wasm_func_call( results: &mut wasm_val_vec_t, ) -> Option> { let params = args - .into_slice()? - .into_iter() - .map(TryInto::try_into) - .collect::, _>>() - .expect("Argument conversion failed"); + .into_slice() + .map(|slice| { + slice + .into_iter() + .map(TryInto::try_into) + .collect::, _>>() + .expect("Argument conversion failed") + }) + .unwrap_or_else(|| Vec::new()); match func.inner.call(¶ms) { Ok(wasm_results) => { From 4584a5384054fd2f6f85f40e1f7f5365f3461973 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 13:12:37 +0200 Subject: [PATCH 10/25] fix(c-api) Remove `rustc` warnings. --- lib/c-api/src/wasm_c_api/engine.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index 72aacf2c548..1a72355eb2e 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -87,6 +87,7 @@ pub extern "C" fn wasm_config_set_engine(config: &mut wasm_config_t, engine: was } /// cbindgen:ignore +#[allow(non_camel_case_types)] pub struct wasm_engine_t { pub(crate) inner: Arc, } @@ -170,6 +171,7 @@ pub extern "C" fn wasm_engine_new_with_config( // TODO: return useful error messages in failure branches cfg_if! { if #[cfg(feature = "compiler")] { + #[allow(unused_mut)] let mut compiler_config: Box = match config.compiler { wasmer_compiler_t::CRANELIFT => { cfg_if! { From 5bf90558c7a59594ceb483ba4f25bfd6aae1bd82 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 13:17:40 +0200 Subject: [PATCH 11/25] test(c-api) Fix the `early-exit` test. --- lib/c-api/tests/wasm_c_api/test-early-exit.c | 25 ++++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/c-api/tests/wasm_c_api/test-early-exit.c b/lib/c-api/tests/wasm_c_api/test-early-exit.c index bbc70af7dc6..d98b5417c48 100644 --- a/lib/c-api/tests/wasm_c_api/test-early-exit.c +++ b/lib/c-api/tests/wasm_c_api/test-early-exit.c @@ -27,9 +27,9 @@ void print_frame(wasm_frame_t* frame) { wasm_store_t *store = NULL; -own wasm_trap_t *early_exit(const wasm_val_t args[], wasm_val_t results[]) { +own wasm_trap_t* early_exit(const wasm_val_vec_t* args, wasm_val_vec_t* results) { own wasm_message_t trap_message; - wasm_name_new_from_string(&trap_message, "trapping from a host import"); + wasm_name_new_from_string_nt(&trap_message, "trapping from a host import"); own wasm_trap_t *trap = wasm_trap_new(store, &trap_message); wasm_name_delete(&trap_message); return trap; @@ -77,9 +77,13 @@ int main(int argc, const char *argv[]) { wasm_functype_delete(host_func_type); - const wasm_extern_t *imports[] = {wasm_func_as_extern(host_func)}; + wasm_extern_vec_t imports; + wasm_extern_vec_new_uninitialized(&imports, 1); + imports.data[0] = wasm_func_as_extern(host_func); + own wasm_instance_t *instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, &imports, NULL); + if (!instance) { printf("> Error instantiating module!\n"); print_wasmer_error(); @@ -110,12 +114,12 @@ int main(int argc, const char *argv[]) { // Call. printf("Calling export...\n"); - own const wasm_val_t args[] = { - {.kind = WASM_I32, .of = {.i32 = 1}}, - {.kind = WASM_I32, .of = {.i32 = 7}}, - }; - own wasm_val_t rets[1] = {}; - own wasm_trap_t *trap = wasm_func_call(run_func, args, rets); + wasm_val_t values[2] = { WASM_I32_VAL(1), WASM_I32_VAL(7) }; + own wasm_val_vec_t args = WASM_ARRAY_VEC(values); + wasm_val_t result = WASM_INIT_VAL; + own wasm_val_vec_t rets = { 1, &result }; + own wasm_trap_t *trap = wasm_func_call(run_func, &args, &rets); + if (!trap) { printf("> Error calling function: expected trap!\n"); return 1; @@ -151,6 +155,7 @@ int main(int argc, const char *argv[]) { wasm_name_delete(&message); wasm_extern_vec_delete(&exports); + wasm_extern_vec_delete(&imports); // Shut down. printf("Shutting down...\n"); From 4186d1ce58f9811732d059b47d22134df88bb75e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 13:33:46 +0200 Subject: [PATCH 12/25] test(c-api) Use `wasm_extern_vec_t` for `wasm_get_imports`. --- lib/c-api/tests/wasm_c_api/test-wasi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/c-api/tests/wasm_c_api/test-wasi.c b/lib/c-api/tests/wasm_c_api/test-wasi.c index 81c22fd92dc..2a21cdec9bf 100644 --- a/lib/c-api/tests/wasm_c_api/test-wasi.c +++ b/lib/c-api/tests/wasm_c_api/test-wasi.c @@ -18,7 +18,6 @@ void print_wasmer_error() printf("Error str: `%s`\n", error_str); } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -71,18 +70,22 @@ int main(int argc, const char* argv[]) { printf("Instantiating module...\n"); wasm_importtype_vec_t import_types; wasm_module_imports(module, &import_types); - int num_imports = import_types.size; - wasm_extern_t** imports = malloc(num_imports * sizeof(wasm_extern_t*)); + + wasm_extern_vec_t imports; + wasm_extern_vec_new_uninitialized(&imports, import_types.size); wasm_importtype_vec_delete(&import_types); - bool get_imports_result = wasi_get_imports(store, module, wasi_env, imports); + bool get_imports_result = wasi_get_imports(store, module, wasi_env, &imports); + if (!get_imports_result) { printf("> Error getting WASI imports!\n"); print_wasmer_error(); return 1; } + own wasm_instance_t* instance = - wasm_instance_new(store, module, (const wasm_extern_t *const *) imports, NULL); + wasm_instance_new(store, module, &imports, NULL); + if (!instance) { printf("> Error instantiating module!\n"); print_wasmer_error(); From 0b4ef7add7821d29ff31cdafb01e48b3009dbdbf Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 13:34:20 +0200 Subject: [PATCH 13/25] test(c-api) Don't pass `NULL` for zero args/results to `wasm_func_call`! We must pass an empty array. --- lib/c-api/tests/wasm_c_api/test-wasi.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/c-api/tests/wasm_c_api/test-wasi.c b/lib/c-api/tests/wasm_c_api/test-wasi.c index 2a21cdec9bf..1c7c244db91 100644 --- a/lib/c-api/tests/wasm_c_api/test-wasi.c +++ b/lib/c-api/tests/wasm_c_api/test-wasi.c @@ -117,7 +117,11 @@ int main(int argc, const char* argv[]) { // Call. printf("Calling export...\n"); printf("Evaluating \"%s\"\n", js_string); - if (wasm_func_call(run_func, NULL, NULL)) { + + wasm_val_vec_t args = WASM_EMPTY_VEC; + wasm_val_vec_t res = WASM_EMPTY_VEC; + + if (wasm_func_call(run_func, &args, &res)) { printf("> Error calling function!\n"); return 1; } @@ -134,12 +138,7 @@ int main(int argc, const char* argv[]) { printf("\n"); wasm_extern_vec_delete(&exports); - - // NEEDS REVIEW: - for(int i = 0; i < num_imports; ++i) { - wasm_extern_delete(imports[i]); - } - free(imports); + wasm_extern_vec_delete(&imports); // Shut down. printf("Shutting down...\n"); From 437426d8b18e3c9e4db1eb5fb61c7063fb01ef84 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 13:34:55 +0200 Subject: [PATCH 14/25] feat(c-api) Update `wasmer_wasm.h`. --- lib/c-api/wasmer_wasm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index b9eea99ae71..bdd06f88b32 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -139,7 +139,7 @@ void wasi_env_set_memory(wasi_env_t *env, const wasm_memory_t *memory); bool wasi_get_imports(const wasm_store_t *store, const wasm_module_t *module, const wasi_env_t *wasi_env, - wasm_extern_t **imports); + wasm_extern_vec_t *imports); #endif #if defined(WASMER_WASI_ENABLED) From 202301616f8f6de300982e1861907c9bef869ef2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 13:37:45 +0200 Subject: [PATCH 15/25] doc(changelog) Add #1699. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41c7a1d46ed..50a98db4011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## **[Unreleased]** +- [#1699](https://github.com/wasmerio/wasmer/pull/1699) Update `wasm.h` to its latest version. - [#1700](https://github.com/wasmerio/wasmer/pull/1700) Implement `wasm_externtype_copy` in the Wasm C API. ## 1.0.0-alpha4 - 2020-10-08 From 44632946c1f57b8f6f6fca041992fe096b0c2663 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 12 Oct 2020 13:49:02 +0200 Subject: [PATCH 16/25] doc(changelog) Add #1685. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50a98db4011..4de1ec274b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## **[Unreleased]** - [#1699](https://github.com/wasmerio/wasmer/pull/1699) Update `wasm.h` to its latest version. +- [#1685](https://github.com/wasmerio/wasmer/pull/1685) Implement `wasm_exporttype_delete` in the Wasm C API. - [#1700](https://github.com/wasmerio/wasmer/pull/1700) Implement `wasm_externtype_copy` in the Wasm C API. ## 1.0.0-alpha4 - 2020-10-08 From e29ea25dcd612e2660ce0a86d0ac5a418d86874c Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 10:17:23 +0200 Subject: [PATCH 17/25] feat(c-api) Simplify code with `unwrap_or_default`. --- lib/c-api/src/wasm_c_api/externals/function.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index 0b9ae3ff407..33505f7d445 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -150,7 +150,7 @@ pub unsafe extern "C" fn wasm_func_call( .collect::, _>>() .expect("Argument conversion failed") }) - .unwrap_or_else(|| Vec::new()); + .unwrap_or_default(); match func.inner.call(¶ms) { Ok(wasm_results) => { From ddf2459632b70a25ba22d40a1401c3fcb482326e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 10:19:26 +0200 Subject: [PATCH 18/25] chore(changelog) Fix merge. --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fda20f52b64..40a4ce36bfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,10 @@ ## **[Unreleased]** -- [#1699](https://github.com/wasmerio/wasmer/pull/1699) Update `wasm.h` to its latest version. -- [#1685](https://github.com/wasmerio/wasmer/pull/1685) Implement `wasm_exporttype_delete` in the Wasm C API. ### Added +- [#1699](https://github.com/wasmerio/wasmer/pull/1699) Update `wasm.h` to its latest version. +- [#1685](https://github.com/wasmerio/wasmer/pull/1685) Implement `wasm_exporttype_delete` in the Wasm C API. - [#1715](https://github.com/wasmerio/wasmer/pull/1715) Register errors from `wasm_module_serialize` in the Wasm C API. - [#1709](https://github.com/wasmerio/wasmer/pull/1709) Implement `wasm_module_name` and `wasm_module_set_name` in the Wasm(er) C API. - [#1700](https://github.com/wasmerio/wasmer/pull/1700) Implement `wasm_externtype_copy` in the Wasm C API. From 4f9932c3508d6ead9f2ef2b1ca6ce89017acfba9 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 10:46:28 +0200 Subject: [PATCH 19/25] feat(cli) Update the `crate_exe_main.c` file to the latest Wasm C API. --- lib/cli/src/commands/wasmer_create_exe_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/cli/src/commands/wasmer_create_exe_main.c b/lib/cli/src/commands/wasmer_create_exe_main.c index 11adb1656a8..27df043245e 100644 --- a/lib/cli/src/commands/wasmer_create_exe_main.c +++ b/lib/cli/src/commands/wasmer_create_exe_main.c @@ -134,20 +134,22 @@ int main(int argc, char* argv[]) { wasm_importtype_vec_t import_types; wasm_module_imports(module, &import_types); - int num_imports = import_types.size; - wasm_extern_t** imports = (wasm_extern_t**) malloc(num_imports * sizeof(wasm_extern_t*)); + + wasm_extern_vec_new_uninitialized(&imports, import_type.size); wasm_importtype_vec_delete(&import_types); #ifdef WASI - bool get_imports_result = wasi_get_imports(store, module, wasi_env, imports); + bool get_imports_result = wasi_get_imports(store, module, wasi_env, &imports); + if (!get_imports_result) { fprintf(stderr, "Error getting WASI imports!\n"); print_wasmer_error(); + return 1; } #endif - wasm_instance_t* instance = wasm_instance_new(store, module, (const wasm_extern_t* const*) imports, NULL); + wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL); if (! instance) { fprintf(stderr, "Failed to create instance\n"); print_wasmer_error(); From 5601ecb07d3cb44e508cd300dea3517801f57cec Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 10:50:18 +0200 Subject: [PATCH 20/25] test(integration) Add `-x c` to force `clang++` to treat code as C. --- tests/integration/cli/tests/compile.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/integration/cli/tests/compile.rs b/tests/integration/cli/tests/compile.rs index 71fa6bd58c9..319af0bc95c 100644 --- a/tests/integration/cli/tests/compile.rs +++ b/tests/integration/cli/tests/compile.rs @@ -92,6 +92,8 @@ fn run_c_compile( let output = Command::new(c_compiler) .current_dir(current_dir) + .arg("-x") + .arg("c") .arg("-O2") .arg("-c") .arg(path_to_c_src) From cb5afa1b844d48b51b06861ff20f06469948967c Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 10:52:49 +0200 Subject: [PATCH 21/25] test(integration) Update to use the latest Wasm C API. --- .../tests/object_file_engine_test_c_source.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/integration/cli/tests/object_file_engine_test_c_source.c b/tests/integration/cli/tests/object_file_engine_test_c_source.c index ec00f917942..caee5c4af50 100644 --- a/tests/integration/cli/tests/object_file_engine_test_c_source.c +++ b/tests/integration/cli/tests/object_file_engine_test_c_source.c @@ -30,7 +30,8 @@ int main() { wasm_store_t* store = wasm_store_new(engine); wasm_module_t* module = wasmer_object_file_engine_new(store, "qjs.wasm"); - if (! module) { + + if (!module) { printf("Failed to create module\n"); print_wasmer_error(); return -1; @@ -45,6 +46,7 @@ int main() { wasi_config_arg(wasi_config, "--eval"); wasi_config_arg(wasi_config, js_string); wasi_env_t* wasi_env = wasi_env_new(wasi_config); + if (!wasi_env) { printf("> Error building WASI env!\n"); print_wasmer_error(); @@ -53,19 +55,23 @@ int main() { wasm_importtype_vec_t import_types; wasm_module_imports(module, &import_types); - int num_imports = import_types.size; - wasm_extern_t** imports = (wasm_extern_t**) malloc(num_imports * sizeof(wasm_extern_t*)); + + wasm_extern_vec_t imports; + wasm_extern_vec_new_uninitialized(&imports, import_types.size); + wasm_importtype_vec_delete(&import_types); - bool get_imports_result = wasi_get_imports(store, module, wasi_env, imports); + bool get_imports_result = wasi_get_imports(store, module, wasi_env, &imports); + if (!get_imports_result) { printf("> Error getting WASI imports!\n"); print_wasmer_error(); return 1; } - wasm_instance_t* instance = wasm_instance_new(store, module, (const wasm_extern_t* const*) imports, NULL); - if (! instance) { + wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL); + + if (!instance) { printf("Failed to create instance\n"); print_wasmer_error(); return -1; @@ -81,9 +87,11 @@ int main() { // We're able to call our compiled function directly through a trampoline. wasmer_trampoline_function_call__1(vmctx, wasmer_function__1, &inout); + wasm_extern_vec_delete(&imports); wasm_instance_delete(instance); wasm_module_delete(module); wasm_store_delete(store); wasm_engine_delete(engine); + return 0; } From 2fc1aaa1fe84f884c7757ccb37d5b32a38339f94 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 10:53:10 +0200 Subject: [PATCH 22/25] chore(test) Format code. --- .../tests/object_file_engine_test_c_source.c | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/tests/integration/cli/tests/object_file_engine_test_c_source.c b/tests/integration/cli/tests/object_file_engine_test_c_source.c index caee5c4af50..7d16826244d 100644 --- a/tests/integration/cli/tests/object_file_engine_test_c_source.c +++ b/tests/integration/cli/tests/object_file_engine_test_c_source.c @@ -15,83 +15,83 @@ extern "C" { void print_wasmer_error() { - int error_len = wasmer_last_error_length(); - printf("Error len: `%d`\n", error_len); - char* error_str = (char*) malloc(error_len); - wasmer_last_error_message(error_str, error_len); - printf("Error str: `%s`\n", error_str); + int error_len = wasmer_last_error_length(); + printf("Error len: `%d`\n", error_len); + char* error_str = (char*) malloc(error_len); + wasmer_last_error_message(error_str, error_len); + printf("Error str: `%s`\n", error_str); } int main() { - printf("Initializing...\n"); - wasm_config_t* config = wasm_config_new(); - wasm_config_set_engine(config, OBJECT_FILE); - wasm_engine_t* engine = wasm_engine_new_with_config(config); - wasm_store_t* store = wasm_store_new(engine); - - wasm_module_t* module = wasmer_object_file_engine_new(store, "qjs.wasm"); - - if (!module) { - printf("Failed to create module\n"); - print_wasmer_error(); - return -1; - } + printf("Initializing...\n"); + wasm_config_t* config = wasm_config_new(); + wasm_config_set_engine(config, OBJECT_FILE); + wasm_engine_t* engine = wasm_engine_new_with_config(config); + wasm_store_t* store = wasm_store_new(engine); + + wasm_module_t* module = wasmer_object_file_engine_new(store, "qjs.wasm"); + + if (!module) { + printf("Failed to create module\n"); + print_wasmer_error(); + return -1; + } - // We have now finished the memory buffer book keeping and we have a valid Module. + // We have now finished the memory buffer book keeping and we have a valid Module. - // In this example we're passing some JavaScript source code as a command line argument - // to a WASI module that can evaluate JavaScript. - wasi_config_t* wasi_config = wasi_config_new("constant_value_here"); - const char* js_string = "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));"; - wasi_config_arg(wasi_config, "--eval"); - wasi_config_arg(wasi_config, js_string); - wasi_env_t* wasi_env = wasi_env_new(wasi_config); + // In this example we're passing some JavaScript source code as a command line argument + // to a WASI module that can evaluate JavaScript. + wasi_config_t* wasi_config = wasi_config_new("constant_value_here"); + const char* js_string = "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));"; + wasi_config_arg(wasi_config, "--eval"); + wasi_config_arg(wasi_config, js_string); + wasi_env_t* wasi_env = wasi_env_new(wasi_config); - if (!wasi_env) { - printf("> Error building WASI env!\n"); - print_wasmer_error(); - return 1; - } + if (!wasi_env) { + printf("> Error building WASI env!\n"); + print_wasmer_error(); + return 1; + } - wasm_importtype_vec_t import_types; - wasm_module_imports(module, &import_types); + wasm_importtype_vec_t import_types; + wasm_module_imports(module, &import_types); - wasm_extern_vec_t imports; - wasm_extern_vec_new_uninitialized(&imports, import_types.size); + wasm_extern_vec_t imports; + wasm_extern_vec_new_uninitialized(&imports, import_types.size); - wasm_importtype_vec_delete(&import_types); + wasm_importtype_vec_delete(&import_types); - bool get_imports_result = wasi_get_imports(store, module, wasi_env, &imports); - - if (!get_imports_result) { - printf("> Error getting WASI imports!\n"); - print_wasmer_error(); - return 1; - } - - wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL); - - if (!instance) { - printf("Failed to create instance\n"); - print_wasmer_error(); - return -1; - } - wasi_env_set_instance(wasi_env, instance); + bool get_imports_result = wasi_get_imports(store, module, wasi_env, &imports); + + if (!get_imports_result) { + printf("> Error getting WASI imports!\n"); + print_wasmer_error(); + return 1; + } + + wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL); + + if (!instance) { + printf("Failed to create instance\n"); + print_wasmer_error(); + return -1; + } + wasi_env_set_instance(wasi_env, instance); - // WASI is now set up. + // WASI is now set up. - void* vmctx = wasm_instance_get_vmctx_ptr(instance); - wasm_val_t* inout[2] = { NULL, NULL }; + void* vmctx = wasm_instance_get_vmctx_ptr(instance); + wasm_val_t* inout[2] = { NULL, NULL }; - fflush(stdout); - // We're able to call our compiled function directly through a trampoline. - wasmer_trampoline_function_call__1(vmctx, wasmer_function__1, &inout); + fflush(stdout); + // We're able to call our compiled function directly through a trampoline. + wasmer_trampoline_function_call__1(vmctx, wasmer_function__1, &inout); - wasm_extern_vec_delete(&imports); - wasm_instance_delete(instance); - wasm_module_delete(module); - wasm_store_delete(store); - wasm_engine_delete(engine); + wasm_extern_vec_delete(&imports); + wasm_instance_delete(instance); + wasm_module_delete(module); + wasm_store_delete(store); + wasm_engine_delete(engine); - return 0; + return 0; } From 3b05c2612dfb83612838adedc6a88029872f55ec Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 20:44:49 +0200 Subject: [PATCH 23/25] fix(c-api) Fix last edit of the `wasmer_create_exe_main.c` file. --- lib/cli/src/commands/wasmer_create_exe_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/cli/src/commands/wasmer_create_exe_main.c b/lib/cli/src/commands/wasmer_create_exe_main.c index 27df043245e..5095fd32238 100644 --- a/lib/cli/src/commands/wasmer_create_exe_main.c +++ b/lib/cli/src/commands/wasmer_create_exe_main.c @@ -135,6 +135,7 @@ int main(int argc, char* argv[]) { wasm_importtype_vec_t import_types; wasm_module_imports(module, &import_types); + wasm_extern_vec_t imports; wasm_extern_vec_new_uninitialized(&imports, import_type.size); wasm_importtype_vec_delete(&import_types); @@ -150,7 +151,8 @@ int main(int argc, char* argv[]) { #endif wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL); - if (! instance) { + + if (!instance) { fprintf(stderr, "Failed to create instance\n"); print_wasmer_error(); return -1; From 1cdb5b58768d6203afbec90b2efb457d26dbb90c Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 21:24:36 +0200 Subject: [PATCH 24/25] fix(c-api) Fix another typo. Damn. --- lib/cli/src/commands/wasmer_create_exe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cli/src/commands/wasmer_create_exe_main.c b/lib/cli/src/commands/wasmer_create_exe_main.c index 5095fd32238..bc5ecf7820e 100644 --- a/lib/cli/src/commands/wasmer_create_exe_main.c +++ b/lib/cli/src/commands/wasmer_create_exe_main.c @@ -136,7 +136,7 @@ int main(int argc, char* argv[]) { wasm_module_imports(module, &import_types); wasm_extern_vec_t imports; - wasm_extern_vec_new_uninitialized(&imports, import_type.size); + wasm_extern_vec_new_uninitialized(&imports, import_types.size); wasm_importtype_vec_delete(&import_types); #ifdef WASI From 9955da1eccdae7a6ace28515d587ca94beff9910 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 16 Oct 2020 21:30:53 +0200 Subject: [PATCH 25/25] test: Remove a warning fix for Windows. Windows will raise a warning because `clang++` is used to handle C code, so I previously add `-x c` to tell `clang++` to handle code as C code. Bbut if code is treated as C, it will fail because `static_assert` is not available for C on Windows. So let's live with the warning. --- tests/integration/cli/tests/compile.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/integration/cli/tests/compile.rs b/tests/integration/cli/tests/compile.rs index 319af0bc95c..71fa6bd58c9 100644 --- a/tests/integration/cli/tests/compile.rs +++ b/tests/integration/cli/tests/compile.rs @@ -92,8 +92,6 @@ fn run_c_compile( let output = Command::new(c_compiler) .current_dir(current_dir) - .arg("-x") - .arg("c") .arg("-O2") .arg("-c") .arg(path_to_c_src)