From ee4114027e4aa3eae4fbe2dd87eab5d704dae006 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 27 Nov 2024 01:16:51 +0000 Subject: [PATCH 01/26] [inst-link function]Refactor: rename 'is_sub_inst' parameter to 'is_spawned' for clarity in deinstantiation functions --- core/iwasm/aot/aot_runtime.c | 32 ++++++++++++++----------- core/iwasm/aot/aot_runtime.h | 4 ++-- core/iwasm/common/wasm_runtime_common.c | 6 ++--- core/iwasm/common/wasm_runtime_common.h | 2 +- core/iwasm/interpreter/wasm_runtime.c | 30 +++++++++++------------ core/iwasm/interpreter/wasm_runtime.h | 2 +- 6 files changed, 40 insertions(+), 36 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 4b2d4ac93c..9ef36ff3c8 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1938,7 +1938,7 @@ lookup_post_instantiate_func(AOTModuleInstance *module_inst, static bool execute_post_instantiate_functions(AOTModuleInstance *module_inst, - bool is_sub_inst, WASMExecEnv *exec_env_main) + bool is_spawned, WASMExecEnv *exec_env_main) { AOTModule *module = (AOTModule *)module_inst->module; AOTFunctionInstance *initialize_func = NULL; @@ -1957,7 +1957,7 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, * the environment at most once, and that none of their other exports * are accessed before that call. */ - if (!is_sub_inst && module->import_wasi_api) { + if (!is_spawned && module->import_wasi_api) { initialize_func = lookup_post_instantiate_func(module_inst, "_initialize"); } @@ -1965,7 +1965,7 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, /* Execute possible "__post_instantiate" function if wasm app is compiled by emsdk's early version */ - if (!is_sub_inst) { + if (!is_spawned) { post_inst_func = lookup_post_instantiate_func(module_inst, "__post_instantiate"); } @@ -1973,7 +1973,7 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, #if WASM_ENABLE_BULK_MEMORY != 0 /* Only execute the memory init function for main instance since the data segments will be dropped once initialized */ - if (!is_sub_inst + if (!is_spawned #if WASM_ENABLE_LIBC_WASI != 0 && !module->import_wasi_api #endif @@ -1989,7 +1989,7 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, return true; } - if (is_sub_inst) { + if (is_spawned) { bh_assert(exec_env_main); #ifdef OS_ENABLE_HW_BOUND_CHECK /* May come from pthread_create_wrapper, thread_spawn_wrapper and @@ -2082,7 +2082,7 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, ret = true; fail: - if (is_sub_inst) { + if (is_spawned) { /* Restore the parent exec_env's module inst */ wasm_exec_env_restore_module_inst(exec_env_main, module_inst_main); } @@ -2116,7 +2116,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, uint64 total_size, table_size = 0; uint8 *p; uint32 i, extra_info_offset; - const bool is_sub_inst = parent != NULL; + const bool is_spawned = parent != NULL; #if WASM_ENABLE_MULTI_MODULE != 0 bool ret = false; #endif @@ -2183,7 +2183,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, #if WASM_ENABLE_GC != 0 /* Initialize gc heap first since it may be used when initializing globals and others */ - if (!is_sub_inst) { + if (!is_spawned) { uint32 gc_heap_size = wasm_runtime_get_gc_heap_size_default(); if (gc_heap_size < GC_HEAP_SIZE_MIN) @@ -2308,7 +2308,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, goto fail; #if WASM_ENABLE_LIBC_WASI != 0 - if (!is_sub_inst) { + if (!is_spawned) { if (!wasm_runtime_init_wasi( (WASMModuleInstanceCommon *)module_inst, module->wasi_args.dir_list, module->wasi_args.dir_count, @@ -2504,7 +2504,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, } #endif - if (!execute_post_instantiate_functions(module_inst, is_sub_inst, + if (!execute_post_instantiate_functions(module_inst, is_spawned, exec_env_main)) { set_error_buf(error_buf, error_buf_size, module_inst->cur_exception); goto fail; @@ -2518,7 +2518,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, return module_inst; fail: - aot_deinstantiate(module_inst, is_sub_inst); + aot_deinstantiate(module_inst, is_spawned); return NULL; } @@ -2546,7 +2546,7 @@ destroy_c_api_frames(Vector *frames) #endif void -aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) +aot_deinstantiate(AOTModuleInstance *module_inst, bool is_spawned) { AOTModuleInstanceExtra *extra = (AOTModuleInstanceExtra *)module_inst->e; WASMModuleInstanceExtraCommon *common = &extra->common; @@ -2623,7 +2623,7 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) wasm_runtime_free(module_inst->c_api_func_imports); #if WASM_ENABLE_GC != 0 - if (!is_sub_inst) { + if (!is_spawned) { if (common->gc_heap_handle) mem_allocator_destroy(common->gc_heap_handle); if (common->gc_heap_pool) @@ -2631,7 +2631,7 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) } #endif - if (!is_sub_inst) { + if (!is_spawned) { wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst); } @@ -2836,6 +2836,10 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, snprintf(buf, sizeof(buf), "invalid argument count %u, must be no smaller than %u", argc, func_type->param_cell_num); + /* + * TODO: might need to roll back to the original module_inst + * if has been changed to sub module instance + */ aot_set_exception(module_inst, buf); return false; } diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 22e50fbe7e..0f5e6e0657 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -575,10 +575,10 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, * Deinstantiate a AOT module instance, destroy the resources. * * @param module_inst the AOT module instance to destroy - * @param is_sub_inst the flag of sub instance + * @param is_spawned the flag of sub instance */ void -aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst); +aot_deinstantiate(AOTModuleInstance *module_inst, bool is_spawned); AOTMemoryInstance * aot_create_memory(const AOTModule *module, const AOTMemoryType *type); diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 271e139494..6d1d31927a 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1681,17 +1681,17 @@ wasm_runtime_instantiate_ex(WASMModuleCommon *module, void wasm_runtime_deinstantiate_internal(WASMModuleInstanceCommon *module_inst, - bool is_sub_inst) + bool is_spawned) { #if WASM_ENABLE_INTERP != 0 if (module_inst->module_type == Wasm_Module_Bytecode) { - wasm_deinstantiate((WASMModuleInstance *)module_inst, is_sub_inst); + wasm_deinstantiate((WASMModuleInstance *)module_inst, is_spawned); return; } #endif #if WASM_ENABLE_AOT != 0 if (module_inst->module_type == Wasm_Module_AoT) { - aot_deinstantiate((AOTModuleInstance *)module_inst, is_sub_inst); + aot_deinstantiate((AOTModuleInstance *)module_inst, is_spawned); return; } #endif diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index e9643c2347..780696693c 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -582,7 +582,7 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module, /* Internal API */ void wasm_runtime_deinstantiate_internal(WASMModuleInstanceCommon *module_inst, - bool is_sub_inst); + bool is_spawned); /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon * diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 4c5883b650..cfbe7046fe 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1786,7 +1786,7 @@ lookup_post_instantiate_func(WASMModuleInstance *module_inst, static bool execute_post_instantiate_functions(WASMModuleInstance *module_inst, - bool is_sub_inst, WASMExecEnv *exec_env_main) + bool is_spawned, WASMExecEnv *exec_env_main) { WASMFunctionInstance *start_func = module_inst->e->start_function; WASMFunctionInstance *initialize_func = NULL; @@ -1808,7 +1808,7 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, * the environment at most once, and that none of their other exports * are accessed before that call. */ - if (!is_sub_inst && module->import_wasi_api) { + if (!is_spawned && module->import_wasi_api) { initialize_func = lookup_post_instantiate_func(module_inst, "_initialize"); } @@ -1816,7 +1816,7 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, /* Execute possible "__post_instantiate" function if wasm app is compiled by emsdk's early version */ - if (!is_sub_inst) { + if (!is_spawned) { post_inst_func = lookup_post_instantiate_func(module_inst, "__post_instantiate"); } @@ -1824,7 +1824,7 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, #if WASM_ENABLE_BULK_MEMORY != 0 /* Only execute the memory init function for main instance since the data segments will be dropped once initialized */ - if (!is_sub_inst + if (!is_spawned #if WASM_ENABLE_LIBC_WASI != 0 && !module->import_wasi_api #endif @@ -1840,7 +1840,7 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, return true; } - if (is_sub_inst) { + if (is_spawned) { bh_assert(exec_env_main); #ifdef OS_ENABLE_HW_BOUND_CHECK /* May come from pthread_create_wrapper, thread_spawn_wrapper and @@ -1915,7 +1915,7 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, ret = true; fail: - if (is_sub_inst) { + if (is_spawned) { /* Restore the parent exec_env's module inst */ wasm_exec_env_restore_module_inst(exec_env_main, module_inst_main); } @@ -2592,7 +2592,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, #if WASM_ENABLE_MULTI_MODULE != 0 bool ret = false; #endif - const bool is_sub_inst = parent != NULL; + const bool is_spawned = parent != NULL; if (!module) return NULL; @@ -2714,7 +2714,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, #endif #if WASM_ENABLE_GC != 0 - if (!is_sub_inst) { + if (!is_spawned) { uint32 gc_heap_size = wasm_runtime_get_gc_heap_size_default(); if (gc_heap_size < GC_HEAP_SIZE_MIN) @@ -2958,7 +2958,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, if (data_seg->is_passive) continue; #endif - if (is_sub_inst) + if (is_spawned) /* Ignore setting memory init data if the memory has been initialized */ continue; @@ -3471,7 +3471,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, #if WASM_ENABLE_LIBC_WASI != 0 /* The sub-instance will get the wasi_ctx from main-instance */ - if (!is_sub_inst) { + if (!is_spawned) { if (!wasm_runtime_init_wasi( (WASMModuleInstanceCommon *)module_inst, module->wasi_args.dir_list, module->wasi_args.dir_count, @@ -3489,7 +3489,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, #endif #if WASM_ENABLE_DEBUG_INTERP != 0 - if (!is_sub_inst) { + if (!is_spawned) { /* Add module instance into module's instance list */ os_mutex_lock(&module->instance_list_lock); if (module->instance_list) { @@ -3518,7 +3518,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, &module_inst->e->functions[module->start_function]; } - if (!execute_post_instantiate_functions(module_inst, is_sub_inst, + if (!execute_post_instantiate_functions(module_inst, is_spawned, exec_env_main)) { set_error_buf(error_buf, error_buf_size, module_inst->cur_exception); goto fail; @@ -3561,7 +3561,7 @@ destroy_c_api_frames(Vector *frames) #endif void -wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) +wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_spawned) { if (!module_inst) return; @@ -3659,7 +3659,7 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) #endif #if WASM_ENABLE_GC != 0 - if (!is_sub_inst) { + if (!is_spawned) { if (module_inst->e->common.gc_heap_handle) mem_allocator_destroy(module_inst->e->common.gc_heap_handle); if (module_inst->e->common.gc_heap_pool) @@ -3678,7 +3678,7 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) if (module_inst->c_api_func_imports) wasm_runtime_free(module_inst->c_api_func_imports); - if (!is_sub_inst) { + if (!is_spawned) { wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst); } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index e76ee487bc..97e0f6337d 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -624,7 +624,7 @@ wasm_get_wasm_func_exec_time(const WASMModuleInstance *inst, const char *func_name); void -wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst); +wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_spawned); bool wasm_set_running_mode(WASMModuleInstance *module_inst, From ba233d042a058081d549880ec7fb846d1e206d88 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 27 Nov 2024 01:36:06 +0000 Subject: [PATCH 02/26] Refactor: simplify function pointer retrieval in aot_call_function for clarity --- core/iwasm/aot/aot_runtime.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 9ef36ff3c8..3e9dde3419 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -2798,10 +2798,10 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, uint32 result_count = func_type->result_count; uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0; bool ret; - void *func_ptr = function->is_import_func - ? function->u.func_import->func_ptr_linked - : function->u.func.func_ptr; + /* init_func_ptrs() has already copied func_ptr_linked value*/ + void *func_ptr = function->u.func.func_ptr; void *attachment = NULL; + #if WASM_ENABLE_MULTI_MODULE != 0 bh_list *sub_module_list_node = NULL; const char *sub_inst_name = NULL; From 295cbbbb168e38db4ecae1bd99f43cb74554d8db Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 27 Nov 2024 02:21:49 +0000 Subject: [PATCH 03/26] Refactor: streamline import function resolution logic and improve error handling --- core/iwasm/aot/aot_runtime.c | 54 +++++++++++--------- core/iwasm/interpreter/wasm_interp_classic.c | 6 ++- core/iwasm/interpreter/wasm_runtime.c | 38 ++++++++------ 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 3e9dde3419..8dd192b0ce 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -5703,11 +5703,6 @@ aot_resolve_function(const AOTModule *module, const char *function_name, bool aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) { -#if WASM_ENABLE_MULTI_MODULE != 0 - char error_buf[128]; - AOTModule *sub_module = NULL; -#endif - import_func->func_ptr_linked = wasm_native_resolve_symbol( import_func->module_name, import_func->func_name, import_func->func_type, &import_func->signature, @@ -5715,24 +5710,37 @@ aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) #if WASM_ENABLE_MULTI_MODULE != 0 if (!import_func->func_ptr_linked) { - if (!wasm_runtime_is_built_in_module(import_func->module_name)) { - sub_module = (AOTModule *)wasm_runtime_load_depended_module( - (WASMModuleCommon *)module, import_func->module_name, error_buf, - sizeof(error_buf)); - if (!sub_module) { - LOG_WARNING("Failed to load sub module: %s", error_buf); - } - if (!sub_module) - import_func->func_ptr_linked = aot_resolve_function_ex( - import_func->module_name, import_func->func_name, - import_func->func_type, error_buf, sizeof(error_buf)); - else - import_func->func_ptr_linked = aot_resolve_function( - sub_module, import_func->func_name, import_func->func_type, - error_buf, sizeof(error_buf)); - if (!import_func->func_ptr_linked) { - LOG_WARNING("Failed to link function: %s", error_buf); - } + char error_buf[128]; + AOTModule *sub_module = NULL; + /* + * after wasm_native_resolve_symbol(), + * wasm_runtime_is_built_in_module isn't necessary + */ + bh_assert(!wasm_runtime_is_built_in_module(import_func->module_name)); + + sub_module = (AOTModule *)wasm_runtime_load_depended_module( + (WASMModuleCommon *)module, import_func->module_name, error_buf, + sizeof(error_buf)); + + if (!sub_module) { + LOG_DEBUG("Failed to load sub module: %s", error_buf); + /* + * TOOD: call in wasm_runtime_find_module_registered() + * in aot_resolve_function_ex() is not necessary + * since wasm_runtime_load_depended_module() has been called + */ + import_func->func_ptr_linked = aot_resolve_function_ex( + import_func->module_name, import_func->func_name, + import_func->func_type, error_buf, sizeof(error_buf)); + } + else { + import_func->func_ptr_linked = aot_resolve_function( + sub_module, import_func->func_name, import_func->func_type, + error_buf, sizeof(error_buf)); + } + + if (!import_func->func_ptr_linked) { + LOG_WARNING("Failed to link function: %s", error_buf); } } #else diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index e0803f358d..b52fb72e08 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1392,8 +1392,10 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, return; } - /* Switch exec_env but keep using the same one by replacing necessary - * variables */ + /* + * Switch the WASMExecEnv while retaining the same content + * by updating the necessary variables + */ sub_module_exec_env = wasm_runtime_get_exec_env_singleton( (WASMModuleInstanceCommon *)sub_module_inst); if (!sub_module_exec_env) { diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index cfbe7046fe..6df22a9fd1 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -162,10 +162,7 @@ wasm_resolve_function(const char *module_name, const char *function_name, bool wasm_resolve_import_func(const WASMModule *module, WASMFunctionImport *function) { -#if WASM_ENABLE_MULTI_MODULE != 0 - char error_buf[128]; - WASMModule *sub_module = NULL; -#endif + /* from builtin functions */ function->func_ptr_linked = wasm_native_resolve_symbol( function->module_name, function->field_name, function->func_type, &function->signature, &function->attachment, &function->call_conv_raw); @@ -175,27 +172,34 @@ wasm_resolve_import_func(const WASMModule *module, WASMFunctionImport *function) } #if WASM_ENABLE_MULTI_MODULE != 0 - if (!wasm_runtime_is_built_in_module(function->module_name)) { - sub_module = (WASMModule *)wasm_runtime_load_depended_module( - (WASMModuleCommon *)module, function->module_name, error_buf, - sizeof(error_buf)); - if (!sub_module) { - LOG_WARNING("failed to load sub module: %s", error_buf); - return false; - } + /* from other .wasms' export functions */ + char error_buf[128]; + WASMModule *sub_module = NULL; + + /* + * after wasm_native_resolve_symbol(), + * wasm_runtime_is_built_in_module isn't necessary + */ + bh_assert(!wasm_runtime_is_built_in_module(function->module_name)); + + sub_module = (WASMModule *)wasm_runtime_load_depended_module( + (WASMModuleCommon *)module, function->module_name, error_buf, + sizeof(error_buf)); + if (!sub_module) { + LOG_WARNING("failed to load sub module: %s", error_buf); + return false; } + function->import_func_linked = wasm_resolve_function( function->module_name, function->field_name, function->func_type, error_buf, sizeof(error_buf)); - if (function->import_func_linked) { function->import_module = sub_module; return true; } - else { - LOG_WARNING("failed to link function (%s, %s): %s", - function->module_name, function->field_name, error_buf); - } + + LOG_WARNING("failed to link function (%s, %s): %s", function->module_name, + function->field_name, error_buf); #endif return false; From 83686473d66f56bb303a45a260adfa6090b3123a Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Fri, 29 Nov 2024 12:41:32 +0000 Subject: [PATCH 04/26] Refactor: improve comments for clarity in AOT function handling and context creation --- core/iwasm/aot/aot_runtime.c | 4 ++++ core/iwasm/compilation/aot_llvm.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 8dd192b0ce..c9fed6df35 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -2803,6 +2803,10 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, void *attachment = NULL; #if WASM_ENABLE_MULTI_MODULE != 0 + /* + * TODO: this searching for sub_module_inst + * should have been done during loading) + */ bh_list *sub_module_list_node = NULL; const char *sub_inst_name = NULL; const char *func_name = function->u.func_import->module_name; diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 51f33dffb1..7e454502a4 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -1934,7 +1934,7 @@ aot_create_func_contexts(const AOTCompData *comp_data, AOTCompContext *comp_ctx) memset(func_ctxes, 0, size); - /* Create each function context */ + /* Create each function(non-import) context */ for (i = 0; i < comp_data->func_count; i++) { AOTFunc *func = comp_data->funcs[i]; if (!(func_ctxes[i] = From d440f6fd719caac407349b5fef410a30a430cd70 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Sun, 1 Dec 2024 06:06:36 +0000 Subject: [PATCH 05/26] Refactor: enhance import function resolution by adding module name checks and improving error handling --- core/iwasm/aot/aot_runtime.c | 62 ++++++++++++++------------- core/iwasm/interpreter/wasm_runtime.c | 17 ++++---- core/iwasm/interpreter/wasm_runtime.h | 3 ++ 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index c9fed6df35..d4292a241a 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -5712,40 +5712,42 @@ aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) import_func->func_type, &import_func->signature, &import_func->attachment, &import_func->call_conv_raw); + if (import_func->func_ptr_linked) { + return true; + } + #if WASM_ENABLE_MULTI_MODULE != 0 - if (!import_func->func_ptr_linked) { - char error_buf[128]; - AOTModule *sub_module = NULL; + if (!import_func->module_name) { + LOG_VERBOSE( + "does't have module name for function %s. host should provide link", + import_func->func_name); + return false; + } + + char error_buf[128]; + AOTModule *sub_module = (AOTModule *)wasm_runtime_load_depended_module( + (WASMModuleCommon *)module, import_func->module_name, error_buf, + sizeof(error_buf)); + + if (!sub_module) { + LOG_DEBUG("Failed to load sub module: %s", error_buf); /* - * after wasm_native_resolve_symbol(), - * wasm_runtime_is_built_in_module isn't necessary + * TOOD: call in wasm_runtime_find_module_registered() + * in aot_resolve_function_ex() is not necessary + * since wasm_runtime_load_depended_module() has been called */ - bh_assert(!wasm_runtime_is_built_in_module(import_func->module_name)); - - sub_module = (AOTModule *)wasm_runtime_load_depended_module( - (WASMModuleCommon *)module, import_func->module_name, error_buf, - sizeof(error_buf)); - - if (!sub_module) { - LOG_DEBUG("Failed to load sub module: %s", error_buf); - /* - * TOOD: call in wasm_runtime_find_module_registered() - * in aot_resolve_function_ex() is not necessary - * since wasm_runtime_load_depended_module() has been called - */ - import_func->func_ptr_linked = aot_resolve_function_ex( - import_func->module_name, import_func->func_name, - import_func->func_type, error_buf, sizeof(error_buf)); - } - else { - import_func->func_ptr_linked = aot_resolve_function( - sub_module, import_func->func_name, import_func->func_type, - error_buf, sizeof(error_buf)); - } + import_func->func_ptr_linked = aot_resolve_function_ex( + import_func->module_name, import_func->func_name, + import_func->func_type, error_buf, sizeof(error_buf)); + } + else { + import_func->func_ptr_linked = aot_resolve_function( + sub_module, import_func->func_name, import_func->func_type, + error_buf, sizeof(error_buf)); + } - if (!import_func->func_ptr_linked) { - LOG_WARNING("Failed to link function: %s", error_buf); - } + if (!import_func->func_ptr_linked) { + LOG_WARNING("Failed to link function: %s", error_buf); } #else (void)module; diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 6df22a9fd1..3f64d9c5d6 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -172,17 +172,16 @@ wasm_resolve_import_func(const WASMModule *module, WASMFunctionImport *function) } #if WASM_ENABLE_MULTI_MODULE != 0 + if (!function->module_name) { + LOG_VERBOSE( + "does't have module name for function %s. host should provide link", + function->field_name); + return false; + } + /* from other .wasms' export functions */ char error_buf[128]; - WASMModule *sub_module = NULL; - - /* - * after wasm_native_resolve_symbol(), - * wasm_runtime_is_built_in_module isn't necessary - */ - bh_assert(!wasm_runtime_is_built_in_module(function->module_name)); - - sub_module = (WASMModule *)wasm_runtime_load_depended_module( + WASMModule *sub_module = (WASMModule *)wasm_runtime_load_depended_module( (WASMModuleCommon *)module, function->module_name, error_buf, sizeof(error_buf)); if (!sub_module) { diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 97e0f6337d..5b3fbbe5b1 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -436,6 +436,9 @@ struct WASMModuleInstance { DefPointer(WASMModule *, module); DefPointer(WASMExecEnv *, exec_env_singleton); + /* + * TODO: is able to be merged with func_ptrs + */ /* Array of function pointers to import functions, not available in AOTModuleInstance */ DefPointer(void **, import_func_ptrs); From 949eb16cf2bdd10684a36901a0dc6b37395e9c20 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Mon, 2 Dec 2024 02:45:36 +0000 Subject: [PATCH 06/26] Refactor: update TODO comment to indicate removal of import_func_ptrs --- core/iwasm/interpreter/wasm_runtime.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 5b3fbbe5b1..294065b513 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -437,7 +437,8 @@ struct WASMModuleInstance { DefPointer(WASMExecEnv *, exec_env_singleton); /* - * TODO: is able to be merged with func_ptrs + * TODO: is able to be removed. + * interp and fast-jit can use func_ptrs instead of this. */ /* Array of function pointers to import functions, not available in AOTModuleInstance */ From ed6372150063f2ba747653cc3c191760b7223f12 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Mon, 2 Dec 2024 12:32:17 +0000 Subject: [PATCH 07/26] Refactor: add internal functions for creating and destroying WASM function instances --- core/iwasm/common/wasm_runtime_common.c | 65 +++++++++++ core/iwasm/common/wasm_runtime_common.h | 6 + core/iwasm/include/wasm_export.h | 9 ++ core/iwasm/interpreter/wasm.h | 9 +- core/iwasm/interpreter/wasm_interp_classic.c | 6 +- core/iwasm/interpreter/wasm_runtime.c | 111 ++++++++++++++++--- core/iwasm/interpreter/wasm_runtime.h | 15 ++- 7 files changed, 198 insertions(+), 23 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 6d1d31927a..7b33ebfba5 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8111,6 +8111,71 @@ wasm_runtime_destroy_extern_inst(WASMModuleCommon *module, extern_inst->field_name = NULL; } +WASMFunctionInstanceCommon * +wasm_runtime_create_function_internal(struct WASMModuleCommon *const module, + WASMModuleInstanceCommon *dep_inst, + struct WASMFuncType *const type, + bool from_wasm_c_api, void *callback) +{ +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + WASMFunctionInstance *func = wasm_create_function( + (WASMModule *)module, (WASMModuleInstance *)dep_inst, type, + callback); + + if (!func) { + return NULL; + } + + func->u.func_import->call_conv_wasm_c_api = from_wasm_c_api; + return (WASMFunctionInstanceCommon *)func; + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + // return aot_create_function((AOTModuleInstance *)module, type); + bh_assert(false && "not supported yet"); + } +#endif + + LOG_ERROR("create function failed, invalid module type %d", + module->module_type); + return NULL; +} + +WASMFunctionInstanceCommon * +wasm_runtime_create_function(struct WASMModuleCommon *const module, + struct WASMFuncType *const type, void *callback) +{ + return wasm_runtime_create_function_internal(module, NULL, type, false, + callback); +} + +void +wasm_runtime_destroy_function(struct WASMModuleCommon *const module, + WASMFunctionInstanceCommon *func) +{ +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + wasm_destroy_function(func); + return; + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + bh_assert(false && "not supported yet"); + // aot_destroy_function(func); + return; + } +#endif + + LOG_ERROR("destroy function failed, invalid module type %d", + module->module_type); + return; +} + #if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_WASI_TEST != 0 /* * Be aware that it will remove all items in the list, regardless of whether diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 780696693c..157fb718ba 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -1243,6 +1243,12 @@ struct WASMTableInstance * wasm_runtime_create_table_internal(WASMModuleCommon *const module, WASMTableType *const type); +wasm_function_inst_t +wasm_runtime_create_function_internal(wasm_module_t const module, + wasm_module_inst_t dep_inst, + wasm_func_type_t const type, + bool from_wasm_c_api, void *callback); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 92633781da..6b4e3afdf4 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -296,6 +296,7 @@ typedef struct WASMExternInstance { wasm_memory_inst_t memory; wasm_table_inst_t table; wasm_global_inst_t global; + wasm_function_inst_t function; } u; /* @@ -2378,6 +2379,14 @@ wasm_runtime_create_table(const wasm_module_t module, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_table(const wasm_module_t module, wasm_table_inst_t table); +WASM_RUNTIME_API_EXTERN wasm_function_inst_t +wasm_runtime_create_function(const wasm_module_t module, + const wasm_func_type_t type, void *callback); + +WASM_RUNTIME_API_EXTERN void +wasm_runtime_destroy_function(const wasm_module_t module, + wasm_function_inst_t func); + /*TODO: take me out when have a linker */ WASM_RUNTIME_API_EXTERN wasm_module_inst_t wasm_runtime_instantiate_with_builtin_linker(wasm_module_t module, diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 4c9f9faafe..1ef13c8ee6 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -563,7 +563,12 @@ typedef struct WASMFunctionImport { char *field_name; /* function type */ WASMFuncType *func_type; - /* native function pointer after linked */ + /* + * native function pointer after linked + * - native functions via wasm_native + * - native functions via wasm_c_api. just indicators. + * - wasm function in other modules. jitted + */ void *func_ptr_linked; /* signature from registered native symbols */ const char *signature; @@ -575,10 +580,12 @@ typedef struct WASMFunctionImport { #endif bool call_conv_raw; bool call_conv_wasm_c_api; + #if WASM_ENABLE_MULTI_MODULE != 0 WASMModule *import_module; WASMFunction *import_func_linked; #endif + } WASMFunctionImport; #if WASM_ENABLE_TAGS != 0 diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index b52fb72e08..e492db3d64 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -6639,7 +6639,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, call_func_from_entry: { if (cur_func->is_import_func) { -#if WASM_ENABLE_MULTI_MODULE != 0 + /* from other .wasm */ if (cur_func->import_func_inst) { wasm_interp_call_func_import(module, exec_env, cur_func, prev_frame); @@ -6700,9 +6700,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, } #endif /* end of WASM_ENABLE_EXCE_HANDLING != 0 */ } - else -#endif /* end of WASM_ENABLE_MULTI_MODULE != 0 */ - { + else { wasm_interp_call_func_native(module, exec_env, cur_func, prev_frame); #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0 diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 3f64d9c5d6..9b481324a9 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -980,6 +980,7 @@ functions_deinstantiate(WASMFunctionInstance *functions) */ static WASMFunctionInstance * functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, + const WASMExternInstance *imports, uint32 import_count, char *error_buf, uint32 error_buf_size) { WASMImport *import; @@ -1003,9 +1004,30 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, /* instantiate functions from import section */ function = functions; import = module->import_functions; - for (i = 0; i < module->import_function_count; i++, import++) { + for (i = 0; i < module->import_function_count; i++, import++, function++) { function->is_import_func = true; + WASMFunctionImport *import_func_type = &(import->u.function); + function->u.func_import = import_func_type; + function->param_cell_num = import_func_type->func_type->param_cell_num; + function->ret_cell_num = import_func_type->func_type->ret_cell_num; + function->param_count = + (uint16)import_func_type->func_type->param_count; + function->param_types = import_func_type->func_type->types; + function->local_cell_num = 0; + function->local_count = 0; + function->local_types = NULL; + + /* Copy the function pointer to current instance + * + * both + * - from wasm_native + * - from wasm_c_api + * + * WASM_ENABLE_MULTI_MODULE == 0 + * - other .wasm + * - from wasm_export + */ #if WASM_ENABLE_MULTI_MODULE != 0 if (import->u.function.import_module) { function->import_module_inst = get_sub_module_inst( @@ -1017,22 +1039,39 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, import->u.function.field_name); } } -#endif /* WASM_ENABLE_MULTI_MODULE */ - function->u.func_import = &import->u.function; - function->param_cell_num = import->u.function.func_type->param_cell_num; - function->ret_cell_num = import->u.function.func_type->ret_cell_num; - function->param_count = - (uint16)function->u.func_import->func_type->param_count; - function->param_types = function->u.func_import->func_type->types; - function->local_cell_num = 0; - function->local_count = 0; - function->local_types = NULL; - /* Copy the function pointer to current instance */ - module_inst->import_func_ptrs[i] = - function->u.func_import->func_ptr_linked; + module_inst->import_func_ptrs[i] = import_func_type->func_ptr_linked; +#else + const WASMExternInstance *extern_inst = + wasm_runtime_get_extern_instance(imports, import_count, + WASM_IMPORT_EXPORT_KIND_FUNC, i); + if (!extern_inst) { + LOG_ERROR("no import function(%s, %s) from imports list, might " + "provied by wasm_native", + import_func_type->module_name, + import_func_type->field_name); + /* so it's from wasm_native */ + module_inst->import_func_ptrs[i] = + import_func_type->func_ptr_linked; + } + else { + /* don't allow wrong matchment */ + if (strcmp(import_func_type->field_name, extern_inst->field_name)) { + LOG_ERROR( + "mismatched import memory name: expect \"%s\", got \"%s\"", + import_func_type->field_name, extern_inst->field_name); + return NULL; + } - function++; + /* if extern_inst is about a wasm function from other .wasm */ + WASMFunctionInstance *extern_inst_func = + (WASMFunctionInstance *)extern_inst->u.function; + function->import_module_inst = extern_inst_func->import_module_inst; + function->import_func_inst = extern_inst_func->import_func_inst; + module_inst->import_func_ptrs[i] = + extern_inst_func->u.func_import->func_ptr_linked; + } +#endif } /* instantiate functions from function section */ @@ -2808,7 +2847,8 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, error_buf, error_buf_size))) || (module_inst->e->function_count > 0 && !(module_inst->e->functions = functions_instantiate( - module, module_inst, error_buf, error_buf_size))) + module, module_inst, imports, import_count, error_buf, + error_buf_size))) || (module_inst->export_func_count > 0 && !(module_inst->export_functions = export_functions_instantiate( module, module_inst, module_inst->export_func_count, @@ -5427,6 +5467,7 @@ wasm_destroy_table(WASMTableInstance *table) wasm_runtime_free(table); } +/*TODO: add init_value */ WASMGlobalInstance * wasm_create_global(const WASMModule *module, WASMModuleInstance *dep_inst, WASMGlobalType *type) @@ -5458,4 +5499,42 @@ wasm_destroy_global(WASMGlobalInstance *global) return; wasm_runtime_free(global); +} + +WASMFunctionInstance * +wasm_create_function(const WASMModule *module, WASMModuleInstance *dep_inst, + WASMFuncType *type, void *callback) +{ + WASMFunctionInstance *function = + runtime_malloc(sizeof(WASMFunctionInstance) + sizeof(WASMFunctionImport) + + sizeof(WASMFuncType), + NULL, 0); + if (!function) { + return NULL; + } + + /* initialize carefully */ + function->is_import_func = true; + + WASMFunctionImport *func_import = (WASMFunctionImport *)(function + 1); + func_import->func_ptr_linked = callback; + + WASMFuncType *func_type = (WASMFuncType *)(func_import + 1); + *func_type = *type; + + /* connect all three parts */ + function->u.func_import = func_import; + function->u.func_import->func_type = func_type; + function->import_module_inst = dep_inst; + + return function; +} + +void +wasm_destroy_function(WASMFunctionInstance *function) +{ + if (!function) + return; + + wasm_runtime_free(function); } \ No newline at end of file diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 294065b513..37bb4691ec 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -233,14 +233,18 @@ struct WASMFunctionInstance { uint8 *param_types; /* local types, NULL for import function */ uint8 *local_types; + union { + /* from wasm_native and wasm_import (interp) */ WASMFunctionImport *func_import; + /* locate bytecode */ WASMFunction *func; } u; -#if WASM_ENABLE_MULTI_MODULE != 0 + + /* only for wasm functions of other .wasm */ WASMModuleInstance *import_module_inst; WASMFunctionInstance *import_func_inst; -#endif + #if WASM_ENABLE_PERF_PROFILING != 0 /* total execution time */ uint64 total_exec_time; @@ -992,6 +996,13 @@ wasm_set_global_value(WASMGlobalInstance *global, const WASMValue *value); void wasm_destroy_global(WASMGlobalInstance *global); +WASMFunctionInstance * +wasm_create_function(const WASMModule *module, WASMModuleInstance *dep_inst, + WASMFuncType *type, void *callback); + +void +wasm_destroy_function(WASMFunctionInstance *function); + #ifdef __cplusplus } #endif From 3adfbb9cbeaca7e3cfaa82b9dd2b7e4b210deb9a Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 3 Dec 2024 09:22:58 +0000 Subject: [PATCH 08/26] Refactor: update WASM function import structure and improve memory management functions --- core/iwasm/common/wasm_c_api.c | 132 ++++++++++----- core/iwasm/common/wasm_c_api_internal.h | 40 ++++- core/iwasm/common/wasm_c_api_type_conv.c | 206 +++++++++++++++++++++++ core/iwasm/common/wasm_runtime_common.c | 14 +- core/iwasm/include/wasm_c_api.h | 3 +- core/iwasm/include/wasm_export.h | 4 + core/iwasm/interpreter/wasm.h | 1 + core/iwasm/interpreter/wasm_runtime.c | 29 ++-- 8 files changed, 358 insertions(+), 71 deletions(-) create mode 100644 core/iwasm/common/wasm_c_api_type_conv.c diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index cbb99bb1b7..e28022c8db 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -744,27 +744,6 @@ wasm_store_delete(wasm_store_t *store) } /* Type Representations */ -static inline wasm_valkind_t -val_type_rt_2_valkind(uint8 val_type_rt) -{ - switch (val_type_rt) { -#define WAMR_VAL_TYPE_2_WASM_VAL_KIND(name) \ - case VALUE_TYPE_##name: \ - return WASM_##name; - - WAMR_VAL_TYPE_2_WASM_VAL_KIND(I32) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(I64) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(F32) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(F64) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(V128) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(FUNCREF) -#undef WAMR_VAL_TYPE_2_WASM_VAL_KIND - - default: - return WASM_EXTERNREF; - } -} - static wasm_valtype_t * wasm_valtype_new_internal(uint8 val_type_rt) { @@ -3104,7 +3083,7 @@ wasm_func_new_with_env(wasm_store_t *store, const wasm_functype_t *type, } wasm_func_t * -wasm_func_new_internal(wasm_store_t *store, uint16 func_idx_rt, +wasm_func_new_internal(wasm_store_t *store, uint32 func_idx_rt, WASMModuleInstanceCommon *inst_comm_rt) { wasm_func_t *func = NULL; @@ -3605,7 +3584,7 @@ wasm_global_delete(wasm_global_t *global) #if WASM_ENABLE_INTERP != 0 static bool -interp_global_set(const WASMModuleInstance *inst_interp, uint16 global_idx_rt, +interp_global_set(const WASMModuleInstance *inst_interp, uint32 global_idx_rt, const wasm_val_t *v) { const WASMGlobalInstance *global_interp = @@ -3625,7 +3604,7 @@ interp_global_set(const WASMModuleInstance *inst_interp, uint16 global_idx_rt, } static bool -interp_global_get(const WASMModuleInstance *inst_interp, uint16 global_idx_rt, +interp_global_get(const WASMModuleInstance *inst_interp, uint32 global_idx_rt, wasm_val_t *out) { WASMGlobalInstance *global_interp = inst_interp->e->globals + global_idx_rt; @@ -3645,7 +3624,7 @@ interp_global_get(const WASMModuleInstance *inst_interp, uint16 global_idx_rt, #if WASM_ENABLE_AOT != 0 static bool -aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, +aot_global_set(const AOTModuleInstance *inst_aot, uint32 global_idx_rt, const wasm_val_t *v) { AOTModule *module_aot = (AOTModule *)inst_aot->module; @@ -3672,7 +3651,7 @@ aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, } static bool -aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, +aot_global_get(const AOTModuleInstance *inst_aot, uint32 global_idx_rt, wasm_val_t *out) { AOTModule *module_aot = (AOTModule *)inst_aot->module; @@ -3765,7 +3744,7 @@ wasm_global_get(const wasm_global_t *global, wasm_val_t *out) } wasm_global_t * -wasm_global_new_internal(wasm_store_t *store, uint16 global_idx_rt, +wasm_global_new_internal(wasm_store_t *store, uint32 global_idx_rt, WASMModuleInstanceCommon *inst_comm_rt) { wasm_global_t *global = NULL; @@ -3892,7 +3871,7 @@ wasm_table_new_basic(wasm_store_t *store, const wasm_tabletype_t *type) } wasm_table_t * -wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt, +wasm_table_new_internal(wasm_store_t *store, uint32 table_idx_rt, WASMModuleInstanceCommon *inst_comm_rt) { wasm_table_t *table = NULL; @@ -4272,7 +4251,7 @@ wasm_memory_copy(const wasm_memory_t *src) } wasm_memory_t * -wasm_memory_new_internal(wasm_store_t *store, uint16 memory_idx_rt, +wasm_memory_new_internal(wasm_store_t *store, uint32 memory_idx_rt, WASMModuleInstanceCommon *inst_comm_rt) { wasm_memory_t *memory = NULL; @@ -4490,7 +4469,7 @@ wasm_memory_grow(wasm_memory_t *memory, wasm_memory_pages_t delta) #if WASM_ENABLE_INTERP != 0 static bool interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, - uint16 func_idx_rt, wasm_func_t *import) + uint32 func_idx_rt, wasm_func_t *import) { WASMImport *imported_func_interp = NULL; @@ -4512,6 +4491,7 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, return false; imported_func_interp->u.function.call_conv_wasm_c_api = true; + /*TODO: we can avoid this step */ /* only set func_ptr_linked to avoid unlink warning during instantiation, func_ptr_linked, with_env and env will be stored in module instance's c_api_func_imports later and used when calling import function */ @@ -4528,7 +4508,7 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, } static bool -interp_link_global(const WASMModule *module_interp, uint16 global_idx_rt, +interp_link_global(const WASMModule *module_interp, uint32 global_idx_rt, wasm_global_t *import) { WASMImport *imported_global_interp = NULL; @@ -4702,7 +4682,7 @@ aot_link_func(const wasm_instance_t *inst, const AOTModule *module_aot, } static bool -aot_link_global(const AOTModule *module_aot, uint16 global_idx_rt, +aot_link_global(const AOTModule *module_aot, uint32 global_idx_rt, wasm_global_t *import) { AOTImportGlobal *import_aot_global = NULL; @@ -4953,6 +4933,70 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, &inst_args); } +bool +wasm_instance_create_import_list(const wasm_module_t *module, + const wasm_extern_vec_t *imports_src, + WASMExternInstance **imports_dst, + uint32 *imports_dst_count) +{ + *imports_dst = NULL; + *imports_dst_count = 0; + + if (!imports_src) { + LOG_VERBOSE("doesn't provide imports\n"); + *imports_dst_count = 0; + return true; + } + + wasm_importtype_vec_t import_types = { 0 }; + wasm_module_imports(module, &import_types); + + if (import_types.num_elems == 0) { + LOG_VERBOSE("module has no imports\n"); + return true; + } + + if (import_types.num_elems > imports_src->num_elems) { + LOG_ERROR("module has %d imports but only %d provided. Placeholders " + "are even allowed.\n", + import_types.num_elems, imports_src->num_elems); + return false; + } + + *imports_dst = + malloc_internal(sizeof(WASMExternInstance) * imports_src->num_elems); + if (!*imports_dst) { + return false; + } + + *imports_dst_count = (uint32)imports_src->num_elems; + + uint32 i = 0; + WASMExternInstance *import_out = *imports_dst; + for (; i < imports_src->num_elems; i++, import_out++) { + wasm_importtype_t *import_type = import_types.data[i]; + wasm_extern_t *import_in = imports_src->data[i]; + + if (!import_in) { + LOG_VERBOSE("imports[%d] is NULL and wasm_native may provide it\n", + i); + continue; + } + + if (!extern_t_to_WASMExternInstance(module, import_in, import_type, + import_out)) { + wasm_runtime_destroy_imports(*module, *imports_dst); + wasm_runtime_free(*imports_dst); + + *imports_dst = NULL; + *imports_dst_count = 0; + return false; + } + } + + return true; +} + wasm_instance_t * wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module, const wasm_extern_vec_t *imports, @@ -4986,19 +5030,25 @@ wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module, } /* executes the instantiate-time linking if provided */ - if (imports) { - if (!do_link(instance, module, imports)) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Failed to validate imports"); - goto failed; - } + struct WASMExternInstance *imports_out = NULL; + uint32 imports_out_count = 0; + if (!wasm_instance_create_import_list(module, imports, &imports_out, + &imports_out_count)) { + snprintf(sub_error_buf, sizeof(sub_error_buf), + "Failed to create import list"); + goto failed; } + + InstantiationArgs inst_args_w_imports = *inst_args; + inst_args_w_imports.imports = imports_out; + inst_args_w_imports.import_count = imports_out_count; + /* - * will do the linking result check at the end of wasm_runtime_instantiate + * will do the linking result check at the end of + * wasm_runtime_instantiate */ - instance->inst_comm_rt = wasm_runtime_instantiate_ex( - *module, inst_args, sub_error_buf, sizeof(sub_error_buf)); + *module, &inst_args_w_imports, sub_error_buf, sizeof(sub_error_buf)); if (!instance->inst_comm_rt) { goto failed; } diff --git a/core/iwasm/common/wasm_c_api_internal.h b/core/iwasm/common/wasm_c_api_internal.h index 49a17a964b..b137b98270 100644 --- a/core/iwasm/common/wasm_c_api_internal.h +++ b/core/iwasm/common/wasm_c_api_internal.h @@ -70,7 +70,7 @@ struct wasm_memorytype_t { }; struct wasm_externtype_t { - uint32 extern_kind; + wasm_externkind_t extern_kind; /* reserved space */ uint8 data[1]; }; @@ -146,7 +146,7 @@ struct wasm_func_t { * an index in both functions runtime instance lists * of interpreter mode and aot mode */ - uint16 func_idx_rt; + uint32 func_idx_rt; WASMModuleInstanceCommon *inst_comm_rt; WASMFunctionInstanceCommon *func_comm_rt; }; @@ -164,7 +164,7 @@ struct wasm_global_t { * an index in both global runtime instance lists * of interpreter mode and aot mode */ - uint16 global_idx_rt; + uint32 global_idx_rt; WASMModuleInstanceCommon *inst_comm_rt; }; @@ -180,7 +180,7 @@ struct wasm_memory_t { * an index in both memory runtime instance lists * of interpreter mode and aot mode */ - uint16 memory_idx_rt; + uint32 memory_idx_rt; WASMModuleInstanceCommon *inst_comm_rt; }; @@ -196,7 +196,7 @@ struct wasm_table_t { * an index in both table runtime instance lists * of interpreter mode and aot mode */ - uint16 table_idx_rt; + uint32 table_idx_rt; WASMModuleInstanceCommon *inst_comm_rt; }; @@ -226,21 +226,43 @@ wasm_foreign_new_internal(wasm_store_t *store, uint32 foreign_idx_rt, WASMModuleInstanceCommon *inst_comm_rt); wasm_func_t * -wasm_func_new_internal(wasm_store_t *store, uint16 func_idx_rt, +wasm_func_new_internal(wasm_store_t *store, uint32 func_idx_rt, WASMModuleInstanceCommon *inst_comm_rt); wasm_global_t * -wasm_global_new_internal(wasm_store_t *store, uint16 global_idx_rt, +wasm_global_new_internal(wasm_store_t *store, uint32 global_idx_rt, WASMModuleInstanceCommon *inst_comm_rt); wasm_memory_t * -wasm_memory_new_internal(wasm_store_t *store, uint16 memory_idx_rt, +wasm_memory_new_internal(wasm_store_t *store, uint32 memory_idx_rt, WASMModuleInstanceCommon *inst_comm_rt); wasm_table_t * -wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt, +wasm_table_new_internal(wasm_store_t *store, uint32 table_idx_rt, WASMModuleInstanceCommon *inst_comm_rt); void wasm_frame_vec_clone_internal(Vector *src, Vector *out); + +/* type conversions */ +wasm_valkind_t +val_type_rt_2_valkind(uint8 val_type_rt); + +bool +valkind_to_WASMValueType(wasm_valkind_t src, uint8 *dst); + +wasm_import_export_kind_t +externkind_to_import_export_kind(wasm_externkind_t src); + +bool +globaltype_to_WASMGlobalType(wasm_globaltype_t *src, WASMGlobalType *dst); + +bool +val_to_WASMValue(wasm_val_t *src, WASMValue *dst); + +bool +extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, + wasm_importtype_t *type, + WASMExternInstance *dst); + #endif /* _WASM_C_API_INTERNAL_H */ diff --git a/core/iwasm/common/wasm_c_api_type_conv.c b/core/iwasm/common/wasm_c_api_type_conv.c new file mode 100644 index 0000000000..34e3935ee2 --- /dev/null +++ b/core/iwasm/common/wasm_c_api_type_conv.c @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "bh_log.h" +#include "wasm_c_api_internal.h" +#include "wasm_export.h" + +/* wasm_export.h types -> wasm_c_api.h types*/ + +wasm_valkind_t +val_type_rt_2_valkind(uint8 val_type_rt) +{ + switch (val_type_rt) { +#define WAMR_VAL_TYPE_2_WASM_VAL_KIND(name) \ + case VALUE_TYPE_##name: \ + return WASM_##name; + + WAMR_VAL_TYPE_2_WASM_VAL_KIND(I32) + WAMR_VAL_TYPE_2_WASM_VAL_KIND(I64) + WAMR_VAL_TYPE_2_WASM_VAL_KIND(F32) + WAMR_VAL_TYPE_2_WASM_VAL_KIND(F64) + WAMR_VAL_TYPE_2_WASM_VAL_KIND(V128) + WAMR_VAL_TYPE_2_WASM_VAL_KIND(FUNCREF) +#undef WAMR_VAL_TYPE_2_WASM_VAL_KIND + + default: + return WASM_EXTERNREF; + } +} + +/* wasm_c_api.h types -> wasm_export.h types*/ +bool +valkind_to_WASMValueType(wasm_valkind_t src, uint8 *dst) +{ + switch (src) { +#define WASM_VAL_KIND_2_WAMR_VAL_TYPE(name) \ + case WASM_##name: \ + { \ + *dst = VALUE_TYPE_##name; \ + return true; \ + } + + WASM_VAL_KIND_2_WAMR_VAL_TYPE(I32) + WASM_VAL_KIND_2_WAMR_VAL_TYPE(I64) + WASM_VAL_KIND_2_WAMR_VAL_TYPE(F32) + WASM_VAL_KIND_2_WAMR_VAL_TYPE(F64) + WASM_VAL_KIND_2_WAMR_VAL_TYPE(V128) + WASM_VAL_KIND_2_WAMR_VAL_TYPE(FUNCREF) +#undef WASM_VAL_KIND_2_WAMR_VAL_TYPE + + default: + { + bh_assert(0); + return false; + } + } +} + +wasm_import_export_kind_t +externkind_to_import_export_kind(wasm_externkind_t src) +{ + if (src == WASM_EXTERN_FUNC) { + return WASM_IMPORT_EXPORT_KIND_FUNC; + } + else if (src == WASM_EXTERN_GLOBAL) { + return WASM_IMPORT_EXPORT_KIND_GLOBAL; + } + else if (src == WASM_EXTERN_TABLE) { + return WASM_IMPORT_EXPORT_KIND_TABLE; + } + else if (src == WASM_EXTERN_MEMORY) { + return WASM_IMPORT_EXPORT_KIND_MEMORY; + } + else { + bh_assert(0); + LOG_ERROR("Invalid wasm_externkind_t value. Can't convert to " + "wasm_import_export_kind_t"); + return 0; + } +} + +bool +globaltype_to_WASMGlobalType(wasm_globaltype_t *src, WASMGlobalType *dst) +{ + if (!valkind_to_WASMValueType(src->val_type->kind, &dst->val_type)) { + return false; + } + + dst->is_mutable = src->mutability == WASM_VAR ? WASM_VAR : WASM_CONST; + return true; +} + +bool +val_to_WASMValue(wasm_val_t *src, WASMValue *dst) +{ + switch (src->kind) { + case WASM_I32: + { + dst->i32 = src->of.i32; + break; + } + case WASM_I64: + { + dst->i64 = src->of.i64; + break; + } + case WASM_F32: + { + dst->f32 = src->of.f32; + break; + } + case WASM_F64: + { + dst->f64 = src->of.f64; + break; + } + case WASM_FUNCREF: + case WASM_EXTERNREF: + { + LOG_WARNING("Unsupported value type: %d", src->kind); + return false; + } + default: + { + return false; + } + } + + return true; +} + +bool +extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, + wasm_importtype_t *type, WASMExternInstance *dst) +{ + dst->module_name = wasm_importtype_module(type)->data; + dst->field_name = wasm_importtype_name(type)->data; + + dst->kind = externkind_to_import_export_kind(wasm_extern_kind(src)); + + switch (wasm_extern_kind(src)) { + case WASM_EXTERN_FUNC: + { + wasm_func_t *function_in = wasm_extern_as_func(src); + + WASMFuncType type = { 0 }; + /*TODO: fill more fields? */ + type.param_count = (uint16)wasm_func_param_arity(function_in); + type.result_count = (uint16)wasm_func_result_arity(function_in); + + void *function_host_ptr = function_in->with_env + ? (void *)function_in->u.cb_env.cb + : (void *)function_in->u.cb; + + dst->u.function = + wasm_runtime_create_function(*module, &type, function_host_ptr); + if (!dst->u.function) { + return false; + } + break; + } + case WASM_EXTERN_GLOBAL: + { + wasm_global_t *global_in = wasm_extern_as_global(src); + + WASMGlobalType type = { 0 }; + if (!globaltype_to_WASMGlobalType(wasm_global_type(global_in), + &type)) { + return false; + } + + dst->u.global = + wasm_runtime_create_global_internal(*module, NULL, &type); + if (!dst->u.global) { + return false; + } + + wasm_val_t val_in = { 0 }; + wasm_global_get(global_in, &val_in); + + WASMValue val_out = { 0 }; + if (!val_to_WASMValue(&val_in, &val_out)) { + return false; + } + + wasm_runtime_set_global_value(*module, dst->u.global, &val_out); + break; + } + case WASM_EXTERN_MEMORY: + { + break; + } + case WASM_EXTERN_TABLE: + { + break; + } + default: + { + return false; + } + } + + return true; +} \ No newline at end of file diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 7b33ebfba5..e6d185992f 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8089,7 +8089,11 @@ wasm_runtime_destroy_extern_inst(WASMModuleCommon *module, if (!extern_inst) return; - if (extern_inst->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { + if (extern_inst->kind == WASM_IMPORT_EXPORT_KIND_FUNC) { + wasm_runtime_destroy_function(module, extern_inst->u.function); + extern_inst->u.function = NULL; + } + else if (extern_inst->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { wasm_runtime_destroy_memory(module, extern_inst->u.memory); extern_inst->u.memory = NULL; } @@ -8176,24 +8180,22 @@ wasm_runtime_destroy_function(struct WASMModuleCommon *const module, return; } -#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_WASI_TEST != 0 /* * Be aware that it will remove all items in the list, regardless of whether * they were created by the runtime (for built-ins) or by users. */ -static void +void wasm_runtime_destroy_imports(WASMModuleCommon *module, WASMExternInstance *extern_inst_list) { if (!module || !extern_inst_list) return; - for (int32 i = 0, import_count = wasm_runtime_get_import_count(module); - i < import_count; i++) { + int32 import_count = wasm_runtime_get_import_count(module); + for (int32 i = 0; i < import_count; i++) { wasm_runtime_destroy_extern_inst(module, extern_inst_list + i); } } -#endif /* WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_WASI_TEST != 0 */ bool wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module, diff --git a/core/iwasm/include/wasm_c_api.h b/core/iwasm/include/wasm_c_api.h index 2d8e1f62bc..1946fe1fce 100644 --- a/core/iwasm/include/wasm_c_api.h +++ b/core/iwasm/include/wasm_c_api.h @@ -194,12 +194,13 @@ struct wasm_config_t { #ifndef INSTANTIATION_ARGS_OPTION_DEFINED #define INSTANTIATION_ARGS_OPTION_DEFINED +struct WASMExternInstance; /* WASM module instantiation arguments */ typedef struct InstantiationArgs { uint32_t default_stack_size; uint32_t host_managed_heap_size; uint32_t max_memory_pages; - const struct WasmExternInstance *imports; + const struct WASMExternInstance * imports; uint32_t import_count; } InstantiationArgs; #endif /* INSTANTIATION_ARGS_OPTION_DEFINED */ diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 6b4e3afdf4..5a82092f9f 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -2403,6 +2403,10 @@ wasm_runtime_create_imports_with_builtin(wasm_module_t module, wasm_extern_inst_t out, uint32_t out_len); +WASM_RUNTIME_API_EXTERN void +wasm_runtime_destroy_imports(wasm_module_t module, + wasm_extern_inst_t extern_inst_list); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 1ef13c8ee6..94d31a8b0c 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -578,6 +578,7 @@ typedef struct WASMFunctionImport { /* the type index of this function's func_type */ uint32 type_idx; #endif + /* TODO: both can be variant per instance */ bool call_conv_raw; bool call_conv_wasm_c_api; diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 9b481324a9..228361331d 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2167,13 +2167,11 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, uint32 i; for (i = 0; i < module->import_function_count; i++) { - WASMFunctionImport *func = - &((module->import_functions + i)->u.function); - if (!func->func_ptr_linked -#if WASM_ENABLE_MULTI_MODULE != 0 - && !func->import_func_linked -#endif - ) { + void *func_ptr_linked = module_inst->import_func_ptrs[i]; + if (!func_ptr_linked) { + WASMFunctionImport *func = + &((module->import_functions + i)->u.function); + LOG_WARNING("warning: failed to link import function (%s, %s)", func->module_name, func->field_name); } @@ -4691,14 +4689,14 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf, /* function name not exported, print number instead */ if (frame.func_name_wp == NULL) { line_length = - snprintf(line_buf, sizeof(line_buf), - "#%02" PRIu32 ": 0x%04x - $f%" PRIu32 "\n", n, - frame.func_offset, frame.func_index); + (uint32)snprintf(line_buf, sizeof(line_buf), + "#%02" PRIu32 ": 0x%04x - $f%" PRIu32 "\n", + n, frame.func_offset, frame.func_index); } else { - line_length = snprintf(line_buf, sizeof(line_buf), - "#%02" PRIu32 ": 0x%04x - %s\n", n, - frame.func_offset, frame.func_name_wp); + line_length = (uint32)snprintf( + line_buf, sizeof(line_buf), "#%02" PRIu32 ": 0x%04x - %s\n", + n, frame.func_offset, frame.func_name_wp); } } @@ -5519,8 +5517,11 @@ wasm_create_function(const WASMModule *module, WASMModuleInstance *dep_inst, WASMFunctionImport *func_import = (WASMFunctionImport *)(function + 1); func_import->func_ptr_linked = callback; + /* actually we don't consume type later */ WASMFuncType *func_type = (WASMFuncType *)(func_import + 1); - *func_type = *type; + if (type) { + *func_type = *type; + } /* connect all three parts */ function->u.func_import = func_import; From 0b25433f7b19fcf037f2194e921517a70290e934 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 3 Dec 2024 12:39:18 +0000 Subject: [PATCH 09/26] Refactor: streamline function call conventions by consolidating call_conv_wasm_c_api and call_conv_raw in WASM function structures --- core/iwasm/common/wasm_c_api.c | 57 +++++++++++--- core/iwasm/common/wasm_c_api_type_conv.c | 81 ++++++++------------ core/iwasm/common/wasm_runtime_common.c | 2 +- core/iwasm/fast-jit/fe/jit_emit_function.c | 7 ++ core/iwasm/interpreter/wasm.h | 6 +- core/iwasm/interpreter/wasm_interp_classic.c | 6 +- core/iwasm/interpreter/wasm_interp_fast.c | 7 +- core/iwasm/interpreter/wasm_runtime.c | 28 ++++--- core/iwasm/interpreter/wasm_runtime.h | 14 ++++ 9 files changed, 131 insertions(+), 77 deletions(-) diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index e28022c8db..40b7d244dd 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -3590,14 +3590,11 @@ interp_global_set(const WASMModuleInstance *inst_interp, uint32 global_idx_rt, const WASMGlobalInstance *global_interp = inst_interp->e->globals + global_idx_rt; uint8 val_type_rt = global_interp->type; -#if WASM_ENABLE_MULTI_MODULE != 0 - uint8 *data = global_interp->import_global_inst + + uint8 *data = global_interp->import_module_inst ? global_interp->import_module_inst->global_data + global_interp->import_global_inst->data_offset : inst_interp->global_data + global_interp->data_offset; -#else - uint8 *data = inst_interp->global_data + global_interp->data_offset; -#endif return wasm_val_to_rt_val((WASMModuleInstanceCommon *)inst_interp, val_type_rt, v, data); @@ -3609,20 +3606,18 @@ interp_global_get(const WASMModuleInstance *inst_interp, uint32 global_idx_rt, { WASMGlobalInstance *global_interp = inst_interp->e->globals + global_idx_rt; uint8 val_type_rt = global_interp->type; -#if WASM_ENABLE_MULTI_MODULE != 0 - uint8 *data = global_interp->import_global_inst + + uint8 *data = global_interp->import_module_inst ? global_interp->import_module_inst->global_data + global_interp->import_global_inst->data_offset : inst_interp->global_data + global_interp->data_offset; -#else - uint8 *data = inst_interp->global_data + global_interp->data_offset; -#endif return rt_val_to_wasm_val(data, val_type_rt, out); } #endif #if WASM_ENABLE_AOT != 0 +/*TODO: get_global_addr() */ static bool aot_global_set(const AOTModuleInstance *inst_aot, uint32 global_idx_rt, const wasm_val_t *v) @@ -4490,7 +4485,10 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, import->type, imported_func_interp->u.function.func_type)) return false; +#if WASM_ENABLE_MULTI_MODULE != 0 imported_func_interp->u.function.call_conv_wasm_c_api = true; +#endif + /*TODO: we can avoid this step */ /* only set func_ptr_linked to avoid unlink warning during instantiation, func_ptr_linked, with_env and env will be stored in module instance's @@ -5029,6 +5027,7 @@ wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module, goto failed; } +#if WASM_ENABLE_MULTI_MODULE == 0 /* executes the instantiate-time linking if provided */ struct WASMExternInstance *imports_out = NULL; uint32 imports_out_count = 0; @@ -5052,6 +5051,26 @@ wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module, if (!instance->inst_comm_rt) { goto failed; } +#else + /* mimic the instantiate-time linking if provided */ + if (imports) { + if (!do_link(instance, module, imports)) { + snprintf(sub_error_buf, sizeof(sub_error_buf), + "Failed to validate imports"); + goto failed; + } + } + + /* + * will do the linking result check at the end of + * wasm_runtime_instantiate + */ + instance->inst_comm_rt = wasm_runtime_instantiate_ex( + *module, inst_args, sub_error_buf, sizeof(sub_error_buf)); + if (!instance->inst_comm_rt) { + goto failed; + } +#endif /*WASM_ENABLE_MULTI_MODULE != 0*/ if (!wasm_runtime_create_exec_env_singleton(instance->inst_comm_rt)) { snprintf(sub_error_buf, sizeof(sub_error_buf), @@ -5116,28 +5135,44 @@ wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module, func_import++; } - /* fill with inst */ + /* fill with inst and index in space(X) */ + uint32 function_idx_rt = 0; + uint32 global_idx_rt = 0; + uint32 memory_idx_rt = 0; + uint32 table_idx_rt = 0; for (i = 0; imports && imports->data && i < imports->num_elems; ++i) { wasm_extern_t *import = imports->data[i]; bh_assert(import); switch (import->kind) { case WASM_EXTERN_FUNC: + { wasm_extern_as_func(import)->inst_comm_rt = instance->inst_comm_rt; + wasm_extern_as_func(import)->func_idx_rt = function_idx_rt++; break; + } case WASM_EXTERN_GLOBAL: + { wasm_extern_as_global(import)->inst_comm_rt = instance->inst_comm_rt; + wasm_extern_as_global(import)->global_idx_rt = global_idx_rt++; break; + } case WASM_EXTERN_MEMORY: + { wasm_extern_as_memory(import)->inst_comm_rt = instance->inst_comm_rt; + wasm_extern_as_memory(import)->memory_idx_rt = memory_idx_rt++; break; + } case WASM_EXTERN_TABLE: + { wasm_extern_as_table(import)->inst_comm_rt = instance->inst_comm_rt; + wasm_extern_as_table(import)->table_idx_rt = table_idx_rt++; break; + } default: snprintf(sub_error_buf, sizeof(sub_error_buf), "Unknown import kind"); diff --git a/core/iwasm/common/wasm_c_api_type_conv.c b/core/iwasm/common/wasm_c_api_type_conv.c index 34e3935ee2..c24d227cc3 100644 --- a/core/iwasm/common/wasm_c_api_type_conv.c +++ b/core/iwasm/common/wasm_c_api_type_conv.c @@ -92,45 +92,6 @@ globaltype_to_WASMGlobalType(wasm_globaltype_t *src, WASMGlobalType *dst) return true; } -bool -val_to_WASMValue(wasm_val_t *src, WASMValue *dst) -{ - switch (src->kind) { - case WASM_I32: - { - dst->i32 = src->of.i32; - break; - } - case WASM_I64: - { - dst->i64 = src->of.i64; - break; - } - case WASM_F32: - { - dst->f32 = src->of.f32; - break; - } - case WASM_F64: - { - dst->f64 = src->of.f64; - break; - } - case WASM_FUNCREF: - case WASM_EXTERNREF: - { - LOG_WARNING("Unsupported value type: %d", src->kind); - return false; - } - default: - { - return false; - } - } - - return true; -} - bool extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, wasm_importtype_t *type, WASMExternInstance *dst) @@ -154,11 +115,12 @@ extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, ? (void *)function_in->u.cb_env.cb : (void *)function_in->u.cb; - dst->u.function = - wasm_runtime_create_function(*module, &type, function_host_ptr); + dst->u.function = wasm_runtime_create_function_internal( + *module, NULL, &type, true, function_host_ptr); if (!dst->u.function) { return false; } + break; } case WASM_EXTERN_GLOBAL: @@ -177,15 +139,38 @@ extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, return false; } - wasm_val_t val_in = { 0 }; - wasm_global_get(global_in, &val_in); - - WASMValue val_out = { 0 }; - if (!val_to_WASMValue(&val_in, &val_out)) { - return false; + /* set init value */ + switch (global_in->init->kind) { + case WASM_I32: + { + WASMValue val = { .i32 = global_in->init->of.i32 }; + wasm_runtime_set_global_value(*module, dst->u.global, &val); + break; + } + case WASM_I64: + { + WASMValue val = { .i64 = global_in->init->of.i64 }; + wasm_runtime_set_global_value(*module, dst->u.global, &val); + break; + } + case WASM_F32: + { + WASMValue val = { .f32 = global_in->init->of.f32 }; + wasm_runtime_set_global_value(*module, dst->u.global, &val); + break; + } + case WASM_F64: + { + WASMValue val = { .f64 = global_in->init->of.f64 }; + wasm_runtime_set_global_value(*module, dst->u.global, &val); + break; + } + default: + { + return false; + } } - wasm_runtime_set_global_value(*module, dst->u.global, &val_out); break; } case WASM_EXTERN_MEMORY: diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index e6d185992f..c03d02caa5 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8131,7 +8131,7 @@ wasm_runtime_create_function_internal(struct WASMModuleCommon *const module, return NULL; } - func->u.func_import->call_conv_wasm_c_api = from_wasm_c_api; + func->call_conv_wasm_c_api = from_wasm_c_api; return (WASMFunctionInstanceCommon *)func; } #endif diff --git a/core/iwasm/fast-jit/fe/jit_emit_function.c b/core/iwasm/fast-jit/fe/jit_emit_function.c index 1e41994407..62746986b0 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_function.c +++ b/core/iwasm/fast-jit/fe/jit_emit_function.c @@ -246,7 +246,14 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call) /* Call fast_jit_invoke_native in some cases */ if (!func_import->func_ptr_linked /* import func hasn't been linked */ +#if WASM_ENABLE_MULTI_MODULE != 0 || func_import->call_conv_wasm_c_api /* linked by wasm_c_api */ +#else + /* + * TODO: can't decide if it is conv_c_api now + * but we didn't setup func_ptr_linked, too + */ +#endif || func_import->call_conv_raw /* registered as raw mode */ || func_type->param_count >= 5 /* registered as normal mode, but jit_emit_callnative only supports diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 94d31a8b0c..c74061a7d4 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -578,11 +578,13 @@ typedef struct WASMFunctionImport { /* the type index of this function's func_type */ uint32 type_idx; #endif - /* TODO: both can be variant per instance */ + + /* from wasm_native. shared in all instances of a module */ bool call_conv_raw; - bool call_conv_wasm_c_api; #if WASM_ENABLE_MULTI_MODULE != 0 + bool call_conv_wasm_c_api; + WASMModule *import_module; WASMFunction *import_func_linked; #endif diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index e492db3d64..5c3d33bc93 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1268,7 +1268,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, cur_func_index = (uint32)(cur_func - module_inst->e->functions); bh_assert(cur_func_index < module_inst->module->import_function_count); - if (!func_import->call_conv_wasm_c_api) { + if (!cur_func->call_conv_wasm_c_api) { native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; } else if (module_inst->c_api_func_imports) { @@ -1284,7 +1284,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, return; } - if (func_import->call_conv_wasm_c_api) { + if (cur_func->call_conv_wasm_c_api) { ret = wasm_runtime_invoke_c_api_native( (WASMModuleInstanceCommon *)module_inst, native_func_pointer, func_import->func_type, cur_func->param_cell_num, frame->lp, @@ -1294,7 +1294,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, argv_ret[1] = frame->lp[1]; } } - else if (!func_import->call_conv_raw) { + else if (!cur_func->call_conv_raw) { ret = wasm_runtime_invoke_native( exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 55d8d6d576..6b42dff9d0 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1209,7 +1209,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, cur_func_index = (uint32)(cur_func - module_inst->e->functions); bh_assert(cur_func_index < module_inst->module->import_function_count); - if (!func_import->call_conv_wasm_c_api) { + + if (!cur_func->call_conv_wasm_c_api) { native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; } else if (module_inst->c_api_func_imports) { @@ -1226,7 +1227,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, return; } - if (func_import->call_conv_wasm_c_api) { + if (cur_func->call_conv_wasm_c_api) { ret = wasm_runtime_invoke_c_api_native( (WASMModuleInstanceCommon *)module_inst, native_func_pointer, func_import->func_type, cur_func->param_cell_num, frame->lp, @@ -1236,7 +1237,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, argv_ret[1] = frame->lp[1]; } } - else if (!func_import->call_conv_raw) { + else if (!cur_func->call_conv_raw) { ret = wasm_runtime_invoke_native( exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 228361331d..b057e3e444 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1017,6 +1017,8 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, function->local_cell_num = 0; function->local_count = 0; function->local_types = NULL; + /* pass value from module to inst */ + function->call_conv_raw = import_func_type->call_conv_raw; /* Copy the function pointer to current instance * @@ -1040,6 +1042,8 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, } } + /* call_conv_wasm_c_api is setup by c_api */ + function->call_conv_wasm_c_api = import_func_type->call_conv_wasm_c_api; module_inst->import_func_ptrs[i] = import_func_type->func_ptr_linked; #else const WASMExternInstance *extern_inst = @@ -1068,6 +1072,9 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, (WASMFunctionInstance *)extern_inst->u.function; function->import_module_inst = extern_inst_func->import_module_inst; function->import_func_inst = extern_inst_func->import_func_inst; + + function->call_conv_wasm_c_api = + extern_inst_func->call_conv_wasm_c_api; module_inst->import_func_ptrs[i] = extern_inst_func->u.func_import->func_ptr_linked; } @@ -4808,7 +4815,10 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, bh_assert(func_idx < module->import_function_count); import_func = &module->import_functions[func_idx].u.function; - if (import_func->call_conv_wasm_c_api) { + + WASMFunctionInstance *func_inst = + wasm_locate_function_instance(module_inst, func_idx); + if (func_inst->call_conv_wasm_c_api) { if (module_inst->c_api_func_imports) { c_api_func_import = module_inst->c_api_func_imports + func_idx; func_ptr = c_api_func_import->func_ptr_linked; @@ -4828,23 +4838,23 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, } attachment = import_func->attachment; - if (import_func->call_conv_wasm_c_api) { + if (func_inst->call_conv_wasm_c_api) { ret = wasm_runtime_invoke_c_api_native( (WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc, argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg); } - else if (!import_func->call_conv_raw) { - signature = import_func->signature; - ret = - wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, - attachment, argv, argc, argv); - } - else { + else if (func_inst->call_conv_raw) { signature = import_func->signature; ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type, signature, attachment, argv, argc, argv); } + else { + signature = import_func->signature; + ret = + wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, + attachment, argv, argc, argv); + } fail: #ifdef OS_ENABLE_HW_BOUND_CHECK diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 37bb4691ec..098547b91a 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -245,6 +245,11 @@ struct WASMFunctionInstance { WASMModuleInstance *import_module_inst; WASMFunctionInstance *import_func_inst; + /* copy it from WASMFunctionImport */ + bool call_conv_raw; + /* write it from wasm_c_api */ + bool call_conv_wasm_c_api; + #if WASM_ENABLE_PERF_PROFILING != 0 /* total execution time */ uint64 total_exec_time; @@ -554,6 +559,15 @@ wasm_locate_table_elems(const WASMModule *module, WASMTableInstance *table, return table->elems; } +static inline WASMFunctionInstance * +wasm_locate_function_instance(const WASMModuleInstance *module_inst, + uint32 func_idx) +{ + WASMModuleInstanceExtra *e = (WASMModuleInstanceExtra *)module_inst->e; + WASMFunctionInstance *func = e->functions + func_idx; + return func; +} + static inline uint32 wasm_get_tbl_data_slots(const WASMTableType *table_type, const WASMTableImport *import_type) From 264c245a0cf725fd466ecbc66b5c0943880bd825 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 3 Dec 2024 23:34:03 +0000 Subject: [PATCH 10/26] Refactor: rename type variables for clarity and improve error logging for function instantiation --- core/iwasm/common/wasm_c_api_type_conv.c | 17 +++++++++-------- core/iwasm/include/wasm_export.h | 2 +- core/iwasm/interpreter/wasm_interp_classic.c | 7 +------ core/iwasm/interpreter/wasm_runtime.c | 7 +++++++ 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/core/iwasm/common/wasm_c_api_type_conv.c b/core/iwasm/common/wasm_c_api_type_conv.c index c24d227cc3..1b5e9a274d 100644 --- a/core/iwasm/common/wasm_c_api_type_conv.c +++ b/core/iwasm/common/wasm_c_api_type_conv.c @@ -106,17 +106,18 @@ extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, { wasm_func_t *function_in = wasm_extern_as_func(src); - WASMFuncType type = { 0 }; + WASMFuncType func_type = { 0 }; /*TODO: fill more fields? */ - type.param_count = (uint16)wasm_func_param_arity(function_in); - type.result_count = (uint16)wasm_func_result_arity(function_in); + func_type.param_count = (uint16)wasm_func_param_arity(function_in); + func_type.result_count = + (uint16)wasm_func_result_arity(function_in); void *function_host_ptr = function_in->with_env ? (void *)function_in->u.cb_env.cb : (void *)function_in->u.cb; dst->u.function = wasm_runtime_create_function_internal( - *module, NULL, &type, true, function_host_ptr); + *module, NULL, &func_type, true, function_host_ptr); if (!dst->u.function) { return false; } @@ -127,14 +128,14 @@ extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, { wasm_global_t *global_in = wasm_extern_as_global(src); - WASMGlobalType type = { 0 }; + WASMGlobalType global_type = { 0 }; if (!globaltype_to_WASMGlobalType(wasm_global_type(global_in), - &type)) { + &global_type)) { return false; } - dst->u.global = - wasm_runtime_create_global_internal(*module, NULL, &type); + dst->u.global = wasm_runtime_create_global_internal(*module, NULL, + &global_type); if (!dst->u.global) { return false; } diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 5a82092f9f..14e309111e 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -301,7 +301,7 @@ typedef struct WASMExternInstance { /* * to handle imports properly, - * especially for wasm_global_inst_t and wasm_func_inst_t + * especially for wasm_global_inst_t and wasm_function_inst_t */ wasm_module_inst_t dep_inst; } WASMExternInstance, *wasm_extern_inst_t; diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 5c3d33bc93..07418bd751 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1354,7 +1354,6 @@ fast_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, } #endif -#if WASM_ENABLE_MULTI_MODULE != 0 static void wasm_interp_call_func_bytecode(WASMModuleInstance *module, WASMExecEnv *exec_env, @@ -1428,7 +1427,6 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, wasm_exec_env_restore_module_inst(exec_env, (WASMModuleInstanceCommon *)module_inst); } -#endif #if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_DEBUG_INTERP != 0 @@ -7485,14 +7483,11 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, #endif if (function->is_import_func) { -#if WASM_ENABLE_MULTI_MODULE != 0 if (function->import_module_inst) { wasm_interp_call_func_import(module_inst, exec_env, function, frame); } - else -#endif - { + else { /* it is a native function */ wasm_interp_call_func_native(module_inst, exec_env, function, frame); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index b057e3e444..cfa882887b 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1070,6 +1070,13 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, /* if extern_inst is about a wasm function from other .wasm */ WASMFunctionInstance *extern_inst_func = (WASMFunctionInstance *)extern_inst->u.function; + if (!extern_inst_func) { + LOG_ERROR("function(%s, %s) is not found in extern_inst(empty)", + import_func_type->module_name, + import_func_type->field_name); + return NULL; + } + function->import_module_inst = extern_inst_func->import_module_inst; function->import_func_inst = extern_inst_func->import_func_inst; From 44c0475340e837a598cf73d9de4bcb765bebf4e5 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 3 Dec 2024 23:34:26 +0000 Subject: [PATCH 11/26] Refactor: add print wrappers and register native functions for spec test --- .../libraries/libc-builtin/builtin_wrapper.h | 4 ++ .../libc-builtin/libc_builtin_wrapper.c | 49 ------------- .../libc-builtin/spec_test_builtin_wrapper.c | 71 ++++++++++++++++++- 3 files changed, 74 insertions(+), 50 deletions(-) diff --git a/core/iwasm/libraries/libc-builtin/builtin_wrapper.h b/core/iwasm/libraries/libc-builtin/builtin_wrapper.h index de5cf77e5d..51e376d127 100644 --- a/core/iwasm/libraries/libc-builtin/builtin_wrapper.h +++ b/core/iwasm/libraries/libc-builtin/builtin_wrapper.h @@ -12,6 +12,10 @@ /************************************* * Functions *************************************/ +/* clang-format off */ +#define REG_NATIVE_FUNC(func_name, signature) \ + { #func_name, func_name##_wrapper, signature, NULL } +/* clang-format on */ /************************************* * Globals diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index ace018332f..48355e104a 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -991,55 +991,6 @@ clock_wrapper(wasm_exec_env_t exec_env) return os_time_get_boot_us() * 1000; } -#if WASM_ENABLE_SPEC_TEST != 0 -static void -print_wrapper(wasm_exec_env_t exec_env) -{ - os_printf("in specttest.print()\n"); -} - -static void -print_i32_wrapper(wasm_exec_env_t exec_env, int32 i32) -{ - os_printf("in specttest.print_i32(%" PRId32 ")\n", i32); -} - -static void -print_i64_wrapper(wasm_exec_env_t exec_env, int64 i64) -{ - os_printf("in specttest.print_i64(%" PRId64 ")\n", i64); -} - -static void -print_i32_f32_wrapper(wasm_exec_env_t exec_env, int32 i32, float f32) -{ - os_printf("in specttest.print_i32_f32(%" PRId32 ", %f)\n", i32, f32); -} - -static void -print_f64_f64_wrapper(wasm_exec_env_t exec_env, double f64_1, double f64_2) -{ - os_printf("in specttest.print_f64_f64(%f, %f)\n", f64_1, f64_2); -} - -static void -print_f32_wrapper(wasm_exec_env_t exec_env, float f32) -{ - os_printf("in specttest.print_f32(%f)\n", f32); -} - -static void -print_f64_wrapper(wasm_exec_env_t exec_env, double f64) -{ - os_printf("in specttest.print_f64(%f)\n", f64); -} -#endif /* WASM_ENABLE_SPEC_TEST */ - -/* clang-format off */ -#define REG_NATIVE_FUNC(func_name, signature) \ - { #func_name, func_name##_wrapper, signature, NULL } -/* clang-format on */ - static NativeSymbol native_symbols_libc_builtin[] = { REG_NATIVE_FUNC(printf, "($*)i"), REG_NATIVE_FUNC(sprintf, "($$*)i"), diff --git a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c index 9305be628d..5a72cde857 100644 --- a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c @@ -10,6 +10,66 @@ * Functions *************************************/ +static NativeSymbol native_symbols_spectest[] = { + REG_NATIVE_FUNC(print, "()"), + REG_NATIVE_FUNC(print_i32, "(i)"), + REG_NATIVE_FUNC(print_i64, "(I)"), + REG_NATIVE_FUNC(print_i32_f32, "(if)"), + REG_NATIVE_FUNC(print_f64_f64, "(FF)"), + REG_NATIVE_FUNC(print_f32, "(f)"), + REG_NATIVE_FUNC(print_f64, "(F)") +}; + +static void +print_wrapper(wasm_exec_env_t exec_env) +{ + os_printf("in specttest.print()\n"); +} + +static void +print_i32_wrapper(wasm_exec_env_t exec_env, int32 i32) +{ + os_printf("in specttest.print_i32(%" PRId32 ")\n", i32); +} + +static void +print_i64_wrapper(wasm_exec_env_t exec_env, int64 i64) +{ + os_printf("in specttest.print_i64(%" PRId64 ")\n", i64); +} + +static void +print_i32_f32_wrapper(wasm_exec_env_t exec_env, int32 i32, float f32) +{ + os_printf("in specttest.print_i32_f32(%" PRId32 ", %f)\n", i32, f32); +} + +static void +print_f64_f64_wrapper(wasm_exec_env_t exec_env, double f64_1, double f64_2) +{ + os_printf("in specttest.print_f64_f64(%f, %f)\n", f64_1, f64_2); +} + +static void +print_f32_wrapper(wasm_exec_env_t exec_env, float f32) +{ + os_printf("in specttest.print_f32(%f)\n", f32); +} + +static void +print_f64_wrapper(wasm_exec_env_t exec_env, double f64) +{ + os_printf("in specttest.print_f64(%f)\n", f64); +} + +static wasm_function_inst_t +create_spec_test_function(wasm_module_t module, const char *module_name, + const char *name, wasm_func_type_t type) +{ + bh_assert(false && "not implemented"); + return NULL; +} + /************************************* * Globals *************************************/ @@ -145,7 +205,16 @@ wasm_runtime_create_extern_inst_for_spec_test(wasm_module_t module, out->field_name = import_type->name; out->kind = import_type->kind; - if (import_type->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { + if (import_type->kind == WASM_IMPORT_EXPORT_KIND_FUNC) { + out->u.function = create_spec_test_function( + module, import_type->module_name, import_type->name, + import_type->u.func_type); + if (!out->u.function) { + LOG_ERROR("create function failed\n"); + return false; + } + } + else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { out->u.memory = create_spec_test_memory( module, import_type->module_name, import_type->name, import_type->u.memory_type); From dff53995e9e0ee44f4a6dc70d6118149bd7adc12 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 4 Dec 2024 00:53:43 +0000 Subject: [PATCH 12/26] Refactor: enhance import function handling and add print wrappers for spec tests --- core/iwasm/interpreter/wasm_runtime.c | 57 ++++++++------ .../libc-builtin/libc_builtin_wrapper.c | 49 ++++++++++++ .../libc-builtin/spec_test_builtin_wrapper.c | 78 ++----------------- 3 files changed, 89 insertions(+), 95 deletions(-) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index cfa882887b..1573cd0fb4 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -201,6 +201,10 @@ wasm_resolve_import_func(const WASMModule *module, WASMFunctionImport *function) function->field_name, error_buf); #endif + LOG_DEBUG("can't resolve import function %s durning loading. wait for " + "instantiation linking", + function->field_name); + return false; } @@ -1050,41 +1054,44 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, wasm_runtime_get_extern_instance(imports, import_count, WASM_IMPORT_EXPORT_KIND_FUNC, i); if (!extern_inst) { - LOG_ERROR("no import function(%s, %s) from imports list, might " + LOG_DEBUG("no import function(%s, %s) from imports list, might " "provied by wasm_native", import_func_type->module_name, import_func_type->field_name); /* so it's from wasm_native */ module_inst->import_func_ptrs[i] = import_func_type->func_ptr_linked; + continue; } - else { - /* don't allow wrong matchment */ - if (strcmp(import_func_type->field_name, extern_inst->field_name)) { - LOG_ERROR( - "mismatched import memory name: expect \"%s\", got \"%s\"", - import_func_type->field_name, extern_inst->field_name); - return NULL; - } - /* if extern_inst is about a wasm function from other .wasm */ - WASMFunctionInstance *extern_inst_func = - (WASMFunctionInstance *)extern_inst->u.function; - if (!extern_inst_func) { - LOG_ERROR("function(%s, %s) is not found in extern_inst(empty)", - import_func_type->module_name, - import_func_type->field_name); - return NULL; - } - - function->import_module_inst = extern_inst_func->import_module_inst; - function->import_func_inst = extern_inst_func->import_func_inst; - - function->call_conv_wasm_c_api = - extern_inst_func->call_conv_wasm_c_api; + /* if extern_inst is about a wasm function from other .wasm */ + WASMFunctionInstance *extern_inst_func = + (WASMFunctionInstance *)extern_inst->u.function; + if (!extern_inst_func) { + LOG_DEBUG("empty extern_inst_func for import function(%s, %s)", + "might provided by wasm_native", + import_func_type->module_name, + import_func_type->field_name); + /* so it's from wasm_native */ module_inst->import_func_ptrs[i] = - extern_inst_func->u.func_import->func_ptr_linked; + import_func_type->func_ptr_linked; + continue; + } + + /* don't allow wrong matchment */ + if (strcmp(import_func_type->field_name, extern_inst->field_name)) { + LOG_ERROR( + "mismatched import memory name: expect \"%s\", got \"%s\"", + import_func_type->field_name, extern_inst->field_name); + return NULL; } + + function->import_module_inst = extern_inst_func->import_module_inst; + function->import_func_inst = extern_inst_func->import_func_inst; + + function->call_conv_wasm_c_api = extern_inst_func->call_conv_wasm_c_api; + module_inst->import_func_ptrs[i] = + extern_inst_func->u.func_import->func_ptr_linked; #endif } diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index 48355e104a..ace018332f 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -991,6 +991,55 @@ clock_wrapper(wasm_exec_env_t exec_env) return os_time_get_boot_us() * 1000; } +#if WASM_ENABLE_SPEC_TEST != 0 +static void +print_wrapper(wasm_exec_env_t exec_env) +{ + os_printf("in specttest.print()\n"); +} + +static void +print_i32_wrapper(wasm_exec_env_t exec_env, int32 i32) +{ + os_printf("in specttest.print_i32(%" PRId32 ")\n", i32); +} + +static void +print_i64_wrapper(wasm_exec_env_t exec_env, int64 i64) +{ + os_printf("in specttest.print_i64(%" PRId64 ")\n", i64); +} + +static void +print_i32_f32_wrapper(wasm_exec_env_t exec_env, int32 i32, float f32) +{ + os_printf("in specttest.print_i32_f32(%" PRId32 ", %f)\n", i32, f32); +} + +static void +print_f64_f64_wrapper(wasm_exec_env_t exec_env, double f64_1, double f64_2) +{ + os_printf("in specttest.print_f64_f64(%f, %f)\n", f64_1, f64_2); +} + +static void +print_f32_wrapper(wasm_exec_env_t exec_env, float f32) +{ + os_printf("in specttest.print_f32(%f)\n", f32); +} + +static void +print_f64_wrapper(wasm_exec_env_t exec_env, double f64) +{ + os_printf("in specttest.print_f64(%f)\n", f64); +} +#endif /* WASM_ENABLE_SPEC_TEST */ + +/* clang-format off */ +#define REG_NATIVE_FUNC(func_name, signature) \ + { #func_name, func_name##_wrapper, signature, NULL } +/* clang-format on */ + static NativeSymbol native_symbols_libc_builtin[] = { REG_NATIVE_FUNC(printf, "($*)i"), REG_NATIVE_FUNC(sprintf, "($$*)i"), diff --git a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c index 5a72cde857..ade392959f 100644 --- a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c @@ -10,66 +10,6 @@ * Functions *************************************/ -static NativeSymbol native_symbols_spectest[] = { - REG_NATIVE_FUNC(print, "()"), - REG_NATIVE_FUNC(print_i32, "(i)"), - REG_NATIVE_FUNC(print_i64, "(I)"), - REG_NATIVE_FUNC(print_i32_f32, "(if)"), - REG_NATIVE_FUNC(print_f64_f64, "(FF)"), - REG_NATIVE_FUNC(print_f32, "(f)"), - REG_NATIVE_FUNC(print_f64, "(F)") -}; - -static void -print_wrapper(wasm_exec_env_t exec_env) -{ - os_printf("in specttest.print()\n"); -} - -static void -print_i32_wrapper(wasm_exec_env_t exec_env, int32 i32) -{ - os_printf("in specttest.print_i32(%" PRId32 ")\n", i32); -} - -static void -print_i64_wrapper(wasm_exec_env_t exec_env, int64 i64) -{ - os_printf("in specttest.print_i64(%" PRId64 ")\n", i64); -} - -static void -print_i32_f32_wrapper(wasm_exec_env_t exec_env, int32 i32, float f32) -{ - os_printf("in specttest.print_i32_f32(%" PRId32 ", %f)\n", i32, f32); -} - -static void -print_f64_f64_wrapper(wasm_exec_env_t exec_env, double f64_1, double f64_2) -{ - os_printf("in specttest.print_f64_f64(%f, %f)\n", f64_1, f64_2); -} - -static void -print_f32_wrapper(wasm_exec_env_t exec_env, float f32) -{ - os_printf("in specttest.print_f32(%f)\n", f32); -} - -static void -print_f64_wrapper(wasm_exec_env_t exec_env, double f64) -{ - os_printf("in specttest.print_f64(%f)\n", f64); -} - -static wasm_function_inst_t -create_spec_test_function(wasm_module_t module, const char *module_name, - const char *name, wasm_func_type_t type) -{ - bh_assert(false && "not implemented"); - return NULL; -} - /************************************* * Globals *************************************/ @@ -198,6 +138,13 @@ wasm_runtime_create_extern_inst_for_spec_test(wasm_module_t module, if (!module || !import_type || !out) return false; + if (import_type->kind == WASM_IMPORT_EXPORT_KIND_FUNC) { + /* Let wasm_native inject wrappers into WASMFunctionImport */ + LOG_DEBUG("skip import(%s,%s) kind %d", import_type->module_name, + import_type->name, import_type->kind); + return true; + } + LOG_DEBUG("create import(%s,%s) kind %d", import_type->module_name, import_type->name, import_type->kind); @@ -205,16 +152,7 @@ wasm_runtime_create_extern_inst_for_spec_test(wasm_module_t module, out->field_name = import_type->name; out->kind = import_type->kind; - if (import_type->kind == WASM_IMPORT_EXPORT_KIND_FUNC) { - out->u.function = create_spec_test_function( - module, import_type->module_name, import_type->name, - import_type->u.func_type); - if (!out->u.function) { - LOG_ERROR("create function failed\n"); - return false; - } - } - else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { + if (import_type->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { out->u.memory = create_spec_test_memory( module, import_type->module_name, import_type->name, import_type->u.memory_type); From c9ede66421b5953b350f8350f2ddbc7718416aad Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 4 Dec 2024 12:13:19 +0000 Subject: [PATCH 13/26] Refactor: enhance function pointer initialization for multi-module support and improve error logging --- core/iwasm/interpreter/wasm_runtime.c | 41 +++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 1573cd0fb4..15b8245ca8 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2260,6 +2260,7 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, #if WASM_ENABLE_JIT != 0 static bool init_func_ptrs(WASMModuleInstance *module_inst, WASMModule *module, + const WASMExternInstance *imports, uint32 import_count, char *error_buf, uint32 error_buf_size) { uint32 i; @@ -2276,8 +2277,43 @@ init_func_ptrs(WASMModuleInstance *module_inst, WASMModule *module, for (i = 0; i < module->import_function_count; i++, func_ptrs++) { WASMFunctionImport *import_func = &module->import_functions[i].u.function; - /* TODO: handle multi module */ + /* + * if WASM_ENABLE_MULTI_MODULE != 0, to see if + * - it is from wasm_native + * - it is from another module + * else, to see if + * - it is from wasm_native + */ + LOG_DEBUG("use loading phase linked functions for (%s,%s)", + import_func->module_name, import_func->field_name); *func_ptrs = import_func->func_ptr_linked; + if (*func_ptrs) { + continue; + } + +#if WASM_ENABLE_MULTI_MODULE == 0 + LOG_DEBUG("use instantiation phase linked for function (%s, %s)", + import_func->module_name, import_func->field_name); + + const WASMExternInstance *extern_inst = + wasm_runtime_get_extern_instance(imports, import_count, + WASM_IMPORT_EXPORT_KIND_FUNC, i); + if (!extern_inst) { + LOG_ERROR("missing an import function(%s, %s)", + import_func->module_name, import_func->field_name); + return false; + } + + WASMFunctionInstance *extern_inst_func = + (WASMFunctionInstance *)extern_inst->u.function; + if (!extern_inst_func) { + LOG_ERROR("empty WASMExternInstance for (%s, %s)", + import_func->module_name, import_func->field_name); + return false; + } + + *func_ptrs = (void *)extern_inst_func->u.func_import->func_ptr_linked; +#endif } /* The defined function pointers will be set in @@ -2895,7 +2931,8 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, #endif #if WASM_ENABLE_JIT != 0 || (module_inst->e->function_count > 0 - && !init_func_ptrs(module_inst, module, error_buf, error_buf_size)) + && !init_func_ptrs(module_inst, module, imports, import_count, + error_buf, error_buf_size)) #endif #if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || (module_inst->e->function_count > 0 From f9383ce0db1dd74b445755b9baf876f53f2de625 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 4 Dec 2024 21:22:00 +0000 Subject: [PATCH 14/26] Refactor: enhance function pointer initialization for multi-module support and improve error handling --- core/iwasm/aot/aot_runtime.c | 62 ++++++++++++++++++++----- core/iwasm/common/wasm_c_api.c | 10 +++- core/iwasm/common/wasm_runtime_common.c | 4 ++ core/iwasm/compilation/aot.h | 1 + core/iwasm/interpreter/wasm.h | 1 - core/iwasm/interpreter/wasm_runtime.c | 31 +++++++++++-- core/iwasm/interpreter/wasm_runtime.h | 32 ++++++++++++- 7 files changed, 121 insertions(+), 20 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index d4292a241a..5a8102d752 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1602,6 +1602,7 @@ aot_destroy_memory(AOTMemoryInstance *memory) static bool init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, + const WASMExternInstance *imports, uint32 import_count, char *error_buf, uint32 error_buf_size) { uint32 i; @@ -1621,13 +1622,43 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, /* Set import function pointers */ func_ptrs = (void **)module_inst->func_ptrs; for (i = 0; i < module->import_func_count; i++, func_ptrs++) { - *func_ptrs = (void *)module->import_funcs[i].func_ptr_linked; - if (!*func_ptrs) { - const char *module_name = module->import_funcs[i].module_name; - const char *field_name = module->import_funcs[i].func_name; - LOG_WARNING("warning: failed to link import function (%s, %s)", - module_name, field_name); + AOTImportFunc *import_func = module->import_funcs + i; + /* + * if WASM_ENABLE_MULTI_MODULE != 0, to see if + * - it is from wasm_native + * - it is from another module + * else, to see if + * - it is from wasm_native + */ + LOG_DEBUG("use loading phase linked functions for (%s,%s)", + import_func->module_name, import_func->func_name); + *func_ptrs = import_func->func_ptr_linked; + if (*func_ptrs) { + continue; + } + +#if WASM_ENABLE_MULTI_MODULE == 0 + LOG_DEBUG("use instantiation phase linked for function (%s, %s)", + import_func->module_name, import_func->func_name); + const WASMExternInstance *extern_inst = + wasm_runtime_get_extern_instance(imports, import_count, + WASM_IMPORT_EXPORT_KIND_FUNC, i); + if (!extern_inst) { + LOG_ERROR("missing an import function(%s, %s)", + import_func->module_name, import_func->func_name); + return false; + } + + AOTFunctionInstance *extern_inst_func = + (AOTFunctionInstance *)extern_inst->u.function; + if (!extern_inst_func) { + LOG_ERROR("empty WASMExternInstance for (%s, %s)", + import_func->module_name, import_func->func_name); + return false; } + + *func_ptrs = (void *)extern_inst_func->u.func_import->func_ptr_linked; +#endif } /* Set defined function pointers */ @@ -2301,7 +2332,8 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, goto fail; /* Initialize function pointers */ - if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size)) + if (!init_func_ptrs(module_inst, module, imports, import_count, error_buf, + error_buf_size)) goto fail; if (!create_exports(module_inst, module, error_buf, error_buf_size)) @@ -5707,6 +5739,7 @@ aot_resolve_function(const AOTModule *module, const char *function_name, bool aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) { + /* from wasm_native */ import_func->func_ptr_linked = wasm_native_resolve_symbol( import_func->module_name, import_func->func_name, import_func->func_type, &import_func->signature, @@ -5724,6 +5757,7 @@ aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) return false; } + /* from other .wasms' export functions */ char error_buf[128]; AOTModule *sub_module = (AOTModule *)wasm_runtime_load_depended_module( (WASMModuleCommon *)module, import_func->module_name, error_buf, @@ -5732,9 +5766,9 @@ aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) if (!sub_module) { LOG_DEBUG("Failed to load sub module: %s", error_buf); /* - * TOOD: call in wasm_runtime_find_module_registered() - * in aot_resolve_function_ex() is not necessary - * since wasm_runtime_load_depended_module() has been called + * TOOD: seems aot_resolve_function_ex()'s only purpose is use + * wasm_runtime_find_module_registered() again, after + * wasm_runtime_load_depended_module() called. */ import_func->func_ptr_linked = aot_resolve_function_ex( import_func->module_name, import_func->func_name, @@ -5747,12 +5781,18 @@ aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) } if (!import_func->func_ptr_linked) { - LOG_WARNING("Failed to link function: %s", error_buf); + LOG_WARNING("failed to link function (%s, %s): %s", + import_func->module_name, import_func->func_name, + error_buf); } #else (void)module; #endif + LOG_DEBUG("can't resolve import function %s durning loading. wait for " + "instantiation linking", + import_func->func_name); + return import_func->func_ptr_linked != NULL; } diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 40b7d244dd..bdf25f01e9 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -949,6 +949,7 @@ wasm_functype_results(const wasm_functype_t *func_type) return func_type->results; } +#if WASM_ENABLE_MULTI_MODULE != 0 static bool cmp_val_kind_with_val_type(wasm_valkind_t v_k, uint8 v_t) { @@ -991,6 +992,7 @@ wasm_functype_same_internal(const wasm_functype_t *type, return true; } +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ wasm_globaltype_t * wasm_globaltype_new(own wasm_valtype_t *val_type, wasm_mutability_t mut) @@ -4462,6 +4464,7 @@ wasm_memory_grow(wasm_memory_t *memory, wasm_memory_pages_t delta) } #if WASM_ENABLE_INTERP != 0 +#if WASM_ENABLE_MULTI_MODULE != 0 static bool interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, uint32 func_idx_rt, wasm_func_t *import) @@ -4485,9 +4488,7 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, import->type, imported_func_interp->u.function.func_type)) return false; -#if WASM_ENABLE_MULTI_MODULE != 0 imported_func_interp->u.function.call_conv_wasm_c_api = true; -#endif /*TODO: we can avoid this step */ /* only set func_ptr_linked to avoid unlink warning during instantiation, @@ -4556,6 +4557,7 @@ interp_link_global(const WASMModule *module_interp, uint32 global_idx_rt, imported_global_interp->u.global.is_linked = true; return true; } +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ static bool interp_process_export(wasm_store_t *store, @@ -4645,6 +4647,7 @@ interp_process_export(wasm_store_t *store, #endif /* WASM_ENABLE_INTERP */ #if WASM_ENABLE_AOT != 0 +#if WASM_ENABLE_MULTI_MODULE != 0 static bool aot_link_func(const wasm_instance_t *inst, const AOTModule *module_aot, uint32 import_func_idx_rt, wasm_func_t *import) @@ -4727,6 +4730,7 @@ aot_link_global(const AOTModule *module_aot, uint32 global_idx_rt, LOG_DEBUG("%s failed", __FUNCTION__); return false; } +#endif /* WASM_ENABLE_MULTI_MODULE != 0*/ static bool aot_process_export(wasm_store_t *store, const AOTModuleInstance *inst_aot, @@ -4821,6 +4825,7 @@ aot_process_export(wasm_store_t *store, const AOTModuleInstance *inst_aot, } #endif /* WASM_ENABLE_AOT */ +#if WASM_ENABLE_MULTI_MODULE != 0 static bool do_link(const wasm_instance_t *inst, const wasm_module_t *module, const wasm_extern_vec_t *imports) @@ -4909,6 +4914,7 @@ do_link(const wasm_instance_t *inst, const wasm_module_t *module, LOG_DEBUG("%s failed", __FUNCTION__); return false; } +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ wasm_instance_t * wasm_instance_new(wasm_store_t *store, const wasm_module_t *module, diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index c03d02caa5..4ef17d1059 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7590,6 +7590,10 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module, sub_module_inst_list_node->module_name = sub_module_list_node->module_name; + /* + * TODO: this is wired. It might be the reason + * why need aot_resolve_function_ex() + */ #if WASM_ENABLE_AOT != 0 if (module_inst->module_type == Wasm_Module_AoT) { AOTModuleInstance *aot_module_inst = diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index c662f52f51..e837d75a9a 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -191,6 +191,7 @@ typedef struct AOTImportFunc { AOTFuncType *func_type; uint32 func_type_index; /* function pointer after linked */ + void *func_ptr_linked; /* signature from registered native symbols */ const char *signature; diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index c74061a7d4..241220409c 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -567,7 +567,6 @@ typedef struct WASMFunctionImport { * native function pointer after linked * - native functions via wasm_native * - native functions via wasm_c_api. just indicators. - * - wasm function in other modules. jitted */ void *func_ptr_linked; /* signature from registered native symbols */ diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 15b8245ca8..4915794ce0 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -90,7 +90,7 @@ wasm_resolve_symbols(WASMModule *module) uint32 idx; for (idx = 0; idx < module->import_function_count; ++idx) { WASMFunctionImport *import = &module->import_functions[idx].u.function; - bool linked = import->func_ptr_linked; + bool linked = import->func_ptr_linked != NULL; #if WASM_ENABLE_MULTI_MODULE != 0 if (import->import_func_linked) { linked = true; @@ -162,7 +162,7 @@ wasm_resolve_function(const char *module_name, const char *function_name, bool wasm_resolve_import_func(const WASMModule *module, WASMFunctionImport *function) { - /* from builtin functions */ + /* from wasm_native functions */ function->func_ptr_linked = wasm_native_resolve_symbol( function->module_name, function->field_name, function->func_type, &function->signature, &function->attachment, &function->call_conv_raw); @@ -199,6 +199,8 @@ wasm_resolve_import_func(const WASMModule *module, WASMFunctionImport *function) LOG_WARNING("failed to link function (%s, %s): %s", function->module_name, function->field_name, error_buf); +#else + (void)module; #endif LOG_DEBUG("can't resolve import function %s durning loading. wait for " @@ -2278,10 +2280,12 @@ init_func_ptrs(WASMModuleInstance *module_inst, WASMModule *module, WASMFunctionImport *import_func = &module->import_functions[i].u.function; /* - * if WASM_ENABLE_MULTI_MODULE != 0, to see if + * if WASM_ENABLE_MULTI_MODULE != 0, if * - it is from wasm_native + * - if is from wasm_c_api * - it is from another module - * else, to see if + * + * otherwise, if * - it is from wasm_native */ LOG_DEBUG("use loading phase linked functions for (%s,%s)", @@ -4869,6 +4873,7 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, WASMFunctionInstance *func_inst = wasm_locate_function_instance(module_inst, func_idx); + if (func_inst->call_conv_wasm_c_api) { if (module_inst->c_api_func_imports) { c_api_func_import = module_inst->c_api_func_imports + func_idx; @@ -4890,17 +4895,35 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, attachment = import_func->attachment; if (func_inst->call_conv_wasm_c_api) { + /* from wasm_c_api */ ret = wasm_runtime_invoke_c_api_native( (WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc, argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg); } else if (func_inst->call_conv_raw) { + /* from wasm_native raw */ signature = import_func->signature; ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type, signature, attachment, argv, argc, argv); } else { + if (func_inst->import_module_inst) { + /* from other .wasm */ + exec_env = wasm_runtime_get_exec_env_singleton( + (WASMModuleInstanceCommon *)func_inst->import_module_inst); + if (!exec_env) { + wasm_runtime_set_exception( + (WASMModuleInstanceCommon *)module_inst, + "create singleton exec_env failed"); + goto fail; + } + } + + /* + * from wasm_native + * from wasm_export + */ signature = import_func->signature; ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 098547b91a..59bdb6ddc8 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -235,13 +235,41 @@ struct WASMFunctionInstance { uint8 *local_types; union { - /* from wasm_native and wasm_import (interp) */ WASMFunctionImport *func_import; /* locate bytecode */ WASMFunction *func; } u; - /* only for wasm functions of other .wasm */ + /* + * for an import funciton, + * - from wasm_natvie, + * - WASMFunctionImport.func_ptr_linked != NULL + * - import_module_inst == NULL + * - import_func_inst == NULL + * - call_conv_wasm_c_api == false + * - call_conv_raw == true or false + * + * - from wasm_c_api, + * - WASMFunctionImport.func_ptr_linked == NULL + * - import_module_inst == NULL + * - import_func_inst != NULL + * - call_conv_wasm_c_api == true + * - call_conv_raw == false + * + * - from wasm_export, + * - WASMFunctionImport.func_ptr_linked != NULL + * - import_module_inst == NULL + * - import_func_inst != NULL + * - call_conv_wasm_c_api == false + * - call_conv_raw == false + * + * - from other .wasm + * - WASMFunctionImport.func_ptr_linked == NULL + * - import_module_inst != NULL + * - import_func_inst != NULL + * - call_conv_wasm_c_api == false + * - call_conv_raw == false + */ WASMModuleInstance *import_module_inst; WASMFunctionInstance *import_func_inst; From 69d006ae5de4067bb65c879f35e2052f8ff3d0c5 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 4 Dec 2024 22:35:48 +0000 Subject: [PATCH 15/26] Refactor: enhance AOT function and import structures for multi-module support and improve clarity --- core/iwasm/aot/aot_runtime.h | 12 ++++++++++ core/iwasm/common/wasm_extern_inst.c | 0 core/iwasm/common/wasm_extern_inst.h | 0 core/iwasm/compilation/aot.h | 3 +-- core/iwasm/interpreter/wasm.h | 14 ++++------- core/iwasm/interpreter/wasm_runtime.h | 34 +++------------------------ 6 files changed, 20 insertions(+), 43 deletions(-) create mode 100644 core/iwasm/common/wasm_extern_inst.c create mode 100644 core/iwasm/common/wasm_extern_inst.h diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 0f5e6e0657..eb07ce9a8b 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -113,6 +113,16 @@ typedef struct AOTFunctionInstance { } func; AOTImportFunc *func_import; } u; + + WASMModuleInstance *import_module_inst; + WASMFunctionInstance *import_func_inst; + + /* copy it from AOTImportFunc */ + bool call_conv_raw; + /* write it from wasm_c_api */ + bool call_conv_wasm_c_api; + /* write it from wasm_c_api */ + CApiFuncImport *import_func_c_api; } AOTFunctionInstance; /* Map of a function index to the element ith in @@ -149,6 +159,8 @@ typedef struct AOTModuleInstanceExtra { #if WASM_ENABLE_MULTI_MODULE != 0 bh_list sub_module_inst_list_head; bh_list *sub_module_inst_list; + + /*TODO: remove*/ WASMModuleInstanceCommon **import_func_module_insts; #endif diff --git a/core/iwasm/common/wasm_extern_inst.c b/core/iwasm/common/wasm_extern_inst.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core/iwasm/common/wasm_extern_inst.h b/core/iwasm/common/wasm_extern_inst.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index e837d75a9a..0ea3ee1d1d 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -198,8 +198,7 @@ typedef struct AOTImportFunc { /* attachment */ void *attachment; bool call_conv_raw; - bool call_conv_wasm_c_api; - bool wasm_c_api_with_env; + } AOTImportFunc; /** diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 241220409c..4f6668983f 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -566,7 +566,9 @@ typedef struct WASMFunctionImport { /* * native function pointer after linked * - native functions via wasm_native - * - native functions via wasm_c_api. just indicators. + * + * if WASM_ENABLE_MULTI_MODULE != 0 + * - native functions via wasm_c_api. */ void *func_ptr_linked; /* signature from registered native symbols */ @@ -578,16 +580,8 @@ typedef struct WASMFunctionImport { uint32 type_idx; #endif - /* from wasm_native. shared in all instances of a module */ + /* via wasm_native */ bool call_conv_raw; - -#if WASM_ENABLE_MULTI_MODULE != 0 - bool call_conv_wasm_c_api; - - WASMModule *import_module; - WASMFunction *import_func_linked; -#endif - } WASMFunctionImport; #if WASM_ENABLE_TAGS != 0 diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 59bdb6ddc8..304aef6a00 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -236,40 +236,10 @@ struct WASMFunctionInstance { union { WASMFunctionImport *func_import; - /* locate bytecode */ + /* local bytecode */ WASMFunction *func; } u; - /* - * for an import funciton, - * - from wasm_natvie, - * - WASMFunctionImport.func_ptr_linked != NULL - * - import_module_inst == NULL - * - import_func_inst == NULL - * - call_conv_wasm_c_api == false - * - call_conv_raw == true or false - * - * - from wasm_c_api, - * - WASMFunctionImport.func_ptr_linked == NULL - * - import_module_inst == NULL - * - import_func_inst != NULL - * - call_conv_wasm_c_api == true - * - call_conv_raw == false - * - * - from wasm_export, - * - WASMFunctionImport.func_ptr_linked != NULL - * - import_module_inst == NULL - * - import_func_inst != NULL - * - call_conv_wasm_c_api == false - * - call_conv_raw == false - * - * - from other .wasm - * - WASMFunctionImport.func_ptr_linked == NULL - * - import_module_inst != NULL - * - import_func_inst != NULL - * - call_conv_wasm_c_api == false - * - call_conv_raw == false - */ WASMModuleInstance *import_module_inst; WASMFunctionInstance *import_func_inst; @@ -277,6 +247,8 @@ struct WASMFunctionInstance { bool call_conv_raw; /* write it from wasm_c_api */ bool call_conv_wasm_c_api; + /* write it from wasm_c_api */ + CApiFuncImport *import_func_c_api; #if WASM_ENABLE_PERF_PROFILING != 0 /* total execution time */ From e4729df57a0c026eab38f32ed14a31b26fa295fd Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 5 Dec 2024 06:57:37 +0000 Subject: [PATCH 16/26] Refactor: enhance C API function import handling and improve function linking logic --- core/iwasm/common/wasm_c_api.c | 7 +- core/iwasm/common/wasm_c_api_type_conv.c | 26 +++--- core/iwasm/common/wasm_runtime_common.c | 82 +++++++++++++++---- core/iwasm/common/wasm_runtime_common.h | 18 +++-- core/iwasm/interpreter/wasm.h | 14 ++-- core/iwasm/interpreter/wasm_interp_classic.c | 13 +-- core/iwasm/interpreter/wasm_interp_fast.c | 14 ++-- core/iwasm/interpreter/wasm_runtime.c | 84 +++++++++----------- core/iwasm/interpreter/wasm_runtime.h | 43 ++++++---- 9 files changed, 184 insertions(+), 117 deletions(-) diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index bdf25f01e9..6ee88f03e5 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -5034,7 +5034,7 @@ wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module, } #if WASM_ENABLE_MULTI_MODULE == 0 - /* executes the instantiate-time linking if provided */ + /* do instantiation-linking */ struct WASMExternInstance *imports_out = NULL; uint32 imports_out_count = 0; if (!wasm_instance_create_import_list(module, imports, &imports_out, @@ -5057,8 +5057,9 @@ wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module, if (!instance->inst_comm_rt) { goto failed; } + wasm_runtime_destroy_imports(*module, imports_out); #else - /* mimic the instantiate-time linking if provided */ + /* do loading-linking */ if (imports) { if (!do_link(instance, module, imports)) { snprintf(sub_error_buf, sizeof(sub_error_buf), @@ -5076,7 +5077,7 @@ wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module, if (!instance->inst_comm_rt) { goto failed; } -#endif /*WASM_ENABLE_MULTI_MODULE != 0*/ +#endif if (!wasm_runtime_create_exec_env_singleton(instance->inst_comm_rt)) { snprintf(sub_error_buf, sizeof(sub_error_buf), diff --git a/core/iwasm/common/wasm_c_api_type_conv.c b/core/iwasm/common/wasm_c_api_type_conv.c index 1b5e9a274d..3d2dfdc3a9 100644 --- a/core/iwasm/common/wasm_c_api_type_conv.c +++ b/core/iwasm/common/wasm_c_api_type_conv.c @@ -6,6 +6,7 @@ #include "bh_log.h" #include "wasm_c_api_internal.h" #include "wasm_export.h" +#include "wasm_runtime_common.h" /* wasm_export.h types -> wasm_c_api.h types*/ @@ -92,6 +93,16 @@ globaltype_to_WASMGlobalType(wasm_globaltype_t *src, WASMGlobalType *dst) return true; } +bool +func_to_CApiFuncImport(wasm_func_t *src, CApiFuncImport *dst) +{ + dst->func_ptr_linked = + src->with_env ? (void *)src->u.cb_env.cb : (void *)src->u.cb; + dst->with_env_arg = src->with_env; + dst->env_arg = src->u.cb_env.env; + return true; +} + bool extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, wasm_importtype_t *type, WASMExternInstance *dst) @@ -106,18 +117,11 @@ extern_t_to_WASMExternInstance(const wasm_module_t *module, wasm_extern_t *src, { wasm_func_t *function_in = wasm_extern_as_func(src); - WASMFuncType func_type = { 0 }; - /*TODO: fill more fields? */ - func_type.param_count = (uint16)wasm_func_param_arity(function_in); - func_type.result_count = - (uint16)wasm_func_result_arity(function_in); - - void *function_host_ptr = function_in->with_env - ? (void *)function_in->u.cb_env.cb - : (void *)function_in->u.cb; + CApiFuncImport c_api_info = { 0 }; + func_to_CApiFuncImport(function_in, &c_api_info); - dst->u.function = wasm_runtime_create_function_internal( - *module, NULL, &func_type, true, function_host_ptr); + dst->u.function = + wasm_runtime_create_function_c_api(*module, &c_api_info); if (!dst->u.function) { return false; } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 4ef17d1059..febbf609c4 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8120,29 +8120,81 @@ wasm_runtime_destroy_extern_inst(WASMModuleCommon *module, } WASMFunctionInstanceCommon * -wasm_runtime_create_function_internal(struct WASMModuleCommon *const module, - WASMModuleInstanceCommon *dep_inst, - struct WASMFuncType *const type, - bool from_wasm_c_api, void *callback) +wasm_runtime_create_function_wasm(struct WASMModuleCommon *const module, + WASMModuleInstanceCommon *dep_inst, + WASMFunctionInstanceCommon *dep_func) { #if WASM_ENABLE_INTERP != 0 if (module->module_type == Wasm_Module_Bytecode) { - WASMFunctionInstance *func = wasm_create_function( - (WASMModule *)module, (WASMModuleInstance *)dep_inst, type, - callback); + WASMFunctionInstance *func_empty = + wasm_create_function_empty((const WASMModule *)module); + func_empty->is_import_func = true; - if (!func) { - return NULL; - } + func_empty->import_module_inst = (WASMModuleInstance *)dep_inst; + func_empty->import_func_inst = (WASMFunctionInstance *)dep_func; + return (WASMFunctionInstanceCommon *)func_empty; + } +#endif - func->call_conv_wasm_c_api = from_wasm_c_api; - return (WASMFunctionInstanceCommon *)func; +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + bh_assert(false && "not supported yet"); + } +#endif + + LOG_ERROR("create function failed, invalid module type %d", + module->module_type); + return NULL; +} + +WASMFunctionInstanceCommon * +wasm_runtime_create_function_c_api(struct WASMModuleCommon *const module, + CApiFuncImport *c_api_info) +{ +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + WASMFunctionInstance *func_empty = + wasm_create_function_empty((const WASMModule *)module); + func_empty->is_import_func = true; + + func_empty->import_func_c_api = *c_api_info; + func_empty->call_conv_wasm_c_api = true; + return (WASMFunctionInstanceCommon *)func_empty; + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + bh_assert(false && "not supported yet"); + } +#endif + + LOG_ERROR("create function failed, invalid module type %d", + module->module_type); + return NULL; +} + +/*might be unused*/ +WASMFunctionInstanceCommon * +wasm_runtime_create_function_native(struct WASMModuleCommon *const module, + void *callback) +{ +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + WASMFunctionInstance *func_empty = + wasm_create_function_empty((const WASMModule *)module); + func_empty->is_import_func = true; + + func_empty->u.func_import->func_ptr_linked = callback; + /*TBC: ?*/ + func_empty->call_conv_raw = false; + + return (WASMFunctionInstanceCommon *)func_empty; } #endif #if WASM_ENABLE_AOT != 0 if (module->module_type == Wasm_Module_AoT) { - // return aot_create_function((AOTModuleInstance *)module, type); bh_assert(false && "not supported yet"); } #endif @@ -8156,8 +8208,8 @@ WASMFunctionInstanceCommon * wasm_runtime_create_function(struct WASMModuleCommon *const module, struct WASMFuncType *const type, void *callback) { - return wasm_runtime_create_function_internal(module, NULL, type, false, - callback); + bh_assert(false && "unimplemented"); + return NULL; } void diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 157fb718ba..922756d949 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -497,6 +497,16 @@ typedef struct WASMSignalInfo { #endif } WASMSignalInfo; +/* wasm-c-api import function info */ +typedef struct CApiFuncImport { + /* host func pointer after linked */ + void *func_ptr_linked; + /* whether the host func has env argument */ + bool with_env_arg; + /* the env argument of the host func */ + void *env_arg; +} CApiFuncImport; + /* Set exec_env of thread local storage */ void wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env); @@ -1240,14 +1250,12 @@ wasm_runtime_set_global_value(wasm_module_t const module, wasm_global_inst_t global, WASMValue *value); struct WASMTableInstance * -wasm_runtime_create_table_internal(WASMModuleCommon *const module, +wasm_runtime_create_table_internal(const wasm_module_t module, WASMTableType *const type); wasm_function_inst_t -wasm_runtime_create_function_internal(wasm_module_t const module, - wasm_module_inst_t dep_inst, - wasm_func_type_t const type, - bool from_wasm_c_api, void *callback); +wasm_runtime_create_function_c_api(const wasm_module_t module, + CApiFuncImport *c_api_info); #ifdef __cplusplus } diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 4f6668983f..7a9d2ff317 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -563,13 +563,7 @@ typedef struct WASMFunctionImport { char *field_name; /* function type */ WASMFuncType *func_type; - /* - * native function pointer after linked - * - native functions via wasm_native - * - * if WASM_ENABLE_MULTI_MODULE != 0 - * - native functions via wasm_c_api. - */ + /* from wasm_native */ void *func_ptr_linked; /* signature from registered native symbols */ const char *signature; @@ -582,6 +576,12 @@ typedef struct WASMFunctionImport { /* via wasm_native */ bool call_conv_raw; +#if WASM_ENABLE_MULTI_MODULE != 0 + /* by loading-link */ + bool call_conv_wasm_c_api; + WASMModule *import_module; + WASMFunction *import_func_linked; +#endif } WASMFunctionImport; #if WASM_ENABLE_TAGS != 0 diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 07418bd751..cb074e2e95 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1268,7 +1268,9 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, cur_func_index = (uint32)(cur_func - module_inst->e->functions); bh_assert(cur_func_index < module_inst->module->import_function_count); + if (!cur_func->call_conv_wasm_c_api) { + /*TODO: use func_ptrs instead */ native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; } else if (module_inst->c_api_func_imports) { @@ -1294,14 +1296,14 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, argv_ret[1] = frame->lp[1]; } } - else if (!cur_func->call_conv_raw) { - ret = wasm_runtime_invoke_native( + else if (cur_func->call_conv_raw) { + ret = wasm_runtime_invoke_native_raw( exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, cur_func->param_cell_num, argv_ret); } else { - ret = wasm_runtime_invoke_native_raw( + ret = wasm_runtime_invoke_native( exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, cur_func->param_cell_num, argv_ret); @@ -6637,8 +6639,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, call_func_from_entry: { if (cur_func->is_import_func) { - /* from other .wasm */ - if (cur_func->import_func_inst) { + if (cur_func->import_module_inst) { + /* from other .wasm */ wasm_interp_call_func_import(module, exec_env, cur_func, prev_frame); #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0 @@ -6699,6 +6701,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #endif /* end of WASM_ENABLE_EXCE_HANDLING != 0 */ } else { + /* from wasm_native or c_api */ wasm_interp_call_func_native(module, exec_env, cur_func, prev_frame); #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0 diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 6b42dff9d0..9b0492449e 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1211,6 +1211,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, bh_assert(cur_func_index < module_inst->module->import_function_count); if (!cur_func->call_conv_wasm_c_api) { + /*TODO: use func_ptrs instead */ native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; } else if (module_inst->c_api_func_imports) { @@ -1237,14 +1238,14 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, argv_ret[1] = frame->lp[1]; } } - else if (!cur_func->call_conv_raw) { - ret = wasm_runtime_invoke_native( + else if (cur_func->call_conv_raw) { + ret = wasm_runtime_invoke_native_raw( exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, cur_func->param_cell_num, argv_ret); } else { - ret = wasm_runtime_invoke_native_raw( + ret = wasm_runtime_invoke_native( exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, cur_func->param_cell_num, argv_ret); @@ -1279,7 +1280,6 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, wasm_exec_env_set_cur_frame(exec_env, prev_frame); } -#if WASM_ENABLE_MULTI_MODULE != 0 static void wasm_interp_call_func_bytecode(WASMModuleInstance *module, WASMExecEnv *exec_env, @@ -1351,7 +1351,6 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, wasm_exec_env_restore_module_inst(exec_env, (WASMModuleInstanceCommon *)module_inst); } -#endif #if WASM_ENABLE_THREAD_MGR != 0 #define CHECK_SUSPEND_FLAGS() \ @@ -6254,15 +6253,12 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, #endif if (function->is_import_func) { -#if WASM_ENABLE_MULTI_MODULE != 0 if (function->import_module_inst) { LOG_DEBUG("it is a function of a sub module"); wasm_interp_call_func_import(module_inst, exec_env, function, frame); } - else -#endif - { + else { LOG_DEBUG("it is an native function"); wasm_interp_call_func_native(module_inst, exec_env, function, frame); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 4915794ce0..273895ed13 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -90,12 +90,14 @@ wasm_resolve_symbols(WASMModule *module) uint32 idx; for (idx = 0; idx < module->import_function_count; ++idx) { WASMFunctionImport *import = &module->import_functions[idx].u.function; + /* by wasm_native */ bool linked = import->func_ptr_linked != NULL; + #if WASM_ENABLE_MULTI_MODULE != 0 - if (import->import_func_linked) { - linked = true; - } + /* by loading-linking */ + linked = import->import_func_linked != NULL; #endif + if (!linked && !wasm_resolve_import_func(module, import)) { ret = false; } @@ -1023,21 +1025,12 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, function->local_cell_num = 0; function->local_count = 0; function->local_types = NULL; - /* pass value from module to inst */ + /* copy value from module to inst */ function->call_conv_raw = import_func_type->call_conv_raw; - /* Copy the function pointer to current instance - * - * both - * - from wasm_native - * - from wasm_c_api - * - * WASM_ENABLE_MULTI_MODULE == 0 - * - other .wasm - * - from wasm_export - */ #if WASM_ENABLE_MULTI_MODULE != 0 if (import->u.function.import_module) { + /* from other .wasm */ function->import_module_inst = get_sub_module_inst( module_inst, import->u.function.import_module); @@ -1048,8 +1041,10 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, } } - /* call_conv_wasm_c_api is setup by c_api */ + /* from c_api (loading)*/ function->call_conv_wasm_c_api = import_func_type->call_conv_wasm_c_api; + + /* from wasm_native and c_api */ module_inst->import_func_ptrs[i] = import_func_type->func_ptr_linked; #else const WASMExternInstance *extern_inst = @@ -1080,6 +1075,8 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, continue; } + bh_assert(extern_inst_func->is_import_func); + /* don't allow wrong matchment */ if (strcmp(import_func_type->field_name, extern_inst->field_name)) { LOG_ERROR( @@ -1088,10 +1085,18 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, return NULL; } + /* from other .wasm */ function->import_module_inst = extern_inst_func->import_module_inst; function->import_func_inst = extern_inst_func->import_func_inst; + /* from c_api (instantiation)*/ function->call_conv_wasm_c_api = extern_inst_func->call_conv_wasm_c_api; + /* TODO: for now, let c_api finish this. Will move it to wasm_runtime + * later */ + /*module_inst->c_api_func_imports[i] = + * extern_inst_func->import_func_c_api;*/ + + /* from wasm_native */ module_inst->import_func_ptrs[i] = extern_inst_func->u.func_import->func_ptr_linked; #endif @@ -2279,17 +2284,18 @@ init_func_ptrs(WASMModuleInstance *module_inst, WASMModule *module, for (i = 0; i < module->import_function_count; i++, func_ptrs++) { WASMFunctionImport *import_func = &module->import_functions[i].u.function; + + LOG_DEBUG("use loading phase linked functions for (%s,%s)", + import_func->module_name, import_func->field_name); /* - * if WASM_ENABLE_MULTI_MODULE != 0, if - * - it is from wasm_native - * - if is from wasm_c_api - * - it is from another module + * if WASM_ENABLE_MULTI_MODULE != 0, + * - from wasm_native + * - from wasm_c_api (loading). use ModuleInstance.c_api_func_imports + * instead * * otherwise, if - * - it is from wasm_native + * - from wasm_native */ - LOG_DEBUG("use loading phase linked functions for (%s,%s)", - import_func->module_name, import_func->field_name); *func_ptrs = import_func->func_ptr_linked; if (*func_ptrs) { continue; @@ -2318,6 +2324,7 @@ init_func_ptrs(WASMModuleInstance *module_inst, WASMModule *module, *func_ptrs = (void *)extern_inst_func->u.func_import->func_ptr_linked; #endif + /* w/o from other .wasm */ } /* The defined function pointers will be set in @@ -4909,7 +4916,7 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, } else { if (func_inst->import_module_inst) { - /* from other .wasm */ + /* from other .wasm. switch */ exec_env = wasm_runtime_get_exec_env_singleton( (WASMModuleInstanceCommon *)func_inst->import_module_inst); if (!exec_env) { @@ -4918,11 +4925,13 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, "create singleton exec_env failed"); goto fail; } + + func_ptr = func_inst->import_module_inst->func_ptrs[func_idx]; + bh_assert(func_ptr); } /* * from wasm_native - * from wasm_export */ signature = import_func->signature; ret = @@ -5584,34 +5593,15 @@ wasm_destroy_global(WASMGlobalInstance *global) } WASMFunctionInstance * -wasm_create_function(const WASMModule *module, WASMModuleInstance *dep_inst, - WASMFuncType *type, void *callback) +wasm_create_function_empty(const WASMModule *module) { - WASMFunctionInstance *function = - runtime_malloc(sizeof(WASMFunctionInstance) + sizeof(WASMFunctionImport) - + sizeof(WASMFuncType), - NULL, 0); + WASMFunctionInstance *function = runtime_malloc( + sizeof(WASMFunctionInstance) + sizeof(WASMFunctionImport), NULL, 0); if (!function) { return NULL; } - /* initialize carefully */ - function->is_import_func = true; - - WASMFunctionImport *func_import = (WASMFunctionImport *)(function + 1); - func_import->func_ptr_linked = callback; - - /* actually we don't consume type later */ - WASMFuncType *func_type = (WASMFuncType *)(func_import + 1); - if (type) { - *func_type = *type; - } - - /* connect all three parts */ - function->u.func_import = func_import; - function->u.func_import->func_type = func_type; - function->import_module_inst = dep_inst; - + function->u.func_import = (WASMFunctionImport *)(function + 1); return function; } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 304aef6a00..763d609505 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -235,20 +235,21 @@ struct WASMFunctionInstance { uint8 *local_types; union { + /* func_ptr_linked setup by wasm_native */ WASMFunctionImport *func_import; /* local bytecode */ WASMFunction *func; } u; + /* from other .wasm */ WASMModuleInstance *import_module_inst; WASMFunctionInstance *import_func_inst; - /* copy it from WASMFunctionImport */ bool call_conv_raw; /* write it from wasm_c_api */ bool call_conv_wasm_c_api; - /* write it from wasm_c_api */ - CApiFuncImport *import_func_c_api; + /* WASMModuleInstance collects it to form c_api_func_imports */ + CApiFuncImport import_func_c_api; #if WASM_ENABLE_PERF_PROFILING != 0 /* total execution time */ @@ -311,16 +312,6 @@ typedef struct WASMExportTagInstance { } WASMExportTagInstance; #endif -/* wasm-c-api import function info */ -typedef struct CApiFuncImport { - /* host func pointer after linked */ - void *func_ptr_linked; - /* whether the host func has env argument */ - bool with_env_arg; - /* the env argument of the host func */ - void *env_arg; -} CApiFuncImport; - /* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */ typedef struct WASMModuleInstanceExtraCommon { #if WASM_ENABLE_MODULE_INST_CONTEXT != 0 @@ -1011,12 +1002,34 @@ void wasm_destroy_global(WASMGlobalInstance *global); WASMFunctionInstance * -wasm_create_function(const WASMModule *module, WASMModuleInstance *dep_inst, - WASMFuncType *type, void *callback); +wasm_create_function_empty(const WASMModule *module); void wasm_destroy_function(WASMFunctionInstance *function); +static inline void +wasm_function_import_from_wasm(WASMFunctionInstance *func, + WASMModuleInstance *dep_inst, + WASMFunctionInstance *dep_func) +{ + func->import_module_inst = dep_inst; + func->import_func_inst = dep_func; +} + +static inline void +wasm_function_import_from_c_api(WASMFunctionInstance *func, + CApiFuncImport *c_api_func_import) +{ + func->import_func_c_api = *c_api_func_import; +} + +/*might be unused*/ +static inline void +wasm_function_import_from_native(WASMFunctionInstance *func, void *callback) +{ + func->u.func_import->func_ptr_linked = callback; +} + #ifdef __cplusplus } #endif From 35949fd034aba789f9e78066960443d6b06b31ba Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 5 Dec 2024 10:38:52 +0000 Subject: [PATCH 17/26] Refactor: enhance multi-module support by adding sub-module instance structure and improving function import handling --- core/iwasm/aot/aot_runtime.c | 394 ++++++++++++++---------- core/iwasm/aot/aot_runtime.h | 55 +++- core/iwasm/common/wasm_runtime_common.c | 52 +--- core/iwasm/common/wasm_runtime_common.h | 9 + core/iwasm/compilation/aot.h | 12 +- core/iwasm/interpreter/wasm_runtime.c | 92 +++--- core/iwasm/interpreter/wasm_runtime.h | 11 +- 7 files changed, 361 insertions(+), 264 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 5a8102d752..e7e594a839 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -127,6 +127,28 @@ runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size) return mem; } +#if WASM_ENABLE_MULTI_MODULE != 0 +static AOTModuleInstance * +get_sub_module_inst(const AOTModuleInstance *parent_module_inst, + const AOTModule *sub_module) +{ + bh_list *sub_module_inst_list = parent_module_inst->e->sub_module_inst_list; + WASMSubModInstNode *node = bh_list_first_elem(sub_module_inst_list); + + AOTModuleInstance *inst = (AOTModuleInstance *)node->module_inst; + while (node && sub_module != (AOTModule *)inst->module) { + node = bh_list_elem_next(node); + inst = (AOTModuleInstance *)node->module_inst; + } + + if (!node) { + LOG_DEBUG("fail to find sub module instance"); + } + + return node ? inst : NULL; +} +#endif + #if WASM_ENABLE_AOT_STACK_FRAME != 0 static bool is_tiny_frame(WASMExecEnv *exec_env) @@ -760,6 +782,111 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, return NULL; } +static AOTFunctionInstance * +functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, + const WASMExternInstance *imports, uint32 import_count, + char *error_buf, uint32 error_buf_size) +{ + uint32 function_count = module->import_func_count + module->func_count; + uint64 total_size = sizeof(AOTFunctionInstance) * (uint64)function_count; + + AOTFunctionInstance *functions = + runtime_malloc(total_size, error_buf, error_buf_size); + if (!functions) { + return NULL; + } + + AOTFunctionInstance *function = functions; + for (uint32 i = 0; i < module->import_func_count; i++, function++) { + function->is_import_func = true; + function->func_index = i; + + AOTImportFunc *import = module->import_funcs + i; + /*TODO: use name section content? */ + function->func_name = import->func_name; + function->u.func_import = import; + +#if WASM_ENABLE_MULTI_MODULE != 0 + if (import->import_module) { + /* from other .wasm */ + function->import_module_inst = + get_sub_module_inst(module_inst, import->import_module); + if (!function->import_module_inst) { + set_error_buf_v(error_buf, error_buf_size, + "unknown import module \"%s\"", + import->module_name); + return NULL; + } + + function->import_func_inst = aot_lookup_function( + function->import_module_inst, import->func_name); + } + + /* from c_api (loading) */ + function->call_conv_wasm_c_api = import->call_conv_wasm_c_api; +#else + const WASMExternInstance *extern_inst = + wasm_runtime_get_extern_instance(imports, import_count, + WASM_IMPORT_EXPORT_KIND_FUNC, i); + if (!extern_inst) { + LOG_DEBUG("no import function(%s, %s) from imports list, might " + "provied by wasm_native", + import->module_name, import->func_name); + /* so it's from wasm_native */ + module_inst->import_func_ptrs[i] = import->func_ptr_linked; + continue; + } + + /* if extern_inst is about a wasm function from other .wasm */ + WASMFunctionInstance *extern_inst_func = + (WASMFunctionInstance *)extern_inst->u.function; + if (!extern_inst_func) { + LOG_DEBUG("empty extern_inst_func for import function(%s, %s)", + "might provided by wasm_native", import->module_name, + import->func_name); + /* so it's from wasm_native */ + module_inst->import_func_ptrs[i] = import->func_ptr_linked; + continue; + } + + bh_assert(extern_inst_func->is_import_func); + + /* don't allow wrong matchment */ + if (strcmp(import->func_name, extern_inst->field_name)) { + LOG_ERROR( + "mismatched import memory name: expect \"%s\", got \"%s\"", + import->func_name, extern_inst->field_name); + return NULL; + } + + /* from other .wasm */ + function->import_module_inst = extern_inst_func->import_module_inst; + function->import_func_inst = extern_inst_func->import_func_inst; + + /* from c_api (instantiation)*/ + function->call_conv_wasm_c_api = extern_inst_func->call_conv_wasm_c_api; + /* TODO: for now, let c_api finish this. Will move it to wasm_runtime + * later */ + /*module_inst->c_api_func_imports[i] = + * extern_inst_func->import_func_c_api;*/ + +#endif + } + + for (uint32 i = 0; i < module->func_count; i++, function++) { + function->is_import_func = false; + function->func_index = i + module->import_func_count; + + uint32 ftype_index = module->func_type_indexes[i]; + function->u.func.func_type = (AOTFuncType *)module->types[ftype_index]; + function->u.func.func_ptr = module->func_ptrs[i]; + } + + bh_assert((uint32)(function - functions) == function_count); + + return functions; +} + /** * Destroy table instances. */ @@ -1622,43 +1749,29 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, /* Set import function pointers */ func_ptrs = (void **)module_inst->func_ptrs; for (i = 0; i < module->import_func_count; i++, func_ptrs++) { - AOTImportFunc *import_func = module->import_funcs + i; - /* - * if WASM_ENABLE_MULTI_MODULE != 0, to see if - * - it is from wasm_native - * - it is from another module - * else, to see if - * - it is from wasm_native - */ - LOG_DEBUG("use loading phase linked functions for (%s,%s)", - import_func->module_name, import_func->func_name); - *func_ptrs = import_func->func_ptr_linked; - if (*func_ptrs) { + AOTFunctionInstance *func = + aot_locate_function_instance(module_inst, i); + bh_assert(func->is_import_func); + + if (func->call_conv_wasm_c_api) { + /* when execution, goes to invoke_native() and use + * c_api_func_imports*/ continue; } -#if WASM_ENABLE_MULTI_MODULE == 0 - LOG_DEBUG("use instantiation phase linked for function (%s, %s)", - import_func->module_name, import_func->func_name); - const WASMExternInstance *extern_inst = - wasm_runtime_get_extern_instance(imports, import_count, - WASM_IMPORT_EXPORT_KIND_FUNC, i); - if (!extern_inst) { - LOG_ERROR("missing an import function(%s, %s)", - import_func->module_name, import_func->func_name); - return false; + if (func->import_module_inst) { + /* when execution, goes to invoke_native() and switch to another + * .wasm */ + continue; } - AOTFunctionInstance *extern_inst_func = - (AOTFunctionInstance *)extern_inst->u.function; - if (!extern_inst_func) { - LOG_ERROR("empty WASMExternInstance for (%s, %s)", - import_func->module_name, import_func->func_name); - return false; - } + AOTImportFunc *import_func = func->u.func_import; - *func_ptrs = (void *)extern_inst_func->u.func_import->func_ptr_linked; -#endif + LOG_DEBUG("use wasm_native linked functions for (%s,%s)", + import_func->module_name, import_func->func_name); + + *func_ptrs = func->u.func_import->func_ptr_linked; + bh_assert(*func_ptrs); } /* Set defined function pointers */ @@ -1728,69 +1841,16 @@ aot_lookup_function_with_idx(AOTModuleInstance *module_inst, uint32 func_idx) return func_inst; } +/*TODO: */ AOTFunctionInstance * aot_get_function_instance(AOTModuleInstance *module_inst, uint32 func_idx) { - AOTModule *module = (AOTModule *)module_inst->module; AOTModuleInstanceExtra *extra = (AOTModuleInstanceExtra *)module_inst->e; - AOTFunctionInstance *func_inst; - - /* lookup from export functions first */ - if ((func_inst = aot_lookup_function_with_idx(module_inst, func_idx))) - return func_inst; - - exception_lock(module_inst); + AOTFunctionInstance *functions = extra->functions; - /* allocate functions array if needed */ - if (!extra->functions) { - uint64 func_count = - ((uint64)module->import_func_count + module->func_count); - uint64 total_size = func_count * (uint64)sizeof(AOTFunctionInstance *); + bh_assert(functions); - if ((func_count == 0) - || !(extra->functions = runtime_malloc(total_size, NULL, 0))) { - exception_unlock(module_inst); - return NULL; - } - - extra->function_count = (uint32)func_count; - } - - /* instantiate function if needed */ - bh_assert(func_idx < extra->function_count); - if (!extra->functions[func_idx]) { - AOTFunctionInstance *function = (AOTFunctionInstance *)runtime_malloc( - sizeof(AOTFunctionInstance), NULL, 0); - if (!function) { - exception_unlock(module_inst); - return NULL; - } - - if (func_idx < module->import_func_count) { - /* instantiate function from import section */ - function->is_import_func = true; - function->func_name = module->import_funcs[func_idx].func_name; - function->func_index = func_idx; - function->u.func_import = &module->import_funcs[func_idx]; - } - else { - /* instantiate non-import function */ - uint32 ftype_index = - module->func_type_indexes[func_idx - module->import_func_count]; - function->is_import_func = false; - function->func_index = func_idx; - function->u.func.func_type = - (AOTFuncType *)module->types[ftype_index]; - function->u.func.func_ptr = - module->func_ptrs[func_idx - module->import_func_count]; - } - - extra->functions[func_idx] = function; - } - - exception_unlock(module_inst); - - return extra->functions[func_idx]; + return functions + func_idx; } static bool @@ -2236,16 +2296,6 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, #if WASM_ENABLE_MULTI_MODULE != 0 extra->sub_module_inst_list = &extra->sub_module_inst_list_head; - - /* Allocate memory for import_func_module_insts*/ - if (module->import_func_count > 0 - && !(extra->import_func_module_insts = - runtime_malloc((uint64)module->import_func_count - * sizeof(WASMModuleInstanceCommon *), - error_buf, error_buf_size))) { - goto fail; - } - ret = wasm_runtime_sub_module_instantiate( (WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst, stack_size, heap_size, max_memory_pages, error_buf, error_buf_size); @@ -2331,6 +2381,15 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, imports, import_count, error_buf, error_buf_size)) goto fail; + extra->function_count = module->import_func_count + module->func_count; + if (extra->function_count > 0) { + extra->functions = + functions_instantiate(module_inst, module, imports, import_count, + error_buf, error_buf_size); + if (!extra->functions) + goto fail; + } + /* Initialize function pointers */ if (!init_func_ptrs(module_inst, module, imports, import_count, error_buf, error_buf_size)) @@ -2604,13 +2663,6 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_spawned) } #endif -#if WASM_ENABLE_MULTI_MODULE != 0 - wasm_runtime_sub_module_deinstantiate( - (WASMModuleInstanceCommon *)module_inst); - if (extra->import_func_module_insts) - wasm_runtime_free(extra->import_func_module_insts); -#endif - tables_deinstantiate(module_inst); if (module_inst->memories) @@ -2632,12 +2684,6 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_spawned) wasm_runtime_free(module_inst->export_tables); if (extra->functions) { - uint32 func_idx; - for (func_idx = 0; func_idx < extra->function_count; ++func_idx) { - if (extra->functions[func_idx]) { - wasm_runtime_free(extra->functions[func_idx]); - } - } wasm_runtime_free(extra->functions); } @@ -3486,10 +3532,7 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, AOTModuleInstance *module_inst = (AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env); AOTModule *aot_module = (AOTModule *)module_inst->module; - CApiFuncImport *c_api_func_import = - module_inst->c_api_func_imports - ? module_inst->c_api_func_imports + func_idx - : NULL; + CApiFuncImport *c_api_func_import = NULL; uint32 *func_type_indexes = module_inst->func_type_indexes; uint32 func_type_idx = func_type_indexes[func_idx]; AOTFuncType *func_type = (AOTFuncType *)aot_module->types[func_type_idx]; @@ -3503,9 +3546,17 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, bh_assert(func_idx < aot_module->import_func_count); import_func = aot_module->import_funcs + func_idx; - if (import_func->call_conv_wasm_c_api) + + AOTFunctionInstance *func_inst = + aot_locate_function_instance(module_inst, func_idx); + + if (func_inst->call_conv_wasm_c_api) { + c_api_func_import = module_inst->c_api_func_imports + ? module_inst->c_api_func_imports + func_idx + : NULL; func_ptr = c_api_func_import ? c_api_func_import->func_ptr_linked : NULL; + } if (!func_ptr) { snprintf(buf, sizeof(buf), @@ -3516,24 +3567,35 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, } attachment = import_func->attachment; - if (import_func->call_conv_wasm_c_api) { + if (func_inst->call_conv_wasm_c_api) { + /* from c_api */ ret = wasm_runtime_invoke_c_api_native( (WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc, argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg); } - else if (!import_func->call_conv_raw) { + else if (func_inst->call_conv_raw) { + /* from wasm_native raw */ signature = import_func->signature; -#if WASM_ENABLE_MULTI_MODULE != 0 - WASMModuleInstanceCommon *sub_inst = NULL; - if ((sub_inst = ((AOTModuleInstanceExtra *)module_inst->e) - ->import_func_module_insts[func_idx])) { - exec_env = wasm_runtime_get_exec_env_singleton(sub_inst); - } - if (exec_env == NULL) { - wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst, - "create singleton exec_env failed"); - goto fail; + ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type, + signature, attachment, argv, argc, + argv); + } + else { + if (func_inst->import_module_inst) { + /* from other .wasm. switch */ + exec_env = wasm_runtime_get_exec_env_singleton( + (WASMModuleInstanceCommon *)func_inst->import_module_inst); + if (exec_env == NULL) { + wasm_runtime_set_exception( + (WASMModuleInstanceCommon *)module_inst, + "create singleton exec_env failed"); + goto fail; + } + + func_ptr = func_inst->import_module_inst->func_ptrs[func_idx]; + bh_assert(func_ptr); } + #if WASM_ENABLE_AOT_STACK_FRAME != 0 void *prev_frame = get_top_frame(exec_env); @@ -3541,11 +3603,14 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, goto fail; } #endif -#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ + + /* from wasm_native */ + signature = import_func->signature; ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, attachment, argv, argc, argv); -#if WASM_ENABLE_MULTI_MODULE != 0 && WASM_ENABLE_AOT_STACK_FRAME != 0 + +#if WASM_ENABLE_AOT_STACK_FRAME != 0 /* Free all frames allocated, note that some frames may be allocated in AOT code and haven't been freed if exception occurred */ @@ -3553,12 +3618,6 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, aot_free_frame(exec_env); #endif } - else { - signature = import_func->signature; - ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type, - signature, attachment, argv, argc, - argv); - } fail: #ifdef OS_ENABLE_HW_BOUND_CHECK @@ -5764,27 +5823,28 @@ aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) sizeof(error_buf)); if (!sub_module) { - LOG_DEBUG("Failed to load sub module: %s", error_buf); - /* - * TOOD: seems aot_resolve_function_ex()'s only purpose is use - * wasm_runtime_find_module_registered() again, after - * wasm_runtime_load_depended_module() called. - */ - import_func->func_ptr_linked = aot_resolve_function_ex( - import_func->module_name, import_func->func_name, - import_func->func_type, error_buf, sizeof(error_buf)); - } - else { - import_func->func_ptr_linked = aot_resolve_function( - sub_module, import_func->func_name, import_func->func_type, - error_buf, sizeof(error_buf)); + LOG_DEBUG("failed to load sub module: %s", error_buf); + // /* + // * TOOD: seems aot_resolve_function_ex()'s only purpose is use + // * wasm_runtime_find_module_registered() again, after + // * wasm_runtime_load_depended_module() called. + // */ + // import_func->func_ptr_linked = aot_resolve_function_ex( + // import_func->module_name, import_func->func_name, + // import_func->func_type, error_buf, sizeof(error_buf)); + return false; } - if (!import_func->func_ptr_linked) { - LOG_WARNING("failed to link function (%s, %s): %s", - import_func->module_name, import_func->func_name, - error_buf); + import_func->func_ptr_linked = aot_resolve_function( + sub_module, import_func->func_name, import_func->func_type, error_buf, + sizeof(error_buf)); + if (import_func->func_ptr_linked) { + import_func->import_module = sub_module; + return true; } + + LOG_WARNING("failed to link function (%s, %s): %s", + import_func->module_name, import_func->func_name, error_buf); #else (void)module; #endif @@ -5793,7 +5853,7 @@ aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func) "instantiation linking", import_func->func_name); - return import_func->func_ptr_linked != NULL; + return false; } #if WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0 @@ -5952,4 +6012,26 @@ aot_destroy_global(AOTGlobalInstance *global) return; wasm_runtime_free(global); -} \ No newline at end of file +} + +AOTFunctionInstance * +aot_create_function_empty(const AOTModule *module) +{ + AOTFunctionInstance *function = runtime_malloc( + sizeof(AOTFunctionInstance) + sizeof(AOTImportFunc), NULL, 0); + if (!function) { + return NULL; + } + + function->u.func_import = (AOTImportFunc *)(function + 1); + return function; +} + +void +aot_destroy_function(AOTFunctionInstance *function) +{ + if (!function) + return; + + wasm_runtime_free(function); +} diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index eb07ce9a8b..cb1cef92c5 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -105,24 +105,25 @@ typedef struct AOTFunctionInstance { char *func_name; uint32 func_index; bool is_import_func; + union { struct { AOTFuncType *func_type; - /* function pointer linked */ void *func_ptr; } func; + /* setup by wasm_native */ AOTImportFunc *func_import; } u; - WASMModuleInstance *import_module_inst; - WASMFunctionInstance *import_func_inst; - + /* from other .wasm */ + AOTModuleInstance *import_module_inst; + struct AOTFunctionInstance *import_func_inst; /* copy it from AOTImportFunc */ bool call_conv_raw; /* write it from wasm_c_api */ bool call_conv_wasm_c_api; - /* write it from wasm_c_api */ - CApiFuncImport *import_func_c_api; + /* AOTModuleInstance collects it to form c_api_func_imports */ + CApiFuncImport import_func_c_api; } AOTFunctionInstance; /* Map of a function index to the element ith in @@ -153,7 +154,7 @@ typedef struct AOTModuleInstanceExtra { * created only when first time used. */ ExportFuncMap *export_func_maps; - AOTFunctionInstance **functions; + AOTFunctionInstance *functions; uint32 function_count; #if WASM_ENABLE_MULTI_MODULE != 0 @@ -161,7 +162,7 @@ typedef struct AOTModuleInstanceExtra { bh_list *sub_module_inst_list; /*TODO: remove*/ - WASMModuleInstanceCommon **import_func_module_insts; + // WASMModuleInstanceCommon **import_func_module_insts; #endif #if WASM_ENABLE_SHARED_HEAP != 0 @@ -517,6 +518,15 @@ aot_locate_table_elems(const AOTModule *module, AOTTableInstance *table, return table->elems; } +static inline AOTFunctionInstance * +aot_locate_function_instance(const AOTModuleInstance *module_inst, + uint32 func_idx) +{ + AOTModuleInstanceExtra *e = (AOTModuleInstanceExtra *)module_inst->e; + AOTFunctionInstance *func = e->functions + func_idx; + return func; +} + /** * Load a AOT module from aot file buffer * @param buf the byte buffer which contains the AOT file data @@ -944,6 +954,35 @@ aot_set_global_value(AOTGlobalInstance *global, const WASMValue *value); void aot_destroy_global(AOTGlobalInstance *global); +AOTFunctionInstance * +aot_create_function_empty(const AOTModule *module); + +void +aot_destroy_function(AOTFunctionInstance *function); + +static inline void +aot_function_import_from_wasm(AOTFunctionInstance *func, + AOTModuleInstance *dep_inst, + AOTFunctionInstance *dep_func) +{ + func->import_module_inst = dep_inst; + func->import_func_inst = dep_func; +} + +static inline void +aot_function_import_from_c_api(AOTFunctionInstance *func, + CApiFuncImport *c_api_func_import) +{ + func->import_func_c_api = *c_api_func_import; +} + +/*might be unused*/ +static inline void +aot_function_import_from_native(AOTFunctionInstance *func, void *callback) +{ + func->u.func_import->func_ptr_linked = callback; +} + #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index febbf609c4..2756db88d9 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7562,8 +7562,12 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module, bh_list_first_elem(((WASMModule *)module)->import_module_list); } #endif + if (!sub_module_inst_list) { + LOG_ERROR("unknown module type %d", module->module_type); + return false; + } + while (sub_module_list_node) { - WASMSubModInstNode *sub_module_inst_list_node = NULL; WASMModuleCommon *sub_module = sub_module_list_node->module; WASMModuleInstanceCommon *sub_module_inst = NULL; sub_module_inst = wasm_runtime_instantiate_internal( @@ -7576,8 +7580,10 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module, sub_module_list_node->module_name); return false; } - sub_module_inst_list_node = loader_malloc(sizeof(WASMSubModInstNode), - error_buf, error_buf_size); + + WASMSubModInstNode *sub_module_inst_list_node = loader_malloc( + sizeof(WASMSubModInstNode), error_buf, error_buf_size); + if (!sub_module_inst_list_node) { LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ: %zu", sizeof(WASMSubModInstNode)); @@ -7585,40 +7591,10 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module, wasm_runtime_deinstantiate_internal(sub_module_inst, false); return false; } - sub_module_inst_list_node->module_inst = - (WASMModuleInstance *)sub_module_inst; + sub_module_inst_list_node->module_inst = sub_module_inst; sub_module_inst_list_node->module_name = sub_module_list_node->module_name; - /* - * TODO: this is wired. It might be the reason - * why need aot_resolve_function_ex() - */ -#if WASM_ENABLE_AOT != 0 - if (module_inst->module_type == Wasm_Module_AoT) { - AOTModuleInstance *aot_module_inst = - (AOTModuleInstance *)module_inst; - AOTModule *aot_module = (AOTModule *)module; - AOTModuleInstanceExtra *aot_extra = - (AOTModuleInstanceExtra *)aot_module_inst->e; - uint32 i; - AOTImportFunc *import_func; - for (i = 0; i < aot_module->import_func_count; i++) { - if (aot_extra->import_func_module_insts[i]) - continue; - - import_func = &aot_module->import_funcs[i]; - if (strcmp(sub_module_inst_list_node->module_name, - import_func->module_name) - == 0) { - aot_extra->import_func_module_insts[i] = - (WASMModuleInstanceCommon *) - sub_module_inst_list_node->module_inst; - } - } - } -#endif - bh_list_status ret = bh_list_insert(sub_module_inst_list, sub_module_inst_list_node); bh_assert(BH_LIST_SUCCESS == ret); @@ -8165,7 +8141,13 @@ wasm_runtime_create_function_c_api(struct WASMModuleCommon *const module, #if WASM_ENABLE_AOT != 0 if (module->module_type == Wasm_Module_AoT) { - bh_assert(false && "not supported yet"); + AOTFunctionInstance *func_empty = + aot_create_function_empty((const AOTModule *)module); + func_empty->is_import_func = true; + + func_empty->import_func_c_api = *c_api_info; + func_empty->call_conv_wasm_c_api = true; + return (AOTFunctionInstance *)func_empty; } #endif diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 922756d949..41f726566f 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -507,6 +507,15 @@ typedef struct CApiFuncImport { void *env_arg; } CApiFuncImport; +#if WASM_ENABLE_MULTI_MODULE != 0 +typedef struct WASMSubModInstNode { + bh_list_link l; + /* point to a string pool */ + const char *module_name; + WASMModuleInstanceCommon *module_inst; +} WASMSubModInstNode; +#endif + /* Set exec_env of thread local storage */ void wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env); diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index 0ea3ee1d1d..0d1a32d4dc 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -51,6 +51,9 @@ typedef WASMMemoryType AOTMemoryType; typedef WASMTableType AOTTableType; typedef WASMTable AOTTable; +struct AOTModule; +struct AOTFunc; + #if WASM_ENABLE_DEBUG_AOT != 0 typedef void *dwarf_extractor_handle_t; #endif @@ -197,8 +200,15 @@ typedef struct AOTImportFunc { const char *signature; /* attachment */ void *attachment; - bool call_conv_raw; + /* via wasm_native */ + bool call_conv_raw; +#if WASM_ENABLE_MULTI_MODULE != 0 + /* by loading-link */ + bool call_conv_wasm_c_api; + struct AOTModule *import_module; + struct AOTFunc *import_func_linked; +#endif } AOTImportFunc; /** diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 273895ed13..3e6b5dbbd0 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -234,10 +234,17 @@ get_sub_module_inst(const WASMModuleInstance *parent_module_inst, bh_list *sub_module_inst_list = parent_module_inst->e->sub_module_inst_list; WASMSubModInstNode *node = bh_list_first_elem(sub_module_inst_list); - while (node && sub_module != node->module_inst->module) { + WASMModuleInstance *inst = (WASMModuleInstance *)node->module_inst; + while (node && sub_module != inst->module) { node = bh_list_elem_next(node); + inst = (WASMModuleInstance *)node->module_inst; } - return node ? node->module_inst : NULL; + + if (!node) { + LOG_DEBUG("fail to find sub module instance"); + } + + return node ? inst : NULL; } #endif @@ -1002,6 +1009,7 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, } total_size = sizeof(void *) * (uint64)module->import_function_count; + /*TODO: remove me if all goes to func_ptrs*/ if (total_size > 0 && !(module_inst->import_func_ptrs = runtime_malloc(total_size, error_buf, error_buf_size))) { @@ -1033,12 +1041,15 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, /* from other .wasm */ function->import_module_inst = get_sub_module_inst( module_inst, import->u.function.import_module); - - if (function->import_module_inst) { - function->import_func_inst = - wasm_lookup_function(function->import_module_inst, - import->u.function.field_name); + if (!function->import_module_inst) { + set_error_buf_v(error_buf, error_buf_size, + "unknown import module \"%s\"", + import->u.function.module_name); + return NULL; } + + function->import_func_inst = wasm_lookup_function( + function->import_module_inst, import->u.function.field_name); } /* from c_api (loading)*/ @@ -2282,49 +2293,27 @@ init_func_ptrs(WASMModuleInstance *module_inst, WASMModule *module, /* Set import function pointers */ for (i = 0; i < module->import_function_count; i++, func_ptrs++) { - WASMFunctionImport *import_func = - &module->import_functions[i].u.function; + WASMFunctionInstance *func = wasm_locate_function_instance(module, i); + bh_assert(func->is_import_func); - LOG_DEBUG("use loading phase linked functions for (%s,%s)", - import_func->module_name, import_func->field_name); - /* - * if WASM_ENABLE_MULTI_MODULE != 0, - * - from wasm_native - * - from wasm_c_api (loading). use ModuleInstance.c_api_func_imports - * instead - * - * otherwise, if - * - from wasm_native - */ - *func_ptrs = import_func->func_ptr_linked; - if (*func_ptrs) { + if (func->call_conv_wasm_c_api) { + /* when execution, goes to invoke_native() and use + * c_api_func_imports*/ continue; } -#if WASM_ENABLE_MULTI_MODULE == 0 - LOG_DEBUG("use instantiation phase linked for function (%s, %s)", - import_func->module_name, import_func->field_name); - - const WASMExternInstance *extern_inst = - wasm_runtime_get_extern_instance(imports, import_count, - WASM_IMPORT_EXPORT_KIND_FUNC, i); - if (!extern_inst) { - LOG_ERROR("missing an import function(%s, %s)", - import_func->module_name, import_func->field_name); - return false; + if (func->import_module_inst) { + /* when execution, goes to invoke_native() and switch to another + * .wasm */ + continue; } - WASMFunctionInstance *extern_inst_func = - (WASMFunctionInstance *)extern_inst->u.function; - if (!extern_inst_func) { - LOG_ERROR("empty WASMExternInstance for (%s, %s)", - import_func->module_name, import_func->field_name); - return false; - } + WASMFunctionImport *import_func = func->u.func_import; - *func_ptrs = (void *)extern_inst_func->u.func_import->func_ptr_linked; -#endif - /* w/o from other .wasm */ + LOG_DEBUG("use wasm_native linked functions for (%s,%s)", + import_func->module_name, import_func->field_name); + *func_ptrs = import_func->func_ptr_linked; + bh_assert(*func_ptrs); } /* The defined function pointers will be set in @@ -4882,14 +4871,11 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, wasm_locate_function_instance(module_inst, func_idx); if (func_inst->call_conv_wasm_c_api) { - if (module_inst->c_api_func_imports) { - c_api_func_import = module_inst->c_api_func_imports + func_idx; - func_ptr = c_api_func_import->func_ptr_linked; - } - else { - c_api_func_import = NULL; - func_ptr = NULL; - } + c_api_func_import = module_inst->c_api_func_imports + ? module_inst->c_api_func_imports + func_idx + : NULL; + func_ptr = + c_api_func_import ? c_api_func_import->func_ptr_linked : NULL; } if (!func_ptr) { @@ -4930,9 +4916,7 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, bh_assert(func_ptr); } - /* - * from wasm_native - */ + /* from wasm_native */ signature = import_func->signature; ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 763d609505..c6c88dba80 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -235,7 +235,7 @@ struct WASMFunctionInstance { uint8 *local_types; union { - /* func_ptr_linked setup by wasm_native */ + /* setup by wasm_native */ WASMFunctionImport *func_import; /* local bytecode */ WASMFunction *func; @@ -489,15 +489,6 @@ struct WASMModuleInstance { struct WASMInterpFrame; typedef struct WASMInterpFrame WASMRuntimeFrame; -#if WASM_ENABLE_MULTI_MODULE != 0 -typedef struct WASMSubModInstNode { - bh_list_link l; - /* point to a string pool */ - const char *module_name; - WASMModuleInstance *module_inst; -} WASMSubModInstNode; -#endif - /** * Return the code block of a function. * From a4019a37d5941177d3d9fd7505079dc97ae06acb Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 5 Dec 2024 12:26:25 +0000 Subject: [PATCH 18/26] Refactor: update function instance handling for improved multi-module support and clarity --- core/iwasm/aot/aot_runtime.c | 6 +++--- core/iwasm/common/wasm_runtime_common.h | 21 ++++++++++----------- core/iwasm/compilation/aot.c | 2 ++ core/iwasm/interpreter/wasm_runtime.c | 1 + 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index e7e594a839..5b62fd6a26 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -838,8 +838,8 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, } /* if extern_inst is about a wasm function from other .wasm */ - WASMFunctionInstance *extern_inst_func = - (WASMFunctionInstance *)extern_inst->u.function; + AOTFunctionInstance *extern_inst_func = + (AOTFunctionInstance *)extern_inst->u.function; if (!extern_inst_func) { LOG_DEBUG("empty extern_inst_func for import function(%s, %s)", "might provided by wasm_native", import->module_name, @@ -1770,7 +1770,7 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, LOG_DEBUG("use wasm_native linked functions for (%s,%s)", import_func->module_name, import_func->func_name); - *func_ptrs = func->u.func_import->func_ptr_linked; + *func_ptrs = import_func->func_ptr_linked; bh_assert(*func_ptrs); } diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 41f726566f..c06d137861 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -497,6 +497,15 @@ typedef struct WASMSignalInfo { #endif } WASMSignalInfo; +/* Set exec_env of thread local storage */ +void +wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env); + +/* Get exec_env of thread local storage */ +WASMExecEnv * +wasm_runtime_get_exec_env_tls(void); +#endif /* OS_ENABLE_HW_BOUND_CHECK */ + /* wasm-c-api import function info */ typedef struct CApiFuncImport { /* host func pointer after linked */ @@ -516,15 +525,6 @@ typedef struct WASMSubModInstNode { } WASMSubModInstNode; #endif -/* Set exec_env of thread local storage */ -void -wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env); - -/* Get exec_env of thread local storage */ -WASMExecEnv * -wasm_runtime_get_exec_env_tls(void); -#endif - /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN bool wasm_runtime_init(void); @@ -1183,12 +1183,11 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst, uint32 argc, uint32 *argv, bool with_env, void *wasm_c_api_env); -struct CApiFuncImport; /* A quick version of wasm_runtime_invoke_c_api_native to directly invoke wasm-c-api import function from jitted code to improve performance */ bool wasm_runtime_quick_invoke_c_api_native(WASMModuleInstanceCommon *module_inst, - struct CApiFuncImport *c_api_import, + CApiFuncImport *c_api_import, wasm_val_t *params, uint32 param_count, wasm_val_t *results, uint32 result_count); diff --git a/core/iwasm/compilation/aot.c b/core/iwasm/compilation/aot.c index 2eb4b32a3a..d44aa9313c 100644 --- a/core/iwasm/compilation/aot.c +++ b/core/iwasm/compilation/aot.c @@ -478,7 +478,9 @@ aot_create_import_funcs(const WASMModule *module) import_funcs[i].signature = import_func->signature; import_funcs[i].attachment = import_func->attachment; import_funcs[i].call_conv_raw = import_func->call_conv_raw; +#if WASM_ENABLE_MULTI_MODULE != 0 import_funcs[i].call_conv_wasm_c_api = false; +#endif /* Resolve function type index */ for (j = 0; j < module->type_count; j++) if (import_func->func_type == (WASMFuncType *)module->types[j]) { diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 3e6b5dbbd0..d4f4c39874 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2312,6 +2312,7 @@ init_func_ptrs(WASMModuleInstance *module_inst, WASMModule *module, LOG_DEBUG("use wasm_native linked functions for (%s,%s)", import_func->module_name, import_func->field_name); + *func_ptrs = import_func->func_ptr_linked; bh_assert(*func_ptrs); } From d619dc99ae10a7c54f1a71cb6b4874d2a11fc93f Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 5 Dec 2024 12:39:58 +0000 Subject: [PATCH 19/26] Refactor: remove redundant import function pointer assignments and improve function instance lookup --- core/iwasm/aot/aot_runtime.c | 2 -- core/iwasm/interpreter/wasm_runtime.c | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 5b62fd6a26..8b5a715020 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -833,7 +833,6 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, "provied by wasm_native", import->module_name, import->func_name); /* so it's from wasm_native */ - module_inst->import_func_ptrs[i] = import->func_ptr_linked; continue; } @@ -845,7 +844,6 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, "might provided by wasm_native", import->module_name, import->func_name); /* so it's from wasm_native */ - module_inst->import_func_ptrs[i] = import->func_ptr_linked; continue; } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index d4f4c39874..0bb66ae008 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2293,7 +2293,8 @@ init_func_ptrs(WASMModuleInstance *module_inst, WASMModule *module, /* Set import function pointers */ for (i = 0; i < module->import_function_count; i++, func_ptrs++) { - WASMFunctionInstance *func = wasm_locate_function_instance(module, i); + WASMFunctionInstance *func = + wasm_locate_function_instance(module_inst, i); bh_assert(func->is_import_func); if (func->call_conv_wasm_c_api) { From 12210571477f4ac29adddaa57bd0b26ef21af8e7 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 5 Dec 2024 14:04:34 +0000 Subject: [PATCH 20/26] Refactor: update memory flag handling and improve type consistency in AOT loader --- core/iwasm/aot/aot_loader.c | 6 +++--- core/iwasm/common/wasm_loader_common.c | 3 ++- core/iwasm/common/wasm_loader_common.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 31d28b83bf..47b42e3b24 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -668,7 +668,7 @@ load_native_symbol_section(const uint8 *buf, const uint8 *buf_end, goto fail; } - for (i = cnt - 1; i >= 0; i--) { + for (i = (int32)cnt - 1; i >= 0; i--) { read_string(p, p_end, symbol); if (!strlen(symbol)) continue; @@ -3840,7 +3840,7 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, /* The layout is: literal size + literal + code (with plt table) */ uint8 *mmap_addr = module->literal - sizeof(uint32); uint32 total_size = - sizeof(uint32) + module->literal_size + module->code_size; + (uint32)sizeof(uint32) + module->literal_size + module->code_size; os_mprotect(mmap_addr, total_size, map_prot); } @@ -4529,7 +4529,7 @@ aot_unload(AOTModule *module) /* The layout is: literal size + literal + code (with plt table) */ uint8 *mmap_addr = module->literal - sizeof(uint32); uint32 total_size = - sizeof(uint32) + module->literal_size + module->code_size; + (uint32)sizeof(uint32) + module->literal_size + module->code_size; os_munmap(mmap_addr, total_size); } diff --git a/core/iwasm/common/wasm_loader_common.c b/core/iwasm/common/wasm_loader_common.c index 97ea5efd19..847c0a153a 100644 --- a/core/iwasm/common/wasm_loader_common.c +++ b/core/iwasm/common/wasm_loader_common.c @@ -51,9 +51,10 @@ check_memory64_flags_consistency(WASMModule *module, char *error_buf, #endif bool -wasm_memory_check_flags(const uint8 mem_flag, char *error_buf, +wasm_memory_check_flags(const uint32 mem_flag_w, char *error_buf, uint32 error_buf_size, bool is_aot) { + uint8 mem_flag = (uint8)(mem_flag_w & 0xFF); /* Check whether certain features indicated by mem_flag are enabled in * runtime */ if (mem_flag > MAX_PAGE_COUNT_FLAG) { diff --git a/core/iwasm/common/wasm_loader_common.h b/core/iwasm/common/wasm_loader_common.h index 81174fb264..2e143d322d 100644 --- a/core/iwasm/common/wasm_loader_common.h +++ b/core/iwasm/common/wasm_loader_common.h @@ -22,7 +22,7 @@ check_memory64_flags_consistency(WASMModule *module, char *error_buf, #endif bool -wasm_memory_check_flags(const uint8 mem_flag, char *error_buf, +wasm_memory_check_flags(const uint32 mem_flag, char *error_buf, uint32 error_buf_size, bool is_aot); bool From a68d9f936ca65ca98a8fc12a84b0c5b230508339 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 5 Dec 2024 15:10:58 +0000 Subject: [PATCH 21/26] Refactor: improve function pointer retrieval and error handling in AOT runtime --- core/iwasm/aot/aot_runtime.c | 51 ++++++++++++--------------- core/iwasm/aot/aot_runtime.h | 38 ++++++++++++++++++-- core/iwasm/interpreter/wasm_runtime.c | 18 +++++++--- core/iwasm/interpreter/wasm_runtime.h | 8 +++++ 4 files changed, 79 insertions(+), 36 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 8b5a715020..83386cda3f 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -820,6 +820,12 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, function->import_func_inst = aot_lookup_function( function->import_module_inst, import->func_name); + if (!function->import_func_inst) { + set_error_buf_v(error_buf, error_buf_size, + "unknown import function \"%s\"", + import->func_name); + return NULL; + } } /* from c_api (loading) */ @@ -1888,6 +1894,7 @@ cmp_func_inst(const void *a, const void *b) return strcmp(func_inst1->func_name, func_inst2->func_name); } +/* TODO: Can I reuse the AOTFunctionInstance ?*/ static bool create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module, char *error_buf, uint32 error_buf_size) @@ -1908,23 +1915,16 @@ create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module, for (i = 0; i < module->export_count; i++) { if (exports[i].kind == EXPORT_KIND_FUNC) { - export_func->func_name = exports[i].name; - export_func->func_index = exports[i].index; - if (export_func->func_index < module->import_func_count) { - export_func->is_import_func = true; - export_func->u.func_import = - &module->import_funcs[export_func->func_index]; - } - else { - export_func->is_import_func = false; - func_index = - export_func->func_index - module->import_func_count; - ftype_index = module->func_type_indexes[func_index]; - export_func->u.func.func_type = - (AOTFuncType *)module->types[ftype_index]; - export_func->u.func.func_ptr = - module->func_ptrs[func_index]; + AOTFunctionInstance *function = + aot_locate_function_instance(module_inst, exports[i].index); + if (!function) { + set_error_buf_v(error_buf, error_buf_size, + "unknown function %s", exports[i].name); + return false; } + + *export_func = *function; + export_func->func_name = exports[i].name; export_func++; } } @@ -2875,9 +2875,12 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0; bool ret; /* init_func_ptrs() has already copied func_ptr_linked value*/ - void *func_ptr = function->u.func.func_ptr; + // bh_assert(false); void *attachment = NULL; + void *func_ptr = + aot_get_function_pointer(module_inst, function->func_index, function); + #if WASM_ENABLE_MULTI_MODULE != 0 /* * TODO: this searching for sub_module_inst @@ -3535,7 +3538,7 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, uint32 func_type_idx = func_type_indexes[func_idx]; AOTFuncType *func_type = (AOTFuncType *)aot_module->types[func_type_idx]; void **func_ptrs = module_inst->func_ptrs; - void *func_ptr = func_ptrs[func_idx]; + void *func_ptr = NULL; AOTImportFunc *import_func; const char *signature; void *attachment; @@ -3548,14 +3551,7 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, AOTFunctionInstance *func_inst = aot_locate_function_instance(module_inst, func_idx); - if (func_inst->call_conv_wasm_c_api) { - c_api_func_import = module_inst->c_api_func_imports - ? module_inst->c_api_func_imports + func_idx - : NULL; - func_ptr = - c_api_func_import ? c_api_func_import->func_ptr_linked : NULL; - } - + func_ptr = aot_get_function_pointer(module_inst, func_idx, func_inst); if (!func_ptr) { snprintf(buf, sizeof(buf), "failed to call unlinked import function (%s, %s)", @@ -3589,9 +3585,6 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, "create singleton exec_env failed"); goto fail; } - - func_ptr = func_inst->import_module_inst->func_ptrs[func_idx]; - bh_assert(func_ptr); } #if WASM_ENABLE_AOT_STACK_FRAME != 0 diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index cb1cef92c5..549f1bbdb3 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -519,14 +519,46 @@ aot_locate_table_elems(const AOTModule *module, AOTTableInstance *table, } static inline AOTFunctionInstance * -aot_locate_function_instance(const AOTModuleInstance *module_inst, - uint32 func_idx) +aot_locate_function_instance(const AOTModuleInstance *inst, uint32 func_idx) { - AOTModuleInstanceExtra *e = (AOTModuleInstanceExtra *)module_inst->e; + AOTModuleInstanceExtra *e = (AOTModuleInstanceExtra *)inst->e; AOTFunctionInstance *func = e->functions + func_idx; return func; } +static inline void * +aot_get_function_pointer(const AOTModuleInstance *module_inst, uint32 func_idx, + const AOTFunctionInstance *func_inst) +{ + void **func_ptrs = module_inst->func_ptrs; + void *func_ptr = NULL; + CApiFuncImport *c_api_func_import = NULL; + + if (func_inst->call_conv_wasm_c_api) { + c_api_func_import = module_inst->c_api_func_imports + ? module_inst->c_api_func_imports + func_idx + : NULL; + func_ptr = + c_api_func_import ? c_api_func_import->func_ptr_linked : NULL; + } + else if (func_inst->call_conv_raw) { + func_ptr = func_ptrs[func_idx]; + } + else { + if (func_inst->import_module_inst) { + uint32 funx_idx_of_import_func = + func_inst->import_func_inst->func_index; + func_ptr = func_inst->import_module_inst + ->func_ptrs[funx_idx_of_import_func]; + } + else { + func_ptr = func_ptrs[func_idx]; + } + } + + return func_ptr; +} + /** * Load a AOT module from aot file buffer * @param buf the byte buffer which contains the AOT file data diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 0bb66ae008..57c7cef534 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4863,7 +4863,6 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, func_type_indexes = module_inst->func_type_indexes; func_type_idx = func_type_indexes[func_idx]; func_type = (WASMFuncType *)module->types[func_type_idx]; - func_ptr = module_inst->func_ptrs[func_idx]; bh_assert(func_idx < module->import_function_count); @@ -4879,6 +4878,20 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, func_ptr = c_api_func_import ? c_api_func_import->func_ptr_linked : NULL; } + else if (func_inst->call_conv_raw) { + func_ptr = module_inst->func_ptrs[func_idx]; + } + else { + if (func_inst->import_module_inst) { + uint32 funx_idx_of_import_func = wasm_calc_function_index( + func_inst->import_module_inst, func_inst->import_func_inst); + func_ptr = func_inst->import_module_inst + ->func_ptrs[funx_idx_of_import_func]; + } + else { + func_ptr = module_inst->func_ptrs[func_idx]; + } + } if (!func_ptr) { snprintf(buf, sizeof(buf), @@ -4913,9 +4926,6 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, "create singleton exec_env failed"); goto fail; } - - func_ptr = func_inst->import_module_inst->func_ptrs[func_idx]; - bh_assert(func_ptr); } /* from wasm_native */ diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index c6c88dba80..ff07ad0d7f 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -550,6 +550,14 @@ wasm_locate_function_instance(const WASMModuleInstance *module_inst, return func; } +static inline uint32 +wasm_calc_function_index(const WASMModuleInstance *module_inst, + const WASMFunctionInstance *func) +{ + return (uint32)(func + - ((WASMModuleInstanceExtra *)module_inst->e)->functions); +} + static inline uint32 wasm_get_tbl_data_slots(const WASMTableType *table_type, const WASMTableImport *import_type) From cbb33b4ae888bcebbbb7e5c18bc5291d66022d3d Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Sat, 7 Dec 2024 11:49:27 +0000 Subject: [PATCH 22/26] Refactor: enhance C API function import handling in native invocation --- core/iwasm/aot/aot_runtime.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 83386cda3f..3533b889e7 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -3563,6 +3563,11 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, attachment = import_func->attachment; if (func_inst->call_conv_wasm_c_api) { /* from c_api */ + c_api_func_import = module_inst->c_api_func_imports + ? module_inst->c_api_func_imports + func_idx + : NULL; + bh_assert(c_api_func_import + && "c_api_func_imports should be set in c_api"); ret = wasm_runtime_invoke_c_api_native( (WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc, argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg); From dbe689acc14f89f77325102cfcc992d736915058 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Mon, 13 Jan 2025 06:16:38 +0000 Subject: [PATCH 23/26] Refactor: rename function pointers for clarity and improve import function handling --- core/iwasm/aot/aot_runtime.c | 99 +++++++++++++++++++----------------- core/iwasm/aot/aot_runtime.h | 70 ++++++++++++++++--------- 2 files changed, 97 insertions(+), 72 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 3533b889e7..54b0c13da1 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -787,8 +787,7 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, const WASMExternInstance *imports, uint32 import_count, char *error_buf, uint32 error_buf_size) { - uint32 function_count = module->import_func_count + module->func_count; - uint64 total_size = sizeof(AOTFunctionInstance) * (uint64)function_count; + uint64 total_size = sizeof(AOTFunctionInstance) * module->import_func_count; AOTFunctionInstance *functions = runtime_malloc(total_size, error_buf, error_buf_size); @@ -815,7 +814,7 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, set_error_buf_v(error_buf, error_buf_size, "unknown import module \"%s\"", import->module_name); - return NULL; + goto fail; } function->import_func_inst = aot_lookup_function( @@ -824,7 +823,7 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, set_error_buf_v(error_buf, error_buf_size, "unknown import function \"%s\"", import->func_name); - return NULL; + goto fail; } } @@ -860,7 +859,7 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, LOG_ERROR( "mismatched import memory name: expect \"%s\", got \"%s\"", import->func_name, extern_inst->field_name); - return NULL; + goto fail; } /* from other .wasm */ @@ -877,18 +876,10 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #endif } - for (uint32 i = 0; i < module->func_count; i++, function++) { - function->is_import_func = false; - function->func_index = i + module->import_func_count; - - uint32 ftype_index = module->func_type_indexes[i]; - function->u.func.func_type = (AOTFuncType *)module->types[ftype_index]; - function->u.func.func_ptr = module->func_ptrs[i]; - } - - bh_assert((uint32)(function - functions) == function_count); - return functions; +fail: + wasm_runtime_free(functions); + return NULL; } /** @@ -1754,7 +1745,7 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, func_ptrs = (void **)module_inst->func_ptrs; for (i = 0; i < module->import_func_count; i++, func_ptrs++) { AOTFunctionInstance *func = - aot_locate_function_instance(module_inst, i); + aot_locate_import_function_instance(module_inst, i); bh_assert(func->is_import_func); if (func->call_conv_wasm_c_api) { @@ -1850,11 +1841,11 @@ AOTFunctionInstance * aot_get_function_instance(AOTModuleInstance *module_inst, uint32 func_idx) { AOTModuleInstanceExtra *extra = (AOTModuleInstanceExtra *)module_inst->e; - AOTFunctionInstance *functions = extra->functions; + AOTFunctionInstance *import_functions = extra->import_functions; - bh_assert(functions); + bh_assert(import_functions); - return functions + func_idx; + return import_functions + func_idx; } static bool @@ -1914,19 +1905,33 @@ create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module, module_inst->export_functions = (void *)export_func; for (i = 0; i < module->export_count; i++) { - if (exports[i].kind == EXPORT_KIND_FUNC) { - AOTFunctionInstance *function = - aot_locate_function_instance(module_inst, exports[i].index); - if (!function) { - set_error_buf_v(error_buf, error_buf_size, - "unknown function %s", exports[i].name); - return false; - } + if (exports[i].kind != EXPORT_KIND_FUNC) { + continue; + } + + export_func->func_index = exports[i].index; - *export_func = *function; - export_func->func_name = exports[i].name; - export_func++; + if (export_func->func_index < module->import_func_count) { + AOTFunctionInstance *import_func = + aot_locate_import_function_instance( + module_inst, export_func->func_index); + *export_func = *import_func; } + else { + export_func->is_import_func = false; + + func_index = + export_func->func_index - module->import_func_count; + ftype_index = module->func_type_indexes[func_index]; + export_func->u.func.func_type = + (AOTFuncType *)module->types[ftype_index]; + + export_func->u.func.func_ptr = module->func_ptrs[func_index]; + } + + /* always use export names */ + export_func->func_name = exports[i].name; + export_func++; } qsort(module_inst->export_functions, module_inst->export_func_count, @@ -2381,10 +2386,10 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, extra->function_count = module->import_func_count + module->func_count; if (extra->function_count > 0) { - extra->functions = + extra->import_functions = functions_instantiate(module_inst, module, imports, import_count, error_buf, error_buf_size); - if (!extra->functions) + if (!extra->import_functions) goto fail; } @@ -2681,8 +2686,8 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_spawned) if (module_inst->export_tables) wasm_runtime_free(module_inst->export_tables); - if (extra->functions) { - wasm_runtime_free(extra->functions); + if (extra->import_functions) { + wasm_runtime_free(extra->import_functions); } if (extra->globals) { @@ -2874,12 +2879,11 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, uint32 result_count = func_type->result_count; uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0; bool ret; - /* init_func_ptrs() has already copied func_ptr_linked value*/ - // bh_assert(false); void *attachment = NULL; + /* init_func_ptrs() has already copied func_ptr_linked value */ void *func_ptr = - aot_get_function_pointer(module_inst, function->func_index, function); + aot_get_function_pointer(module_inst, function->func_index); #if WASM_ENABLE_MULTI_MODULE != 0 /* @@ -3537,7 +3541,6 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, uint32 *func_type_indexes = module_inst->func_type_indexes; uint32 func_type_idx = func_type_indexes[func_idx]; AOTFuncType *func_type = (AOTFuncType *)aot_module->types[func_type_idx]; - void **func_ptrs = module_inst->func_ptrs; void *func_ptr = NULL; AOTImportFunc *import_func; const char *signature; @@ -3548,10 +3551,7 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, import_func = aot_module->import_funcs + func_idx; - AOTFunctionInstance *func_inst = - aot_locate_function_instance(module_inst, func_idx); - - func_ptr = aot_get_function_pointer(module_inst, func_idx, func_inst); + func_ptr = aot_get_function_pointer(module_inst, func_idx); if (!func_ptr) { snprintf(buf, sizeof(buf), "failed to call unlinked import function (%s, %s)", @@ -3560,14 +3560,17 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, goto fail; } - attachment = import_func->attachment; + AOTFunctionInstance *func_inst = + aot_locate_import_function_instance(module_inst, func_idx); if (func_inst->call_conv_wasm_c_api) { /* from c_api */ c_api_func_import = module_inst->c_api_func_imports ? module_inst->c_api_func_imports + func_idx : NULL; - bh_assert(c_api_func_import - && "c_api_func_imports should be set in c_api"); + if (!c_api_func_import) { + LOG_ERROR("c_api_func_imports should be set in c_api"); + goto fail; + } ret = wasm_runtime_invoke_c_api_native( (WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc, argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg); @@ -3575,6 +3578,7 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, else if (func_inst->call_conv_raw) { /* from wasm_native raw */ signature = import_func->signature; + attachment = import_func->attachment; ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type, signature, attachment, argv, argc, argv); @@ -3602,6 +3606,7 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, /* from wasm_native */ signature = import_func->signature; + attachment = import_func->attachment; ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, attachment, argv, argc, argv); @@ -4150,7 +4155,7 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx, return; } - if (!length) { + if (!length || !tbl_seg_init_values) { return; } diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 549f1bbdb3..0e1c3f0fa0 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -154,7 +154,7 @@ typedef struct AOTModuleInstanceExtra { * created only when first time used. */ ExportFuncMap *export_func_maps; - AOTFunctionInstance *functions; + AOTFunctionInstance *import_functions; uint32 function_count; #if WASM_ENABLE_MULTI_MODULE != 0 @@ -238,7 +238,7 @@ typedef struct AOTModule { /* function info */ uint32 func_count; - /* func pointers of AOTed (un-imported) functions */ + /* func pointers of AOTed (imported + local) functions */ void **func_ptrs; /* func type indexes of AOTed (un-imported) functions */ uint32 *func_type_indexes; @@ -519,41 +519,61 @@ aot_locate_table_elems(const AOTModule *module, AOTTableInstance *table, } static inline AOTFunctionInstance * -aot_locate_function_instance(const AOTModuleInstance *inst, uint32 func_idx) +aot_locate_import_function_instance(const AOTModuleInstance *inst, + uint32 func_idx) { + AOTModule *module = (AOTModule *)inst->module; + if (func_idx >= module->import_func_count) { + LOG_ERROR("You can only locate import function instance by func_idx " + "with this function."); + bh_assert(0); + return NULL; + } + AOTModuleInstanceExtra *e = (AOTModuleInstanceExtra *)inst->e; - AOTFunctionInstance *func = e->functions + func_idx; + AOTFunctionInstance *func = e->import_functions + func_idx; + bh_assert(func && "func is NULL"); return func; } static inline void * -aot_get_function_pointer(const AOTModuleInstance *module_inst, uint32 func_idx, - const AOTFunctionInstance *func_inst) +aot_get_function_pointer(const AOTModuleInstance *module_inst, uint32 func_idx) { void **func_ptrs = module_inst->func_ptrs; void *func_ptr = NULL; - CApiFuncImport *c_api_func_import = NULL; - - if (func_inst->call_conv_wasm_c_api) { - c_api_func_import = module_inst->c_api_func_imports - ? module_inst->c_api_func_imports + func_idx - : NULL; - func_ptr = - c_api_func_import ? c_api_func_import->func_ptr_linked : NULL; - } - else if (func_inst->call_conv_raw) { - func_ptr = func_ptrs[func_idx]; - } - else { - if (func_inst->import_module_inst) { - uint32 funx_idx_of_import_func = - func_inst->import_func_inst->func_index; - func_ptr = func_inst->import_module_inst - ->func_ptrs[funx_idx_of_import_func]; + + AOTModule *module = (AOTModule *)module_inst->module; + if (func_idx < module->import_func_count) { + const AOTFunctionInstance *func_inst = + aot_locate_import_function_instance(module_inst, func_idx); + + if (func_inst->call_conv_wasm_c_api) { + CApiFuncImport *c_api_func_import = + module_inst->c_api_func_imports + ? module_inst->c_api_func_imports + func_idx + : NULL; + func_ptr = + c_api_func_import ? c_api_func_import->func_ptr_linked : NULL; } - else { + else if (func_inst->call_conv_raw) { func_ptr = func_ptrs[func_idx]; } + else { + if (func_inst->import_module_inst) { + /* from other module */ + uint32 funx_idx_of_import_func = + func_inst->import_func_inst->func_index; + func_ptr = func_inst->import_module_inst + ->func_ptrs[funx_idx_of_import_func]; + } + else { + /* from host APIs, like wasm_export.h, in the future */ + func_ptr = func_ptrs[func_idx]; + } + } + } + else { + func_ptr = func_ptrs[func_idx]; } return func_ptr; From 897ca2e9e32913eb771d4976248269bd96e7e16e Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 15 Jan 2025 21:38:23 +0000 Subject: [PATCH 24/26] Refactor: rename function instantiation methods for clarity and consistency --- core/iwasm/aot/aot_runtime.c | 16 +++++++++------- core/iwasm/common/wasm_extern_inst.c | 0 core/iwasm/common/wasm_extern_inst.h | 0 core/iwasm/interpreter/wasm_runtime.c | 10 ++++++---- 4 files changed, 15 insertions(+), 11 deletions(-) delete mode 100644 core/iwasm/common/wasm_extern_inst.c delete mode 100644 core/iwasm/common/wasm_extern_inst.h diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 54b0c13da1..c99ad8aee5 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -783,9 +783,10 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, } static AOTFunctionInstance * -functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, - const WASMExternInstance *imports, uint32 import_count, - char *error_buf, uint32 error_buf_size) +import_functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, + const WASMExternInstance *imports, + uint32 import_count, char *error_buf, + uint32 error_buf_size) { uint64 total_size = sizeof(AOTFunctionInstance) * module->import_func_count; @@ -835,7 +836,7 @@ functions_instantiate(AOTModuleInstance *module_inst, AOTModule *module, WASM_IMPORT_EXPORT_KIND_FUNC, i); if (!extern_inst) { LOG_DEBUG("no import function(%s, %s) from imports list, might " - "provied by wasm_native", + "provided by wasm_native", import->module_name, import->func_name); /* so it's from wasm_native */ continue; @@ -2386,9 +2387,9 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, extra->function_count = module->import_func_count + module->func_count; if (extra->function_count > 0) { - extra->import_functions = - functions_instantiate(module_inst, module, imports, import_count, - error_buf, error_buf_size); + extra->import_functions = import_functions_instantiate( + module_inst, module, imports, import_count, error_buf, + error_buf_size); if (!extra->import_functions) goto fail; } @@ -6018,6 +6019,7 @@ aot_destroy_global(AOTGlobalInstance *global) AOTFunctionInstance * aot_create_function_empty(const AOTModule *module) { + /*TODO: might remove tailed AOTImportFunc */ AOTFunctionInstance *function = runtime_malloc( sizeof(AOTFunctionInstance) + sizeof(AOTImportFunc), NULL, 0); if (!function) { diff --git a/core/iwasm/common/wasm_extern_inst.c b/core/iwasm/common/wasm_extern_inst.c deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core/iwasm/common/wasm_extern_inst.h b/core/iwasm/common/wasm_extern_inst.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 57c7cef534..9856c4a6cd 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -994,9 +994,11 @@ functions_deinstantiate(WASMFunctionInstance *functions) * Instantiate functions in a module. */ static WASMFunctionInstance * -functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, - const WASMExternInstance *imports, uint32 import_count, - char *error_buf, uint32 error_buf_size) +import_functions_instantiate(const WASMModule *module, + WASMModuleInstance *module_inst, + const WASMExternInstance *imports, + uint32 import_count, char *error_buf, + uint32 error_buf_size) { WASMImport *import; uint32 i, @@ -2903,7 +2905,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, module, module_inst, first_table, imports, import_count, error_buf, error_buf_size))) || (module_inst->e->function_count > 0 - && !(module_inst->e->functions = functions_instantiate( + && !(module_inst->e->functions = import_functions_instantiate( module, module_inst, imports, import_count, error_buf, error_buf_size))) || (module_inst->export_func_count > 0 From 32dab97b7b41686ad6a9394586ffd898c9b12b82 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 15 Jan 2025 07:31:56 +0000 Subject: [PATCH 25/26] Refactor: improve error handling for import function linking and enhance memory allocation consistency --- core/iwasm/aot/aot_runtime.c | 6 +++++- core/iwasm/common/wasm_c_api.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index c99ad8aee5..9546777d3c 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1767,7 +1767,11 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, import_func->module_name, import_func->func_name); *func_ptrs = import_func->func_ptr_linked; - bh_assert(*func_ptrs); + + if (!func_ptrs) { + LOG_WARNING("warning: failed to link import function (%s,%s)", + import_func->module_name, import_func->func_name); + } } /* Set defined function pointers */ diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 6ee88f03e5..67f0306b0f 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -4968,7 +4968,7 @@ wasm_instance_create_import_list(const wasm_module_t *module, } *imports_dst = - malloc_internal(sizeof(WASMExternInstance) * imports_src->num_elems); + malloc_internal((uint64)sizeof(WASMExternInstance) * imports_src->num_elems); if (!*imports_dst) { return false; } From ee34499554eb15d3ff847eb1719055bf3a418f81 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 16 Jan 2025 07:30:29 +0000 Subject: [PATCH 26/26] Refactor: improve formatting and readability in AOT runtime and C API functions --- core/iwasm/aot/aot_runtime.c | 2 +- core/iwasm/common/wasm_c_api.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 9546777d3c..e32fbbec9c 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1770,7 +1770,7 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, if (!func_ptrs) { LOG_WARNING("warning: failed to link import function (%s,%s)", - import_func->module_name, import_func->func_name); + import_func->module_name, import_func->func_name); } } diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 67f0306b0f..dbb167fbe3 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -4967,8 +4967,8 @@ wasm_instance_create_import_list(const wasm_module_t *module, return false; } - *imports_dst = - malloc_internal((uint64)sizeof(WASMExternInstance) * imports_src->num_elems); + *imports_dst = malloc_internal((uint64)sizeof(WASMExternInstance) + * imports_src->num_elems); if (!*imports_dst) { return false; }