ソースを参照

Register GC symbols to AOT loader (#2654)

And fix issues in AOT loader when loading GC defined types.
Huang Qi 2 年 前
コミット
54fc47e25e
2 ファイル変更85 行追加45 行削除
  1. 68 45
      core/iwasm/aot/aot_loader.c
  2. 17 0
      core/iwasm/aot/aot_reloc.h

+ 68 - 45
core/iwasm/aot/aot_loader.c

@@ -1289,12 +1289,13 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
 
         buf = align_ptr(buf, 4);
 
+        /* Read base type info */
         read_uint16(buf, buf_end, type_flag);
+        read_uint16(buf, buf_end, is_sub_final);
+        read_uint32(buf, buf_end, parent_type_idx);
+
         if (type_flag == WASM_TYPE_FUNC) {
             AOTFuncType *func_type;
-            /* Read base type info */
-            read_uint16(buf, buf_end, is_sub_final);
-            read_uint32(buf, buf_end, parent_type_idx);
 
             /* Read param count */
             read_uint16(buf, buf_end, param_count);
@@ -1337,29 +1338,31 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
             func_type->param_cell_num = param_cell_num;
             func_type->ret_cell_num = ret_cell_num;
 
-            if (ref_type_map_count == 0) {
-                continue;
-            }
-
-            bh_assert(func_type->ref_type_map_count
-                      <= func_type->param_count + func_type->result_count);
+            /* If ref_type_map is not empty, read ref_type_map */
+            if (ref_type_map_count > 0) {
+                bh_assert(func_type->ref_type_map_count
+                          <= func_type->param_count + func_type->result_count);
 
-            if (!(func_type->ref_type_maps = loader_malloc(
-                      sizeof(WASMRefTypeMap) * func_type->ref_type_map_count,
-                      error_buf, error_buf_size))) {
-                goto fail;
-            }
+                if (!(func_type->ref_type_maps =
+                          loader_malloc(sizeof(WASMRefTypeMap)
+                                            * func_type->ref_type_map_count,
+                                        error_buf, error_buf_size))) {
+                    goto fail;
+                }
 
-            for (j = 0; j < func_type->ref_type_map_count; j++) {
-                read_uint8(buf, buf_end,
-                           func_type->ref_type_maps[j]
-                               .ref_type->ref_ht_common.ref_type);
-                read_uint8(buf, buf_end,
-                           func_type->ref_type_maps[j]
-                               .ref_type->ref_ht_common.nullable);
-                read_uint32(buf, buf_end,
-                            func_type->ref_type_maps[j]
-                                .ref_type->ref_ht_common.heap_type);
+                for (j = 0; j < func_type->ref_type_map_count; j++) {
+                    read_uint16(buf, buf_end,
+                                func_type->ref_type_maps[j].index);
+                    read_uint8(buf, buf_end,
+                               func_type->ref_type_maps[j]
+                                   .ref_type->ref_ht_common.ref_type);
+                    read_uint8(buf, buf_end,
+                               func_type->ref_type_maps[j]
+                                   .ref_type->ref_ht_common.nullable);
+                    read_uint32(buf, buf_end,
+                                func_type->ref_type_maps[j]
+                                    .ref_type->ref_ht_common.heap_type);
+                }
             }
         }
         else if (type_flag == WASM_TYPE_STRUCT) {
@@ -1387,29 +1390,31 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
             /* Read ref_type_map_count */
             read_uint16(buf, buf_end, struct_type->ref_type_map_count);
 
-            if (struct_type->ref_type_map_count == 0) {
-                continue;
-            }
+            /* If ref_type_map is not empty, read ref_type_map */
+            if (struct_type->ref_type_map_count > 0) {
 
-            bh_assert(struct_type->ref_type_map_count <= field_count);
+                bh_assert(struct_type->ref_type_map_count <= field_count);
 
-            if (!(struct_type->ref_type_maps = loader_malloc(
-                      sizeof(WASMRefTypeMap) * struct_type->ref_type_map_count,
-                      error_buf, error_buf_size))) {
-                goto fail;
-            }
+                if (!(struct_type->ref_type_maps =
+                          loader_malloc(sizeof(WASMRefTypeMap)
+                                            * struct_type->ref_type_map_count,
+                                        error_buf, error_buf_size))) {
+                    goto fail;
+                }
 
-            for (j = 0; j < struct_type->ref_type_map_count; j++) {
-                read_uint16(buf, buf_end, struct_type->ref_type_maps[j].index);
-                read_uint8(buf, buf_end,
-                           struct_type->ref_type_maps[j]
-                               .ref_type->ref_ht_common.ref_type);
-                read_uint8(buf, buf_end,
-                           struct_type->ref_type_maps[j]
-                               .ref_type->ref_ht_common.nullable);
-                read_uint32(buf, buf_end,
-                            struct_type->ref_type_maps[j]
-                                .ref_type->ref_ht_common.heap_type);
+                for (j = 0; j < struct_type->ref_type_map_count; j++) {
+                    read_uint16(buf, buf_end,
+                                struct_type->ref_type_maps[j].index);
+                    read_uint8(buf, buf_end,
+                               struct_type->ref_type_maps[j]
+                                   .ref_type->ref_ht_common.ref_type);
+                    read_uint8(buf, buf_end,
+                               struct_type->ref_type_maps[j]
+                                   .ref_type->ref_ht_common.nullable);
+                    read_uint32(buf, buf_end,
+                                struct_type->ref_type_maps[j]
+                                    .ref_type->ref_ht_common.heap_type);
+                }
             }
         }
         else if (type_flag == WASM_TYPE_ARRAY) {
@@ -1433,6 +1438,25 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
                             "invalid type flag: %" PRIu32, type_flag);
             goto fail;
         }
+
+        if (parent_type_idx != (uint32)-1) { /* has parent */
+            AOTType *parent_type = module->types[parent_type_idx];
+            if (!wasm_type_is_subtype_of(module->types[i], parent_type,
+                                         module->types, i)) {
+                set_error_buf(error_buf, error_buf_size,
+                              "sub type does not match super type");
+                goto fail;
+            }
+
+            module->types[i]->parent_type = parent_type;
+            module->types[i]->root_type = parent_type->root_type;
+            module->types[i]->inherit_depth = parent_type->inherit_depth + 1;
+        }
+        else {
+            module->types[i]->parent_type = NULL;
+            module->types[i]->root_type = module->types[i];
+            module->types[i]->inherit_depth = 0;
+        }
     }
 
     if (module->type_count) {
@@ -1449,7 +1473,6 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
 fail:
     /* Destroy all types */
     destroy_types(types, module->type_count);
-    wasm_runtime_free(types);
     module->types = NULL;
     return false;
 }

+ 17 - 0
core/iwasm/aot/aot_reloc.h

@@ -129,6 +129,22 @@ typedef struct {
 #define REG_LLVM_PGO_SYM()
 #endif
 
+#if WASM_ENABLE_GC != 0
+#define REG_GC_SYM()                       \
+    REG_SYM(aot_array_init_with_data),     \
+    REG_SYM(aot_create_func_obj),          \
+    REG_SYM(aot_obj_is_instance_of),       \
+    REG_SYM(aot_rtt_type_new),             \
+    REG_SYM(wasm_array_obj_copy),          \
+    REG_SYM(wasm_array_obj_new),           \
+    REG_SYM(wasm_externref_obj_to_internal_obj), \
+    REG_SYM(wasm_internal_obj_to_externref_obj), \
+    REG_SYM(wasm_obj_is_type_of),          \
+    REG_SYM(wasm_struct_obj_new),
+#else
+#define REG_GC_SYM()
+#endif
+
 #define REG_COMMON_SYMBOLS                \
     REG_SYM(aot_set_exception_with_id),   \
     REG_SYM(aot_invoke_native),           \
@@ -159,6 +175,7 @@ typedef struct {
     REG_AOT_TRACE_SYM()                   \
     REG_INTRINSIC_SYM()                   \
     REG_LLVM_PGO_SYM()                    \
+    REG_GC_SYM()                          \
 
 #define CHECK_RELOC_OFFSET(data_size) do {              \
     if (!check_reloc_offset(target_section_size,        \