Sfoglia il codice sorgente

[instantiation linking] refactor wasm_table_inst_t (#3901)

- refactor wasm_table_inst_t and add functions to retrieve export type by name
liang.he 1 anno fa
parent
commit
23c8be1649

+ 10 - 3
core/iwasm/aot/aot_runtime.c

@@ -725,6 +725,7 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
 #if WASM_ENABLE_GC != 0
         table->elem_ref_type.elem_ref_type = table_type->elem_ref_type;
 #endif
+        table->is_table64 = table_type->flags & TABLE64_FLAG;
 
 #if WASM_ENABLE_MULTI_MODULE != 0
         /* Set all elements to -1 or NULL_REF to mark them as uninitialized
@@ -788,6 +789,7 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
 #if WASM_ENABLE_GC != 0
         table->elem_ref_type.elem_ref_type = table_type->elem_ref_type;
 #endif
+        table->is_table64 = table_type->flags & TABLE64_FLAG;
 
         /* Set all elements to -1 or NULL_REF to mark them as uninitialized
          * elements */
@@ -951,15 +953,20 @@ memories_deinstantiate(AOTModuleInstance *module_inst)
 
         memory_deinstantiate(memory);
 
-#if WASM_ENABLE_MULTI_MODULE == 0 && WASM_ENABLE_SHARED_MEMORY != 0
+#if WASM_ENABLE_MULTI_MODULE == 0
+#if WASM_ENABLE_SHARED_MEMORY != 0
         /* for spawned only */
         if (!shared_memory_is_shared(memory)) {
+            wasm_runtime_free(memory);
             continue;
         }
 
         if (shared_memory_get_reference(memory) == 0) {
             wasm_runtime_free(memory);
         }
+#else
+        wasm_runtime_free(memory);
+#endif
 #endif
     }
 
