Parcourir la source

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);
```
Benbuck Nason il y a 1 an
Parent
commit
c85bada2a9

+ 10 - 8
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;

+ 9 - 9
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))

+ 16 - 15
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);

+ 80 - 20
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;
     }

+ 8 - 8
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;

+ 2 - 6
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;

+ 4 - 4
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,

+ 3 - 2
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))

+ 2 - 2
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;
     }
 }
 

+ 11 - 0
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
  *

+ 7 - 4
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

+ 57 - 51
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

+ 39 - 36
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)) {

+ 5 - 5
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

+ 2 - 2
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;
         }