diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 0abafd9d..5c813183 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -634,73 +634,6 @@ str2uint32(const char *buf, uint32 *p_res); static bool str2uint64(const char *buf, uint64 *p_res); -#if WASM_ENABLE_MULTI_MODULE != 0 -static void * -aot_loader_resolve_function(const AOTModule *module, const char *function_name, - const AOTFuncType *expected_function_type, - char *error_buf, uint32 error_buf_size); - -static void * -aot_loader_resolve_function_ex(const char *module_name, - const char *function_name, - const AOTFuncType *expected_function_type, - char *error_buf, uint32 error_buf_size) -{ - WASMModuleCommon *module_reg; - - module_reg = wasm_runtime_find_module_registered(module_name); - if (!module_reg || module_reg->module_type != Wasm_Module_AoT) { - LOG_DEBUG("can not find a module named %s for function %s", module_name, - function_name); - set_error_buf(error_buf, error_buf_size, "unknown import"); - return NULL; - } - return aot_loader_resolve_function((AOTModule *)module_reg, function_name, - expected_function_type, error_buf, - error_buf_size); -} - -static void * -aot_loader_resolve_function(const AOTModule *module, const char *function_name, - const AOTFuncType *expected_function_type, - char *error_buf, uint32 error_buf_size) -{ - void *function = NULL; - AOTExport *export = NULL; - AOTFuncType *target_function_type = NULL; - - export = loader_find_export((WASMModuleCommon *)module, module->name, - function_name, EXPORT_KIND_FUNC, error_buf, - error_buf_size); - if (!export) { - return NULL; - } - - /* resolve function type and function */ - if (export->index < module->import_func_count) { - target_function_type = module->import_funcs[export->index].func_type; - function = module->import_funcs[export->index].func_ptr_linked; - } - else { - target_function_type = - (AOTFuncType *)module - ->types[module->func_type_indexes[export->index - - module->import_func_count]]; - function = - (module->func_ptrs[export->index - module->import_func_count]); - } - /* check function type */ - if (!wasm_type_equal((WASMType *)expected_function_type, - (WASMType *)target_function_type, module->types, - module->type_count)) { - LOG_DEBUG("%s.%s failed the type check", module->name, function_name); - set_error_buf(error_buf, error_buf_size, "incompatible import type"); - return NULL; - } - return function; -} -#endif /* end of WASM_ENABLE_MULTI_MODULE */ - static bool load_native_symbol_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module, bool is_load_from_file_buf, @@ -2285,19 +2218,13 @@ destroy_import_funcs(AOTImportFunc *import_funcs) static bool load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, - bool is_load_from_file_buf, char *error_buf, + bool is_load_from_file_buf, bool no_resolve, char *error_buf, uint32 error_buf_size) { - char *module_name, *field_name; const uint8 *buf = *p_buf; AOTImportFunc *import_funcs; uint64 size; uint32 i; -#if WASM_ENABLE_MULTI_MODULE != 0 - AOTModule *sub_module = NULL; - AOTFunc *linked_func = NULL; - AOTFuncType *declare_func_type = NULL; -#endif /* Allocate memory */ size = sizeof(AOTImportFunc) * (uint64)module->import_func_count; @@ -2314,53 +2241,17 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, return false; } -#if WASM_ENABLE_MULTI_MODULE != 0 - declare_func_type = - (AOTFuncType *)module->types[import_funcs[i].func_type_index]; - read_string(buf, buf_end, module_name); - read_string(buf, buf_end, field_name); - - import_funcs[i].module_name = module_name; - import_funcs[i].func_name = field_name; - linked_func = wasm_native_resolve_symbol( - module_name, field_name, declare_func_type, - &import_funcs[i].signature, &import_funcs[i].attachment, - &import_funcs[i].call_conv_raw); - if (!linked_func) { - sub_module = NULL; - if (!wasm_runtime_is_built_in_module(module_name)) { - sub_module = (AOTModule *)wasm_runtime_load_depended_module( - (WASMModuleCommon *)module, module_name, error_buf, - error_buf_size); - if (!sub_module) { - LOG_ERROR("failed to load sub module: %s", error_buf); - return false; - } - } - if (!sub_module) - linked_func = aot_loader_resolve_function_ex( - module_name, field_name, declare_func_type, error_buf, - error_buf_size); - else - linked_func = aot_loader_resolve_function( - sub_module, field_name, declare_func_type, error_buf, - error_buf_size); - } - import_funcs[i].func_ptr_linked = linked_func; - import_funcs[i].func_type = declare_func_type; - -#else import_funcs[i].func_type = (AOTFuncType *)module->types[import_funcs[i].func_type_index]; read_string(buf, buf_end, import_funcs[i].module_name); read_string(buf, buf_end, import_funcs[i].func_name); - module_name = import_funcs[i].module_name; - field_name = import_funcs[i].func_name; - import_funcs[i].func_ptr_linked = wasm_native_resolve_symbol( - module_name, field_name, import_funcs[i].func_type, - &import_funcs[i].signature, &import_funcs[i].attachment, - &import_funcs[i].call_conv_raw); -#endif + import_funcs[i].attachment = NULL; + import_funcs[i].signature = NULL; + import_funcs[i].call_conv_raw = false; + + if (!no_resolve) { + aot_resolve_import_func(module, &import_funcs[i]); + } #if WASM_ENABLE_LIBC_WASI != 0 if (!strcmp(import_funcs[i].module_name, "wasi_unstable") @@ -2378,7 +2269,7 @@ fail: static bool load_import_func_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, bool is_load_from_file_buf, - char *error_buf, uint32 error_buf_size) + bool no_resolve, char *error_buf, uint32 error_buf_size) { const uint8 *buf = *p_buf; @@ -2387,7 +2278,7 @@ load_import_func_info(const uint8 **p_buf, const uint8 *buf_end, /* load import funcs */ if (module->import_func_count > 0 && !load_import_funcs(&buf, buf_end, module, is_load_from_file_buf, - error_buf, error_buf_size)) + no_resolve, error_buf, error_buf_size)) return false; *p_buf = buf; @@ -2514,7 +2405,7 @@ fail: static bool load_init_data_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module, bool is_load_from_file_buf, - char *error_buf, uint32 error_buf_size) + bool no_resolve, char *error_buf, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end; @@ -2525,7 +2416,7 @@ load_init_data_section(const uint8 *buf, const uint8 *buf_end, error_buf, error_buf_size) || !load_global_info(&p, p_end, module, error_buf, error_buf_size) || !load_import_func_info(&p, p_end, module, is_load_from_file_buf, - error_buf, error_buf_size)) + no_resolve, error_buf, error_buf_size)) return false; /* load function count and start function index */ @@ -3819,7 +3710,7 @@ has_module_memory64(AOTModule *module) static bool load_from_sections(AOTModule *module, AOTSection *sections, - bool is_load_from_file_buf, char *error_buf, + bool is_load_from_file_buf, bool no_resolve, char *error_buf, uint32 error_buf_size) { AOTSection *section = sections; @@ -3852,8 +3743,8 @@ load_from_sections(AOTModule *module, AOTSection *sections, break; case AOT_SECTION_TYPE_INIT_DATA: if (!load_init_data_section(buf, buf_end, module, - is_load_from_file_buf, error_buf, - error_buf_size)) + is_load_from_file_buf, no_resolve, + error_buf, error_buf_size)) return false; break; case AOT_SECTION_TYPE_TEXT: @@ -4076,7 +3967,7 @@ aot_load_from_sections(AOTSection *section_list, char *error_buf, if (!module) return NULL; - if (!load_from_sections(module, section_list, false, error_buf, + if (!load_from_sections(module, section_list, false, false, error_buf, error_buf_size)) { aot_unload(module); return NULL; @@ -4246,7 +4137,8 @@ fail: static bool load(const uint8 *buf, uint32 size, AOTModule *module, - bool wasm_binary_freeable, char *error_buf, uint32 error_buf_size) + bool wasm_binary_freeable, bool no_resolve, char *error_buf, + uint32 error_buf_size) { const uint8 *buf_end = buf + size; const uint8 *p = buf, *p_end = buf_end; @@ -4273,7 +4165,7 @@ load(const uint8 *buf, uint32 size, AOTModule *module, return false; ret = load_from_sections(module, section_list, !wasm_binary_freeable, - error_buf, error_buf_size); + no_resolve, error_buf, error_buf_size); if (!ret) { /* If load_from_sections() fails, then aot text is destroyed in destroy_sections() */ @@ -4321,8 +4213,8 @@ aot_load_from_aot_file(const uint8 *buf, uint32 size, const LoadArgs *args, return NULL; os_thread_jit_write_protect_np(false); /* Make memory writable */ - if (!load(buf, size, module, args->wasm_binary_freeable, error_buf, - error_buf_size)) { + if (!load(buf, size, module, args->wasm_binary_freeable, args->no_resolve, + error_buf, error_buf_size)) { aot_unload(module); return NULL; } diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index f1e63802..63a3c83c 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -5111,3 +5111,125 @@ aot_get_module_name(AOTModule *module) { return module->name; } + +bool +aot_resolve_symbols(AOTModule *module) +{ + bool ret = true; + uint32 idx; + for (idx = 0; idx < module->import_func_count; ++idx) { + AOTImportFunc *aot_import_func = &module->import_funcs[idx]; + if (!aot_import_func->func_ptr_linked) { + if (!aot_resolve_import_func(module, aot_import_func)) { + LOG_WARNING("Failed to link function (%s, %s)", + aot_import_func->module_name, + aot_import_func->func_name); + ret = false; + } + } + } + return ret; +} + +#if WASM_ENABLE_MULTI_MODULE != 0 +static void * +aot_resolve_function(const AOTModule *module, const char *function_name, + const AOTFuncType *expected_function_type, char *error_buf, + uint32 error_buf_size); + +static void * +aot_resolve_function_ex(const char *module_name, const char *function_name, + const AOTFuncType *expected_function_type, + char *error_buf, uint32 error_buf_size) +{ + WASMModuleCommon *module_reg; + + module_reg = wasm_runtime_find_module_registered(module_name); + if (!module_reg || module_reg->module_type != Wasm_Module_AoT) { + LOG_DEBUG("can not find a module named %s for function %s", module_name, + function_name); + set_error_buf(error_buf, error_buf_size, "unknown import"); + return NULL; + } + return aot_resolve_function((AOTModule *)module_reg, function_name, + expected_function_type, error_buf, + error_buf_size); +} + +static void * +aot_resolve_function(const AOTModule *module, const char *function_name, + const AOTFuncType *expected_function_type, char *error_buf, + uint32 error_buf_size) +{ + void *function = NULL; + AOTExport *export = NULL; + AOTFuncType *target_function_type = NULL; + + export = loader_find_export((WASMModuleCommon *)module, module->name, + function_name, EXPORT_KIND_FUNC, error_buf, + error_buf_size); + if (!export) { + return NULL; + } + + /* resolve function type and function */ + if (export->index < module->import_func_count) { + target_function_type = module->import_funcs[export->index].func_type; + function = module->import_funcs[export->index].func_ptr_linked; + } + else { + target_function_type = + (AOTFuncType *)module + ->types[module->func_type_indexes[export->index + - module->import_func_count]]; + function = + (module->func_ptrs[export->index - module->import_func_count]); + } + /* check function type */ + if (!wasm_type_equal((WASMType *)expected_function_type, + (WASMType *)target_function_type, module->types, + module->type_count)) { + LOG_DEBUG("%s.%s failed the type check", module->name, function_name); + set_error_buf(error_buf, error_buf_size, "incompatible import type"); + return NULL; + } + return function; +} +#endif /* end of WASM_ENABLE_MULTI_MODULE */ + +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, + &import_func->attachment, &import_func->call_conv_raw); +#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); + } + } + } +#endif + return import_func->func_ptr_linked != NULL; +} diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index f13d7eef..9c73dd40 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -492,6 +492,18 @@ aot_load_from_sections(AOTSection *section_list, char *error_buf, void aot_unload(AOTModule *module); +/** + * Resolve symbols for an AOT module + */ +bool +aot_resolve_symbols(AOTModule *module); + +/** + * Helper function to resolve a single function + */ +bool +aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func); + /** * Instantiate a AOT module. * diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 314dc7dd..667cbba0 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1484,6 +1484,22 @@ wasm_runtime_load_ex(uint8 *buf, uint32 size, const LoadArgs *args, error_buf_size); } +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_resolve_symbols(WASMModuleCommon *module) +{ +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + return wasm_resolve_symbols((WASMModule *)module); + } +#endif +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + return aot_resolve_symbols((AOTModule *)module); + } +#endif + return false; +} + WASMModuleCommon * wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size) diff --git a/core/iwasm/include/wasm_c_api.h b/core/iwasm/include/wasm_c_api.h index 4994454b..9fc46014 100644 --- a/core/iwasm/include/wasm_c_api.h +++ b/core/iwasm/include/wasm_c_api.h @@ -534,6 +534,10 @@ typedef struct LoadArgs { bool clone_wasm_binary; /* This option is only used by the AOT/wasm loader (see wasm_export.h) */ bool wasm_binary_freeable; + /* false by default, if true, don't resolve the symbols yet. The + wasm_runtime_load_ex has to be followed by a wasm_runtime_resolve_symbols + call */ + bool no_resolve; /* TODO: more fields? */ } LoadArgs; #endif /* LOAD_ARGS_OPTION_DEFINED */ diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 1a03f728..c9037b3c 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -252,6 +252,11 @@ typedef struct LoadArgs { const strings), making it possible to free the wasm binary buffer after loading. */ bool wasm_binary_freeable; + + /* false by default, if true, don't resolve the symbols yet. The + wasm_runtime_load_ex has to be followed by a wasm_runtime_resolve_symbols + call */ + bool no_resolve; /* TODO: more fields? */ } LoadArgs; #endif /* LOAD_ARGS_OPTION_DEFINED */ @@ -569,6 +574,12 @@ WASM_RUNTIME_API_EXTERN wasm_module_t wasm_runtime_load_ex(uint8_t *buf, uint32_t size, const LoadArgs *args, char *error_buf, uint32_t error_buf_size); +/** + * Resolve symbols for a previously loaded WASM module. Only useful when the + * module was loaded with LoadArgs::no_resolve set to true + */ +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_resolve_symbols(wasm_module_t module); /** * Load a WASM module from a specified WASM or AOT section list. * diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 3a21b1fc..ff3501e3 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -2246,60 +2246,6 @@ wasm_loader_find_export(const WASMModule *module, const char *module_name, #endif #if WASM_ENABLE_MULTI_MODULE != 0 -static WASMFunction * -wasm_loader_resolve_function(const char *module_name, const char *function_name, - const WASMFuncType *expected_function_type, - char *error_buf, uint32 error_buf_size) -{ - WASMModuleCommon *module_reg; - WASMFunction *function = NULL; - WASMExport *export = NULL; - WASMModule *module = NULL; - WASMFuncType *target_function_type = NULL; - - module_reg = wasm_runtime_find_module_registered(module_name); - if (!module_reg || module_reg->module_type != Wasm_Module_Bytecode) { - LOG_DEBUG("can not find a module named %s for function %s", module_name, - function_name); - set_error_buf(error_buf, error_buf_size, "unknown import"); - return NULL; - } - - module = (WASMModule *)module_reg; - export = - wasm_loader_find_export(module, module_name, function_name, - EXPORT_KIND_FUNC, error_buf, error_buf_size); - if (!export) { - return NULL; - } - - /* resolve function type and function */ - if (export->index < module->import_function_count) { - target_function_type = - module->import_functions[export->index].u.function.func_type; - function = module->import_functions[export->index] - .u.function.import_func_linked; - } - else { - target_function_type = - module->functions[export->index - module->import_function_count] - ->func_type; - function = - module->functions[export->index - module->import_function_count]; - } - - /* check function type */ - if (!wasm_type_equal((WASMType *)expected_function_type, - (WASMType *)target_function_type, module->types, - module->type_count)) { - LOG_DEBUG("%s.%s failed the type check", module_name, function_name); - set_error_buf(error_buf, error_buf_size, "incompatible import type"); - return NULL; - } - - return function; -} - static WASMTable * wasm_loader_resolve_table(const char *module_name, const char *table_name, uint32 init_size, uint32 max_size, char *error_buf, @@ -2494,21 +2440,11 @@ static bool load_function_import(const uint8 **p_buf, const uint8 *buf_end, const WASMModule *parent_module, const char *sub_module_name, const char *function_name, - WASMFunctionImport *function, char *error_buf, - uint32 error_buf_size) + WASMFunctionImport *function, bool no_resolve, + char *error_buf, uint32 error_buf_size) { const uint8 *p = *p_buf, *p_end = buf_end; uint32 declare_type_index = 0; - WASMFuncType *declare_func_type = NULL; - WASMFunction *linked_func = NULL; -#if WASM_ENABLE_MULTI_MODULE != 0 - WASMModule *sub_module = NULL; - bool is_built_in_module = false; -#endif - const char *linked_signature = NULL; - void *linked_attachment = NULL; - bool linked_call_conv_raw = false; - bool is_native_symbol = false; read_leb_uint32(p, p_end, declare_type_index); *p_buf = p; @@ -2527,43 +2463,19 @@ load_function_import(const uint8 **p_buf, const uint8 *buf_end, parent_module->types, parent_module->type_count, declare_type_index); #endif - declare_func_type = + function->func_type = (WASMFuncType *)parent_module->types[declare_type_index]; - /* lookup registered native symbols first */ - linked_func = wasm_native_resolve_symbol( - sub_module_name, function_name, declare_func_type, &linked_signature, - &linked_attachment, &linked_call_conv_raw); - if (linked_func) { - is_native_symbol = true; - } -#if WASM_ENABLE_MULTI_MODULE != 0 - else { - if (!(is_built_in_module = - wasm_runtime_is_built_in_module(sub_module_name))) { - sub_module = (WASMModule *)wasm_runtime_load_depended_module( - (WASMModuleCommon *)parent_module, sub_module_name, error_buf, - error_buf_size); - } - if (is_built_in_module || sub_module) - linked_func = wasm_loader_resolve_function( - sub_module_name, function_name, declare_func_type, error_buf, - error_buf_size); - } -#endif - function->module_name = (char *)sub_module_name; function->field_name = (char *)function_name; - function->func_type = declare_func_type; - /* func_ptr_linked is for native registered symbol */ - function->func_ptr_linked = is_native_symbol ? linked_func : NULL; - function->signature = linked_signature; - function->attachment = linked_attachment; - function->call_conv_raw = linked_call_conv_raw; -#if WASM_ENABLE_MULTI_MODULE != 0 - function->import_module = is_native_symbol ? NULL : sub_module; - function->import_func_linked = is_native_symbol ? NULL : linked_func; -#endif + function->attachment = NULL; + function->signature = NULL; + function->call_conv_raw = false; + + /* lookup registered native symbols first */ + if (!no_resolve) { + wasm_resolve_import_func(parent_module, function); + } return true; fail: return false; @@ -3258,8 +3170,8 @@ fail: static bool load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, - bool is_load_from_file_buf, char *error_buf, - uint32 error_buf_size) + bool is_load_from_file_buf, bool no_resolve, + char *error_buf, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end, *p_old; uint32 import_count, name_len, type_index, i, u32, flags; @@ -3442,9 +3354,10 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, case IMPORT_KIND_FUNC: /* import function */ bh_assert(import_functions); import = import_functions++; - if (!load_function_import( - &p, p_end, module, sub_module_name, field_name, - &import->u.function, error_buf, error_buf_size)) { + if (!load_function_import(&p, p_end, module, + sub_module_name, field_name, + &import->u.function, no_resolve, + error_buf, error_buf_size)) { return false; } break; @@ -5760,7 +5673,7 @@ static void **handle_table; static bool load_from_sections(WASMModule *module, WASMSection *sections, bool is_load_from_file_buf, bool wasm_binary_freeable, - char *error_buf, uint32 error_buf_size) + bool no_resolve, char *error_buf, uint32 error_buf_size) { WASMExport *export; WASMSection *section = sections; @@ -5817,8 +5730,8 @@ load_from_sections(WASMModule *module, WASMSection *sections, break; case SECTION_TYPE_IMPORT: if (!load_import_section(buf, buf_end, module, - reuse_const_strings, error_buf, - error_buf_size)) + reuse_const_strings, no_resolve, + error_buf, error_buf_size)) return false; break; case SECTION_TYPE_FUNC: @@ -6343,7 +6256,7 @@ wasm_loader_load_from_sections(WASMSection *section_list, char *error_buf, if (!module) return NULL; - if (!load_from_sections(module, section_list, false, true, error_buf, + if (!load_from_sections(module, section_list, false, true, false, error_buf, error_buf_size)) { wasm_loader_unload(module); return NULL; @@ -6488,7 +6401,8 @@ static union { static bool load(const uint8 *buf, uint32 size, WASMModule *module, - bool wasm_binary_freeable, char *error_buf, uint32 error_buf_size) + bool wasm_binary_freeable, bool no_resolve, char *error_buf, + uint32 error_buf_size) { const uint8 *buf_end = buf + size; const uint8 *p = buf, *p_end = buf_end; @@ -6519,7 +6433,7 @@ load(const uint8 *buf, uint32 size, WASMModule *module, if (!create_sections(buf, size, §ion_list, error_buf, error_buf_size) || !load_from_sections(module, section_list, true, wasm_binary_freeable, - error_buf, error_buf_size)) { + no_resolve, error_buf, error_buf_size)) { destroy_sections(section_list); return false; } @@ -6695,8 +6609,8 @@ wasm_loader_load(uint8 *buf, uint32 size, module->load_size = size; #endif - if (!load(buf, size, module, args->wasm_binary_freeable, error_buf, - error_buf_size)) { + if (!load(buf, size, module, args->wasm_binary_freeable, args->no_resolve, + error_buf, error_buf_size)) { goto fail; } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index e8f4c749..e4142ab8 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -83,6 +83,124 @@ wasm_unload(WASMModule *module) wasm_loader_unload(module); } +bool +wasm_resolve_symbols(WASMModule *module) +{ + bool ret = true; + 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; +#if WASM_ENABLE_MULTI_MODULE != 0 + if (import->import_func_linked) { + linked = true; + } +#endif + if (!linked && !wasm_resolve_import_func(module, import)) { + ret = false; + } + } + return ret; +} + +#if WASM_ENABLE_MULTI_MODULE != 0 +static WASMFunction * +wasm_resolve_function(const char *module_name, const char *function_name, + const WASMFuncType *expected_function_type, + char *error_buf, uint32 error_buf_size) +{ + WASMModuleCommon *module_reg; + WASMFunction *function = NULL; + WASMExport *export = NULL; + WASMModule *module = NULL; + WASMFuncType *target_function_type = NULL; + + module_reg = wasm_runtime_find_module_registered(module_name); + if (!module_reg || module_reg->module_type != Wasm_Module_Bytecode) { + LOG_DEBUG("can not find a module named %s for function %s", module_name, + function_name); + set_error_buf(error_buf, error_buf_size, "unknown import"); + return NULL; + } + + module = (WASMModule *)module_reg; + export = loader_find_export((WASMModuleCommon *)module, module_name, + function_name, EXPORT_KIND_FUNC, error_buf, + error_buf_size); + if (!export) { + return NULL; + } + + /* resolve function type and function */ + if (export->index < module->import_function_count) { + target_function_type = + module->import_functions[export->index].u.function.func_type; + function = module->import_functions[export->index] + .u.function.import_func_linked; + } + else { + target_function_type = + module->functions[export->index - module->import_function_count] + ->func_type; + function = + module->functions[export->index - module->import_function_count]; + } + + /* check function type */ + if (!wasm_type_equal((WASMType *)expected_function_type, + (WASMType *)target_function_type, module->types, + module->type_count)) { + LOG_DEBUG("%s.%s failed the type check", module_name, function_name); + set_error_buf(error_buf, error_buf_size, "incompatible import type"); + return NULL; + } + + return function; +} +#endif + +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 + 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); + + if (function->func_ptr_linked) { + return true; + } + +#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; + } + } + 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); + } +#endif + + return false; +} + static void * runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size) { diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index c4301869..e46b63cd 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -513,6 +513,13 @@ wasm_load_from_sections(WASMSection *section_list, char *error_buf, void wasm_unload(WASMModule *module); +bool +wasm_resolve_symbols(WASMModule *module); + +bool +wasm_resolve_import_func(const WASMModule *module, + WASMFunctionImport *function); + WASMModuleInstance * wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, WASMExecEnv *exec_env_main, uint32 stack_size,