@@ -1290,8 +1297,8 @@ memories_instantiate(const AOTModule *module, AOTModuleInstance *module_inst,
 #endif
         /*
          *TODO:
-         * - either memories[x] points to an external AOTMemoryInstance.
-         * - or memories[x] points to an internal AOTMemoryInstance in
+         * - either memories[x] points to an external WASM/AOTMemoryInstance.
+         * - or memories[x] points to an internal WASM/AOTMemoryInstance in
          *   global_table_data
          *
          * the first case is simple for maintaining resource management

+ 160 - 175
core/iwasm/common/wasm_runtime_common.c

@@ -454,55 +454,6 @@ wasm_runtime_get_exec_env_tls()
 }
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
-/* FIXME: remove when merging wasm_table_inst_t with WASMTableInstance and
- * AOTTableInstance */
-#if WASM_ENABLE_INTERP != 0
-static void
-WASMTableInstance_to_wasm_table_inst_t(const WASMModule *module,
-                                       const WASMTableInstance *table_rt,
-                                       int64 table_index,
-                                       wasm_table_inst_t *out)
-{
-    out->elem_kind = val_type_to_val_kind(table_rt->elem_type);
-    out->max_size = table_rt->max_size;
-    out->cur_size = table_rt->cur_size;
-
-    /* table_index < 0, it means it is created by host */
-    uintptr_t tmp = (uintptr_t)table_rt->elems;
-    if (table_index > 0 && table_index < (int64)module->import_table_count) {
-        out->elems = *(void **)tmp;
-    }
-    else {
-        out->elems = (void *)tmp;
-    }
-
-    bh_assert(out->elems);
-}
-#endif
-
-#if WASM_ENABLE_AOT != 0
-static void
-AOTTableInstance_to_wasm_table_inst_t(const AOTModule *module,
-                                      const AOTTableInstance *table_rt,
-                                      int64 table_index, wasm_table_inst_t *out)
-{
-    out->elem_kind = val_type_to_val_kind(table_rt->elem_type);
-    out->max_size = table_rt->max_size;
-    out->cur_size = table_rt->cur_size;
-
-    /* table_index < 0, it means it is created by host */
-    uintptr_t tmp = (uintptr_t)table_rt->elems;
-    if (table_index > 0 && table_index < (int64)module->import_table_count) {
-        out->elems = *(void **)tmp;
-    }
-    else {
-        out->elems = (void *)tmp;
-    }
-
-    bh_assert(out->elems);
-}
-#endif
-
 static bool
 wasm_runtime_env_init(void)
 {
@@ -2161,11 +2112,14 @@ wasm_runtime_get_export_global_inst(WASMModuleInstanceCommon *const module_inst,
     return false;
 }
 
-bool
+WASMTableInstance *
 wasm_runtime_get_export_table_inst(WASMModuleInstanceCommon *const module_inst,
-                                   char const *name,
-                                   wasm_table_inst_t *table_inst)
+                                   const char *name)
 {
+    if (!module_inst || !name) {
+        return NULL;
+    }
+
 #if WASM_ENABLE_INTERP != 0
     if (module_inst->module_type == Wasm_Module_Bytecode) {
         const WASMModuleInstance *wasm_module_inst =
@@ -2175,22 +2129,19 @@ wasm_runtime_get_export_table_inst(WASMModuleInstanceCommon *const module_inst,
         for (uint32 i = 0; i < wasm_module->export_count; i++) {
             const WASMExport *wasm_export = &wasm_module->exports[i];
 
-            if (wasm_export->kind != WASM_IMPORT_EXPORT_KIND_TABLE) {
+            if (wasm_export->kind != WASM_IMPORT_EXPORT_KIND_TABLE)
                 continue;
-            }
 
-            if (strcmp(wasm_export->name, name)) {
+            if (strcmp(wasm_export->name, name))
                 continue;
-            }
 
-            const WASMTableInstance *wasm_table_inst =
-                wasm_module_inst->tables[wasm_export->index];
-            WASMTableInstance_to_wasm_table_inst_t(
-                wasm_module, wasm_table_inst, wasm_export->index, table_inst);
-            return true;
+            return wasm_module_inst->tables[wasm_export->index];
         }
+
+        return NULL;
     }
 #endif
+
 #if WASM_ENABLE_AOT != 0
     if (module_inst->module_type == Wasm_Module_AoT) {
         const AOTModuleInstance *aot_module_inst =
@@ -2200,29 +2151,26 @@ wasm_runtime_get_export_table_inst(WASMModuleInstanceCommon *const module_inst,
         for (uint32 i = 0; i < aot_module->export_count; i++) {
             const AOTExport *aot_export = &aot_module->exports[i];
 
-            if (aot_export->kind != WASM_IMPORT_EXPORT_KIND_TABLE) {
+            if (aot_export->kind == WASM_IMPORT_EXPORT_KIND_TABLE)
                 continue;
-            }
 
-            if (strcmp(aot_export->name, name)) {
+            if (strcmp(aot_export->name, name))
                 continue;
-            }
 
-            const AOTTableInstance *aot_table_inst =
-                aot_module_inst->tables[aot_export->index];
-            AOTTableInstance_to_wasm_table_inst_t(
-                aot_module, aot_table_inst, aot_export->index, table_inst);
-            return true;
+            return aot_module_inst->tables[aot_export->index];
         }
+
+        return NULL;
     }
 #endif
 
-    return false;
+    LOG_ERROR("Unsupported module type: %d", module_inst->module_type);
+    return NULL;
 }
 
 WASMFunctionInstanceCommon *
 wasm_table_get_func_inst(struct WASMModuleInstanceCommon *const module_inst,
-                         const wasm_table_inst_t *table_inst, uint32_t idx)
+                         WASMTableInstance *const table_inst, uint32_t idx)
 {
     if (!table_inst) {
         bh_assert(0);
@@ -4302,6 +4250,84 @@ wasm_runtime_get_export_count(WASMModuleCommon *const module)
     return -1;
 }
 
+#if WASM_ENABLE_AOT != 0
+static void
+populate_export_type_from_aot(const AOTModule *module, const AOTExport *export,
+                              wasm_export_t *out)
+{
+    if (!module || !export || !out)
+        return;
+
+    out->name = export->name;
+    out->kind = export->kind;
+
+    switch (out->kind) {
+        case WASM_IMPORT_EXPORT_KIND_FUNC:
+            out->u.func_type =
+                (AOTFuncType *)module
+                    ->types[module->func_type_indexes
+                                [export->index - module->import_func_count]];
+            break;
+        case WASM_IMPORT_EXPORT_KIND_GLOBAL:
+            out->u.global_type =
+                &module->globals[export->index - module->import_global_count]
+                     .type;
+            break;
+        case WASM_IMPORT_EXPORT_KIND_TABLE:
+            out->u.table_type =
+                &module->tables[export->index - module->import_table_count]
+                     .table_type;
+            break;
+        case WASM_IMPORT_EXPORT_KIND_MEMORY:
+            out->u.memory_type =
+                &module->memories[export->index - module->import_memory_count];
+            break;
+        default:
+            bh_assert(0);
+            return;
+    }
+}
+#endif
+
+#if WASM_ENABLE_INTERP != 0
+static void
+populate_export_type_from_wasm(const WASMModule *module,
+                               const WASMExport *export, wasm_export_t *out)
+{
+    if (!out || !module || !export) {
+        return;
+    }
+
+    out->name = export->name;
+    out->kind = export->kind;
+
+    switch (out->kind) {
+        case WASM_IMPORT_EXPORT_KIND_FUNC:
+            out->u.func_type =
+                module->functions[export->index - module->import_function_count]
+                    ->func_type;
+            break;
+        case WASM_IMPORT_EXPORT_KIND_GLOBAL:
+            out->u.global_type =
+                &module->globals[export->index - module->import_global_count]
+                     .type;
+            break;
+        case WASM_IMPORT_EXPORT_KIND_TABLE:
+            out->u.table_type =
+                &module->tables[export->index - module->import_table_count]
+                     .table_type;
+            break;
+        case WASM_IMPORT_EXPORT_KIND_MEMORY:
+            out->u.memory_type =
+                &module->memories[export->index - module->import_memory_count];
+            break;
+        default:
+            bh_assert(0);
+            return;
+    }
+}
+#endif
+
 void
 wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index,
                              wasm_export_t *export_type)
@@ -4328,39 +4354,7 @@ 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;
-        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:
-                export_type->u.table_type =
-                    &aot_module
-                         ->tables[aot_export->index
-                                  - aot_module->import_table_count]
-                         .table_type;
-                break;
-            case WASM_IMPORT_EXPORT_KIND_MEMORY:
-                export_type->u.memory_type =
-                    &aot_module->memories[aot_export->index
-                                          - aot_module->import_memory_count];
-                break;
-            default:
-                bh_assert(0);
-                break;
-        }
+        populate_export_type_from_aot(aot_module, aot_export, export_type);
         return;
     }
 #endif
