From 9c8fb32a22fcfb716a07541e378a759384123692 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Sun, 17 Nov 2024 03:21:29 +0000 Subject: [PATCH 01/20] [rebase confliction] Refactor: streamline global instance handling and improve export retrieval logic Remove me when meeting rebase conflication --- core/iwasm/aot/aot_runtime.h | 12 +++-- core/iwasm/common/wasm_runtime_common.c | 71 +++++++++++++------------ core/iwasm/include/wasm_export.h | 18 +++---- 3 files changed, 53 insertions(+), 48 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 6cfa565fa1..ad06fe3bd4 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -37,6 +37,11 @@ extern "C" { #define WASM_FEATURE_FRAME_NO_FUNC_IDX (1 << 13) #define WASM_FEATURE_MULTI_MODULE (1 << 14) +#define AOTGlobalInstance WASMGlobalInstance +#define AOTMemoryInstance WASMMemoryInstance +#define AOTTableInstance WASMTableInstance +#define AOTModuleInstance WASMModuleInstance + typedef enum AOTSectionType { AOT_SECTION_TYPE_TARGET_INFO = 0, AOT_SECTION_TYPE_INIT_DATA = 1, @@ -137,6 +142,9 @@ typedef struct AOTModuleInstanceExtra { ExportFuncMap *export_func_maps; AOTFunctionInstance **functions; uint32 function_count; + + AOTGlobalInstance *globals; + uint32 global_count; #if WASM_ENABLE_MULTI_MODULE != 0 bh_list sub_module_inst_list_head; bh_list *sub_module_inst_list; @@ -363,10 +371,6 @@ typedef struct AOTModule { #endif } AOTModule; -#define AOTMemoryInstance WASMMemoryInstance -#define AOTTableInstance WASMTableInstance -#define AOTModuleInstance WASMModuleInstance - #if WASM_ENABLE_MULTI_MODULE != 0 #define AOTSubModInstNode WASMSubModInstNode #endif diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index b3bb54f552..8f19672d3b 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -2051,40 +2051,38 @@ wasm_runtime_set_module_inst(WASMExecEnv *exec_env, wasm_exec_env_set_module_inst(exec_env, module_inst); } -bool +WASMGlobalInstance * wasm_runtime_get_export_global_inst(WASMModuleInstanceCommon *const module_inst, - char const *name, - wasm_global_inst_t *global_inst) + char const *name) { + if (!module_inst || !name) { + return NULL; + } + #if WASM_ENABLE_INTERP != 0 if (module_inst->module_type == Wasm_Module_Bytecode) { const WASMModuleInstance *wasm_module_inst = (const WASMModuleInstance *)module_inst; const WASMModule *wasm_module = wasm_module_inst->module; - uint32 i; - for (i = 0; i < wasm_module->export_count; i++) { + + for (uint32 i = 0; i < wasm_module->export_count; i++) { const WASMExport *wasm_export = &wasm_module->exports[i]; - if ((wasm_export->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) - && !strcmp(wasm_export->name, name)) { - const WASMModuleInstanceExtra *e = - (WASMModuleInstanceExtra *)wasm_module_inst->e; - const WASMGlobalInstance *global = - &e->globals[wasm_export->index]; - global_inst->kind = val_type_to_val_kind(global->type); - global_inst->is_mutable = global->is_mutable; -#if WASM_ENABLE_MULTI_MODULE == 0 - global_inst->global_data = - wasm_module_inst->global_data + global->data_offset; -#else - global_inst->global_data = - global->import_global_inst - ? global->import_module_inst->global_data - + global->import_global_inst->data_offset - : wasm_module_inst->global_data + global->data_offset; -#endif - return true; + + if (wasm_export->kind != WASM_IMPORT_EXPORT_KIND_GLOBAL) { + continue; + } + + if (strcmp(wasm_export->name, name)) { + continue; } + + WASMModuleInstanceExtra *e = + (WASMModuleInstanceExtra *)wasm_module_inst->e; + WASMGlobalInstance *global = &e->globals[wasm_export->index]; + return global; } + + return NULL; } #endif #if WASM_ENABLE_AOT != 0 @@ -2095,21 +2093,26 @@ wasm_runtime_get_export_global_inst(WASMModuleInstanceCommon *const module_inst, uint32 i; for (i = 0; i < aot_module->export_count; i++) { const AOTExport *aot_export = &aot_module->exports[i]; - if ((aot_export->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) - && !strcmp(aot_export->name, name)) { - const AOTGlobal *global = - &aot_module->globals[aot_export->index]; - global_inst->kind = val_type_to_val_kind(global->type.val_type); - global_inst->is_mutable = global->type.is_mutable; - global_inst->global_data = - aot_module_inst->global_data + global->data_offset; - return true; + + if (aot_export->kind != WASM_IMPORT_EXPORT_KIND_GLOBAL) { + continue; + } + + if (strcmp(aot_export->name, name)) { + continue; } + + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)aot_module_inst->e; + AOTGlobalInstance *global = &e->globals[aot_export->index]; + return global; } + + return NULL; } #endif - return false; + return NULL; } WASMTableInstance * diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 2461555be1..729c3369fb 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -142,6 +142,11 @@ typedef struct WASMMemoryInstance *wasm_memory_inst_t; struct WASMTableInstance; typedef struct WASMTableInstance *wasm_table_inst_t; +/*TODO: remove me when rebasing*/ +/* Global instance*/ +struct WASMGlobalInstance; +typedef struct WASMGlobalInstance *wasm_global_inst_t; + /* WASM section */ typedef struct wasm_section_t { struct wasm_section_t *next; @@ -289,6 +294,7 @@ typedef struct WASMExternInstance { union { wasm_memory_inst_t memory; wasm_table_inst_t table; + wasm_global_inst_t global; } u; } WASMExternInstance, *wasm_extern_inst_t; @@ -335,13 +341,6 @@ typedef struct wasm_val_t { } wasm_val_t; #endif -/* Global instance*/ -typedef struct wasm_global_inst_t { - wasm_valkind_t kind; - bool is_mutable; - void *global_data; -} wasm_global_inst_t; - typedef enum { WASM_LOG_LEVEL_FATAL = 0, WASM_LOG_LEVEL_ERROR = 1, @@ -1754,10 +1753,9 @@ wasm_runtime_unregister_natives(const char *module_name, * @return true if success, false otherwise * */ -WASM_RUNTIME_API_EXTERN bool +WASM_RUNTIME_API_EXTERN wasm_global_inst_t wasm_runtime_get_export_global_inst(const wasm_module_inst_t module_inst, - const char *name, - wasm_global_inst_t *global_inst); + const char *name); /** * @brief Retrieves the table instance exported from a WebAssembly module From f9a7b6d321f35c79b90ed4b0cf21bcddd978382a Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Mon, 18 Nov 2024 05:09:31 +0000 Subject: [PATCH 02/20] Refactor: improve global instance handling --- core/iwasm/common/wasm_runtime_common.c | 143 +++++++++++++++++++ core/iwasm/include/wasm_export.h | 12 ++ core/iwasm/interpreter/wasm_interp_classic.c | 13 -- core/iwasm/interpreter/wasm_interp_fast.c | 13 -- core/iwasm/interpreter/wasm_loader.c | 7 +- core/iwasm/interpreter/wasm_runtime.c | 138 +++++++++++++----- core/iwasm/interpreter/wasm_runtime.h | 40 +++++- 7 files changed, 296 insertions(+), 70 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 8f19672d3b..31f55b0b89 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7899,6 +7899,115 @@ wasm_runtime_destroy_table(WASMModuleCommon *const module, LOG_ERROR("destroy table failed, invalid module type"); } +WASMGlobalInstance * +wasm_runtime_create_global_internal(WASMModuleCommon *const module, + WASMModuleInstanceCommon *dep_inst, + WASMGlobalType *const type) +{ + if (!module || !type) + return NULL; + +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + return wasm_create_global((WASMModule *)module, + (WASMModuleInstance *)dep_inst, type); + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + return aot_create_global((AOTModule *)module, + (AOTModuleInstance *)dep_inst, type); + } +#endif + + return NULL; +} + +WASMGlobalInstance * +wasm_runtime_create_global(WASMModuleCommon *const module, + WASMGlobalType *const type, const wasm_val_t *value) +{ + WASMGlobalInstance *global = + wasm_runtime_create_global_internal(module, NULL, type); + if (!global) + return NULL; + + /* TODO: make a small function about conversion */ + WASMValue init_value = { 0 }; + /* wasm_val_t to WASMValue */ + switch (value->kind) { + case WASM_I32: + { + init_value.i32 = value->of.i32; + break; + } + case WASM_I64: + { + init_value.i64 = value->of.i64; + break; + } + case WASM_F32: + { + init_value.f32 = value->of.f32; + break; + } + case WASM_F64: + { + init_value.f64 = value->of.f64; + break; + } + // case WASM_V128: + // { + // bh_assert(false && "V128 not supported yet"); + // break; + // } + // case WASM_EXTERNREF: + // case WASM_FUNCREF: + default: + { + bh_assert(false && "unsupported value type"); + break; + } + } + +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + wasm_set_global_value(global, &init_value); + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + aot_set_global_value(global, &init_value); + } +#endif + + return global; +} + +void +wasm_runtime_destroy_global(WASMModuleCommon *const module, + WASMGlobalInstance *global) +{ + if (!module) + return; + +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + wasm_destroy_global(global); + return; + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + aot_destroy_global(global); + return; + } +#endif +} + /*TODO: take us(below) out when have a linker */ WASMModuleInstanceCommon * wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module, @@ -7989,6 +8098,14 @@ wasm_runtime_create_extern_inst(WASMModuleCommon *module, return false; } } + else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { + out->u.global = wasm_runtime_create_global_internal( + module, NULL, import_type->u.global_type); + if (!out->u.global) { + LOG_ERROR("create global failed\n"); + return false; + } + } else { LOG_DEBUG("unimplemented import(%s,%s) kind %d", import_type->module_name, import_type->name, @@ -8068,12 +8185,38 @@ wasm_runtime_create_imports(WASMModuleCommon *module, } WASMExternInstance *extern_instance = out + i; + /* create empty extern_inst */ if (!wasm_runtime_create_extern_inst(module, &import_type, extern_instance)) { wasm_runtime_destroy_imports(module, out); LOG_ERROR("create import failed"); return false; } + + /* assign values */ +#if WASM_ENABLE_SPEC_TEST != 0 + if (import_type.kind != WASM_IMPORT_EXPORT_KIND_GLOBAL + && import_type.kind != WASM_IMPORT_EXPORT_KIND_FUNC) { + continue; + } + + if (!strncmp(import_type.name, "global_i32", 10)) { + WASMValue value = { .i32 = 666 }; + wasm_set_global_value(extern_instance->u.global, &value); + } + else if (!strncmp(import_type.name, "global_i64", 10)) { + WASMValue value = { .i64 = 666 }; + wasm_set_global_value(extern_instance->u.global, &value); + } + else if (!strncmp(import_type.name, "global_f32", 10)) { + WASMValue value = { .f32 = 666.6f }; + wasm_set_global_value(extern_instance->u.global, &value); + } + else if (!strncmp(import_type.name, "global_f64", 10)) { + WASMValue value = { .f64 = 666.6 }; + wasm_set_global_value(extern_instance->u.global, &value); + } +#endif } return true; diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 729c3369fb..4f7b9dcf7f 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -287,6 +287,7 @@ typedef struct LoadArgs { } LoadArgs; #endif /* LOAD_ARGS_OPTION_DEFINED */ +/*TODO: move it to wasm_runtime_common.h? */ typedef struct WASMExternInstance { const char *module_name; const char *field_name; @@ -296,6 +297,12 @@ typedef struct WASMExternInstance { wasm_table_inst_t table; wasm_global_inst_t global; } u; + + /* + * to handle imports properly, + * especially for wasm_global_inst_t and wasm_func_inst_t + */ + wasm_module_inst_t dep_inst; } WASMExternInstance, *wasm_extern_inst_t; #ifndef INSTANTIATION_ARGS_OPTION_DEFINED @@ -1098,6 +1105,11 @@ wasm_memory_get_base_address(const wasm_memory_inst_t memory_inst); WASM_RUNTIME_API_EXTERN bool wasm_memory_enlarge(wasm_memory_inst_t memory_inst, uint64_t inc_page_count); +WASM_RUNTIME_API_EXTERN wasm_global_inst_t +wasm_runtime_create_immutable_global(const wasm_module_t module, + const wasm_global_type_t type, + const wasm_val_t *value); + /** * Call the given WASM function of a WASM module instance with * arguments (bytecode and AoT). diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 21b306cee6..e0803f358d 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1549,19 +1549,6 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, #endif /* end of WASM_ENABLE_LABELS_AS_VALUES */ -static inline uint8 * -get_global_addr(uint8 *global_data, WASMGlobalInstance *global) -{ -#if WASM_ENABLE_MULTI_MODULE == 0 - return global_data + global->data_offset; -#else - return global->import_global_inst - ? global->import_module_inst->global_data - + global->import_global_inst->data_offset - : global_data + global->data_offset; -#endif -} - static void wasm_interp_call_func_bytecode(WASMModuleInstance *module, WASMExecEnv *exec_env, diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 84dbc14f31..55d8d6d576 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1450,19 +1450,6 @@ wasm_interp_dump_op_count() static void **global_handle_table; #endif -static inline uint8 * -get_global_addr(uint8 *global_data, WASMGlobalInstance *global) -{ -#if WASM_ENABLE_MULTI_MODULE == 0 - return global_data + global->data_offset; -#else - return global->import_global_inst - ? global->import_module_inst->global_data - + global->import_global_inst->data_offset - : global_data + global->data_offset; -#endif -} - static void wasm_interp_call_func_bytecode(WASMModuleInstance *module, WASMExecEnv *exec_env, diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index f2ec0886bc..be14d27b31 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -2991,7 +2991,9 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end, return false; } +#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_LIBC_BUILTIN != 0 + /* link with libc-builtin provided */ ret = wasm_native_lookup_libc_builtin_global(sub_module_name, global_name, global); if (ret) { @@ -3004,7 +3006,8 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end, global->is_linked = true; } #endif -#if WASM_ENABLE_MULTI_MODULE != 0 + + /* link with other modules' */ if (!global->is_linked && !wasm_runtime_is_built_in_module(sub_module_name)) { sub_module = (WASMModule *)wasm_runtime_load_depended_module( @@ -3022,7 +3025,7 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end, } } } -#endif +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ global->module_name = sub_module_name; global->field_name = global_name; diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 198b5cc943..bd400fcc05 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1370,6 +1370,7 @@ instantiate_array_global_recursive(WASMModule *module, */ static WASMGlobalInstance * globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, + const WASMExternInstance *imports, uint32 import_count, char *error_buf, uint32 error_buf_size) { WASMImport *import; @@ -1385,48 +1386,80 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, /* instantiate globals from import section */ global = globals; import = module->import_globals; - for (i = 0; i < module->import_global_count; i++, import++) { - WASMGlobalImport *global_import = &import->u.global; - global->type = global_import->type.val_type; - global->is_mutable = global_import->type.is_mutable; + for (i = 0; i < module->import_global_count; i++, import++, global++) { + WASMGlobalImport *import_global_type = &import->u.global; + + global->type = import_global_type->type.val_type; + global->is_mutable = import_global_type->type.is_mutable; #if WASM_ENABLE_GC != 0 - global->ref_type = global_import->ref_type; + global->ref_type = import_global_type->ref_type; +#endif +#if WASM_ENABLE_FAST_JIT != 0 + bh_assert(global_data_offset == import_global_type->data_offset); #endif + global->data_offset = global_data_offset; + global_data_offset += wasm_value_type_size(global->type); + #if WASM_ENABLE_MULTI_MODULE != 0 - if (global_import->import_module) { + if (import_global_type->import_module) { if (!(global->import_module_inst = get_sub_module_inst( - module_inst, global_import->import_module))) { + module_inst, import_global_type->import_module))) { set_error_buf(error_buf, error_buf_size, "unknown global"); goto fail; } - if (!(global->import_global_inst = wasm_lookup_global( - global->import_module_inst, global_import->field_name))) { + if (!(global->import_global_inst = + wasm_lookup_global(global->import_module_inst, + import_global_type->field_name))) { set_error_buf(error_buf, error_buf_size, "unknown global"); goto fail; } /* The linked global instance has been initialized, we just need to copy the value. */ - bh_memcpy_s(&(global->initial_value), sizeof(WASMValue), - &(global_import->import_global_linked->init_expr.u), - sizeof(WASMValue)); + bh_memcpy_s( + &(global->initial_value), sizeof(WASMValue), + &(import_global_type->import_global_linked->init_expr.u), + sizeof(WASMValue)); } - else -#endif - { +#if WASM_ENABLE_LIBC_BUILTIN != 0 + else { /* native globals share their initial_values in one module */ bh_memcpy_s(&(global->initial_value), sizeof(WASMValue), - &(global_import->global_data_linked), + &(import_global_type->global_data_linked), sizeof(WASMValue)); } -#if WASM_ENABLE_FAST_JIT != 0 - bh_assert(global_data_offset == global_import->data_offset); #endif - global->data_offset = global_data_offset; - global_data_offset += wasm_value_type_size(global->type); - global++; +#else + + /* refer to the imported global */ + const WASMExternInstance *extern_inst = + wasm_runtime_get_extern_instance(imports, import_count, + WASM_IMPORT_EXPORT_KIND_GLOBAL, i); + if (!extern_inst) { + LOG_ERROR("missing an import global(%s, %s)", + import_global_type->module_name, + import_global_type->field_name); + return NULL; + } + + /* just in case */ +#ifndef NDEBUG + if (strcmp(import_global_type->field_name, extern_inst->field_name)) { + LOG_ERROR( + "mismatched import global name: expect \"%s\", got \"%s\"", + import_global_type->field_name, extern_inst->field_name); + return NULL; + } +#endif + + bh_memcpy_s(&(global->initial_value), sizeof(WASMValue), + &(extern_inst->u.global->initial_value), sizeof(WASMValue)); + global->import_module_inst = + (WASMModuleInstance *)extern_inst->dep_inst; + global->import_global_inst = extern_inst->u.global; +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ } /* instantiate globals from global section */ @@ -2105,6 +2138,7 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, } } +#if WASM_ENABLE_MULTI_MODULE != 0 for (i = 0; i < module->import_global_count; i++) { WASMGlobalImport *global = &((module->import_globals + i)->u.global); @@ -2126,10 +2160,7 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, WASMTableImport *table = &((module->import_tables + i)->u.table); if (!wasm_runtime_is_built_in_module(table->module_name) -#if WASM_ENABLE_MULTI_MODULE != 0 - && !table->import_table_linked -#endif - ) { + && !table->import_table_linked) { set_error_buf_v(error_buf, error_buf_size, "failed to link import table (%s, %s)", table->module_name, table->field_name); @@ -2138,23 +2169,17 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, } for (i = 0; i < module->import_memory_count; i++) { - WASMMemoryImport *type = &((module->import_memories + i)->u.memory); - WASMMemoryInstance *memory = module_inst->memories[i]; - (void)memory; - if ( -#if WASM_ENABLE_MULTI_MODULE != 0 - !wasm_runtime_is_built_in_module(type->module_name) - && !type->import_memory_linked -#else - !memory -#endif - ) { + WASMMemoryImport *memory = &((module->import_memories + i)->u.memory); + + if (!wasm_runtime_is_built_in_module(memory->module_name) + && !memory->import_memory_linked) { set_error_buf_v(error_buf, error_buf_size, "failed to link import memory (%s, %s)", - type->module_name, type->field_name); + memory->module_name, memory->field_name); return false; } } +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ #if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_TAGS != 0 @@ -2726,8 +2751,9 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, */ global_count = module->import_global_count + module->global_count; if (global_count - && !(globals = globals_instantiate(module, module_inst, error_buf, - error_buf_size))) { + && !(globals = + globals_instantiate(module, module_inst, imports, import_count, + error_buf, error_buf_size))) { goto fail; } module_inst->e->global_count = global_count; @@ -2820,6 +2846,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, goto fail; } + /* WASMGlobalInstance->initial_value => WASMModuleInstance->global_data*/ if (global_count > 0) { /* Initialize the global data */ global_data = module_inst->global_data; @@ -5395,4 +5422,37 @@ wasm_destroy_table(WASMTableInstance *table) return; wasm_runtime_free(table); +} + +WASMGlobalInstance * +wasm_create_global(const WASMModule *module, WASMModuleInstance *dep_inst, + WASMGlobalType *type) +{ + WASMGlobalInstance *global = + runtime_malloc(sizeof(WASMGlobalInstance), NULL, 0); + if (!global) { + return NULL; + } + + global->type = type->val_type; + global->is_mutable = type->is_mutable; + global->import_global_inst = dep_inst; + /* empty global. set value later by wasm_set_global_value */ + return global; +} + +void +wasm_set_global_value(WASMGlobalInstance *global, const WASMValue *value) +{ + bh_memcpy_s(&global->initial_value, sizeof(WASMValue), value, + sizeof(WASMValue)); +} + +void +wasm_destroy_global(WASMGlobalInstance *global) +{ + if (!global) + return; + + wasm_runtime_free(global); } \ No newline at end of file diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 6eebaa1304..bcad16e6ef 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -192,19 +192,25 @@ struct WASMGlobalInstance { uint8 type; /* mutable or constant */ bool is_mutable; + /* data offset to the address of initial_value, started from the end of * WASMMemoryInstance(start of WASMGlobalInstance)*/ uint32 data_offset; - /* initial value */ + + /* + * initial value (before instantiation stage) + * - host creation. store initial value directly. no init expr + * - as a temp value before storing in global_data + */ WASMValue initial_value; + #if WASM_ENABLE_GC != 0 WASMRefType *ref_type; #endif -#if WASM_ENABLE_MULTI_MODULE != 0 + /* just for import, keep the reference here */ WASMModuleInstance *import_module_inst; WASMGlobalInstance *import_global_inst; -#endif }; struct WASMFunctionInstance { @@ -563,6 +569,24 @@ wasm_get_tbl_data_slots(const WASMTableType *table_type, #endif } +static inline uint8 * +get_global_addr(uint8 *global_data, WASMGlobalInstance *global) +{ + /* + * global->import_global_inst != NULL means the global is imported + * from another module. + * global->import_module_isnt != NULL means the data is stored in + * local module instance. + * + * A host created global doesn't have its own global_data need to + * be maintained. + */ + return global->import_module_inst + ? global->import_module_inst->global_data + + global->import_global_inst->data_offset + : global_data + global->data_offset; +} + WASMModule * wasm_load(uint8 *buf, uint32 size, #if WASM_ENABLE_MULTI_MODULE != 0 @@ -956,6 +980,16 @@ wasm_set_table_elem(const WASMModule *module, WASMTableInstance *table, void wasm_destroy_table(WASMTableInstance *table); +WASMGlobalInstance * +wasm_create_global(const WASMModule *module, WASMModuleInstance *dep_inst, + WASMGlobalType *type); + +void +wasm_set_global_value(WASMGlobalInstance *global, const WASMValue *value); + +void +wasm_destroy_global(WASMGlobalInstance *global); + #ifdef __cplusplus } #endif From f81662d66b0d0ce4cf651881bb6df67f5466c1e2 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 19 Nov 2024 03:05:20 +0000 Subject: [PATCH 03/20] llvm-jit can read global values from local inst and import inst --- core/iwasm/aot/aot_runtime.c | 33 ++++ core/iwasm/aot/aot_runtime.h | 10 ++ core/iwasm/compilation/aot_emit_table.c | 1 + core/iwasm/compilation/aot_emit_variable.c | 182 ++++++++++++++++++--- core/iwasm/interpreter/wasm.h | 5 + core/iwasm/interpreter/wasm_runtime.c | 2 +- core/iwasm/interpreter/wasm_runtime.h | 1 + 7 files changed, 212 insertions(+), 22 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index ecc8380d68..15d06f854b 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -5788,4 +5788,37 @@ aot_destroy_table(AOTTableInstance *table) return; wasm_runtime_free(table); +} + +AOTGlobalInstance * +aot_create_global(const AOTModule *module, AOTModuleInstance *dep_inst, + WASMGlobalType *type) +{ + AOTGlobalInstance *global = + runtime_malloc(sizeof(AOTGlobalInstance), NULL, 0); + if (!global) { + return NULL; + } + + global->type = type->val_type; + global->is_mutable = type->is_mutable; + global->import_module_inst = dep_inst; + /* empty global. set value later by wasm_set_global_value */ + return global; +} + +void +aot_set_global_value(AOTGlobalInstance *global, const WASMValue *value) +{ + bh_memcpy_s(&global->initial_value, sizeof(WASMValue), value, + sizeof(WASMValue)); +} + +void +aot_destroy_global(AOTGlobalInstance *global) +{ + if (!global) + return; + + wasm_runtime_free(global); } \ No newline at end of file diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index ad06fe3bd4..17418c7ee9 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -921,6 +921,16 @@ aot_set_table_elem(const AOTModule *module, AOTTableInstance *table, void aot_destroy_table(AOTTableInstance *table); +AOTGlobalInstance * +aot_create_global(const AOTModule *module, AOTModuleInstance *dep_inst, + WASMGlobalType *type); + +void +aot_set_global_value(AOTGlobalInstance *global, const WASMValue *value); + +void +aot_destroy_global(AOTGlobalInstance *global); + #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/core/iwasm/compilation/aot_emit_table.c b/core/iwasm/compilation/aot_emit_table.c index c5d0cf6c85..cd43ea0151 100644 --- a/core/iwasm/compilation/aot_emit_table.c +++ b/core/iwasm/compilation/aot_emit_table.c @@ -132,6 +132,7 @@ get_tbl_inst_offset(const AOTCompContext *comp_ctx, return offset; } +/*TODO: move it to aot_llvm.c/h */ uint32 get_module_inst_extra_offset(AOTCompContext *comp_ctx) { diff --git a/core/iwasm/compilation/aot_emit_variable.c b/core/iwasm/compilation/aot_emit_variable.c index bb6d10b8ec..00e7fc221b 100644 --- a/core/iwasm/compilation/aot_emit_variable.c +++ b/core/iwasm/compilation/aot_emit_variable.c @@ -6,6 +6,7 @@ #include "aot_emit_variable.h" #include "aot_emit_exception.h" #include "../aot/aot_runtime.h" +#include "aot_emit_table.h" #define CHECK_LOCAL(idx) \ do { \ @@ -149,6 +150,132 @@ aot_compile_op_tee_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return aot_compile_op_set_or_tee_local(comp_ctx, func_ctx, local_idx, true); } +/*TODO: should be optimized by moving globals to WASMModuleInstance */ +LLVMValueRef +get_global_from_wasm_inst(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + uint32 global_idx) +{ + /* WASMModuleInstance->e */ + uint32 e_offset_val = offsetof(WASMModuleInstance, e); + LLVMValueRef e_offset = I32_CONST(e_offset_val); + LLVMValueRef e_ptr_u8 = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, + &e_offset, 1, "e_ptr"); + LLVMValueRef e_ptr = + LLVMBuildBitCast(comp_ctx->builder, e_ptr_u8, OPQ_PTR_TYPE, "e_ptr"); + LLVMValueRef e = + LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, e_ptr, "e"); + + uint32 globals_offset_val; + if (comp_ctx->is_jit_mode) { + /* WASMModuleInstanceExtra->globals */ + globals_offset_val = offsetof(WASMModuleInstanceExtra, globals); + } + else { + /* AOTModuleInstanceExtra->globals */ + globals_offset_val = offsetof(AOTModuleInstanceExtra, globals); + } + LLVMValueRef globals_offset = I32_CONST(globals_offset_val); + LLVMValueRef globals_ptr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, e, &globals_offset, 1, "globals_ptr"); + + LLVMValueRef globals = + LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, globals_ptr, "globals"); + + /* WASMGlobalInstance[global_idx] */ + uint32 global_offset_val = global_idx * sizeof(WASMGlobalInstance); + LLVMValueRef global_offset = I32_CONST(global_offset_val); + LLVMValueRef global_ptr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, globals, &global_offset, 1, "global_ptr"); + + return global_ptr; +} + +static LLVMValueRef +get_global_value_addr(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + uint32 global_idx) +{ + /* WASMGlobalInstance[global_idx] */ + LLVMValueRef global_ptr = + get_global_from_wasm_inst(comp_ctx, func_ctx, global_idx); + + /* WASMGlobalInstance->import_module_inst */ + uint32 import_inst_offset_val = + offsetof(WASMGlobalInstance, import_module_inst); + LLVMValueRef import_inst_offset = I32_CONST(import_inst_offset_val); + LLVMValueRef import_inst_ptr_u8 = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, global_ptr, + &import_inst_offset, 1, "import_inst_u8_ptr"); + LLVMValueRef import_inst_ptr = LLVMBuildBitCast( + comp_ctx->builder, import_inst_ptr_u8, OPQ_PTR_TYPE, "import_inst_ptr"); + LLVMValueRef import_inst = LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, + import_inst_ptr, "import_inst"); + + /* WASMGlobalInstance->data_offset */ + uint32 data_offset_offset_val = offsetof(WASMGlobalInstance, data_offset); + LLVMValueRef data_offset_offset = I32_CONST(data_offset_offset_val); + LLVMValueRef data_offset_ptr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, global_ptr, + &data_offset_offset, 1, "data_offset_ptr"); + LLVMValueRef data_offset = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, + data_offset_ptr, "data_offset"); + + /* WASMModuleInstance->global_data preparation */ + uint32 global_data_offset_val = + offsetof(WASMModuleInstance, global_table_data.bytes) + + sizeof(AOTMemoryInstance) + * (comp_ctx->comp_data->memory_count + + comp_ctx->comp_data->import_memory_count); + LLVMValueRef global_data_offset = I32_CONST(global_data_offset_val); + + // Check if import_module_inst is NULL + LLVMBasicBlockRef then_block = LLVMAppendBasicBlockInContext( + comp_ctx->context, func_ctx->func, "then"); + LLVMBasicBlockRef else_block = LLVMAppendBasicBlockInContext( + comp_ctx->context, func_ctx->func, "else"); + LLVMBasicBlockRef merge_block = LLVMAppendBasicBlockInContext( + comp_ctx->context, func_ctx->func, "merge"); + + LLVMBuildCondBr(comp_ctx->builder, + LLVMBuildIsNull(comp_ctx->builder, import_inst, "is_null"), + then_block, else_block); + + // If import_module_inst is NULL + LLVMPositionBuilderAtEnd(comp_ctx->builder, then_block); + // load global_data from local module instance + LLVMValueRef local_global_data = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, + &global_data_offset, 1, "local_global_data"); + // global value pointer + LLVMValueRef local_global_value_ptr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, local_global_data, + &data_offset, 1, "local_global_value_ptr"); + + LLVMBuildBr(comp_ctx->builder, merge_block); + + // If import_module_inst is not NULL + LLVMPositionBuilderAtEnd(comp_ctx->builder, else_block); + // load global_data in import module instance + LLVMValueRef import_global_data = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, import_inst, + &global_data_offset, 1, "import_global_data"); + + LLVMValueRef import_global_value_ptr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, import_global_data, + &data_offset, 1, "import_global_value_ptr"); + + LLVMBuildBr(comp_ctx->builder, merge_block); + + // Merge block + LLVMPositionBuilderAtEnd(comp_ctx->builder, merge_block); + LLVMValueRef phi = + LLVMBuildPhi(comp_ctx->builder, OPQ_PTR_TYPE, "global_value_addr"); + LLVMAddIncoming(phi, &local_global_value_ptr, &then_block, 1); + LLVMAddIncoming(phi, &import_global_value_ptr, &else_block, 1); + + return phi; +} + static bool compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 global_idx, bool is_set, bool is_aux_stack) @@ -169,23 +296,9 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, bh_assert(global_idx < import_global_count + comp_data->global_count); if (global_idx < import_global_count) { - global_offset = - global_base_offset - /* Get global data offset according to target info */ - + (comp_ctx->pointer_size == sizeof(uint64) - ? comp_data->import_globals[global_idx].data_offset_64bit - : comp_data->import_globals[global_idx].data_offset_32bit); global_type = comp_data->import_globals[global_idx].type.val_type; } else { - global_offset = - global_base_offset - /* Get global data offset according to target info */ - + (comp_ctx->pointer_size == sizeof(uint64) - ? comp_data->globals[global_idx - import_global_count] - .data_offset_64bit - : comp_data->globals[global_idx - import_global_count] - .data_offset_32bit); global_type = comp_data->globals[global_idx - import_global_count].type.val_type; } @@ -193,13 +306,40 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (comp_ctx->enable_gc && aot_is_type_gc_reftype(global_type)) global_type = VALUE_TYPE_GC_REF; - offset = I32_CONST(global_offset); - if (!(global_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, - func_ctx->aot_inst, &offset, 1, - "global_ptr_tmp"))) { - aot_set_last_error("llvm build in bounds gep failed."); - return false; - } + // if (comp_ctx->is_jit_mode) { + global_ptr = get_global_value_addr(comp_ctx, func_ctx, global_idx); + // } + // else { + // if (global_idx < import_global_count) { + // global_offset = + // global_base_offset + // /* Get global data offset according to target info */ + // + (comp_ctx->pointer_size == sizeof(uint64) + // ? + // comp_data->import_globals[global_idx].data_offset_64bit + // : comp_data->import_globals[global_idx] + // .data_offset_32bit); + // } + // else { + // global_offset = + // global_base_offset + // /* Get global data offset according to target info */ + // + (comp_ctx->pointer_size == sizeof(uint64) + // ? comp_data->globals[global_idx - import_global_count] + // .data_offset_64bit + // : comp_data->globals[global_idx - import_global_count] + // .data_offset_32bit); + // } + + // offset = I32_CONST(global_offset); + // if (!(global_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, + // INT8_TYPE, + // func_ctx->aot_inst, &offset, + // 1, "global_ptr_tmp"))) { + // aot_set_last_error("llvm build in bounds gep failed."); + // return false; + // } + // } switch (global_type) { case VALUE_TYPE_I32: diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 46129d5177..4c9f9faafe 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -608,18 +608,23 @@ typedef struct WASMGlobalImport { char *module_name; char *field_name; WASMGlobalType type; + + /*TODO: not necessary if WASM_ENABLE_MULTI_MODULE == 0*/ bool is_linked; /* global data after linked */ WASMValue global_data_linked; + #if WASM_ENABLE_GC != 0 WASMRefType *ref_type; #endif + #if WASM_ENABLE_MULTI_MODULE != 0 /* imported function pointer after linked */ /* TODO: remove if not needed */ WASMModule *import_module; WASMGlobal *import_global_linked; #endif + #if WASM_ENABLE_FAST_JIT != 0 /* The data offset of current global in global data */ uint32 data_offset; diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index bd400fcc05..dee0291c24 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -5436,7 +5436,7 @@ wasm_create_global(const WASMModule *module, WASMModuleInstance *dep_inst, global->type = type->val_type; global->is_mutable = type->is_mutable; - global->import_global_inst = dep_inst; + global->import_module_inst = dep_inst; /* empty global. set value later by wasm_set_global_value */ return global; } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index bcad16e6ef..f1c142e165 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -315,6 +315,7 @@ typedef struct CApiFuncImport { } CApiFuncImport; /* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */ +/* but different size */ typedef struct WASMModuleInstanceExtraCommon { #if WASM_ENABLE_MODULE_INST_CONTEXT != 0 void *contexts[WASM_MAX_INSTANCE_CONTEXTS]; From 28c70c62f594891dc0880228a2232ac217d51bde Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 19 Nov 2024 08:44:35 +0000 Subject: [PATCH 04/20] Refactor: streamline global instance structure and improve global value handling --- core/iwasm/aot/aot_loader.c | 38 +++--- core/iwasm/aot/aot_runtime.c | 157 +++++++++++++++--------- core/iwasm/aot/aot_runtime.h | 5 +- core/iwasm/common/wasm_runtime_common.c | 44 ++++--- core/iwasm/interpreter/wasm_runtime.c | 31 +++-- core/iwasm/interpreter/wasm_runtime.h | 11 +- 6 files changed, 168 insertions(+), 118 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index b2bf1a96da..a6b4f5cb54 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -2167,24 +2167,26 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end, return false; } -#if WASM_ENABLE_LIBC_BUILTIN != 0 - if (wasm_native_lookup_libc_builtin_global( - import_globals[i].module_name, import_globals[i].global_name, - &tmp_global)) { - if (tmp_global.type.val_type != import_globals[i].type.val_type - || tmp_global.type.is_mutable - != import_globals[i].type.is_mutable) { - set_error_buf(error_buf, error_buf_size, - "incompatible import type"); - return false; - } - import_globals[i].global_data_linked = - tmp_global.global_data_linked; - import_globals[i].is_linked = true; - } -#else - import_globals[i].is_linked = false; -#endif + /*TODO: move to built-in linker */ + // #if WASM_ENABLE_LIBC_BUILTIN != 0 + // if (wasm_native_lookup_libc_builtin_global( + // import_globals[i].module_name, + // import_globals[i].global_name, &tmp_global)) { + // if (tmp_global.type.val_type != + // import_globals[i].type.val_type + // || tmp_global.type.is_mutable + // != import_globals[i].type.is_mutable) { + // set_error_buf(error_buf, error_buf_size, + // "incompatible import type"); + // return false; + // } + // import_globals[i].global_data_linked = + // tmp_global.global_data_linked; + // import_globals[i].is_linked = true; + // } + // #else + // import_globals[i].is_linked = false; + // #endif import_globals[i].size = wasm_value_type_size(import_globals[i].type.val_type); diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 15d06f854b..d104c43219 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -283,18 +283,11 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module, error_buf, error_buf_size)) { return false; } - if (init_expr->u.global_index < module->import_global_count) { - PUT_REF_TO_ADDR( - addr, module->import_globals[init_expr->u.global_index] - .global_data_linked.gc_obj); - } - else { - uint32 global_idx = - init_expr->u.global_index - module->import_global_count; - return assign_table_init_value( - module_inst, module, &module->globals[global_idx].init_expr, - addr, error_buf, error_buf_size); - } + + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)module_inst->e; + AOTGlobalInstance *global = e->globals + init_expr->u.global_index; + PUT_REF_TO_ADDR(addr, global->initial_value.gc_obj); break; } case INIT_EXPR_TYPE_REFNULL_CONST: @@ -444,58 +437,90 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module, } #endif /* end of WASM_ENABLE_GC != 0 */ -static bool -global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, - char *error_buf, uint32 error_buf_size) +static AOTGlobalInstance * +globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, + const WASMExternInstance *imports, uint32 import_count, + char *error_buf, uint32 error_buf_size) { uint32 i; - InitializerExpression *init_expr; uint8 *p = module_inst->global_data; - AOTImportGlobal *import_global = module->import_globals; - AOTGlobal *global = module->globals; + + uint64 total_size = + sizeof(AOTGlobalInstance) + * (uint64)(module->global_count + module->import_global_count); + AOTGlobalInstance *globals = + runtime_malloc(total_size, error_buf, error_buf_size); + if (!globals) { + return NULL; + } /* Initialize import global data */ - for (i = 0; i < module->import_global_count; i++, import_global++) { - bh_assert(import_global->data_offset + AOTGlobalInstance *global = globals; + AOTImportGlobal *import_global_type = module->import_globals; + for (i = 0; i < module->import_global_count; + i++, import_global_type++, global++) { + global->type = import_global_type->type.val_type; + global->is_mutable = import_global_type->type.is_mutable; + + bh_assert(import_global_type->data_offset == (uint32)(p - module_inst->global_data)); - init_global_data(p, import_global->type.val_type, - &import_global->global_data_linked); - p += import_global->size; + global->data_offset = import_global_type->data_offset; + + const WASMExternInstance *extern_inst = + wasm_runtime_get_extern_instance(imports, import_count, + WASM_IMPORT_EXPORT_KIND_GLOBAL, i); + if (!extern_inst) { + LOG_ERROR("missing an import global(%s, %s)", + import_global_type->module_name, + import_global_type->global_name); + goto fail; + } + + /* just in case */ +#ifndef NDEBUG + if (strcmp(import_global_type->global_name, extern_inst->field_name)) { + LOG_ERROR( + "mismatched import global name: expect \"%s\", got \"%s\"", + import_global_type->global_name, extern_inst->field_name); + goto fail; + } +#endif + + bh_memcpy_s(&global->initial_value, sizeof(WASMValue), + &extern_inst->u.global->initial_value, sizeof(WASMValue)); + global->import_module_inst = + (WASMModuleInstance *)extern_inst->dep_inst; + /* write into global_data */ + init_global_data(p, global->type, &global->initial_value); + + p += import_global_type->size; } /* Initialize defined global data */ - for (i = 0; i < module->global_count; i++, global++) { - uint8 flag; - bh_assert(global->data_offset + AOTGlobal *global_type = module->globals; + for (i = 0; i < module->global_count; i++, global_type++, global++) { + global->type = global_type->type.val_type; + global->is_mutable = global_type->type.is_mutable; + + bh_assert(global_type->data_offset == (uint32)(p - module_inst->global_data)); - init_expr = &global->init_expr; - flag = init_expr->init_expr_type; + global->data_offset = global_type->data_offset; + + InitializerExpression *init_expr = &global_type->init_expr; + uint8 flag = init_expr->init_expr_type; switch (flag) { case INIT_EXPR_TYPE_GET_GLOBAL: { if (!check_global_init_expr(module, init_expr->u.global_index, error_buf, error_buf_size)) { - return false; - } -#if WASM_ENABLE_GC == 0 - init_global_data( - p, global->type.val_type, - &module->import_globals[init_expr->u.global_index] - .global_data_linked); -#else - if (init_expr->u.global_index < module->import_global_count) { - init_global_data( - p, global->type.val_type, - &module->import_globals[init_expr->u.global_index] - .global_data_linked); - } - else { - uint32 global_idx = - init_expr->u.global_index - module->import_global_count; - init_global_data(p, global->type.val_type, - &module->globals[global_idx].init_expr.u); + goto fail; } -#endif + + bh_memcpy_s(&(global->initial_value), sizeof(WASMValue), + &(globals[init_expr->u.global_index].initial_value), + sizeof(WASMValue)); + + init_global_data(p, global->type, &global->initial_value); break; } #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0 @@ -522,7 +547,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, if (!(func_obj = aot_create_func_obj(module_inst, func_idx, false, error_buf, error_buf_size))) { - return false; + goto fail; } } @@ -559,7 +584,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, module->type_count, &module->rtt_type_lock))) { set_error_buf(error_buf, error_buf_size, "create rtt object failed"); - return false; + goto fail; } if (!(struct_obj = wasm_struct_obj_new_internal( @@ -568,7 +593,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, rtt_type))) { set_error_buf(error_buf, error_buf_size, "create struct object failed"); - return false; + goto fail; } if (flag == INIT_EXPR_TYPE_STRUCT_NEW) { @@ -620,7 +645,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, module->type_count, &module->rtt_type_lock))) { set_error_buf(error_buf, error_buf_size, "create rtt object failed"); - return false; + goto fail; } if (!(array_obj = wasm_array_obj_new_internal( @@ -629,7 +654,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, rtt_type, len, arr_init_val))) { set_error_buf(error_buf, error_buf_size, "create array object failed"); - return false; + goto fail; } if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) { @@ -650,16 +675,23 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #endif /* end of WASM_ENABLE_GC != 0 */ default: { - init_global_data(p, global->type.val_type, &init_expr->u); + bh_memcpy_s(&global->initial_value, sizeof(WASMValue), + &init_expr->u, sizeof(WASMValue)); + init_global_data(p, global->type, &global->initial_value); break; } } - p += global->size; + + p += global_type->size; } bh_assert(module_inst->global_data_size == (uint32)(p - module_inst->global_data)); - return true; + + return globals; +fail: + wasm_runtime_free(globals); + return NULL; } /** @@ -2193,8 +2225,13 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, + module_inst_mem_inst_size; module_inst->global_data = p; module_inst->global_data_size = module->global_data_size; - if (!global_instantiate(module_inst, module, error_buf, error_buf_size)) - goto fail; + if (module->import_global_count + module->global_count > 0) { + extra->globals = + globals_instantiate(module_inst, module, imports, import_count, + error_buf, error_buf_size); + if (!extra->globals) + goto fail; + } /* __heap_base */ uint8 *aux_heap_base_global_data = NULL; @@ -2223,8 +2260,8 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size)) goto fail; - if (!check_linked_symbol(module, error_buf, error_buf_size)) - goto fail; + // if (!check_linked_symbol(module, error_buf, error_buf_size)) + // goto fail; if (!create_exports(module_inst, module, error_buf, error_buf_size)) goto fail; diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 17418c7ee9..22e50fbe7e 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -132,6 +132,9 @@ typedef struct AOTModuleInstanceExtra { DefPointer(uint8 *, shared_heap_base_addr_adj); MemBound shared_heap_start_off; + DefPointer(AOTGlobalInstance *, globals); + uint32 global_count; + WASMModuleInstanceExtraCommon common; /** @@ -143,8 +146,6 @@ typedef struct AOTModuleInstanceExtra { AOTFunctionInstance **functions; uint32 function_count; - AOTGlobalInstance *globals; - uint32 global_count; #if WASM_ENABLE_MULTI_MODULE != 0 bh_list sub_module_inst_list_head; bh_list *sub_module_inst_list; diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 31f55b0b89..9618ab5b32 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7924,6 +7924,26 @@ wasm_runtime_create_global_internal(WASMModuleCommon *const module, return NULL; } +void +wasm_runtime_set_global_value(WASMModuleCommon *module, + WASMGlobalInstance *global, WASMValue *value) +{ + if (!global || !value) + return; + +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + wasm_set_global_value(global, value); + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + aot_set_global_value(global, value); + } +#endif +} + WASMGlobalInstance * wasm_runtime_create_global(WASMModuleCommon *const module, WASMGlobalType *const type, const wasm_val_t *value) @@ -7971,17 +7991,7 @@ wasm_runtime_create_global(WASMModuleCommon *const module, } } -#if WASM_ENABLE_INTERP != 0 - if (module->module_type == Wasm_Module_Bytecode) { - wasm_set_global_value(global, &init_value); - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (module->module_type == Wasm_Module_AoT) { - aot_set_global_value(global, &init_value); - } -#endif + wasm_runtime_set_global_value(module, global, &init_value); return global; } @@ -8202,19 +8212,23 @@ wasm_runtime_create_imports(WASMModuleCommon *module, if (!strncmp(import_type.name, "global_i32", 10)) { WASMValue value = { .i32 = 666 }; - wasm_set_global_value(extern_instance->u.global, &value); + wasm_runtime_set_global_value(module, extern_instance->u.global, + &value); } else if (!strncmp(import_type.name, "global_i64", 10)) { WASMValue value = { .i64 = 666 }; - wasm_set_global_value(extern_instance->u.global, &value); + wasm_runtime_set_global_value(module, extern_instance->u.global, + &value); } else if (!strncmp(import_type.name, "global_f32", 10)) { WASMValue value = { .f32 = 666.6f }; - wasm_set_global_value(extern_instance->u.global, &value); + wasm_runtime_set_global_value(module, extern_instance->u.global, + &value); } else if (!strncmp(import_type.name, "global_f64", 10)) { WASMValue value = { .f64 = 666.6 }; - wasm_set_global_value(extern_instance->u.global, &value); + wasm_runtime_set_global_value(module, extern_instance->u.global, + &value); } #endif } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index dee0291c24..f03a4cbaeb 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1441,7 +1441,7 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, LOG_ERROR("missing an import global(%s, %s)", import_global_type->module_name, import_global_type->field_name); - return NULL; + goto fail; } /* just in case */ @@ -1450,7 +1450,7 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, LOG_ERROR( "mismatched import global name: expect \"%s\", got \"%s\"", import_global_type->field_name, extern_inst->field_name); - return NULL; + goto fail; } #endif @@ -1463,21 +1463,22 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, } /* instantiate globals from global section */ - for (i = 0; i < module->global_count; i++) { - InitializerExpression *init_expr = &(module->globals[i].init_expr); - uint8 flag = init_expr->init_expr_type; - + for (i = 0; i < module->global_count; i++, global++) { global->type = module->globals[i].type.val_type; global->is_mutable = module->globals[i].type.is_mutable; + +#if WASM_ENABLE_GC != 0 + global->ref_type = module->globals[i].ref_type; +#endif + #if WASM_ENABLE_FAST_JIT != 0 bh_assert(global_data_offset == module->globals[i].data_offset); #endif global->data_offset = global_data_offset; global_data_offset += wasm_value_type_size(global->type); -#if WASM_ENABLE_GC != 0 - global->ref_type = module->globals[i].ref_type; -#endif + InitializerExpression *init_expr = &(module->globals[i].init_expr); + uint8 flag = init_expr->init_expr_type; switch (flag) { case INIT_EXPR_TYPE_GET_GLOBAL: { @@ -1486,10 +1487,9 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, goto fail; } - bh_memcpy_s( - &(global->initial_value), sizeof(WASMValue), - &(globals[init_expr->u.global_index].initial_value), - sizeof(globals[init_expr->u.global_index].initial_value)); + bh_memcpy_s(&(global->initial_value), sizeof(WASMValue), + &(globals[init_expr->u.global_index].initial_value), + sizeof(WASMValue)); break; } #if WASM_ENABLE_GC != 0 @@ -1558,11 +1558,9 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, #endif /* end of WASM_ENABLE_GC != 0 */ default: bh_memcpy_s(&(global->initial_value), sizeof(WASMValue), - &(init_expr->u), sizeof(init_expr->u)); + &(init_expr->u), sizeof(WASMValue)); break; } - - global++; } bh_assert((uint32)(global - globals) == global_count); @@ -2846,6 +2844,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, goto fail; } + /*TODO: init_global_data() ?*/ /* WASMGlobalInstance->initial_value => WASMModuleInstance->global_data*/ if (global_count > 0) { /* Initialize the global data */ diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index f1c142e165..e76ee487bc 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -204,13 +204,11 @@ struct WASMGlobalInstance { */ WASMValue initial_value; -#if WASM_ENABLE_GC != 0 - WASMRefType *ref_type; -#endif - /* just for import, keep the reference here */ - WASMModuleInstance *import_module_inst; - WASMGlobalInstance *import_global_inst; + DefPointer(WASMModuleInstance *, import_module_inst); + DefPointer(WASMGlobalInstance *, import_global_inst); + /* WASMRefType *ref_type */ + DefPointer(void *, ref_type); }; struct WASMFunctionInstance { @@ -315,7 +313,6 @@ typedef struct CApiFuncImport { } CApiFuncImport; /* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */ -/* but different size */ typedef struct WASMModuleInstanceExtraCommon { #if WASM_ENABLE_MODULE_INST_CONTEXT != 0 void *contexts[WASM_MAX_INSTANCE_CONTEXTS]; From b5593e511b2267aac3d2e9dd9b10d34a6f0a795f Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 19 Nov 2024 11:24:42 +0000 Subject: [PATCH 05/20] Refactor: remove unused global linking logic and clean up import handling --- core/iwasm/aot/aot_loader.c | 24 ------------------------ core/iwasm/aot/aot_runtime.c | 23 ----------------------- 2 files changed, 47 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index a6b4f5cb54..efe2cfb7e5 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -2144,9 +2144,6 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end, AOTImportGlobal *import_globals; uint64 size; uint32 i, data_offset = 0; -#if WASM_ENABLE_LIBC_BUILTIN != 0 - WASMGlobalImport tmp_global; -#endif /* Allocate memory */ size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count; @@ -2167,27 +2164,6 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end, return false; } - /*TODO: move to built-in linker */ - // #if WASM_ENABLE_LIBC_BUILTIN != 0 - // if (wasm_native_lookup_libc_builtin_global( - // import_globals[i].module_name, - // import_globals[i].global_name, &tmp_global)) { - // if (tmp_global.type.val_type != - // import_globals[i].type.val_type - // || tmp_global.type.is_mutable - // != import_globals[i].type.is_mutable) { - // set_error_buf(error_buf, error_buf_size, - // "incompatible import type"); - // return false; - // } - // import_globals[i].global_data_linked = - // tmp_global.global_data_linked; - // import_globals[i].is_linked = true; - // } - // #else - // import_globals[i].is_linked = false; - // #endif - import_globals[i].size = wasm_value_type_size(import_globals[i].type.val_type); import_globals[i].data_offset = data_offset; diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index d104c43219..8e3491d720 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -2034,26 +2034,6 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, return ret; } -static bool -check_linked_symbol(AOTModule *module, char *error_buf, uint32 error_buf_size) -{ - uint32 i; - - /* init_func_ptrs() will go through import functions */ - - for (i = 0; i < module->import_global_count; i++) { - AOTImportGlobal *global = module->import_globals + i; - if (!global->is_linked) { - set_error_buf_v(error_buf, error_buf_size, - "failed to link import global (%s, %s)", - global->module_name, global->global_name); - return false; - } - } - - return true; -} - AOTModuleInstance * aot_instantiate(AOTModule *module, AOTModuleInstance *parent, WASMExecEnv *exec_env_main, uint32 stack_size, uint32 heap_size, @@ -2260,9 +2240,6 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size)) goto fail; - // if (!check_linked_symbol(module, error_buf, error_buf_size)) - // goto fail; - if (!create_exports(module_inst, module, error_buf, error_buf_size)) goto fail; From 673c0059534ac791cde51aa72b785e7d593c79a8 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Wed, 20 Nov 2024 07:11:18 +0000 Subject: [PATCH 06/20] Refactor: remove unused global offset calculations and simplify global pointer retrieval --- core/iwasm/compilation/aot_emit_variable.c | 42 +--------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/core/iwasm/compilation/aot_emit_variable.c b/core/iwasm/compilation/aot_emit_variable.c index 00e7fc221b..d374fc6799 100644 --- a/core/iwasm/compilation/aot_emit_variable.c +++ b/core/iwasm/compilation/aot_emit_variable.c @@ -282,17 +282,10 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, { const AOTCompData *comp_data = comp_ctx->comp_data; uint32 import_global_count = comp_data->import_global_count; - uint32 global_base_offset; - uint32 global_offset; uint8 global_type; - LLVMValueRef offset, global_ptr, global, res; + LLVMValueRef global_ptr, global, res; LLVMTypeRef ptr_type = NULL; - global_base_offset = offsetof(AOTModuleInstance, global_table_data.bytes) - + sizeof(AOTMemoryInstance) - * (comp_ctx->comp_data->memory_count - + comp_ctx->comp_data->import_memory_count); - bh_assert(global_idx < import_global_count + comp_data->global_count); if (global_idx < import_global_count) { @@ -306,40 +299,7 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (comp_ctx->enable_gc && aot_is_type_gc_reftype(global_type)) global_type = VALUE_TYPE_GC_REF; - // if (comp_ctx->is_jit_mode) { global_ptr = get_global_value_addr(comp_ctx, func_ctx, global_idx); - // } - // else { - // if (global_idx < import_global_count) { - // global_offset = - // global_base_offset - // /* Get global data offset according to target info */ - // + (comp_ctx->pointer_size == sizeof(uint64) - // ? - // comp_data->import_globals[global_idx].data_offset_64bit - // : comp_data->import_globals[global_idx] - // .data_offset_32bit); - // } - // else { - // global_offset = - // global_base_offset - // /* Get global data offset according to target info */ - // + (comp_ctx->pointer_size == sizeof(uint64) - // ? comp_data->globals[global_idx - import_global_count] - // .data_offset_64bit - // : comp_data->globals[global_idx - import_global_count] - // .data_offset_32bit); - // } - - // offset = I32_CONST(global_offset); - // if (!(global_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, - // INT8_TYPE, - // func_ctx->aot_inst, &offset, - // 1, "global_ptr_tmp"))) { - // aot_set_last_error("llvm build in bounds gep failed."); - // return false; - // } - // } switch (global_type) { case VALUE_TYPE_I32: From 1f2f89b54ad45737fba1ceaf18053ec72086b0e3 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 21 Nov 2024 02:09:20 +0000 Subject: [PATCH 07/20] Refactor: improve memory management in module deinstantiation and handle global imports correctly --- core/iwasm/aot/aot_runtime.c | 19 +++++++++++++++++++ core/iwasm/common/wasm_runtime_common.c | 6 ++++++ core/iwasm/interpreter/wasm_runtime.c | 14 ++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 8e3491d720..5c8b80a4e3 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -2553,6 +2553,10 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) wasm_runtime_free(extra->functions); } + if (extra->globals) { + wasm_runtime_free(extra->globals); + } + if (module_inst->func_ptrs) wasm_runtime_free(module_inst->func_ptrs); @@ -2583,6 +2587,21 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) #endif (void)common; +#if WASM_ENABLE_MULTI_MODULE == 0 + AOTModule *module = (AOTModule *)module_inst->module; + for (uint32 i = 0; i < module->import_table_count; i++) { + AOTTableInstance *table = module_inst->tables[i]; + + if (!table) + continue; + + void *table_imported = + (void *)((uint8 *)(table)-offsetof(AOTTableInstance, elems)); + + wasm_runtime_free(table_imported); + } +#endif + wasm_runtime_free(module_inst); } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 9618ab5b32..17aaa4930b 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8070,6 +8070,12 @@ wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module, * WASMExternInstance->u.global */ if (imports) { + for (uint32 i = 0; i < import_count; i++) { + if (imports[i].kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { + wasm_runtime_destroy_global(module, imports[i].u.global); + } + } + wasm_runtime_free(imports); } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index f03a4cbaeb..1efc438e27 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -3688,6 +3688,20 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) bh_bitmap_delete(module_inst->e->common.elem_dropped); #endif +#if WASM_ENABLE_MULTI_MODULE == 0 + for (uint32 i = 0; i < module_inst->module->import_table_count; i++) { + WASMTableInstance *table = module_inst->tables[i]; + + if (!table) + continue; + + void *table_imported = + (void *)((uint8 *)table - offsetof(WASMTableInstance, elems)); + + wasm_runtime_free(table_imported); + } +#endif + wasm_runtime_free(module_inst); } From 32f276f4b8e85debef6d9e7e65f436b6bfc5fe24 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Sun, 24 Nov 2024 18:08:31 +0000 Subject: [PATCH 08/20] Refactor: enhance multi-module support for global imports and initialization --- core/iwasm/aot/aot_loader.c | 28 ++++++++++ core/iwasm/aot/aot_runtime.c | 77 +++++++++++++++++++-------- core/iwasm/interpreter/wasm_runtime.c | 14 ----- 3 files changed, 82 insertions(+), 37 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index efe2cfb7e5..31d28b83bf 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -2144,6 +2144,11 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end, AOTImportGlobal *import_globals; uint64 size; uint32 i, data_offset = 0; +#if WASM_ENABLE_MULTI_MODULE != 0 +#if WASM_ENABLE_LIBC_BUILTIN != 0 + WASMGlobalImport tmp_global; +#endif +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ /* Allocate memory */ size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count; @@ -2164,6 +2169,29 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end, return false; } +#if WASM_ENABLE_MULTI_MODULE != 0 +#if WASM_ENABLE_LIBC_BUILTIN != 0 + if (wasm_native_lookup_libc_builtin_global( + import_globals[i].module_name, import_globals[i].global_name, + &tmp_global)) { + if (tmp_global.type.val_type != import_globals[i].type.val_type + || tmp_global.type.is_mutable + != import_globals[i].type.is_mutable) { + set_error_buf(error_buf, error_buf_size, + "incompatible import type"); + return false; + } + import_globals[i].global_data_linked = + tmp_global.global_data_linked; + import_globals[i].is_linked = true; + } + else +#endif +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ + { + import_globals[i].is_linked = false; + } + import_globals[i].size = wasm_value_type_size(import_globals[i].type.val_type); import_globals[i].data_offset = data_offset; diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 5c8b80a4e3..a635e52ad4 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -284,10 +284,25 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module, return false; } +#if WASM_ENABLE_MULTI_MODULE != 0 + if (init_expr->u.global_index < module->import_global_count) { + PUT_REF_TO_ADDR( + addr, module->import_globals[init_expr->u.global_index] + .global_data_linked.gc_obj); + } + else { + uint32 global_idx = + init_expr->u.global_index - module->import_global_count; + return assign_table_init_value( + module_inst, module, &module->globals[global_idx].init_expr, + addr, error_buf, error_buf_size); + } +#else AOTModuleInstanceExtra *e = (AOTModuleInstanceExtra *)module_inst->e; AOTGlobalInstance *global = e->globals + init_expr->u.global_index; PUT_REF_TO_ADDR(addr, global->initial_value.gc_obj); +#endif break; } case INIT_EXPR_TYPE_REFNULL_CONST: @@ -466,6 +481,10 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, == (uint32)(p - module_inst->global_data)); global->data_offset = import_global_type->data_offset; +#if WASM_ENABLE_MULTI_MODULE != 0 + init_global_data(p, import_global_type->type.val_type, + &import_global_type->global_data_linked); +#else const WASMExternInstance *extern_inst = wasm_runtime_get_extern_instance(imports, import_count, WASM_IMPORT_EXPORT_KIND_GLOBAL, i); @@ -492,6 +511,7 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, (WASMModuleInstance *)extern_inst->dep_inst; /* write into global_data */ init_global_data(p, global->type, &global->initial_value); +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ p += import_global_type->size; } @@ -516,11 +536,39 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, goto fail; } - bh_memcpy_s(&(global->initial_value), sizeof(WASMValue), - &(globals[init_expr->u.global_index].initial_value), - sizeof(WASMValue)); + uint32 global_index_in_expr = init_expr->u.global_index; + if (global_index_in_expr < module->import_global_count) { +#if WASM_ENABLE_MULTI_MODULE != 0 + /* from WASMImportGlobal or WASMGlobal to global_data */ + init_global_data( + p, global_type->type.val_type, + &module->import_globals[global_index_in_expr] + .global_data_linked); +#else + /* + * from WASMImportGlobal or WASMGlobal to WASMGlobalInstance + * to global_data + */ + global->initial_value = + globals[init_expr->u.global_index].initial_value; + init_global_data(p, global_type->type.val_type, + &global->initial_value); +#endif /* WASM_ENABLE_MULTI_MODULE != 0*/ + } + else { +#if WASM_ENABLE_GC == 0 + bh_assert(false + && "only GC mode support using non-import global " + "in a constant expression"); +#endif + uint32 adjusted_global_index_in_expr = + global_index_in_expr - module->import_global_count; + init_global_data( + p, global_type->type.val_type, + &module->globals[adjusted_global_index_in_expr] + .init_expr.u); + } - init_global_data(p, global->type, &global->initial_value); break; } #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0 @@ -675,8 +723,7 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #endif /* end of WASM_ENABLE_GC != 0 */ default: { - bh_memcpy_s(&global->initial_value, sizeof(WASMValue), - &init_expr->u, sizeof(WASMValue)); + global->initial_value = init_expr->u; init_global_data(p, global->type, &global->initial_value); break; } @@ -2587,21 +2634,6 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) #endif (void)common; -#if WASM_ENABLE_MULTI_MODULE == 0 - AOTModule *module = (AOTModule *)module_inst->module; - for (uint32 i = 0; i < module->import_table_count; i++) { - AOTTableInstance *table = module_inst->tables[i]; - - if (!table) - continue; - - void *table_imported = - (void *)((uint8 *)(table)-offsetof(AOTTableInstance, elems)); - - wasm_runtime_free(table_imported); - } -#endif - wasm_runtime_free(module_inst); } @@ -5843,8 +5875,7 @@ aot_create_global(const AOTModule *module, AOTModuleInstance *dep_inst, void aot_set_global_value(AOTGlobalInstance *global, const WASMValue *value) { - bh_memcpy_s(&global->initial_value, sizeof(WASMValue), value, - sizeof(WASMValue)); + global->initial_value = *value; } void diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 1efc438e27..f03a4cbaeb 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -3688,20 +3688,6 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) bh_bitmap_delete(module_inst->e->common.elem_dropped); #endif -#if WASM_ENABLE_MULTI_MODULE == 0 - for (uint32 i = 0; i < module_inst->module->import_table_count; i++) { - WASMTableInstance *table = module_inst->tables[i]; - - if (!table) - continue; - - void *table_imported = - (void *)((uint8 *)table - offsetof(WASMTableInstance, elems)); - - wasm_runtime_free(table_imported); - } -#endif - wasm_runtime_free(module_inst); } From 3242e32f5e8866893143cda728cdfcbc51f5a569 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Mon, 25 Nov 2024 13:57:27 +0000 Subject: [PATCH 09/20] Refactor: remove unused import functions and enhance global instance creation for spec tests --- core/iwasm/aot/aot_runtime.c | 86 +++++------ core/iwasm/common/wasm_native.h | 18 +++ core/iwasm/common/wasm_runtime_common.c | 104 +++++-------- core/iwasm/common/wasm_runtime_common.h | 13 ++ core/iwasm/include/wasm_export.h | 8 - core/iwasm/interpreter/wasm_runtime.c | 16 +- .../libraries/libc-builtin/libc_builtin.cmake | 13 +- .../libc-builtin/libc_builtin_wrapper.c | 7 +- .../libc-builtin/spec_test_builtin_wrapper.c | 143 ++++++++++++++++++ 9 files changed, 279 insertions(+), 129 deletions(-) create mode 100644 core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index a635e52ad4..230c43ed9e 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -284,11 +284,19 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module, return false; } -#if WASM_ENABLE_MULTI_MODULE != 0 + /*TODO: via WASMGlobalInstance->init_value ? */ if (init_expr->u.global_index < module->import_global_count) { +#if WASM_ENABLE_MULTI_MODULE != 0 PUT_REF_TO_ADDR( addr, module->import_globals[init_expr->u.global_index] .global_data_linked.gc_obj); +#else + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)module_inst->e; + AOTGlobalInstance *global = + e->globals + init_expr->u.global_index; + PUT_REF_TO_ADDR(addr, global->initial_value.gc_obj); +#endif } else { uint32 global_idx = @@ -297,12 +305,6 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module, module_inst, module, &module->globals[global_idx].init_expr, addr, error_buf, error_buf_size); } -#else - AOTModuleInstanceExtra *e = - (AOTModuleInstanceExtra *)module_inst->e; - AOTGlobalInstance *global = e->globals + init_expr->u.global_index; - PUT_REF_TO_ADDR(addr, global->initial_value.gc_obj); -#endif break; } case INIT_EXPR_TYPE_REFNULL_CONST: @@ -546,11 +548,11 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, .global_data_linked); #else /* - * from WASMImportGlobal or WASMGlobal to WASMGlobalInstance + * from WASMImportGlobal to WASMGlobalInstance * to global_data */ global->initial_value = - globals[init_expr->u.global_index].initial_value; + globals[global_index_in_expr].initial_value; init_global_data(p, global_type->type.val_type, &global->initial_value); #endif /* WASM_ENABLE_MULTI_MODULE != 0*/ @@ -563,10 +565,16 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #endif uint32 adjusted_global_index_in_expr = global_index_in_expr - module->import_global_count; - init_global_data( - p, global_type->type.val_type, - &module->globals[adjusted_global_index_in_expr] - .init_expr.u); + + /* + * from WASMGlobal to WASMGlobalInstance + * to global_data + */ + global->initial_value = + module->globals[adjusted_global_index_in_expr] + .init_expr.u; + init_global_data(p, global_type->type.val_type, + &global->initial_value); } break; @@ -574,12 +582,14 @@ globals_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0 case INIT_EXPR_TYPE_REFNULL_CONST: { + /* no need to assign global->initial_value */ *(uint32 *)p = NULL_REF; break; } #elif WASM_ENABLE_GC != 0 case INIT_EXPR_TYPE_REFNULL_CONST: { + /* no need to assign global->initial_value */ WASMObjectRef gc_obj = NULL_REF; PUT_REF_TO_ADDR(p, gc_obj); break; @@ -918,7 +928,7 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module, /* Resolve table data base offset */ /* TODO: The table64 current implementation assumes table max size * UINT32_MAX, so the offset conversion here is safe */ - uint32 base_offset; + uint32 base_offset = 0; if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) { uint32 global_index = table_seg->offset.u.global_index; uint32 global_data_offset; @@ -928,13 +938,10 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module, return false; } - if (global_index < module->import_global_count) - global_data_offset = - module->import_globals[global_index].data_offset; - else - global_data_offset = - module->globals[global_index - module->import_global_count] - .data_offset; + /* since we have transfer data_offset into WASMGlobalInstance */ + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)module_inst->e; + global_data_offset = e->globals[global_index].data_offset; base_offset = *(uint32 *)(module_inst->global_data + global_data_offset); @@ -2252,7 +2259,8 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, + module_inst_mem_inst_size; module_inst->global_data = p; module_inst->global_data_size = module->global_data_size; - if (module->import_global_count + module->global_count > 0) { + extra->global_count = module->import_global_count + module->global_count; + if (extra->global_count > 0) { extra->globals = globals_instantiate(module_inst, module, imports, import_count, error_buf, error_buf_size); @@ -2404,10 +2412,11 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, &tbl_init_size, &tbl_max_size); if (!wasm_elem_is_declarative(table_init_data->mode) - && !wasm_reftype_is_subtype_of( - table_init_data->elem_type, table_init_data->elem_ref_type, - table->elem_type, table->elem_ref_type.elem_ref_type, - module->types, module->type_count)) { + && !wasm_reftype_is_subtype_of((uint8)table_init_data->elem_type, + table_init_data->elem_ref_type, + table->elem_type, + table->elem_ref_type.elem_ref_type, + module->types, module->type_count)) { set_error_buf(error_buf, error_buf_size, "type mismatch: elements segment does not fit"); goto fail; @@ -2432,30 +2441,21 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, /* init vec(funcidx) or vec(expr) */ if (table_init_data->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) { - uint32 data_offset; + uint32 data_offset = 0; if (!check_global_init_expr(module, table_init_data->offset.u.global_index, error_buf, error_buf_size)) { goto fail; } - if (table_init_data->offset.u.global_index - < module->import_global_count) { - data_offset = - module - ->import_globals[table_init_data->offset.u.global_index] - .data_offset; - } - else { - data_offset = - module - ->globals[table_init_data->offset.u.global_index - - module->import_global_count] - .data_offset; - } + /* since we have transfer data_offset into WASMGlobalInstance */ + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)module_inst->e; + data_offset = + e->globals[table_init_data->offset.u.global_index].data_offset; table_init_data->offset.u.i32 = - *(uint32 *)(module_inst->global_data + data_offset); + *(int32 *)(module_inst->global_data + data_offset); } /* check offset since length might negative */ @@ -2477,7 +2477,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, goto fail; } - for (j = 0; j < module->table_init_data_list[i]->value_count; j++) { + for (j = 0; j < table_init_data->value_count; j++) { if (!assign_table_init_value( module_inst, module, &table_init_data->init_values[j], table_data + table_init_data->offset.u.i32 + j, error_buf, diff --git a/core/iwasm/common/wasm_native.h b/core/iwasm/common/wasm_native.h index 9a6afee195..5018c2cbab 100644 --- a/core/iwasm/common/wasm_native.h +++ b/core/iwasm/common/wasm_native.h @@ -110,6 +110,24 @@ void * wasm_native_lookup_quick_aot_entry(const WASMFuncType *func_type); #endif +wasm_global_inst_t +wasm_native_create_spec_test_builtin_global(wasm_module_t module, + const char *module_name, + const char *name, + wasm_global_type_t type); + +wasm_table_inst_t * +wasm_native_create_spec_test_builtin_table(wasm_module_t module, + const char *module_name, + const char *name, + wasm_table_type_t type); + +wasm_memory_inst_t +wasm_native_create_spec_test_builtin_memory(wasm_module_t module, + const char *module_name, + const char *name, + wasm_memory_type_t type); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 17aaa4930b..5a984d9b4c 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7840,8 +7840,9 @@ wasm_table_inst_t wasm_runtime_create_table(WASMModuleCommon *const module, wasm_table_type_t const type) { - if (!module || !type) + if (!module || !type) { return NULL; + } #if WASM_ENABLE_INTERP != 0 if (module->module_type == Wasm_Module_Bytecode) { @@ -7855,7 +7856,6 @@ wasm_runtime_create_table(WASMModuleCommon *const module, } #endif - LOG_ERROR("create table failed, invalid module type"); return NULL; } @@ -8064,7 +8064,8 @@ wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module, * WASMExternInstance->u.memory content * * WASModuleInstance->tables[i].elems takes - * the ownership of WASMExternInstance->u.table + * the ownership of WASMExternInstance->u.table as WASMTableInstance + * BUT, there is a shell table wasm_table_inst_t * * WASMModuleInstance->e->globals[i] copies the content of * WASMExternInstance->u.global @@ -8074,6 +8075,10 @@ wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module, if (imports[i].kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { wasm_runtime_destroy_global(module, imports[i].u.global); } + /* FIXME: with reusing WASMTableInstance */ + if (imports[i].kind == WASM_IMPORT_EXPORT_KIND_TABLE) { + wasm_runtime_free(imports[i].u.table); + } } wasm_runtime_free(imports); @@ -8082,10 +8087,11 @@ wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module, return inst; } +#if WASM_ENABLE_SPEC_TEST != 0 bool -wasm_runtime_create_extern_inst(WASMModuleCommon *module, - wasm_import_t *import_type, - WASMExternInstance *out) +wasm_runtime_create_extern_inst_for_spec_test(WASMModuleCommon *module, + wasm_import_t *import_type, + WASMExternInstance *out) { if (!out) return false; @@ -8098,25 +8104,27 @@ wasm_runtime_create_extern_inst(WASMModuleCommon *module, out->kind = import_type->kind; if (import_type->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { - out->u.memory = - wasm_runtime_create_memory(module, import_type->u.memory_type); + out->u.memory = wasm_native_create_spec_test_builtin_memory( + module, import_type->module_name, import_type->name, + import_type->u.memory_type); if (!out->u.memory) { LOG_ERROR("create memory failed\n"); return false; } } else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_TABLE) { - wasm_table_inst_t table = - wasm_runtime_create_table(module, import_type->u.table_type); - out->u.table = table; + out->u.table = wasm_native_create_spec_test_builtin_table( + module, import_type->module_name, import_type->name, + import_type->u.table_type); if (!out->u.table) { LOG_ERROR("create table failed\n"); return false; } } else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { - out->u.global = wasm_runtime_create_global_internal( - module, NULL, import_type->u.global_type); + out->u.global = wasm_native_create_spec_test_builtin_global( + module, import_type->module_name, import_type->name, + import_type->u.global_type); if (!out->u.global) { LOG_ERROR("create global failed\n"); return false; @@ -8130,6 +8138,7 @@ wasm_runtime_create_extern_inst(WASMModuleCommon *module, return true; } +#endif void wasm_runtime_destroy_extern_inst(WASMModuleCommon *module, @@ -8142,6 +8151,14 @@ wasm_runtime_destroy_extern_inst(WASMModuleCommon *module, wasm_runtime_destroy_memory(module, extern_inst->u.memory); extern_inst->u.memory = NULL; } + else if (extern_inst->kind == WASM_IMPORT_EXPORT_KIND_TABLE) { + wasm_runtime_destroy_table(module, extern_inst->u.table); + extern_inst->u.table = NULL; + } + else if (extern_inst->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { + wasm_runtime_destroy_global(module, extern_inst->u.global); + extern_inst->u.global = NULL; + } else { LOG_DEBUG("unimplemented import(%s,%s) kind %d", extern_inst->module_name, extern_inst->field_name, @@ -8156,7 +8173,7 @@ wasm_runtime_destroy_extern_inst(WASMModuleCommon *module, * 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. */ -void +static void wasm_runtime_destroy_imports(WASMModuleCommon *module, WASMExternInstance *extern_inst_list) { @@ -8170,10 +8187,12 @@ wasm_runtime_destroy_imports(WASMModuleCommon *module, } bool -wasm_runtime_create_imports(WASMModuleCommon *module, - bool (*module_name_filter)(const char *), - WASMExternInstance *out, uint32 out_len) +wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module, + WASMExternInstance *out, + uint32 out_len) { + LOG_DEBUG("create imports with builtin"); + int32 import_count_s = wasm_runtime_get_import_count(module); if (import_count_s < 0) @@ -8193,65 +8212,20 @@ wasm_runtime_create_imports(WASMModuleCommon *module, wasm_import_t import_type = { 0 }; wasm_runtime_get_import_type(module, i, &import_type); - if (module_name_filter - && !module_name_filter(import_type.module_name)) { - LOG_DEBUG("skip import(%s,%s)", import_type.module_name, - import_type.name); - continue; - } - WASMExternInstance *extern_instance = out + i; - /* create empty extern_inst */ - if (!wasm_runtime_create_extern_inst(module, &import_type, - extern_instance)) { +#if WASM_ENABLE_SPEC_TEST != 0 + if (!wasm_runtime_create_extern_inst_for_spec_test(module, &import_type, + extern_instance)) { wasm_runtime_destroy_imports(module, out); LOG_ERROR("create import failed"); return false; } - - /* assign values */ -#if WASM_ENABLE_SPEC_TEST != 0 - if (import_type.kind != WASM_IMPORT_EXPORT_KIND_GLOBAL - && import_type.kind != WASM_IMPORT_EXPORT_KIND_FUNC) { - continue; - } - - if (!strncmp(import_type.name, "global_i32", 10)) { - WASMValue value = { .i32 = 666 }; - wasm_runtime_set_global_value(module, extern_instance->u.global, - &value); - } - else if (!strncmp(import_type.name, "global_i64", 10)) { - WASMValue value = { .i64 = 666 }; - wasm_runtime_set_global_value(module, extern_instance->u.global, - &value); - } - else if (!strncmp(import_type.name, "global_f32", 10)) { - WASMValue value = { .f32 = 666.6f }; - wasm_runtime_set_global_value(module, extern_instance->u.global, - &value); - } - else if (!strncmp(import_type.name, "global_f64", 10)) { - WASMValue value = { .f64 = 666.6 }; - wasm_runtime_set_global_value(module, extern_instance->u.global, - &value); - } #endif } return true; } -bool -wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module, - WASMExternInstance *out, - uint32 out_len) -{ - LOG_DEBUG("create imports with builtin"); - return wasm_runtime_create_imports(module, wasm_runtime_is_built_in_module, - out, out_len); -} - #if WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0 /* diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 0460c5ea87..e9643c2347 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -1230,6 +1230,19 @@ wasm_runtime_get_extern_instance(const WASMExternInstance *imports, uint32 import_count, wasm_import_export_kind_t kind, uint32 index); +struct WASMGlobalInstance * +wasm_runtime_create_global_internal(wasm_module_t const module, + wasm_module_inst_t dep_inst, + wasm_global_type_t type); + +void +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, + WASMTableType *const type); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 4f7b9dcf7f..92633781da 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -2394,14 +2394,6 @@ 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 imports); - -WASM_RUNTIME_API_EXTERN bool -wasm_runtime_create_imports(wasm_module_t module, - bool (*module_name_filter)(const char *), - wasm_extern_inst_t out, uint32_t out_len); - #ifdef __cplusplus } #endif diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index f03a4cbaeb..2a3f747623 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -772,8 +772,10 @@ tables_deinstantiate(WASMModuleInstance *module_inst) } #endif - wasm_runtime_free(module_inst->tables); - module_inst->tables = NULL; + if (module_inst->tables) { + wasm_runtime_free(module_inst->tables); + module_inst->tables = NULL; + } } /** @@ -1265,7 +1267,7 @@ instantiate_struct_global_recursive(WASMModule *module, (WASMStructNewInitValues *)wasm_value->data; WASMStructObjectRef field = instantiate_struct_global_recursive( - module, module_inst, heap_type, + module, module_inst, (uint32)heap_type, init_values1 ? INIT_EXPR_TYPE_STRUCT_NEW : INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT, init_values1, error_buf, error_buf_size); @@ -2177,9 +2179,7 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, return false; } } -#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ -#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_TAGS != 0 for (i = 0; i < module->import_tag_count; i++) { WASMTagImport *tag = &((module->import_tags + i)->u.tag); @@ -2192,7 +2192,7 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, } } #endif /* WASM_ENABLE_TAGS != 0 */ -#endif +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ return true; } @@ -2918,7 +2918,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, /* UINT32_MAX indicates that it is a null reference */ if ((uint32)global->initial_value.i32 != UINT32_MAX) { if (!(func_obj = wasm_create_func_obj( - module_inst, global->initial_value.i32, + module_inst, global->initial_value.u32, false, error_buf, error_buf_size))) goto fail; } @@ -3436,7 +3436,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, } case INIT_EXPR_TYPE_I31_NEW: { - ref = (wasm_obj_t)wasm_i31_obj_new(init_expr->u.i32); + ref = (wasm_obj_t)wasm_i31_obj_new(init_expr->u.u32); break; } #endif /* end of WASM_ENABLE_GC != 0 */ diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin.cmake b/core/iwasm/libraries/libc-builtin/libc_builtin.cmake index 0838712b86..859eb9cbb6 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin.cmake +++ b/core/iwasm/libraries/libc-builtin/libc_builtin.cmake @@ -5,9 +5,16 @@ set (LIBC_BUILTIN_DIR ${CMAKE_CURRENT_LIST_DIR}) add_definitions (-DWASM_ENABLE_LIBC_BUILTIN=1) -include_directories(${LIBC_BUILTIN_DIR}) +include_directories (${LIBC_BUILTIN_DIR}) -file (GLOB source_all ${LIBC_BUILTIN_DIR}/*.c) +list (APPEND source_all ${LIBC_BUILTIN_DIR}/libc_builtin_wrapper.c) -set (LIBC_BUILTIN_SOURCE ${source_all}) +if (WAMR_BUILD_SPEC_TEST EQUAL 1) + list (APPEND source_all ${LIBC_BUILTIN_DIR}/spec_test_builtin_wrapper.c) +endif () + +if (WAMR_BUILD_WASI_TEST EQUAL 1) + list (APPEND source_all ${LIBC_BUILTIN_DIR}/wasi_test_builtin_wrapper.c) +endif () +set (LIBC_BUILTIN_SOURCE ${source_all}) diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index a68c074941..349a3d0cad 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -7,6 +7,7 @@ #include "bh_log.h" #include "wasm_export.h" #include "../interpreter/wasm.h" +#include "../common/wasm_runtime_common.h" #if defined(_WIN32) || defined(_WIN32_) #define strncasecmp _strnicmp @@ -1153,8 +1154,10 @@ static WASMNativeGlobalDef native_global_defs[] = { { "M", "g", REF_TYPE_HT_NON_NULLABLE, false, .value.gc_obj = 0 }, #endif #endif - { "global", "NaN", VALUE_TYPE_F64, .value.u64 = 0x7FF8000000000000LL }, - { "global", "Infinity", VALUE_TYPE_F64, .value.u64 = 0x7FF0000000000000LL } + { "global", "NaN", VALUE_TYPE_F64, false, + .value.u64 = 0x7FF8000000000000LL }, + { "global", "Infinity", VALUE_TYPE_F64, false, + .value.u64 = 0x7FF0000000000000LL } }; bool diff --git a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c new file mode 100644 index 0000000000..6ef5c479a2 --- /dev/null +++ b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "bh_log.h" +#include "wasm_export.h" +#include "../common/wasm_runtime_common.h" + +/************************************* + * Functions + *************************************/ + +/************************************* + * Globals + *************************************/ + +typedef struct WASMNativeGlobalDef { + const char *module_name; + const char *name; + uint8 type; + bool is_mutable; + WASMValue value; +} WASMNativeGlobalDef; + +static WASMNativeGlobalDef native_global_defs[] = { + /* for standard spec test */ + { "spectest", "global_i32", VALUE_TYPE_I32, false, .value.i32 = 666 }, + { "spectest", "global_i64", VALUE_TYPE_I64, false, .value.i64 = 666 }, + { "spectest", "global_f32", VALUE_TYPE_F32, false, .value.f32 = 666.6f }, + { "spectest", "global_f64", VALUE_TYPE_F64, false, .value.f64 = 666.6 }, + { "test", "global-i32", VALUE_TYPE_I32, false, .value.i32 = 0 }, + { "test", "global-f32", VALUE_TYPE_F32, false, .value.f32 = 0 }, + { "test", "global-mut-i32", VALUE_TYPE_I32, true, .value.i32 = 0 }, + { "test", "global-mut-i64", VALUE_TYPE_I64, true, .value.i64 = 0 }, + { "test", "g", VALUE_TYPE_I32, true, .value.i32 = 0 }, +/* for gc spec test */ +#if WASM_ENABLE_GC != 0 + { "G", "g", VALUE_TYPE_I32, false, .value.i32 = 4 }, + { "M", "g", REF_TYPE_HT_NON_NULLABLE, false, .value.gc_obj = 0 }, +#endif +}; + +wasm_global_inst_t +wasm_native_create_spec_test_builtin_global(wasm_module_t module, + const char *module_name, + const char *name, + wasm_global_type_t type) +{ + if (!module || !module_name || !name || !type) { + return NULL; + } + + uint32 size = sizeof(native_global_defs) / sizeof(WASMNativeGlobalDef); + WASMNativeGlobalDef *global_def = native_global_defs; + WASMNativeGlobalDef *global_def_end = global_def + size; + for (; global_def < global_def_end; global_def++) { + if (strcmp(global_def->module_name, module_name) != 0) { + continue; + } + + if (strcmp(global_def->name, name) != 0) { + continue; + } + + wasm_global_inst_t global = + wasm_runtime_create_global_internal(module, NULL, type); + if (!global) { + return NULL; + } + + wasm_runtime_set_global_value(module, global, &global_def->value); + return global; + } + + return NULL; +} + +/************************************* + * Tables + *************************************/ + +typedef struct WASMNativeTableDef { + const char *module_name; + const char *name; + uint8 elem_type; + +} WASMNativeTableDef; + +/*TODO: fix me*/ +wasm_table_inst_t * +wasm_native_create_spec_test_builtin_table(wasm_module_t module, + const char *module_name, + const char *name, + wasm_table_type_t type) +{ + if (!module || !module_name || !name || !type) { + return NULL; + } + + if (strcmp(module_name, "spectest") != 0) { + return NULL; + } + + if (strcmp(name, "table") != 0) { + return NULL; + } + + return wasm_runtime_create_table(module, type); +} + +/************************************* + * Memories + *************************************/ + +typedef struct WASMNativeMemoryDef { + const char *module_name; + const char *name; +} WASMNativeMemoryDef; + +/* + * no predefined memory for spec test + */ +wasm_memory_inst_t +wasm_native_create_spec_test_builtin_memory(wasm_module_t module, + const char *module_name, + const char *name, + wasm_memory_type_t type) +{ + if (!module || !module_name || !name || !type) { + return NULL; + } + + if (strcmp(module_name, "spectest") != 0) { + return NULL; + } + + if (strcmp(name, "memory") != 0) { + return NULL; + } + + return wasm_runtime_create_memory(module, type); +} From 1f1724560803894c0557c4d43a7a69a12ae9bf9f Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 26 Nov 2024 09:44:24 +0000 Subject: [PATCH 10/20] Refactor: streamline WASI and spec test integration by consolidating global definitions and removing unused code --- core/iwasm/common/wasm_native.h | 30 +++--- core/iwasm/common/wasm_runtime_common.c | 67 +++---------- .../libraries/libc-builtin/builtin_wrapper.h | 43 +++++++++ .../libc-builtin/libc_builtin_wrapper.c | 14 +-- .../libc-builtin/spec_test_builtin_wrapper.c | 78 ++++++++++----- .../libc-builtin/wasi_test_builtin_wrapper.c | 94 +++++++++++++++++++ tests/wamr-test-suites/test_wamr.sh | 2 +- 7 files changed, 222 insertions(+), 106 deletions(-) create mode 100644 core/iwasm/libraries/libc-builtin/builtin_wrapper.h create mode 100644 core/iwasm/libraries/libc-builtin/wasi_test_builtin_wrapper.c diff --git a/core/iwasm/common/wasm_native.h b/core/iwasm/common/wasm_native.h index 5018c2cbab..f1188d8323 100644 --- a/core/iwasm/common/wasm_native.h +++ b/core/iwasm/common/wasm_native.h @@ -110,23 +110,19 @@ void * wasm_native_lookup_quick_aot_entry(const WASMFuncType *func_type); #endif -wasm_global_inst_t -wasm_native_create_spec_test_builtin_global(wasm_module_t module, - const char *module_name, - const char *name, - wasm_global_type_t type); - -wasm_table_inst_t * -wasm_native_create_spec_test_builtin_table(wasm_module_t module, - const char *module_name, - const char *name, - wasm_table_type_t type); - -wasm_memory_inst_t -wasm_native_create_spec_test_builtin_memory(wasm_module_t module, - const char *module_name, - const char *name, - wasm_memory_type_t type); +#if WASM_ENABLE_SPEC_TEST != 0 +bool +wasm_runtime_create_extern_inst_for_spec_test(wasm_module_t module, + wasm_import_t *import_type, + WASMExternInstance *out); +#endif + +#if WASM_ENABLE_WASI_TEST != 0 +bool +wasm_runtime_create_extern_inst_for_wasi_test(wasm_module_t module, + wasm_import_t *import_type, + WASMExternInstance *out); +#endif #ifdef __cplusplus } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 5a984d9b4c..b2598fb35b 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8087,59 +8087,6 @@ wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module, return inst; } -#if WASM_ENABLE_SPEC_TEST != 0 -bool -wasm_runtime_create_extern_inst_for_spec_test(WASMModuleCommon *module, - wasm_import_t *import_type, - WASMExternInstance *out) -{ - if (!out) - return false; - - LOG_DEBUG("create import(%s,%s) kind %d", import_type->module_name, - import_type->name, import_type->kind); - - out->module_name = import_type->module_name; - out->field_name = import_type->name; - out->kind = import_type->kind; - - if (import_type->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { - out->u.memory = wasm_native_create_spec_test_builtin_memory( - module, import_type->module_name, import_type->name, - import_type->u.memory_type); - if (!out->u.memory) { - LOG_ERROR("create memory failed\n"); - return false; - } - } - else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_TABLE) { - out->u.table = wasm_native_create_spec_test_builtin_table( - module, import_type->module_name, import_type->name, - import_type->u.table_type); - if (!out->u.table) { - LOG_ERROR("create table failed\n"); - return false; - } - } - else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { - out->u.global = wasm_native_create_spec_test_builtin_global( - module, import_type->module_name, import_type->name, - import_type->u.global_type); - if (!out->u.global) { - LOG_ERROR("create global failed\n"); - return false; - } - } - else { - LOG_DEBUG("unimplemented import(%s,%s) kind %d", - import_type->module_name, import_type->name, - import_type->kind); - } - - return true; -} -#endif - void wasm_runtime_destroy_extern_inst(WASMModuleCommon *module, WASMExternInstance *extern_inst) @@ -8213,14 +8160,26 @@ wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module, wasm_runtime_get_import_type(module, i, &import_type); WASMExternInstance *extern_instance = out + i; + #if WASM_ENABLE_SPEC_TEST != 0 if (!wasm_runtime_create_extern_inst_for_spec_test(module, &import_type, extern_instance)) { wasm_runtime_destroy_imports(module, out); - LOG_ERROR("create import failed"); + LOG_ERROR("create imports for spec test failed"); return false; } #endif + +#if WASM_ENABLE_WASI_TEST != 0 + if (!wasm_runtime_create_extern_inst_for_wasi_test(module, &import_type, + extern_instance)) { + wasm_runtime_destroy_imports(module, out); + LOG_ERROR("create imports for wasi test failed"); + return false; + } +#endif + + (void)extern_instance; } return true; diff --git a/core/iwasm/libraries/libc-builtin/builtin_wrapper.h b/core/iwasm/libraries/libc-builtin/builtin_wrapper.h new file mode 100644 index 0000000000..8beca04330 --- /dev/null +++ b/core/iwasm/libraries/libc-builtin/builtin_wrapper.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_export.h" +#include "../interpreter/wasm.h" +#include "../common/wasm_runtime_common.h" + +/************************************* + * Functions + *************************************/ + +/************************************* + * Globals + *************************************/ +typedef struct WASMNativeGlobalDef { + const char *module_name; + const char *name; + uint8 type; + bool is_mutable; + WASMValue value; +} WASMNativeGlobalDef; + +/************************************* + * Tables + *************************************/ + +typedef struct WASMNativeTableDef { + const char *module_name; + const char *name; + uint8 elem_type; + +} WASMNativeTableDef; + +/************************************* + * Memories + *************************************/ + +typedef struct WASMNativeMemoryDef { + const char *module_name; + const char *name; +} WASMNativeMemoryDef; diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index 349a3d0cad..6630e13d2a 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -5,9 +5,7 @@ #include "bh_common.h" #include "bh_log.h" -#include "wasm_export.h" -#include "../interpreter/wasm.h" -#include "../common/wasm_runtime_common.h" +#include "builtin_wrapper.h" #if defined(_WIN32) || defined(_WIN32_) #define strncasecmp _strnicmp @@ -1130,14 +1128,6 @@ get_spectest_export_apis(NativeSymbol **p_libc_builtin_apis) * Global Variables * *************************************/ -typedef struct WASMNativeGlobalDef { - const char *module_name; - const char *global_name; - uint8 type; - bool is_mutable; - WASMValue value; -} WASMNativeGlobalDef; - static WASMNativeGlobalDef native_global_defs[] = { #if WASM_ENABLE_SPEC_TEST != 0 { "spectest", "global_i32", VALUE_TYPE_I32, false, .value.i32 = 666 }, @@ -1175,7 +1165,7 @@ wasm_native_lookup_libc_builtin_global(const char *module_name, /* Lookup constant globals which can be defined by table */ while (global_def < global_def_end) { if (!strcmp(global_def->module_name, module_name) - && !strcmp(global_def->global_name, global_name)) { + && !strcmp(global_def->name, global_name)) { global->type.val_type = global_def->type; global->type.is_mutable = global_def->is_mutable; global->global_data_linked = global_def->value; 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 6ef5c479a2..fe6b2c70cc 100644 --- a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c @@ -4,8 +4,7 @@ */ #include "bh_log.h" -#include "wasm_export.h" -#include "../common/wasm_runtime_common.h" +#include "builtin_wrapper.h" /************************************* * Functions @@ -15,14 +14,6 @@ * Globals *************************************/ -typedef struct WASMNativeGlobalDef { - const char *module_name; - const char *name; - uint8 type; - bool is_mutable; - WASMValue value; -} WASMNativeGlobalDef; - static WASMNativeGlobalDef native_global_defs[] = { /* for standard spec test */ { "spectest", "global_i32", VALUE_TYPE_I32, false, .value.i32 = 666 }, @@ -80,13 +71,6 @@ wasm_native_create_spec_test_builtin_global(wasm_module_t module, * Tables *************************************/ -typedef struct WASMNativeTableDef { - const char *module_name; - const char *name; - uint8 elem_type; - -} WASMNativeTableDef; - /*TODO: fix me*/ wasm_table_inst_t * wasm_native_create_spec_test_builtin_table(wasm_module_t module, @@ -113,11 +97,6 @@ wasm_native_create_spec_test_builtin_table(wasm_module_t module, * Memories *************************************/ -typedef struct WASMNativeMemoryDef { - const char *module_name; - const char *name; -} WASMNativeMemoryDef; - /* * no predefined memory for spec test */ @@ -141,3 +120,58 @@ wasm_native_create_spec_test_builtin_memory(wasm_module_t module, return wasm_runtime_create_memory(module, type); } + +/************************************* + * Extern + *************************************/ + +bool +wasm_runtime_create_extern_inst_for_spec_test(wasm_module_t module, + wasm_import_t *import_type, + WASMExternInstance *out) +{ + if (!module || !import_type || !out) + return false; + + LOG_DEBUG("create import(%s,%s) kind %d", import_type->module_name, + import_type->name, import_type->kind); + + out->module_name = import_type->module_name; + out->field_name = import_type->name; + out->kind = import_type->kind; + + if (import_type->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { + out->u.memory = wasm_native_create_spec_test_builtin_memory( + module, import_type->module_name, import_type->name, + import_type->u.memory_type); + if (!out->u.memory) { + LOG_ERROR("create memory failed\n"); + return false; + } + } + else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_TABLE) { + out->u.table = wasm_native_create_spec_test_builtin_table( + module, import_type->module_name, import_type->name, + import_type->u.table_type); + if (!out->u.table) { + LOG_ERROR("create table failed\n"); + return false; + } + } + else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { + out->u.global = wasm_native_create_spec_test_builtin_global( + module, import_type->module_name, import_type->name, + import_type->u.global_type); + if (!out->u.global) { + LOG_ERROR("create global failed\n"); + return false; + } + } + else { + LOG_DEBUG("unimplemented import(%s,%s) kind %d for spec test", + import_type->module_name, import_type->name, + import_type->kind); + } + + return true; +} diff --git a/core/iwasm/libraries/libc-builtin/wasi_test_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/wasi_test_builtin_wrapper.c new file mode 100644 index 0000000000..a294b77ae9 --- /dev/null +++ b/core/iwasm/libraries/libc-builtin/wasi_test_builtin_wrapper.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "bh_log.h" +#include "builtin_wrapper.h" + +/************************************* + * Functions + *************************************/ + +/************************************* + * Globals + *************************************/ + +/************************************* + * Tables + *************************************/ + +/************************************* + * Memories + *************************************/ + +static WASMNativeMemoryDef builtin_memory_defs[] = { + { "foo", "bar" }, + { "env", "memory" }, +}; + +wasm_memory_inst_t +wasm_native_create_wasi_test_builtin_memory(wasm_module_t module, + const char *module_name, + const char *name, + wasm_memory_type_t type) +{ + if (!module || !module_name || !name || !type) { + return NULL; + } + + WASMNativeMemoryDef *memory_def = builtin_memory_defs; + size_t count = sizeof(builtin_memory_defs) / sizeof(WASMNativeMemoryDef); + WASMNativeMemoryDef *memory_def_end = builtin_memory_defs + count; + + for (; memory_def < memory_def_end; memory_def++) { + if (strcmp(memory_def->module_name, module_name) != 0) { + continue; + } + + if (strcmp(memory_def->name, name) != 0) { + continue; + } + + return wasm_runtime_create_memory(module, type); + } + + return NULL; +} + +/************************************* + * Extern + *************************************/ + +bool +wasm_runtime_create_extern_inst_for_wasi_test(wasm_module_t module, + wasm_import_t *import_type, + WASMExternInstance *out) +{ + if (!module || !import_type || !out) + return false; + + LOG_DEBUG("create import(%s,%s) kind %d", import_type->module_name, + import_type->name, import_type->kind); + + out->module_name = import_type->module_name; + out->field_name = import_type->name; + out->kind = import_type->kind; + + if (import_type->kind != WASM_IMPORT_EXPORT_KIND_MEMORY) { + LOG_DEBUG("unimplemented import(%s,%s) kind %d for wasi test", + import_type->module_name, import_type->name, + import_type->kind); + return true; + } + + out->u.memory = wasm_native_create_wasi_test_builtin_memory( + module, import_type->module_name, import_type->name, + import_type->u.memory_type); + if (!out->u.memory) { + LOG_ERROR("create memory failed\n"); + return false; + } + + return true; +} \ No newline at end of file diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index fbcbfe2026..b7a9248bc8 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -1048,7 +1048,7 @@ function trigger() if [[ $TEST_CASE_ARR ]]; then for test in "${TEST_CASE_ARR[@]}"; do if [[ "$test" == "wasi_certification" ]]; then - EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_WASI_TEST=1" + EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_WASI_TEST=1 -DWAMR_BUILD_SPEC_TEST=0" fi if [[ "$test" == "wasi_certification" || "$test" == "standalone" ]]; then From 6918aff38ad44d3fbb4e93c9117de0167d7e8392 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 26 Nov 2024 10:14:12 +0000 Subject: [PATCH 11/20] Refactor: rename native creation functions for spec and wasi test builtins for clarity --- core/iwasm/libraries/libc-builtin/SConscript | 2 ++ .../libc-builtin/spec_test_builtin_wrapper.c | 36 ++++++++----------- .../libc-builtin/wasi_test_builtin_wrapper.c | 14 ++++---- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/core/iwasm/libraries/libc-builtin/SConscript b/core/iwasm/libraries/libc-builtin/SConscript index 8dd0043823..34483c6684 100644 --- a/core/iwasm/libraries/libc-builtin/SConscript +++ b/core/iwasm/libraries/libc-builtin/SConscript @@ -10,6 +10,8 @@ cwd = GetCurrentDir() #src = Split(''' #libc_builtin_wrapper.c +#spec_test_builtin_wrapper.c +#wasi_test_builtin_wrapper.c #''') src = Glob('*.c') 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 fe6b2c70cc..5c5e13dc36 100644 --- a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c @@ -32,18 +32,16 @@ static WASMNativeGlobalDef native_global_defs[] = { #endif }; -wasm_global_inst_t -wasm_native_create_spec_test_builtin_global(wasm_module_t module, - const char *module_name, - const char *name, - wasm_global_type_t type) +static wasm_global_inst_t +create_spec_test_global(wasm_module_t module, const char *module_name, + const char *name, wasm_global_type_t type) { if (!module || !module_name || !name || !type) { return NULL; } - uint32 size = sizeof(native_global_defs) / sizeof(WASMNativeGlobalDef); WASMNativeGlobalDef *global_def = native_global_defs; + uint32 size = sizeof(native_global_defs) / sizeof(WASMNativeGlobalDef); WASMNativeGlobalDef *global_def_end = global_def + size; for (; global_def < global_def_end; global_def++) { if (strcmp(global_def->module_name, module_name) != 0) { @@ -72,11 +70,9 @@ wasm_native_create_spec_test_builtin_global(wasm_module_t module, *************************************/ /*TODO: fix me*/ -wasm_table_inst_t * -wasm_native_create_spec_test_builtin_table(wasm_module_t module, - const char *module_name, - const char *name, - wasm_table_type_t type) +static wasm_table_inst_t * +create_spec_test_table(wasm_module_t module, const char *module_name, + const char *name, wasm_table_type_t type) { if (!module || !module_name || !name || !type) { return NULL; @@ -100,11 +96,9 @@ wasm_native_create_spec_test_builtin_table(wasm_module_t module, /* * no predefined memory for spec test */ -wasm_memory_inst_t -wasm_native_create_spec_test_builtin_memory(wasm_module_t module, - const char *module_name, - const char *name, - wasm_memory_type_t type) +static wasm_memory_inst_t +create_spec_test_memory(wasm_module_t module, const char *module_name, + const char *name, wasm_memory_type_t type) { if (!module || !module_name || !name || !type) { return NULL; @@ -141,7 +135,7 @@ wasm_runtime_create_extern_inst_for_spec_test(wasm_module_t module, out->kind = import_type->kind; if (import_type->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) { - out->u.memory = wasm_native_create_spec_test_builtin_memory( + out->u.memory = create_spec_test_memory( module, import_type->module_name, import_type->name, import_type->u.memory_type); if (!out->u.memory) { @@ -150,16 +144,16 @@ wasm_runtime_create_extern_inst_for_spec_test(wasm_module_t module, } } else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_TABLE) { - out->u.table = wasm_native_create_spec_test_builtin_table( - module, import_type->module_name, import_type->name, - import_type->u.table_type); + out->u.table = create_spec_test_table(module, import_type->module_name, + import_type->name, + import_type->u.table_type); if (!out->u.table) { LOG_ERROR("create table failed\n"); return false; } } else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { - out->u.global = wasm_native_create_spec_test_builtin_global( + out->u.global = create_spec_test_global( module, import_type->module_name, import_type->name, import_type->u.global_type); if (!out->u.global) { diff --git a/core/iwasm/libraries/libc-builtin/wasi_test_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/wasi_test_builtin_wrapper.c index a294b77ae9..7767c6a24a 100644 --- a/core/iwasm/libraries/libc-builtin/wasi_test_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/wasi_test_builtin_wrapper.c @@ -27,11 +27,9 @@ static WASMNativeMemoryDef builtin_memory_defs[] = { { "env", "memory" }, }; -wasm_memory_inst_t -wasm_native_create_wasi_test_builtin_memory(wasm_module_t module, - const char *module_name, - const char *name, - wasm_memory_type_t type) +static wasm_memory_inst_t +create_wasi_test_memory(wasm_module_t module, const char *module_name, + const char *name, wasm_memory_type_t type) { if (!module || !module_name || !name || !type) { return NULL; @@ -82,9 +80,9 @@ wasm_runtime_create_extern_inst_for_wasi_test(wasm_module_t module, return true; } - out->u.memory = wasm_native_create_wasi_test_builtin_memory( - module, import_type->module_name, import_type->name, - import_type->u.memory_type); + out->u.memory = + create_wasi_test_memory(module, import_type->module_name, + import_type->name, import_type->u.memory_type); if (!out->u.memory) { LOG_ERROR("create memory failed\n"); return false; From 972466fddded5770fd618cf10b832ebf5d0970c3 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 26 Nov 2024 11:35:42 +0000 Subject: [PATCH 12/20] Refactor: enhance table initialization checks and improve spec test table creation logic --- core/iwasm/interpreter/wasm_runtime.c | 26 ++++++++++--------- .../libc-builtin/spec_test_builtin_wrapper.c | 24 ++++++++++++----- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 2a3f747623..d875d0b5e9 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -3201,19 +3201,21 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, #endif #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 - bh_assert(table_seg->base_offset.init_expr_type - == INIT_EXPR_TYPE_I32_CONST - || table_seg->base_offset.init_expr_type - == INIT_EXPR_TYPE_GET_GLOBAL - || table_seg->base_offset.init_expr_type - == INIT_EXPR_TYPE_FUNCREF_CONST - || table_seg->base_offset.init_expr_type - == INIT_EXPR_TYPE_REFNULL_CONST); + bh_assert( + table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST + || table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I64_CONST + || table_seg->base_offset.init_expr_type + == INIT_EXPR_TYPE_GET_GLOBAL + || table_seg->base_offset.init_expr_type + == INIT_EXPR_TYPE_FUNCREF_CONST + || table_seg->base_offset.init_expr_type + == INIT_EXPR_TYPE_REFNULL_CONST); #else - bh_assert(table_seg->base_offset.init_expr_type - == INIT_EXPR_TYPE_I32_CONST - || table_seg->base_offset.init_expr_type - == INIT_EXPR_TYPE_GET_GLOBAL); + bh_assert( + table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST + || table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I64_CONST + || table_seg->base_offset.init_expr_type + == INIT_EXPR_TYPE_GET_GLOBAL); #endif /* init vec(funcidx) or vec(expr) */ 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 5c5e13dc36..c39348c727 100644 --- a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c @@ -68,6 +68,10 @@ create_spec_test_global(wasm_module_t module, const char *module_name, /************************************* * Tables *************************************/ +static WASMNativeTableDef builtin_table_defs[] = { + { "spectest", "table", VALUE_TYPE_FUNCREF }, + { "spectest", "table64", VALUE_TYPE_FUNCREF }, +}; /*TODO: fix me*/ static wasm_table_inst_t * @@ -78,15 +82,23 @@ create_spec_test_table(wasm_module_t module, const char *module_name, return NULL; } - if (strcmp(module_name, "spectest") != 0) { - return NULL; - } + WASMNativeTableDef *table_def = builtin_table_defs; + size_t count = sizeof(builtin_table_defs) / sizeof(WASMNativeTableDef); + WASMNativeTableDef *table_def_end = builtin_table_defs + count; - if (strcmp(name, "table") != 0) { - return NULL; + for (; table_def < table_def_end; table_def++) { + if (strcmp(table_def->module_name, module_name) != 0) { + continue; + } + + if (strcmp(table_def->name, name) != 0) { + continue; + } + + return wasm_runtime_create_table(module, type); } - return wasm_runtime_create_table(module, type); + return NULL; } /************************************* From be317cee815b3c32fedcfb960bcadeee2ddf6a15 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 26 Nov 2024 11:45:19 +0000 Subject: [PATCH 13/20] Refactor: conditionally compile extern instance destruction for spec and WASI tests --- core/iwasm/common/wasm_runtime_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index b2598fb35b..a7562a5a7c 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8116,6 +8116,7 @@ wasm_runtime_destroy_extern_inst(WASMModuleCommon *module, extern_inst->field_name = NULL; } +#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. @@ -8132,6 +8133,7 @@ wasm_runtime_destroy_imports(WASMModuleCommon *module, 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, From 26d8def60fce8ca36c48d8fd3a8fdae7f8f470e7 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Sat, 7 Dec 2024 03:56:54 +0000 Subject: [PATCH 14/20] Refactor: simplify memory deinstantiation logic and improve extern instance handling for shared memory --- core/iwasm/aot/aot_runtime.c | 5 +++-- core/iwasm/common/wasm_runtime_common.c | 4 +++- core/iwasm/interpreter/wasm_runtime.c | 3 +-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 230c43ed9e..97d4eacc5d 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1053,7 +1053,7 @@ memories_deinstantiate(AOTModuleInstance *module_inst) #else wasm_runtime_free(memory); #endif -#endif +#endif /* WASM_ENABLE_MULTI_MODULE == 0 */ } for (; mem_index < module->memory_count; mem_index++) { @@ -5565,7 +5565,8 @@ aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module, #if WASM_ENABLE_DYNAMIC_AOT_DEBUG != 0 AOTModule *g_dynamic_aot_module = NULL; -void __attribute__((noinline)) __enable_dynamic_aot_debug(void) +void __attribute__((noinline)) +__enable_dynamic_aot_debug(void) { /* empty implementation. */ } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index a7562a5a7c..d02183ae5f 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8163,6 +8163,7 @@ wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module, WASMExternInstance *extern_instance = out + i; +#if WASM_ENABLE_LIBC_BUILTIN != 0 #if WASM_ENABLE_SPEC_TEST != 0 if (!wasm_runtime_create_extern_inst_for_spec_test(module, &import_type, extern_instance)) { @@ -8180,8 +8181,9 @@ wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module, return false; } #endif - +#else (void)extern_instance; +#endif } return true; diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index d875d0b5e9..4c5883b650 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -296,8 +296,7 @@ memories_deinstantiate(WASMModuleInstance *module_inst) #else wasm_runtime_free(memory); #endif -#endif - (void)memory; +#endif /* WASM_ENABLE_MULTI_MODULE == 0 */ } for (; mem_index < module->memory_count; mem_index++) { From fd7dee55fcd445002b96d086627d99b983020397 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Sat, 7 Dec 2024 04:31:44 +0000 Subject: [PATCH 15/20] a workaround to fix a compilation issue on Nuttx --- .../libraries/libc-builtin/builtin_wrapper.h | 4 +++ .../libc-builtin/libc_builtin_wrapper.c | 27 +++++++++---------- .../libc-builtin/spec_test_builtin_wrapper.c | 6 ++--- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/core/iwasm/libraries/libc-builtin/builtin_wrapper.h b/core/iwasm/libraries/libc-builtin/builtin_wrapper.h index 8beca04330..de5cf77e5d 100644 --- a/core/iwasm/libraries/libc-builtin/builtin_wrapper.h +++ b/core/iwasm/libraries/libc-builtin/builtin_wrapper.h @@ -2,6 +2,8 @@ * Copyright (C) 2019 Intel Corporation. All rights reserved. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ +#ifndef _BUILTIN_WRAPPER_H_ +#define _BUILTIN_WRAPPER_H_ #include "wasm_export.h" #include "../interpreter/wasm.h" @@ -41,3 +43,5 @@ typedef struct WASMNativeMemoryDef { const char *module_name; const char *name; } WASMNativeMemoryDef; + +#endif diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index 6630e13d2a..c536b40158 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -1129,21 +1129,6 @@ get_spectest_export_apis(NativeSymbol **p_libc_builtin_apis) *************************************/ static WASMNativeGlobalDef native_global_defs[] = { -#if WASM_ENABLE_SPEC_TEST != 0 - { "spectest", "global_i32", VALUE_TYPE_I32, false, .value.i32 = 666 }, - { "spectest", "global_i64", VALUE_TYPE_I64, false, .value.i64 = 666 }, - { "spectest", "global_f32", VALUE_TYPE_F32, false, .value.f32 = 666.6 }, - { "spectest", "global_f64", VALUE_TYPE_F64, false, .value.f64 = 666.6 }, - { "test", "global-i32", VALUE_TYPE_I32, false, .value.i32 = 0 }, - { "test", "global-f32", VALUE_TYPE_F32, false, .value.f32 = 0 }, - { "test", "global-mut-i32", VALUE_TYPE_I32, true, .value.i32 = 0 }, - { "test", "global-mut-i64", VALUE_TYPE_I64, true, .value.i64 = 0 }, - { "test", "g", VALUE_TYPE_I32, true, .value.i32 = 0 }, -#if WASM_ENABLE_GC != 0 - { "G", "g", VALUE_TYPE_I32, false, .value.i32 = 4 }, - { "M", "g", REF_TYPE_HT_NON_NULLABLE, false, .value.gc_obj = 0 }, -#endif -#endif { "global", "NaN", VALUE_TYPE_F64, false, .value.u64 = 0x7FF8000000000000LL }, { "global", "Infinity", VALUE_TYPE_F64, false, @@ -1176,3 +1161,15 @@ wasm_native_lookup_libc_builtin_global(const char *module_name, return false; } + +/* + * it is a workaround to fix undefined reference to + * `wasm_runtime_create_extern_inst_for_spec_test' + */ +#if defined(__NuttX__) + +#if WASM_ENABLE_SPEC_TEST != 0 +#include "./spec_test_builtin_wrapper.c" +#endif + +#endif 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 c39348c727..cf05c0ca3e 100644 --- a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c @@ -14,7 +14,7 @@ * Globals *************************************/ -static WASMNativeGlobalDef native_global_defs[] = { +static WASMNativeGlobalDef spec_test_global_defs[] = { /* for standard spec test */ { "spectest", "global_i32", VALUE_TYPE_I32, false, .value.i32 = 666 }, { "spectest", "global_i64", VALUE_TYPE_I64, false, .value.i64 = 666 }, @@ -40,8 +40,8 @@ create_spec_test_global(wasm_module_t module, const char *module_name, return NULL; } - WASMNativeGlobalDef *global_def = native_global_defs; - uint32 size = sizeof(native_global_defs) / sizeof(WASMNativeGlobalDef); + WASMNativeGlobalDef *global_def = spec_test_global_defs; + uint32 size = sizeof(spec_test_global_defs) / sizeof(WASMNativeGlobalDef); WASMNativeGlobalDef *global_def_end = global_def + size; for (; global_def < global_def_end; global_def++) { if (strcmp(global_def->module_name, module_name) != 0) { From 36b8555f63cab02c616d40467c7a36cb15b6c4ed Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Sat, 7 Dec 2024 11:08:34 +0000 Subject: [PATCH 16/20] Add global definitions for spectest and test modules in libc_builtin_wrapper --- .../libc-builtin/libc_builtin_wrapper.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index c536b40158..ace018332f 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -1129,6 +1129,26 @@ get_spectest_export_apis(NativeSymbol **p_libc_builtin_apis) *************************************/ static WASMNativeGlobalDef native_global_defs[] = { +#if WASM_ENABLE_MULTI_MODULE != 0 +#if WASM_ENABLE_SPEC_TEST != 0 + { "spectest", "global_i32", VALUE_TYPE_I32, false, .value.i32 = 666 }, + { "spectest", "global_i64", VALUE_TYPE_I64, false, .value.i64 = 666 }, + { "spectest", "global_f32", VALUE_TYPE_F32, false, .value.f32 = 666.6 }, + { "spectest", "global_f64", VALUE_TYPE_F64, false, .value.f64 = 666.6 }, + { "test", "global-i32", VALUE_TYPE_I32, false, .value.i32 = 0 }, + { "test", "global-f32", VALUE_TYPE_F32, false, .value.f32 = 0 }, + { "test", "global-mut-i32", VALUE_TYPE_I32, true, .value.i32 = 0 }, + { "test", "global-mut-i64", VALUE_TYPE_I64, true, .value.i64 = 0 }, + { "test", "g", VALUE_TYPE_I32, true, .value.i32 = 0 }, + +#if WASM_ENABLE_GC != 0 + { "G", "g", VALUE_TYPE_I32, false, .value.i32 = 4 }, + { "M", "g", REF_TYPE_HT_NON_NULLABLE, false, .value.gc_obj = 0 }, +#endif + +#endif /* WASM_ENABLE_SPEC_TEST != 0 */ +#endif /* WASM_ENABLE_MULTI_MODULE != 0 */ + { "global", "NaN", VALUE_TYPE_F64, false, .value.u64 = 0x7FF8000000000000LL }, { "global", "Infinity", VALUE_TYPE_F64, false, From b1b6a32814c47bc058ae1150bf429a526e952ca2 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 12 Dec 2024 12:29:52 +0000 Subject: [PATCH 17/20] Refactor: remove unused table deallocation logic in wasm_runtime_instantiate_with_builtin_linker --- core/iwasm/common/wasm_runtime_common.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index d02183ae5f..3fe27ea722 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8065,7 +8065,6 @@ wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module, * * WASModuleInstance->tables[i].elems takes * the ownership of WASMExternInstance->u.table as WASMTableInstance - * BUT, there is a shell table wasm_table_inst_t * * WASMModuleInstance->e->globals[i] copies the content of * WASMExternInstance->u.global @@ -8075,10 +8074,6 @@ wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module, if (imports[i].kind == WASM_IMPORT_EXPORT_KIND_GLOBAL) { wasm_runtime_destroy_global(module, imports[i].u.global); } - /* FIXME: with reusing WASMTableInstance */ - if (imports[i].kind == WASM_IMPORT_EXPORT_KIND_TABLE) { - wasm_runtime_free(imports[i].u.table); - } } wasm_runtime_free(imports); From 98333b61c1769966bd27d71b98d1422f9294a7f0 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Thu, 12 Dec 2024 12:37:36 +0000 Subject: [PATCH 18/20] format problem --- core/iwasm/aot/aot_runtime.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 97d4eacc5d..103b660b49 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -5565,8 +5565,7 @@ aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module, #if WASM_ENABLE_DYNAMIC_AOT_DEBUG != 0 AOTModule *g_dynamic_aot_module = NULL; -void __attribute__((noinline)) -__enable_dynamic_aot_debug(void) +void __attribute__((noinline)) __enable_dynamic_aot_debug(void) { /* empty implementation. */ } From 9079012d1587c659921f4f81d8315ff12e209d1b Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 17 Dec 2024 08:13:01 +0000 Subject: [PATCH 19/20] Refactor: enhance global instance handling and add static assertions for offsets --- core/iwasm/aot/aot_runtime.c | 9 ++ core/iwasm/compilation/aot_emit_variable.c | 161 +++++++++++++++++---- core/iwasm/compilation/aot_llvm.c | 1 + 3 files changed, 146 insertions(+), 25 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 103b660b49..7bc90605fa 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -60,6 +60,7 @@ bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0); bh_static_assert(offsetof(AOTModuleInstanceExtra, shared_heap_base_addr_adj) == 8); bh_static_assert(offsetof(AOTModuleInstanceExtra, shared_heap_start_off) == 16); +bh_static_assert(offsetof(AOTModuleInstanceExtra, globals) == 24); bh_static_assert(sizeof(CApiFuncImport) == sizeof(uintptr_t) * 3); @@ -80,6 +81,14 @@ bh_static_assert(offsetof(AOTTinyFrame, func_index) == sizeof(uint32) * 0); bh_static_assert(offsetof(AOTTinyFrame, ip_offset) == sizeof(uint32) * 1); bh_static_assert(sizeof(AOTTinyFrame) == sizeof(uint32) * 2); +bh_static_assert(offsetof(AOTGlobalInstance, initial_value) == 8); +bh_static_assert(offsetof(AOTGlobalInstance, import_module_inst) + == 8 + sizeof(WASMValue)); +bh_static_assert(offsetof(AOTGlobalInstance, import_global_inst) + == 8 + sizeof(WASMValue) + sizeof(uintptr_t)); +bh_static_assert(offsetof(AOTGlobalInstance, ref_type) + == 8 + sizeof(WASMValue) + sizeof(uintptr_t) * 2); + static void set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) { diff --git a/core/iwasm/compilation/aot_emit_variable.c b/core/iwasm/compilation/aot_emit_variable.c index d374fc6799..7833eabdda 100644 --- a/core/iwasm/compilation/aot_emit_variable.c +++ b/core/iwasm/compilation/aot_emit_variable.c @@ -155,38 +155,51 @@ LLVMValueRef get_global_from_wasm_inst(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 global_idx) { - /* WASMModuleInstance->e */ - uint32 e_offset_val = offsetof(WASMModuleInstance, e); - LLVMValueRef e_offset = I32_CONST(e_offset_val); - LLVMValueRef e_ptr_u8 = - LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, - &e_offset, 1, "e_ptr"); - LLVMValueRef e_ptr = - LLVMBuildBitCast(comp_ctx->builder, e_ptr_u8, OPQ_PTR_TYPE, "e_ptr"); - LLVMValueRef e = - LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, e_ptr, "e"); + /* WASMModuleInstance->e->globals */ + uint32 e_offset_val = get_module_inst_extra_offset(comp_ctx); + uint32 globals_offset_val = e_offset_val; +#if WASM_ENABLE_JIT != 0 + if (comp_ctx->is_jit_mode) + globals_offset_val += offsetof(WASMModuleInstanceExtra, globals); + else +#endif + globals_offset_val += offsetof(AOTModuleInstanceExtra, globals); - uint32 globals_offset_val; - if (comp_ctx->is_jit_mode) { - /* WASMModuleInstanceExtra->globals */ - globals_offset_val = offsetof(WASMModuleInstanceExtra, globals); + LLVMValueRef globals_offset = I32_CONST(globals_offset_val); + if (!globals_offset) { + aot_set_last_error("I32_CONST failed for globals_offset"); + return NULL; } - else { - /* AOTModuleInstanceExtra->globals */ - globals_offset_val = offsetof(AOTModuleInstanceExtra, globals); + + LLVMValueRef globals_ptr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, + &globals_offset, 1, "globals_ptr"); + if (!globals_ptr) { + aot_set_last_error("LLVMBuildInBoundsGEP2 failed for globals_ptr"); + return NULL; } - LLVMValueRef globals_offset = I32_CONST(globals_offset_val); - LLVMValueRef globals_ptr = LLVMBuildInBoundsGEP2( - comp_ctx->builder, INT8_TYPE, e, &globals_offset, 1, "globals_ptr"); LLVMValueRef globals = LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, globals_ptr, "globals"); + if (!globals) { + aot_set_last_error("LLVMBuildLoad2 failed for globals"); + return NULL; + } /* WASMGlobalInstance[global_idx] */ uint32 global_offset_val = global_idx * sizeof(WASMGlobalInstance); LLVMValueRef global_offset = I32_CONST(global_offset_val); + if (!global_offset) { + aot_set_last_error("I32_CONST failed for global_offset"); + return NULL; + } + LLVMValueRef global_ptr = LLVMBuildInBoundsGEP2( comp_ctx->builder, INT8_TYPE, globals, &global_offset, 1, "global_ptr"); + if (!global_ptr) { + aot_set_last_error("LLVMBuildInBoundsGEP2 failed for global_ptr"); + return NULL; + } return global_ptr; } @@ -198,27 +211,65 @@ get_global_value_addr(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* WASMGlobalInstance[global_idx] */ LLVMValueRef global_ptr = get_global_from_wasm_inst(comp_ctx, func_ctx, global_idx); + if (!global_ptr) { + aot_set_last_error("get_global_from_wasm_inst failed"); + return NULL; + } /* WASMGlobalInstance->import_module_inst */ uint32 import_inst_offset_val = offsetof(WASMGlobalInstance, import_module_inst); LLVMValueRef import_inst_offset = I32_CONST(import_inst_offset_val); + if (!import_inst_offset) { + aot_set_last_error("I32_CONST failed for import_inst_offset"); + return NULL; + } + LLVMValueRef import_inst_ptr_u8 = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, global_ptr, &import_inst_offset, 1, "import_inst_u8_ptr"); + if (!import_inst_ptr_u8) { + aot_set_last_error( + "LLVMBuildInBoundsGEP2 failed for import_inst_ptr_u8"); + return NULL; + } + LLVMValueRef import_inst_ptr = LLVMBuildBitCast( comp_ctx->builder, import_inst_ptr_u8, OPQ_PTR_TYPE, "import_inst_ptr"); + if (!import_inst_ptr) { + aot_set_last_error("LLVMBuildBitCast failed for import_inst_ptr"); + return NULL; + } + LLVMValueRef import_inst = LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, import_inst_ptr, "import_inst"); + if (!import_inst) { + aot_set_last_error("LLVMBuildLoad2 failed for import_inst"); + return NULL; + } /* WASMGlobalInstance->data_offset */ uint32 data_offset_offset_val = offsetof(WASMGlobalInstance, data_offset); LLVMValueRef data_offset_offset = I32_CONST(data_offset_offset_val); + if (!data_offset_offset) { + aot_set_last_error("I32_CONST failed for data_offset_offset"); + return NULL; + } + LLVMValueRef data_offset_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, global_ptr, &data_offset_offset, 1, "data_offset_ptr"); + if (!data_offset_ptr) { + aot_set_last_error("LLVMBuildInBoundsGEP2 failed for data_offset_ptr"); + return NULL; + } + LLVMValueRef data_offset = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, data_offset_ptr, "data_offset"); + if (!data_offset) { + aot_set_last_error("LLVMBuildLoad2 failed for data_offset"); + return NULL; + } /* WASMModuleInstance->global_data preparation */ uint32 global_data_offset_val = @@ -227,18 +278,44 @@ get_global_value_addr(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, * (comp_ctx->comp_data->memory_count + comp_ctx->comp_data->import_memory_count); LLVMValueRef global_data_offset = I32_CONST(global_data_offset_val); + if (!global_data_offset) { + aot_set_last_error("I32_CONST failed for global_data_offset"); + return NULL; + } // Check if import_module_inst is NULL LLVMBasicBlockRef then_block = LLVMAppendBasicBlockInContext( comp_ctx->context, func_ctx->func, "then"); + if (!then_block) { + aot_set_last_error( + "LLVMAppendBasicBlockInContext failed for then_block"); + return NULL; + } + LLVMBasicBlockRef else_block = LLVMAppendBasicBlockInContext( comp_ctx->context, func_ctx->func, "else"); + if (!else_block) { + aot_set_last_error( + "LLVMAppendBasicBlockInContext failed for else_block"); + return NULL; + } + LLVMBasicBlockRef merge_block = LLVMAppendBasicBlockInContext( comp_ctx->context, func_ctx->func, "merge"); + if (!merge_block) { + aot_set_last_error( + "LLVMAppendBasicBlockInContext failed for merge_block"); + return NULL; + } - LLVMBuildCondBr(comp_ctx->builder, - LLVMBuildIsNull(comp_ctx->builder, import_inst, "is_null"), - then_block, else_block); + LLVMValueRef terminator = LLVMBuildCondBr( + comp_ctx->builder, + LLVMBuildIsNull(comp_ctx->builder, import_inst, "is_null"), then_block, + else_block); + if (!terminator) { + aot_set_last_error("LLVMBuildCondBr failed"); + return NULL; + } // If import_module_inst is NULL LLVMPositionBuilderAtEnd(comp_ctx->builder, then_block); @@ -246,12 +323,27 @@ get_global_value_addr(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef local_global_data = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &global_data_offset, 1, "local_global_data"); + if (!local_global_data) { + aot_set_last_error( + "LLVMBuildInBoundsGEP2 failed for local_global_data"); + return NULL; + } + // global value pointer LLVMValueRef local_global_value_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, local_global_data, &data_offset, 1, "local_global_value_ptr"); + if (!local_global_value_ptr) { + aot_set_last_error( + "LLVMBuildInBoundsGEP2 failed for local_global_value_ptr"); + return NULL; + } - LLVMBuildBr(comp_ctx->builder, merge_block); + terminator = LLVMBuildBr(comp_ctx->builder, merge_block); + if (!terminator) { + aot_set_last_error("LLVMBuildBr failed"); + return NULL; + } // If import_module_inst is not NULL LLVMPositionBuilderAtEnd(comp_ctx->builder, else_block); @@ -259,17 +351,36 @@ get_global_value_addr(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef import_global_data = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, import_inst, &global_data_offset, 1, "import_global_data"); + if (!import_global_data) { + aot_set_last_error( + "LLVMBuildInBoundsGEP2 failed for import_global_data"); + return NULL; + } LLVMValueRef import_global_value_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, import_global_data, &data_offset, 1, "import_global_value_ptr"); + if (!import_global_value_ptr) { + aot_set_last_error( + "LLVMBuildInBoundsGEP2 failed for import_global_value_ptr"); + return NULL; + } - LLVMBuildBr(comp_ctx->builder, merge_block); + terminator = LLVMBuildBr(comp_ctx->builder, merge_block); + if (!terminator) { + aot_set_last_error("LLVMBuildBr failed"); + return NULL; + } // Merge block LLVMPositionBuilderAtEnd(comp_ctx->builder, merge_block); LLVMValueRef phi = LLVMBuildPhi(comp_ctx->builder, OPQ_PTR_TYPE, "global_value_addr"); + if (!phi) { + aot_set_last_error("LLVMBuildPhi failed for global_value_addr"); + return NULL; + } + LLVMAddIncoming(phi, &local_global_value_ptr, &then_block, 1); LLVMAddIncoming(phi, &import_global_value_ptr, &else_block, 1); diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index d9974eed4c..51f33dffb1 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -7,6 +7,7 @@ #include "aot_llvm_extra2.h" #include "aot_compiler.h" #include "aot_emit_exception.h" +// TODO: remove me if get_module_inst_extra_offset() has been moved out #include "aot_emit_table.h" #include "../aot/aot_runtime.h" #include "../aot/aot_intrinsic.h" From c36a203c2600219b8b6b9563ce09be119d44b1e0 Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Tue, 17 Dec 2024 08:53:06 +0000 Subject: [PATCH 20/20] Refactor: update static assertions for AOTGlobalInstance offsets and clean up import instance handling --- core/iwasm/aot/aot_runtime.c | 4 ++-- core/iwasm/common/wasm_runtime_common.c | 4 +--- core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 7bc90605fa..4b2d4ac93c 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -85,9 +85,9 @@ bh_static_assert(offsetof(AOTGlobalInstance, initial_value) == 8); bh_static_assert(offsetof(AOTGlobalInstance, import_module_inst) == 8 + sizeof(WASMValue)); bh_static_assert(offsetof(AOTGlobalInstance, import_global_inst) - == 8 + sizeof(WASMValue) + sizeof(uintptr_t)); + == 8 + sizeof(WASMValue) + 8); bh_static_assert(offsetof(AOTGlobalInstance, ref_type) - == 8 + sizeof(WASMValue) + sizeof(uintptr_t) * 2); + == 8 + sizeof(WASMValue) + 16); static void set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 3fe27ea722..271e139494 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -8156,9 +8156,8 @@ wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module, wasm_import_t import_type = { 0 }; wasm_runtime_get_import_type(module, i, &import_type); - WASMExternInstance *extern_instance = out + i; - #if WASM_ENABLE_LIBC_BUILTIN != 0 + WASMExternInstance *extern_instance = out + i; #if WASM_ENABLE_SPEC_TEST != 0 if (!wasm_runtime_create_extern_inst_for_spec_test(module, &import_type, extern_instance)) { @@ -8176,7 +8175,6 @@ wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module, return false; } #endif -#else (void)extern_instance; #endif } 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 cf05c0ca3e..9305be628d 100644 --- a/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/spec_test_builtin_wrapper.c @@ -73,8 +73,7 @@ static WASMNativeTableDef builtin_table_defs[] = { { "spectest", "table64", VALUE_TYPE_FUNCREF }, }; -/*TODO: fix me*/ -static wasm_table_inst_t * +static wasm_table_inst_t create_spec_test_table(wasm_module_t module, const char *module_name, const char *name, wasm_table_type_t type) {