From c94e7525327b275c396ed4394e1d5e7848972616 Mon Sep 17 00:00:00 2001 From: Michael Martin <34528845+mykmartin@users.noreply.github.com> Date: Tue, 12 Oct 2021 19:06:38 +1100 Subject: [PATCH] Allow empty import array for wasm-c-api wasm_instance_new (#782) Allow empty import array (but not NULL) for wasm-c-api wasm_instance_new, which makes the code more robust, especially in use cases where imports might be constructed dynamically. And add a test case in samples/wasm-c-api/src/empty_imports.c to test it. --- core/iwasm/common/wasm_c_api.c | 5 +- samples/wasm-c-api/CMakeLists.txt | 1 + samples/wasm-c-api/src/empty_imports.c | 97 ++++++++++++++++++++++++ samples/wasm-c-api/src/empty_imports.wat | 5 ++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 samples/wasm-c-api/src/empty_imports.c create mode 100644 samples/wasm-c-api/src/empty_imports.wat diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index e08363f84..9bffeb662 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -4230,6 +4230,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, { char error_buf[128] = { 0 }; uint32 import_count = 0; + bool import_count_verified = false; wasm_instance_t *instance = NULL; uint32 i = 0; bool processed = false; @@ -4265,6 +4266,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, goto failed; } } + import_count_verified = true; } #endif @@ -4285,6 +4287,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, goto failed; } } + import_count_verified = true; } #endif @@ -4292,7 +4295,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, * a wrong combination of module filetype and compilation flags * also leads to below branch */ - if (!import_count) { + if (!import_count_verified) { goto failed; } } diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index c1bba6c3c..5d4a34ba1 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -123,6 +123,7 @@ set(MM_UTIL src/utils/multi_module_utils.c) set(EXAMPLES callback callback_chain + empty_imports global hello hostref diff --git a/samples/wasm-c-api/src/empty_imports.c b/samples/wasm-c-api/src/empty_imports.c new file mode 100644 index 000000000..902704ed8 --- /dev/null +++ b/samples/wasm-c-api/src/empty_imports.c @@ -0,0 +1,97 @@ +#include + +#include "wasm_c_api.h" + +#define own + +int main(int argc, const char* argv[]) { + // Initialize. + printf("Initializing...\n"); + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + // Load binary. + printf("Loading binary...\n"); +#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0 + FILE* file = fopen("empty_imports.aot", "rb"); +#else + FILE* file = fopen("empty_imports.wasm", "rb"); +#endif + if (!file) { + printf("> Error loading module!\n"); + return 1; + } + fseek(file, 0L, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0L, SEEK_SET); + wasm_byte_vec_t binary; + wasm_byte_vec_new_uninitialized(&binary, file_size); + if (fread(binary.data, file_size, 1, file) != 1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + fclose(file); + + // Compile. + printf("Compiling module...\n"); + own wasm_module_t* module = wasm_module_new(store, &binary); + if (!module) { + printf("> Error compiling module!\n"); + return 1; + } + + wasm_byte_vec_delete(&binary); + + // Instantiate with non-null but empty imports array. + printf("Instantiating module...\n"); + 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; + } + + // Run an exported function to verify that the instance was created correctly. + printf("Extracting export...\n"); + own wasm_extern_vec_t exports; + wasm_instance_exports(instance, &exports); + if (exports.size == 0) { + printf("> Error accessing exports!\n"); + return 1; + } + + const wasm_func_t* add_func = wasm_extern_as_func(exports.data[0]); + if (add_func == NULL) { + printf("> Error accessing export!\n"); + return 1; + } + + wasm_module_delete(module); + wasm_instance_delete(instance); + + printf("Calling export...\n"); + wasm_val_t args[2] = { WASM_I32_VAL(3), WASM_I32_VAL(4) }; + wasm_val_vec_t args_vec = WASM_ARRAY_VEC(args); + + wasm_val_t results[1] = { WASM_INIT_VAL }; + wasm_val_vec_t results_vec = WASM_ARRAY_VEC(results); + + if (wasm_func_call(add_func, &args_vec, &results_vec) + || results_vec.data[0].of.i32 != 7) { + printf("> Error calling function!\n"); + return 1; + } + + wasm_extern_vec_delete(&exports); + + // Shut down. + printf("Shutting down...\n"); + wasm_store_delete(store); + wasm_engine_delete(engine); + + // All done. + printf("Done.\n"); + return 0; +} diff --git a/samples/wasm-c-api/src/empty_imports.wat b/samples/wasm-c-api/src/empty_imports.wat new file mode 100644 index 000000000..38639790b --- /dev/null +++ b/samples/wasm-c-api/src/empty_imports.wat @@ -0,0 +1,5 @@ +(module + (func (export "add") (param i32 i32) (result i32) + (i32.add (local.get 0) (local.get 1)) + ) +)