@@ -4374,41 +4368,62 @@ 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;
-        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:
-                export_type->u.table_type =
-                    &wasm_module
-                         ->tables[wasm_export->index
-                                  - wasm_module->import_table_count]
-                         .table_type;
-                break;
-            case WASM_IMPORT_EXPORT_KIND_MEMORY:
-                export_type->u.memory_type =
-                    &wasm_module->memories[wasm_export->index
-                                           - wasm_module->import_memory_count];
-                break;
-            default:
-                bh_assert(0);
-                break;
-        }
+        populate_export_type_from_wasm(wasm_module, wasm_export, export_type);
+        return;
+    }
+#endif
+}
+
+void
+wasm_runtime_get_export_type_by_name(WASMModuleCommon *const module,
+                                     const char *name,
+                                     wasm_export_t *export_type)
+{
+    if (!export_type) {
+        bh_assert(0);
+        return;
+    }
+
+    memset(export_type, 0, sizeof(wasm_export_t));
+
+    if (!module) {
+        bh_assert(0);
         return;
     }
+
+#if WASM_ENABLE_INTERP != 0
+    if (module->module_type == Wasm_Module_Bytecode) {
+        const WASMModule *wasm_module = (const WASMModule *)module;
+
+        for (uint32 i = 0; i < wasm_module->export_count; i++) {
+            WASMExport *wasm_export = &wasm_module->exports[i];
+
+            if (strcmp(name, wasm_export->name)) {
+                continue;
+            }
+
+            populate_export_type_from_wasm(wasm_module, wasm_export,
+                                           export_type);
+            return;
+        }
+    }
+#endif
+
+#if WASM_ENABLE_AOT != 0
+    if (module->module_type == Wasm_Module_AoT) {
+        const AOTModule *aot_module = (const AOTModule *)module;
+
+        for (uint32 i = 0; i < aot_module->export_count; i++) {
+            AOTExport *aot_export = &aot_module->exports[i];
+
+            if (strcmp(name, aot_export->name)) {
+                continue;
+            }
+
+            populate_export_type_from_aot(aot_module, aot_export, export_type);
+            return;
+        }
+    }
 #endif
 }
 
