From c85bada2a9c85bc80f4c1a6baa7cefb662013eb4 Mon Sep 17 00:00:00 2001 From: Benbuck Nason Date: Thu, 9 May 2024 18:15:58 -0700 Subject: [PATCH] Add wasm module global type information APIs (#3406) Support getting global type from `wasm_runtime_get_import_type` and `wasm_runtime_get_export_type`, and add two APIs: ```C wasm_valkind_t wasm_global_type_get_valkind(const wasm_global_type_t global_type); bool wasm_global_type_get_mutable(const wasm_global_type_t global_type); ``` --- core/iwasm/aot/aot_loader.c | 18 +-- core/iwasm/aot/aot_runtime.c | 18 +-- core/iwasm/common/wasm_c_api.c | 31 ++--- core/iwasm/common/wasm_runtime_common.c | 100 ++++++++++++---- core/iwasm/compilation/aot.c | 16 +-- core/iwasm/compilation/aot.h | 8 +- core/iwasm/compilation/aot_emit_aot_file.c | 8 +- core/iwasm/compilation/aot_emit_variable.c | 5 +- core/iwasm/fast-jit/fe/jit_emit_variable.c | 4 +- core/iwasm/include/wasm_export.h | 11 ++ core/iwasm/interpreter/wasm.h | 11 +- core/iwasm/interpreter/wasm_loader.c | 108 +++++++++--------- core/iwasm/interpreter/wasm_mini_loader.c | 75 ++++++------ core/iwasm/interpreter/wasm_runtime.c | 10 +- .../libc-builtin/libc_builtin_wrapper.c | 4 +- 15 files changed, 255 insertions(+), 172 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index d635e59d..b67f9c68 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -2042,8 +2042,8 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end, /* Create each import global */ for (i = 0; i < module->import_global_count; i++) { buf = (uint8 *)align_ptr(buf, 2); - read_uint8(buf, buf_end, import_globals[i].type); - read_uint8(buf, buf_end, import_globals[i].is_mutable); + read_uint8(buf, buf_end, import_globals[i].type.val_type); + read_uint8(buf, buf_end, import_globals[i].type.is_mutable); read_string(buf, buf_end, import_globals[i].module_name); read_string(buf, buf_end, import_globals[i].global_name); @@ -2051,8 +2051,9 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end, if (wasm_native_lookup_libc_builtin_global( import_globals[i].module_name, import_globals[i].global_name, &tmp_global)) { - if (tmp_global.type != import_globals[i].type - || tmp_global.is_mutable != import_globals[i].is_mutable) { + 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; @@ -2065,7 +2066,8 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end, import_globals[i].is_linked = false; #endif - import_globals[i].size = wasm_value_type_size(import_globals[i].type); + import_globals[i].size = + wasm_value_type_size(import_globals[i].type.val_type); import_globals[i].data_offset = data_offset; data_offset += import_globals[i].size; module->global_data_size += import_globals[i].size; @@ -2130,8 +2132,8 @@ load_globals(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, /* Create each global */ for (i = 0; i < module->global_count; i++) { - read_uint8(buf, buf_end, globals[i].type); - read_uint8(buf, buf_end, globals[i].is_mutable); + read_uint8(buf, buf_end, globals[i].type.val_type); + read_uint8(buf, buf_end, globals[i].type.is_mutable); buf = align_ptr(buf, 4); @@ -2139,7 +2141,7 @@ load_globals(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, error_buf, error_buf_size)) return false; - globals[i].size = wasm_value_type_size(globals[i].type); + globals[i].size = wasm_value_type_size(globals[i].type.val_type); globals[i].data_offset = data_offset; data_offset += globals[i].size; module->global_data_size += globals[i].size; diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index a0d7f108..1668ed01 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -129,7 +129,7 @@ check_global_init_expr(const AOTModule *module, uint32 global_index, * And initializer expression cannot reference a mutable global. */ if (global_index >= module->import_global_count - || module->import_globals->is_mutable) { + || module->import_globals->type.is_mutable) { set_error_buf(error_buf, error_buf_size, "constant expression required"); return false; @@ -141,7 +141,7 @@ check_global_init_expr(const AOTModule *module, uint32 global_index, return false; } if (global_index < module->import_global_count - && module->import_globals[global_index].is_mutable) { + && module->import_globals[global_index].type.is_mutable) { set_error_buf(error_buf, error_buf_size, "constant expression required"); return false; @@ -389,7 +389,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, for (i = 0; i < module->import_global_count; i++, import_global++) { bh_assert(import_global->data_offset == (uint32)(p - module_inst->global_data)); - init_global_data(p, import_global->type, + init_global_data(p, import_global->type.val_type, &import_global->global_data_linked); p += import_global->size; } @@ -410,20 +410,20 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, } #if WASM_ENABLE_GC == 0 init_global_data( - p, global->type, + 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, + 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, + init_global_data(p, global->type.val_type, &module->globals[global_idx].init_expr.u); } #endif @@ -581,7 +581,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #endif /* end of WASM_ENABLE_GC != 0 */ default: { - init_global_data(p, global->type, &init_expr->u); + init_global_data(p, global->type.val_type, &init_expr->u); break; } } @@ -4549,7 +4549,7 @@ aot_global_traverse_gc_rootset(AOTModuleInstance *module_inst, void *heap) uint32 i; for (i = 0; i < module->import_global_count; i++, import_global++) { - if (wasm_is_type_reftype(import_global->type)) { + if (wasm_is_type_reftype(import_global->type.val_type)) { gc_obj = GET_REF_FROM_ADDR((uint32 *)global_data); if (wasm_obj_is_created_from_heap(gc_obj)) { if (0 != mem_allocator_add_root((mem_allocator_t)heap, gc_obj)) @@ -4560,7 +4560,7 @@ aot_global_traverse_gc_rootset(AOTModuleInstance *module_inst, void *heap) } for (i = 0; i < module->global_count; i++, global++) { - if (wasm_is_type_reftype(global->type)) { + if (wasm_is_type_reftype(global->type.val_type)) { gc_obj = GET_REF_FROM_ADDR((uint32 *)global_data); if (wasm_obj_is_created_from_heap(gc_obj)) { if (0 != mem_allocator_add_root((mem_allocator_t)heap, gc_obj)) diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 9005d711..36bd129b 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -2521,8 +2521,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out) + (i - import_func_count); module_name_rt = import->u.names.module_name; field_name_rt = import->u.names.field_name; - val_type_rt = import->u.global.type; - mutability_rt = import->u.global.is_mutable; + val_type_rt = import->u.global.type.val_type; + mutability_rt = import->u.global.type.is_mutable; } #endif @@ -2532,8 +2532,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out) + (i - import_func_count); module_name_rt = import->module_name; field_name_rt = import->global_name; - val_type_rt = import->type; - mutability_rt = import->is_mutable; + val_type_rt = import->type.val_type; + mutability_rt = import->type.is_mutable; } #endif @@ -3634,7 +3634,7 @@ aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, if (global_idx_rt < module_aot->import_global_count) { data_offset = module_aot->import_globals[global_idx_rt].data_offset; - val_type_rt = module_aot->import_globals[global_idx_rt].type; + val_type_rt = module_aot->import_globals[global_idx_rt].type.val_type; } else { data_offset = @@ -3642,7 +3642,7 @@ aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, .data_offset; val_type_rt = module_aot->globals[global_idx_rt - module_aot->import_global_count] - .type; + .type.val_type; } data = (void *)(inst_aot->global_data + data_offset); @@ -3661,7 +3661,7 @@ aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, if (global_idx_rt < module_aot->import_global_count) { data_offset = module_aot->import_globals[global_idx_rt].data_offset; - val_type_rt = module_aot->import_globals[global_idx_rt].type; + val_type_rt = module_aot->import_globals[global_idx_rt].type.val_type; } else { data_offset = @@ -3669,7 +3669,7 @@ aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, .data_offset; val_type_rt = module_aot->globals[global_idx_rt - module_aot->import_global_count] - .type; + .type.val_type; } data = inst_aot->global_data + data_offset; @@ -3786,15 +3786,15 @@ wasm_global_new_internal(wasm_store_t *store, uint16 global_idx_rt, if (global_idx_rt < module_aot->import_global_count) { AOTImportGlobal *global_import_aot = module_aot->import_globals + global_idx_rt; - val_type_rt = global_import_aot->type; - is_mutable = global_import_aot->is_mutable; + val_type_rt = global_import_aot->type.val_type; + is_mutable = global_import_aot->type.is_mutable; } else { AOTGlobal *global_aot = module_aot->globals + (global_idx_rt - module_aot->import_global_count); - val_type_rt = global_aot->type; - is_mutable = global_aot->is_mutable; + val_type_rt = global_aot->type.val_type; + is_mutable = global_aot->type.is_mutable; } } #endif @@ -4511,8 +4511,9 @@ interp_link_global(const WASMModule *module_interp, uint16 global_idx_rt, return true; /* type comparison */ - if (!cmp_val_kind_with_val_type(wasm_valtype_kind(import->type->val_type), - imported_global_interp->u.global.type)) + if (!cmp_val_kind_with_val_type( + wasm_valtype_kind(import->type->val_type), + imported_global_interp->u.global.type.val_type)) return false; /* set init value */ @@ -4685,7 +4686,7 @@ aot_link_global(const AOTModule *module_aot, uint16 global_idx_rt, bh_assert(val_type); if (!cmp_val_kind_with_val_type(wasm_valtype_kind(val_type), - import_aot_global->type)) + import_aot_global->type.val_type)) return false; bh_assert(import->init); diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index cfbbdd7e..fbab98fe 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -3795,6 +3795,8 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index, import_type->name = aot_import_global->global_name; import_type->kind = WASM_IMPORT_EXPORT_KIND_GLOBAL; import_type->linked = aot_import_global->is_linked; + import_type->u.global_type = + (WASMGlobalType *)&aot_import_global->type; return; } @@ -3845,6 +3847,8 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index, break; case WASM_IMPORT_EXPORT_KIND_GLOBAL: import_type->linked = wasm_import->u.global.is_linked; + import_type->u.global_type = + (WASMGlobalType *)&wasm_import->u.global.type; break; case WASM_IMPORT_EXPORT_KIND_TABLE: /* not supported */ @@ -3916,11 +3920,32 @@ wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index, const AOTExport *aot_export = &aot_module->exports[export_index]; export_type->name = aot_export->name; export_type->kind = aot_export->kind; - if (export_type->kind == EXPORT_KIND_FUNC) { - export_type->u.func_type = - (AOTFuncType *)aot_module->types - [aot_module->func_type_indexes - [aot_export->index - aot_module->import_func_count]]; + switch (export_type->kind) { + case WASM_IMPORT_EXPORT_KIND_FUNC: + export_type->u.func_type = + (AOTFuncType *)aot_module + ->types[aot_module->func_type_indexes + [aot_export->index + - aot_module->import_func_count]]; + break; + case WASM_IMPORT_EXPORT_KIND_GLOBAL: + export_type->u.global_type = + &aot_module + ->globals[aot_export->index + - aot_module->import_global_count] + .type; + break; + case WASM_IMPORT_EXPORT_KIND_TABLE: + /* not supported */ + // export_type->linked = false; + break; + case WASM_IMPORT_EXPORT_KIND_MEMORY: + /* not supported */ + // export_type->linked = false; + break; + default: + bh_assert(0); + break; } return; } @@ -3937,12 +3962,31 @@ wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index, const WASMExport *wasm_export = &wasm_module->exports[export_index]; export_type->name = wasm_export->name; export_type->kind = wasm_export->kind; - if (wasm_export->kind == EXPORT_KIND_FUNC) { - export_type->u.func_type = - wasm_module - ->functions[wasm_export->index - - wasm_module->import_function_count] - ->func_type; + switch (export_type->kind) { + case WASM_IMPORT_EXPORT_KIND_FUNC: + export_type->u.func_type = + wasm_module + ->functions[wasm_export->index + - wasm_module->import_function_count] + ->func_type; + break; + case WASM_IMPORT_EXPORT_KIND_GLOBAL: + export_type->u.global_type = + &wasm_module + ->globals[wasm_export->index + - wasm_module->import_global_count] + .type; + break; + case WASM_IMPORT_EXPORT_KIND_TABLE: + /* not supported */ + // export_type->linked = false; + break; + case WASM_IMPORT_EXPORT_KIND_MEMORY: + /* not supported */ + // export_type->linked = false; + break; + bh_assert(0); + break; } return; } @@ -4033,6 +4077,22 @@ wasm_func_type_get_result_valkind(WASMFuncType *const func_type, } } +wasm_valkind_t +wasm_global_type_get_valkind(const wasm_global_type_t global_type) +{ + bh_assert(global_type); + + return val_type_to_val_kind(global_type->val_type); +} + +bool +wasm_global_type_get_mutable(const wasm_global_type_t global_type) +{ + bh_assert(global_type); + + return global_type->is_mutable; +} + bool wasm_runtime_register_natives(const char *module_name, NativeSymbol *native_symbols, @@ -5991,7 +6051,7 @@ aot_mark_all_externrefs(AOTModuleInstance *module_inst) const AOTTableInstance *table_inst; for (i = 0; i < module->global_count; i++, global++) { - if (global->type == VALUE_TYPE_EXTERNREF) { + if (global->type.val_type == VALUE_TYPE_EXTERNREF) { mark_externref( *(uint32 *)(module_inst->global_data + global->data_offset)); } @@ -6320,14 +6380,14 @@ wasm_runtime_get_export_global_type(const WASMModuleCommon *module_comm, if (export->index < module->import_global_count) { WASMGlobalImport *import_global = &((module->import_globals + export->index)->u.global); - *out_val_type = import_global->type; - *out_mutability = import_global->is_mutable; + *out_val_type = import_global->type.val_type; + *out_mutability = import_global->type.is_mutable; } else { WASMGlobal *global = module->globals + (export->index - module->import_global_count); - *out_val_type = global->type; - *out_mutability = global->is_mutable; + *out_val_type = global->type.val_type; + *out_mutability = global->type.is_mutable; } return true; } @@ -6340,14 +6400,14 @@ wasm_runtime_get_export_global_type(const WASMModuleCommon *module_comm, if (export->index < module->import_global_count) { AOTImportGlobal *import_global = module->import_globals + export->index; - *out_val_type = import_global->type; - *out_mutability = import_global->is_mutable; + *out_val_type = import_global->type.val_type; + *out_mutability = import_global->type.is_mutable; } else { AOTGlobal *global = module->globals + (export->index - module->import_global_count); - *out_val_type = global->type; - *out_mutability = global->is_mutable; + *out_val_type = global->type.val_type; + *out_mutability = global->type.is_mutable; } return true; } diff --git a/core/iwasm/compilation/aot.c b/core/iwasm/compilation/aot.c index f4532a5f..0d1b9028 100644 --- a/core/iwasm/compilation/aot.c +++ b/core/iwasm/compilation/aot.c @@ -221,16 +221,16 @@ aot_create_import_globals(const WASMModule *module, bool gc_enabled, WASMGlobalImport *import_global = &module->import_globals[i].u.global; import_globals[i].module_name = import_global->module_name; import_globals[i].global_name = import_global->field_name; - import_globals[i].type = import_global->type; - import_globals[i].is_mutable = import_global->is_mutable; + import_globals[i].type.val_type = import_global->type.val_type; + import_globals[i].type.is_mutable = import_global->type.is_mutable; import_globals[i].global_data_linked = import_global->global_data_linked; import_globals[i].data_offset_64bit = data_offset_64bit; import_globals[i].data_offset_32bit = data_offset_32bit; - get_value_type_size(import_global->type, gc_enabled, &value_size_64bit, - &value_size_32bit); + get_value_type_size(import_global->type.val_type, gc_enabled, + &value_size_64bit, &value_size_32bit); import_globals[i].size_64bit = value_size_64bit; import_globals[i].size_32bit = value_size_32bit; @@ -269,16 +269,16 @@ aot_create_globals(const WASMModule *module, bool gc_enabled, /* Create each global */ for (i = 0; i < module->global_count; i++) { WASMGlobal *global = &module->globals[i]; - globals[i].type = global->type; - globals[i].is_mutable = global->is_mutable; + globals[i].type.val_type = global->type.val_type; + globals[i].type.is_mutable = global->type.is_mutable; memcpy(&globals[i].init_expr, &global->init_expr, sizeof(global->init_expr)); globals[i].data_offset_64bit = data_offset_64bit; globals[i].data_offset_32bit = data_offset_32bit; - get_value_type_size(global->type, gc_enabled, &value_size_64bit, - &value_size_32bit); + get_value_type_size(global->type.val_type, gc_enabled, + &value_size_64bit, &value_size_32bit); globals[i].size_64bit = value_size_64bit; globals[i].size_32bit = value_size_32bit; diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index c0b68e05..ae04dfbc 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -175,9 +175,7 @@ typedef struct AOTTableInitData { typedef struct AOTImportGlobal { char *module_name; char *global_name; - /* VALUE_TYPE_I32/I64/F32/F64 */ - uint8 type; - bool is_mutable; + WASMGlobalType type; uint32 size; /* The data offset of current global in global data */ uint32 data_offset; @@ -203,9 +201,7 @@ typedef struct AOTImportGlobal { * Global variable */ typedef struct AOTGlobal { - /* VALUE_TYPE_I32/I64/F32/F64 */ - uint8 type; - bool is_mutable; + WASMGlobalType type; uint32 size; /* The data offset of current global in global data */ uint32 data_offset; diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 28b05968..509c4184 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -2241,8 +2241,8 @@ aot_emit_import_global_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset, for (i = 0; i < comp_data->import_global_count; i++, import_global++) { offset = align_uint(offset, 2); - EMIT_U8(import_global->type); - EMIT_U8(import_global->is_mutable); + EMIT_U8(import_global->type.val_type); + EMIT_U8(import_global->type.is_mutable); EMIT_STR(import_global->module_name); offset = align_uint(offset, 2); EMIT_STR(import_global->global_name); @@ -2273,8 +2273,8 @@ aot_emit_global_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset, for (i = 0; i < comp_data->global_count; i++, global++) { offset = align_uint(offset, 4); - EMIT_U8(global->type); - EMIT_U8(global->is_mutable); + EMIT_U8(global->type.val_type); + EMIT_U8(global->type.is_mutable); offset = align_uint(offset, 4); if (!aot_emit_init_expr(buf, buf_end, &offset, comp_ctx, diff --git a/core/iwasm/compilation/aot_emit_variable.c b/core/iwasm/compilation/aot_emit_variable.c index 6cd32217..fed8c555 100644 --- a/core/iwasm/compilation/aot_emit_variable.c +++ b/core/iwasm/compilation/aot_emit_variable.c @@ -174,7 +174,7 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + (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; + global_type = comp_data->import_globals[global_idx].type.val_type; } else { global_offset = @@ -185,7 +185,8 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, .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; + global_type = + comp_data->globals[global_idx - import_global_count].type.val_type; } if (comp_ctx->enable_gc && aot_is_type_gc_reftype(global_type)) diff --git a/core/iwasm/fast-jit/fe/jit_emit_variable.c b/core/iwasm/fast-jit/fe/jit_emit_variable.c index ffbf06ab..72f040a3 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_variable.c +++ b/core/iwasm/fast-jit/fe/jit_emit_variable.c @@ -168,12 +168,12 @@ get_global_type(const WASMModule *module, uint32 global_idx) if (global_idx < module->import_global_count) { const WASMGlobalImport *import_global = &((module->import_globals + global_idx)->u.global); - return import_global->type; + return import_global->type.val_type; } else { const WASMGlobal *global = module->globals + (global_idx - module->import_global_count); - return global->type; + return global->type.val_type; } } diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 6405a018..ca1d1a1b 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -75,6 +75,9 @@ typedef enum { struct WASMFuncType; typedef struct WASMFuncType *wasm_func_type_t; +struct WASMGlobalType; +typedef struct WASMGlobalType *wasm_global_type_t; + typedef struct wasm_import_t { const char *module_name; const char *name; @@ -82,6 +85,7 @@ typedef struct wasm_import_t { bool linked; union { wasm_func_type_t func_type; + wasm_global_type_t global_type; } u; } wasm_import_t; @@ -90,6 +94,7 @@ typedef struct wasm_export_t { wasm_import_export_kind_t kind; union { wasm_func_type_t func_type; + wasm_global_type_t global_type; } u; } wasm_export_t; @@ -1310,6 +1315,12 @@ WASM_RUNTIME_API_EXTERN wasm_valkind_t wasm_func_type_get_result_valkind(wasm_func_type_t const func_type, uint32_t result_index); +WASM_RUNTIME_API_EXTERN wasm_valkind_t +wasm_global_type_get_valkind(const wasm_global_type_t global_type); + +WASM_RUNTIME_API_EXTERN bool +wasm_global_type_get_mutable(const wasm_global_type_t global_type); + /** * Register native functions with same module name * diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 26d57d40..5401153a 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -584,11 +584,15 @@ typedef struct WASMTagImport { } WASMTagImport; #endif +typedef struct WASMGlobalType { + uint8 val_type; + bool is_mutable; +} WASMGlobalType; + typedef struct WASMGlobalImport { char *module_name; char *field_name; - uint8 type; - bool is_mutable; + WASMGlobalType type; bool is_linked; /* global data after linked */ WASMValue global_data_linked; @@ -705,8 +709,7 @@ struct WASMTag { #endif struct WASMGlobal { - uint8 type; - bool is_mutable; + WASMGlobalType type; #if WASM_ENABLE_GC != 0 WASMRefType *ref_type; #endif diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index f865d2d1..8af0fd9f 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -841,7 +841,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end, "unknown global %u", global_idx); goto fail; } - if (module->import_globals[global_idx].u.global.is_mutable) { + if (module->import_globals[global_idx] + .u.global.type.is_mutable) { set_error_buf_v(error_buf, error_buf_size, "constant expression required"); goto fail; @@ -854,7 +855,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end, goto fail; } if (global_idx < module->import_global_count - && module->import_globals[global_idx].u.global.is_mutable) { + && module->import_globals[global_idx] + .u.global.type.is_mutable) { set_error_buf_v(error_buf, error_buf_size, "constant expression required"); goto fail; @@ -862,8 +864,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end, #endif if (global_idx < module->import_global_count) { - global_type = - module->import_globals[global_idx].u.global.type; + global_type = module->import_globals[global_idx] + .u.global.type.val_type; #if WASM_ENABLE_GC != 0 if (wasm_is_type_multi_byte_type(global_type)) { WASMRefType *global_ref_type = @@ -880,7 +882,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end, global_type = module ->globals[global_idx - module->import_global_count] - .type; + .type.val_type; #if WASM_ENABLE_GC != 0 if (wasm_is_type_multi_byte_type(global_type)) { WASMRefType *global_ref_type = @@ -2404,7 +2406,8 @@ wasm_loader_resolve_global(const char *module_name, const char *global_name, global = &(module->globals[export->index - module->import_global_count]); } - if (global->type != type || global->is_mutable != is_mutable) { + if (global->type.val_type != type + || global->type.is_mutable != is_mutable) { LOG_DEBUG("%s,%s failed type check(%d, %d), expected(%d, %d)", module_name, global_name, global->type, global->is_mutable, type, is_mutable); @@ -3059,8 +3062,8 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end, ret = wasm_native_lookup_libc_builtin_global(sub_module_name, global_name, global); if (ret) { - if (global->type != declare_type - || global->is_mutable != declare_mutable) { + if (global->type.val_type != declare_type + || global->type.is_mutable != declare_mutable) { set_error_buf(error_buf, error_buf_size, "incompatible import type"); return false; @@ -3092,13 +3095,13 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end, global->module_name = sub_module_name; global->field_name = global_name; - global->type = declare_type; - global->is_mutable = (declare_mutable == 1); + global->type.val_type = declare_type; + global->type.is_mutable = (declare_mutable == 1); #if WASM_ENABLE_WAMR_COMPILER != 0 - if (global->type == VALUE_TYPE_V128) + if (global->type.val_type == VALUE_TYPE_V128) parent_module->is_simd_used = true; - else if (global->type == VALUE_TYPE_EXTERNREF) + else if (global->type.val_type == VALUE_TYPE_EXTERNREF) parent_module->is_ref_types_used = true; #endif (void)parent_module; @@ -4005,7 +4008,7 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, for (i = 0; i < global_count; i++, global++) { #if WASM_ENABLE_GC == 0 CHECK_BUF(p, p_end, 2); - global->type = read_uint8(p); + global->type.val_type = read_uint8(p); mutable = read_uint8(p); #else if (!resolve_value_type(&p, p_end, module, module->type_count, @@ -4013,27 +4016,27 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, error_buf, error_buf_size)) { return false; } - global->type = ref_type.ref_type; + global->type.val_type = ref_type.ref_type; CHECK_BUF(p, p_end, 1); mutable = read_uint8(p); #endif /* end of WASM_ENABLE_GC */ #if WASM_ENABLE_WAMR_COMPILER != 0 - if (global->type == VALUE_TYPE_V128) + if (global->type.val_type == VALUE_TYPE_V128) module->is_simd_used = true; - else if (global->type == VALUE_TYPE_FUNCREF - || global->type == VALUE_TYPE_EXTERNREF) + else if (global->type.val_type == VALUE_TYPE_FUNCREF + || global->type.val_type == VALUE_TYPE_EXTERNREF) module->is_ref_types_used = true; #endif if (!check_mutability(mutable, error_buf, error_buf_size)) { return false; } - global->is_mutable = mutable ? true : false; + global->type.is_mutable = mutable ? true : false; /* initialize expression */ if (!load_init_expr(module, &p, p_end, &(global->init_expr), - global->type, + global->type.val_type, #if WASM_ENABLE_GC == 0 NULL, #else @@ -4055,8 +4058,8 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } if (global_idx < module->import_global_count) { - global_type = - module->import_globals[global_idx].u.global.type; + global_type = module->import_globals[global_idx] + .u.global.type.val_type; global_ref_type = module->import_globals[global_idx].u.global.ref_type; } @@ -4064,14 +4067,14 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, global_type = module ->globals[global_idx - module->import_global_count] - .type; + .type.val_type; global_ref_type = module ->globals[global_idx - module->import_global_count] .ref_type; } if (!wasm_reftype_is_subtype_of( - global_type, global_ref_type, global->type, + global_type, global_ref_type, global->type.val_type, global->ref_type, module->types, module->type_count)) { set_error_buf(error_buf, error_buf_size, "type mismatch"); return false; @@ -5182,7 +5185,7 @@ calculate_global_data_offset(WASMModule *module) #if WASM_ENABLE_FAST_JIT != 0 import_global->data_offset = data_offset; #endif - data_offset += wasm_value_type_size(import_global->type); + data_offset += wasm_value_type_size(import_global->type.val_type); } for (i = 0; i < module->global_count; i++) { @@ -5190,7 +5193,7 @@ calculate_global_data_offset(WASMModule *module) #if WASM_ENABLE_FAST_JIT != 0 global->data_offset = data_offset; #endif - data_offset += wasm_value_type_size(global->type); + data_offset += wasm_value_type_size(global->type.val_type); } module->global_data_size = data_offset; @@ -5807,7 +5810,8 @@ load_from_sections(WASMModule *module, WASMSection *sections, if (!strcmp(export->name, "__heap_base")) { global_index = export->index - module->import_global_count; global = module->globals + global_index; - if (global->type == VALUE_TYPE_I32 && !global->is_mutable + if (global->type.val_type == VALUE_TYPE_I32 + && !global->type.is_mutable && global->init_expr.init_expr_type == INIT_EXPR_TYPE_I32_CONST) { aux_heap_base_global = global; @@ -5820,7 +5824,8 @@ load_from_sections(WASMModule *module, WASMSection *sections, else if (!strcmp(export->name, "__data_end")) { global_index = export->index - module->import_global_count; global = module->globals + global_index; - if (global->type == VALUE_TYPE_I32 && !global->is_mutable + if (global->type.val_type == VALUE_TYPE_I32 + && !global->type.is_mutable && global->init_expr.init_expr_type == INIT_EXPR_TYPE_I32_CONST) { aux_data_end_global = global; @@ -5860,9 +5865,9 @@ load_from_sections(WASMModule *module, WASMSection *sections, for (global_index = 0; global_index < module->global_count; global_index++) { global = module->globals + global_index; - if (global->is_mutable /* heap_base and data_end is + if (global->type.is_mutable /* heap_base and data_end is not mutable */ - && global->type == VALUE_TYPE_I32 + && global->type.val_type == VALUE_TYPE_I32 && global->init_expr.init_expr_type == INIT_EXPR_TYPE_I32_CONST && (uint64)(uint32)global->init_expr.u.i32 @@ -12383,7 +12388,8 @@ re_scan: uint32 j; for (i = 0; i < module->global_count; i++) { - if (module->globals[i].type == VALUE_TYPE_FUNCREF + if (module->globals[i].type.val_type + == VALUE_TYPE_FUNCREF && module->globals[i].init_expr.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST && module->globals[i].init_expr.u.u32 == func_idx) { @@ -12767,13 +12773,13 @@ re_scan: goto fail; } - global_type = - global_idx < module->import_global_count - ? module->import_globals[global_idx].u.global.type - : module - ->globals[global_idx - - module->import_global_count] - .type; + global_type = global_idx < module->import_global_count + ? module->import_globals[global_idx] + .u.global.type.val_type + : module + ->globals[global_idx + - module->import_global_count] + .type.val_type; #if WASM_ENABLE_GC != 0 ref_type = global_idx < module->import_global_count @@ -12827,13 +12833,13 @@ re_scan: goto fail; } - is_mutable = - global_idx < module->import_global_count - ? module->import_globals[global_idx].u.global.is_mutable - : module - ->globals[global_idx - - module->import_global_count] - .is_mutable; + is_mutable = global_idx < module->import_global_count + ? module->import_globals[global_idx] + .u.global.type.is_mutable + : module + ->globals[global_idx + - module->import_global_count] + .type.is_mutable; if (!is_mutable) { #if WASM_ENABLE_GC == 0 set_error_buf(error_buf, error_buf_size, @@ -12845,13 +12851,13 @@ re_scan: goto fail; } - global_type = - global_idx < module->import_global_count - ? module->import_globals[global_idx].u.global.type - : module - ->globals[global_idx - - module->import_global_count] - .type; + global_type = global_idx < module->import_global_count + ? module->import_globals[global_idx] + .u.global.type.val_type + : module + ->globals[global_idx + - module->import_global_count] + .type.val_type; #if WASM_ENABLE_GC != 0 ref_type = global_idx < module->import_global_count diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index f619adae..ff37d818 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -478,14 +478,14 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end, !module->import_globals[global_idx].u.global.is_mutable); if (global_idx < module->import_global_count) { - global_type = - module->import_globals[global_idx].u.global.type; + global_type = module->import_globals[global_idx] + .u.global.type.val_type; } else { global_type = module ->globals[global_idx - module->import_global_count] - .type; + .type.val_type; } if (!push_const_expr_stack(&const_expr_ctx, flag, global_type, @@ -834,8 +834,8 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end, global->is_linked = ret; global->module_name = sub_module_name; global->field_name = global_name; - global->type = declare_type; - global->is_mutable = is_mutable; + global->type.val_type = declare_type; + global->type.is_mutable = is_mutable; (void)p_end; return true; } @@ -1373,14 +1373,15 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, for (i = 0; i < global_count; i++, global++) { CHECK_BUF(p, p_end, 2); - global->type = read_uint8(p); + global->type.val_type = read_uint8(p); mutable = read_uint8(p); bh_assert(mutable < 2); - global->is_mutable = mutable ? true : false; + global->type.is_mutable = mutable ? true : false; /* initialize expression */ if (!load_init_expr(module, &p, p_end, &(global->init_expr), - global->type, error_buf, error_buf_size)) + global->type.val_type, error_buf, + error_buf_size)) return false; if (INIT_EXPR_TYPE_GET_GLOBAL == global->init_expr.init_expr_type) { @@ -2065,7 +2066,7 @@ calculate_global_data_offset(WASMModule *module) #if WASM_ENABLE_FAST_JIT != 0 import_global->data_offset = data_offset; #endif - data_offset += wasm_value_type_size(import_global->type); + data_offset += wasm_value_type_size(import_global->type.val_type); } for (i = 0; i < module->global_count; i++) { @@ -2073,7 +2074,7 @@ calculate_global_data_offset(WASMModule *module) #if WASM_ENABLE_FAST_JIT != 0 global->data_offset = data_offset; #endif - data_offset += wasm_value_type_size(global->type); + data_offset += wasm_value_type_size(global->type.val_type); } module->global_data_size = data_offset; @@ -2702,7 +2703,8 @@ load_from_sections(WASMModule *module, WASMSection *sections, if (!strcmp(export->name, "__heap_base")) { global_index = export->index - module->import_global_count; global = module->globals + global_index; - if (global->type == VALUE_TYPE_I32 && !global->is_mutable + if (global->type.val_type == VALUE_TYPE_I32 + && !global->type.is_mutable && global->init_expr.init_expr_type == INIT_EXPR_TYPE_I32_CONST) { aux_heap_base_global = global; @@ -2715,7 +2717,8 @@ load_from_sections(WASMModule *module, WASMSection *sections, else if (!strcmp(export->name, "__data_end")) { global_index = export->index - module->import_global_count; global = module->globals + global_index; - if (global->type == VALUE_TYPE_I32 && !global->is_mutable + if (global->type.val_type == VALUE_TYPE_I32 + && !global->type.is_mutable && global->init_expr.init_expr_type == INIT_EXPR_TYPE_I32_CONST) { aux_data_end_global = global; @@ -2754,9 +2757,9 @@ load_from_sections(WASMModule *module, WASMSection *sections, for (global_index = 0; global_index < module->global_count; global_index++) { global = module->globals + global_index; - if (global->is_mutable /* heap_base and data_end is - not mutable */ - && global->type == VALUE_TYPE_I32 + if (global->type.is_mutable /* heap_base and data_end is + not mutable */ + && global->type.val_type == VALUE_TYPE_I32 && global->init_expr.init_expr_type == INIT_EXPR_TYPE_I32_CONST && (uint64)(uint32)global->init_expr.u.i32 @@ -7149,13 +7152,13 @@ re_scan: read_leb_uint32(p, p_end, global_idx); bh_assert(global_idx < global_count); - global_type = - global_idx < module->import_global_count - ? module->import_globals[global_idx].u.global.type - : module - ->globals[global_idx - - module->import_global_count] - .type; + global_type = global_idx < module->import_global_count + ? module->import_globals[global_idx] + .u.global.type.val_type + : module + ->globals[global_idx + - module->import_global_count] + .type.val_type; PUSH_TYPE(global_type); @@ -7183,22 +7186,22 @@ re_scan: read_leb_uint32(p, p_end, global_idx); bh_assert(global_idx < global_count); - is_mutable = - global_idx < module->import_global_count - ? module->import_globals[global_idx].u.global.is_mutable - : module - ->globals[global_idx - - module->import_global_count] - .is_mutable; + is_mutable = global_idx < module->import_global_count + ? module->import_globals[global_idx] + .u.global.type.is_mutable + : module + ->globals[global_idx + - module->import_global_count] + .type.is_mutable; bh_assert(is_mutable); - global_type = - global_idx < module->import_global_count - ? module->import_globals[global_idx].u.global.type - : module - ->globals[global_idx - - module->import_global_count] - .type; + global_type = global_idx < module->import_global_count + ? module->import_globals[global_idx] + .u.global.type.val_type + : module + ->globals[global_idx + - module->import_global_count] + .type.val_type; #if WASM_ENABLE_FAST_INTERP == 0 if (is_64bit_type(global_type)) { diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index fd290afa..c0e325b5 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -856,7 +856,7 @@ check_global_init_expr(const WASMModule *module, uint32 global_index, * And initializer expression cannot reference a mutable global. */ if (global_index >= module->import_global_count - || (module->import_globals + global_index)->u.global.is_mutable) { + || (module->import_globals + global_index)->u.global.type.is_mutable) { set_error_buf(error_buf, error_buf_size, "constant expression required"); return false; @@ -888,8 +888,8 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, 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; - global->is_mutable = global_import->is_mutable; + global->type = global_import->type.val_type; + global->is_mutable = global_import->type.is_mutable; #if WASM_ENABLE_GC != 0 global->ref_type = global_import->ref_type; #endif @@ -935,8 +935,8 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst, InitializerExpression *init_expr = &(module->globals[i].init_expr); uint8 flag = init_expr->init_expr_type; - global->type = module->globals[i].type; - global->is_mutable = module->globals[i].is_mutable; + global->type = module->globals[i].type.val_type; + global->is_mutable = module->globals[i].type.is_mutable; #if WASM_ENABLE_FAST_JIT != 0 bh_assert(global_data_offset == module->globals[i].data_offset); #endif diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index 2ac38103..e266ba6c 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -1161,8 +1161,8 @@ wasm_native_lookup_libc_builtin_global(const char *module_name, while (global_def < global_def_end) { if (!strcmp(global_def->module_name, module_name) && !strcmp(global_def->global_name, global_name)) { - global->type = global_def->type; - global->is_mutable = global_def->is_mutable; + global->type.val_type = global_def->type; + global->type.is_mutable = global_def->is_mutable; global->global_data_linked = global_def->value; return true; }