@@ -4551,7 +4566,7 @@ wasm_table_type_get_shared(WASMTableType *const table_type)
 {
     bh_assert(table_type);
 
-    return (table_type->flags & 2) ? true : false;
+    return (table_type->flags & SHARED_TABLE_FLAG) ? true : false;
 }
 
 uint32
@@ -7818,7 +7833,7 @@ wasm_runtime_is_underlying_binary_freeable(WASMModuleCommon *const module)
     return true;
 }
 
-wasm_table_inst_t *
+wasm_table_inst_t
 wasm_runtime_create_table(WASMModuleCommon *const module,
                           wasm_table_type_t const type)
 {
@@ -7827,43 +7842,13 @@ wasm_runtime_create_table(WASMModuleCommon *const module,
 
 #if WASM_ENABLE_INTERP != 0
     if (module->module_type == Wasm_Module_Bytecode) {
-        wasm_table_inst_t *out_table =
-            runtime_malloc(sizeof(wasm_table_inst_t), NULL, NULL, 0);
-        if (!out_table)
-            return NULL;
-
-        WASMTableInstance *wasm_table =
-            wasm_create_table((WASMModule *)module, type);
-        if (!wasm_table) {
-            wasm_runtime_free(wasm_table);
-            return NULL;
-        }
-
-        WASMTableInstance_to_wasm_table_inst_t((WASMModule *)module, wasm_table,
-                                               -1, out_table);
-        /* TODO: wasm_table ownership ?*/
-        return out_table;
+        return wasm_create_table((WASMModule *)module, type);
     }
 #endif
 
 #if WASM_ENABLE_AOT != 0
     if (module->module_type == Wasm_Module_AoT) {
-        wasm_table_inst_t *out_table =
-            runtime_malloc(sizeof(wasm_table_inst_t), NULL, NULL, 0);
-        if (!out_table)
-            return NULL;
-
-        AOTTableInstance *aot_table =
-            aot_create_table((AOTModule *)module, type);
-        if (!aot_table) {
-            wasm_runtime_free(aot_table);
-            return NULL;
-        }
-
-        AOTTableInstance_to_wasm_table_inst_t((AOTModule *)module, aot_table,
-                                              -1, out_table);
-        /* TODO: aot_table ownership ?*/
-        return out_table;
+        return aot_create_table((AOTModule *)module, type);
     }
 #endif
 
@@ -7873,7 +7858,7 @@ wasm_runtime_create_table(WASMModuleCommon *const module,
 
 void
 wasm_runtime_destroy_table(WASMModuleCommon *const module,
-                           wasm_table_inst_t *table)
+                           wasm_table_inst_t table)
 {
     if (!module || !table)
         return;
@@ -7954,7 +7939,7 @@ wasm_runtime_instantiate_with_builtin_linker(WASMModuleCommon *module,
      * during wasm_instantiate()/aot_instantiate()
      *
      * WASModuleInstance->memories[i] takes the ownership of
-     * WASMExternInstance->u.memory
+     * WASMExternInstance->u.memory content
      *
      * WASModuleInstance->tables[i].elems takes
      * the ownership of WASMExternInstance->u.table
@@ -7993,7 +7978,7 @@ wasm_runtime_create_extern_inst(WASMModuleCommon *module,
         }
     }
     else if (import_type->kind == WASM_IMPORT_EXPORT_KIND_TABLE) {
-        wasm_table_inst_t *table =
+        wasm_table_inst_t table =
             wasm_runtime_create_table(module, import_type->u.table_type);
         out->u.table = table;
         if (!out->u.table) {

+ 33 - 24
core/iwasm/include/wasm_export.h

@@ -138,16 +138,9 @@ typedef WASMFunctionInstanceCommon *wasm_function_inst_t;
 struct WASMMemoryInstance;
 typedef struct WASMMemoryInstance *wasm_memory_inst_t;
 
-/* Table instance*/
-/*TODO: better to use WASMTableInstance and AOTTableInstance directly */
-typedef struct wasm_table_inst_t {
-    wasm_valkind_t elem_kind;
-    uint32_t cur_size;
-    uint32_t max_size;
-    /* represents the elements of the table, for internal use only */
-    /* always a table_elem_type_t elems[] */
-    void *elems;
-} wasm_table_inst_t;
+/* Table instance */
+struct WASMTableInstance;
+typedef struct WASMTableInstance *wasm_table_inst_t;
 
 /* WASM section */
 typedef struct wasm_section_t {
@@ -295,7 +288,7 @@ typedef struct WASMExternInstance {
     wasm_import_export_kind_t kind;
     union {
         wasm_memory_inst_t memory;
-        wasm_table_inst_t *table;
+        wasm_table_inst_t table;
     } u;
 } WASMExternInstance, *wasm_extern_inst_t;
 
@@ -1529,6 +1522,23 @@ WASM_RUNTIME_API_EXTERN void
 wasm_runtime_get_export_type(const wasm_module_t module, int32_t export_index,
                              wasm_export_t *export_type);
 
+/**
+ * @brief Retrieves the export type of a given name from the specified WASM
+ * module.
+ *
+ * This function searches for an export with the specified name within the
+ * provided WebAssembly module and returns its type information.
+ *
+ * @param module The WebAssembly module to search within.
+ * @param name The name of the export to find.
+ * @param export_type A pointer to a wasm_export_t structure where the export
+ * type information will be stored if found.
+ */
+WASM_RUNTIME_API_EXTERN void
+wasm_runtime_get_export_type_by_name(const wasm_module_t module,
+                                     const char *name,
+                                     wasm_export_t *export_type);
+
 /**
  * Get the number of parameters for a function type
  *
@@ -1750,19 +1760,19 @@ wasm_runtime_get_export_global_inst(const wasm_module_inst_t module_inst,
                                     wasm_global_inst_t *global_inst);
 
 /**
- * Get an export table instance
+ * @brief Retrieves the table instance exported from a WebAssembly module
+ * instance.
  *
- * @param module_inst the module instance
- * @param name the export table name
- * @param table_inst location to store the table instance
- *
- * @return true if success, false otherwise
+ * This function looks up a table instance by its export name from the given
+ * WebAssembly module instance.
  *
+ * @param module_inst The WebAssembly module instance.
+ * @param name The name of the exported table.
+ * @return The table instance if found, otherwise NULL.
  */
-WASM_RUNTIME_API_EXTERN bool
+WASM_RUNTIME_API_EXTERN wasm_table_inst_t
 wasm_runtime_get_export_table_inst(const wasm_module_inst_t module_inst,
-                                   const char *name,
-                                   wasm_table_inst_t *table_inst);
+                                   const char *name);
 
 /**
  * Get a function instance from a table.
@@ -1775,7 +1785,7 @@ wasm_runtime_get_export_table_inst(const wasm_module_inst_t module_inst,
  */
 WASM_RUNTIME_API_EXTERN wasm_function_inst_t
 wasm_table_get_func_inst(const wasm_module_inst_t module_inst,
-                         const wasm_table_inst_t *table_inst, uint32_t idx);
+                         const wasm_table_inst_t table_inst, uint32_t idx);
 
 /**
  * Get attachment of native function from execution environment
@@ -2351,13 +2361,12 @@ wasm_runtime_shared_heap_malloc(wasm_module_inst_t module_inst, uint64_t size,
 WASM_RUNTIME_API_EXTERN void
 wasm_runtime_shared_heap_free(wasm_module_inst_t module_inst, uint64_t ptr);
 
-WASM_RUNTIME_API_EXTERN wasm_table_inst_t *
+WASM_RUNTIME_API_EXTERN wasm_table_inst_t
 wasm_runtime_create_table(const wasm_module_t module,
                           const wasm_table_type_t type);
 
 WASM_RUNTIME_API_EXTERN void
-wasm_runtime_destroy_table(const wasm_module_t module,
-                           wasm_table_inst_t *table);
+wasm_runtime_destroy_table(const wasm_module_t module, wasm_table_inst_t table);
 
 /*TODO: take me out when have a linker */
 WASM_RUNTIME_API_EXTERN wasm_module_inst_t

+ 11 - 5
core/iwasm/interpreter/wasm_runtime.c

@@ -274,6 +274,7 @@ memories_deinstantiate(WASMModuleInstance *module_inst)
     WASMMemoryInstance **memories = module_inst->memories;
     for (; mem_index < module->import_memory_count; mem_index++) {
         WASMMemoryInstance *memory = memories[mem_index];
+
 #if WASM_ENABLE_MULTI_MODULE != 0
         if (module->import_memories[mem_index].u.memory.import_module) {
             continue;
@@ -282,16 +283,21 @@ memories_deinstantiate(WASMModuleInstance *module_inst)
         memory_deinstantiate(memory);
 #endif
 
-#if WASM_ENABLE_MULTI_MODULE == 0 && WASM_ENABLE_SHARED_MEMORY != 0
-        /* for spawned only */
+#if WASM_ENABLE_MULTI_MODULE == 0
+#if WASM_ENABLE_SHARED_MEMORY != 0
         if (!shared_memory_is_shared(memory)) {
+            wasm_runtime_free(memory);
             continue;
         }
 
         if (shared_memory_get_reference(memory) == 0) {
             wasm_runtime_free(memory);
         }
+#else
+        wasm_runtime_free(memory);
 #endif
+#endif
+        (void)memory;
     }
 
     for (; mem_index < module->memory_count; mem_index++) {
@@ -635,8 +641,8 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
 #endif
         /*
          *TODO:
-         * - either memories[x] points to an external AOTMemoryInstance.
-         * - or memories[x] points to an internal AOTMemoryInstance in
+         * - either memories[x] points to an external WASM/AOTMemoryInstance.
+         * - or memories[x] points to an internal WASM/AOTMemoryInstance in
          *   global_table_data
          *
          * the first case is simple for maintaining resource management
@@ -5308,7 +5314,7 @@ wasm_inherit_imports(WASMModule *module, WASMModuleInstance *inst,
         }
         /*TODO: shared_table, shared_global ?*/
         else {
-            LOG_WARNING("for spawned, inherit() import(%s,%s) kind %d",
+            LOG_WARNING("for spawned, skip inherit() import(%s,%s) kind %d",
                         import_type.module_name, import_type.name,
                         import_type.kind);
         }

+ 4 - 4
samples/linking/import-table/main.c

@@ -64,7 +64,7 @@ main(int argc, char *argv_main[])
 
     /* host table */
     wasm_table_type_t table_type = import_type.u.table_type;
-    wasm_table_inst_t *table = wasm_runtime_create_table(module, table_type);
+    wasm_table_inst_t table = wasm_runtime_create_table(module, table_type);
     if (!table) {
         printf("Create table failed.\n");
         goto unload_module;
@@ -86,7 +86,9 @@ main(int argc, char *argv_main[])
         module, &inst_args, error_buf, sizeof(error_buf));
     if (!inst) {
         printf("Instantiate wasm file failed: %s\n", error_buf);
-        goto destroy_table;
+        wasm_runtime_destroy_table(module, table);
+        table = NULL;
+        goto unload_module;
     }
 
     /* export function */
@@ -100,8 +102,6 @@ main(int argc, char *argv_main[])
 
 destroy_inst:
     wasm_runtime_deinstantiate(inst);
-destroy_table:
-    wasm_runtime_destroy_table(module, table);
 unload_module:
     wasm_runtime_unload(module);
 release_file_buffer: