Explorar o código

Merge pull request #3612 from bytecodealliance/main

Merge branch main into dev/multi_memory
Wenyong Huang hai 1 ano
pai
achega
adb4eaeb3a

+ 1 - 1
.github/workflows/compilation_on_android_ubuntu.yml

@@ -645,7 +645,7 @@ jobs:
         uses: actions/checkout@v4
 
       - name: Set-up OCaml
-        uses: ocaml/setup-ocaml@v2
+        uses: ocaml/setup-ocaml@v3
         if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS'
         with:
           ocaml-compiler: 4.13

+ 5 - 2
CMakeLists.txt

@@ -142,12 +142,15 @@ endif ()
 
 include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
 
+set (THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads REQUIRED)
+
 # STATIC LIBRARY
 if (WAMR_BUILD_STATIC)
     add_library(iwasm_static STATIC ${WAMR_RUNTIME_LIB_SOURCE})
     set_target_properties (iwasm_static PROPERTIES OUTPUT_NAME vmlib)
     target_include_directories(iwasm_static INTERFACE ${WAMR_ROOT_DIR}/core/iwasm/include)
-    target_link_libraries (iwasm_static INTERFACE ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
+    target_link_libraries (iwasm_static INTERFACE ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl ${CMAKE_THREAD_LIBS_INIT})
     if (WAMR_BUILD_WASM_CACHE EQUAL 1)
       target_link_libraries(iwasm_static INTERFACE boringssl_crypto)
     endif ()
@@ -160,7 +163,7 @@ if (WAMR_BUILD_SHARED)
     add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE})
     set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm)
     target_include_directories(iwasm_shared INTERFACE ${WAMR_ROOT_DIR}/core/iwasm/include)
-    target_link_libraries (iwasm_shared INTERFACE ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
+    target_link_libraries (iwasm_shared INTERFACE ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl ${CMAKE_THREAD_LIBS_INIT})
     if (WAMR_BUILD_WASM_CACHE EQUAL 1)
       target_link_libraries(iwasm_shared INTERFACE boringssl_crypto)
     endif ()

+ 46 - 13
core/iwasm/aot/aot_loader.c

@@ -591,15 +591,17 @@ str2uint64(const char *buf, uint64 *p_res);
 
 #if WASM_ENABLE_MULTI_MODULE != 0
 static void *
-aot_loader_resolve_function(const char *module_name, const char *function_name,
+aot_loader_resolve_function(const AOTModule *module, const char *function_name,
                             const AOTFuncType *expected_function_type,
-                            char *error_buf, uint32 error_buf_size)
+                            char *error_buf, uint32 error_buf_size);
+
+static void *
+aot_loader_resolve_function_ex(const char *module_name,
+                               const char *function_name,
+                               const AOTFuncType *expected_function_type,
+                               char *error_buf, uint32 error_buf_size)
 {
     WASMModuleCommon *module_reg;
-    void *function = NULL;
-    AOTExport *export = NULL;
-    AOTModule *module = NULL;
-    AOTFuncType *target_function_type = NULL;
 
     module_reg = wasm_runtime_find_module_registered(module_name);
     if (!module_reg || module_reg->module_type != Wasm_Module_AoT) {
@@ -608,10 +610,23 @@ aot_loader_resolve_function(const char *module_name, const char *function_name,
         set_error_buf(error_buf, error_buf_size, "unknown import");
         return NULL;
     }
+    return aot_loader_resolve_function((AOTModule *)module_reg, function_name,
+                                       expected_function_type, error_buf,
+                                       error_buf_size);
+}
 
-    module = (AOTModule *)module_reg;
-    export = loader_find_export(module_reg, module_name, function_name,
-                                EXPORT_KIND_FUNC, error_buf, error_buf_size);
+static void *
+aot_loader_resolve_function(const AOTModule *module, const char *function_name,
+                            const AOTFuncType *expected_function_type,
+                            char *error_buf, uint32 error_buf_size)
+{
+    void *function = NULL;
+    AOTExport *export = NULL;
+    AOTFuncType *target_function_type = NULL;
+
+    export = loader_find_export((WASMModuleCommon *)module, module->name,
+                                function_name, EXPORT_KIND_FUNC, error_buf,
+                                error_buf_size);
     if (!export) {
         return NULL;
     }
@@ -633,7 +648,7 @@ aot_loader_resolve_function(const char *module_name, const char *function_name,
     if (!wasm_type_equal((WASMType *)expected_function_type,
                          (WASMType *)target_function_type, module->types,
                          module->type_count)) {
-        LOG_DEBUG("%s.%s failed the type check", module_name, function_name);
+        LOG_DEBUG("%s.%s failed the type check", module->name, function_name);
         set_error_buf(error_buf, error_buf_size, "incompatible import type");
         return NULL;
     }
@@ -2082,6 +2097,10 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
         read_string(buf, buf_end, import_globals[i].module_name);
         read_string(buf, buf_end, import_globals[i].global_name);
 
+        if (!is_valid_value_type(import_globals[i].type.val_type)) {
+            return false;
+        }
+
 #if WASM_ENABLE_LIBC_BUILTIN != 0
         if (wasm_native_lookup_libc_builtin_global(
                 import_globals[i].module_name, import_globals[i].global_name,
@@ -2198,6 +2217,9 @@ load_global_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
     const uint8 *buf = *p_buf;
 
     read_uint32(buf, buf_end, module->global_count);
+    if (is_indices_overflow(module->import_global_count, module->global_count,
+                            error_buf, error_buf_size))
+        return false;
 
     /* load globals */
     if (module->global_count > 0
@@ -2260,17 +2282,24 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
             &import_funcs[i].signature, &import_funcs[i].attachment,
             &import_funcs[i].call_conv_raw);
         if (!linked_func) {
+            sub_module = NULL;
             if (!wasm_runtime_is_built_in_module(module_name)) {
                 sub_module = (AOTModule *)wasm_runtime_load_depended_module(
                     (WASMModuleCommon *)module, module_name, error_buf,
                     error_buf_size);
                 if (!sub_module) {
+                    LOG_ERROR("failed to load sub module: %s", error_buf);
                     return false;
                 }
             }
-            linked_func = aot_loader_resolve_function(
-                module_name, field_name, declare_func_type, error_buf,
-                error_buf_size);
+            if (!sub_module)
+                linked_func = aot_loader_resolve_function_ex(
+                    module_name, field_name, declare_func_type, error_buf,
+                    error_buf_size);
+            else
+                linked_func = aot_loader_resolve_function(
+                    sub_module, field_name, declare_func_type, error_buf,
+                    error_buf_size);
         }
         import_funcs[i].func_ptr_linked = linked_func;
         import_funcs[i].func_type = declare_func_type;
@@ -2455,6 +2484,10 @@ load_init_data_section(const uint8 *buf, const uint8 *buf_end,
 
     /* load function count and start function index */
     read_uint32(p, p_end, module->func_count);
+    if (is_indices_overflow(module->import_func_count, module->func_count,
+                            error_buf, error_buf_size))
+        return false;
+
     read_uint32(p, p_end, module->start_func_index);
 
     /* check start function index */

+ 16 - 18
core/iwasm/aot/aot_runtime.c

@@ -1640,6 +1640,16 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
 
 #if WASM_ENABLE_MULTI_MODULE != 0
     extra->sub_module_inst_list = &extra->sub_module_inst_list_head;
+
+    /* Allocate memory for import_func_module_insts*/
+    if (module->import_func_count > 0
+        && !(extra->import_func_module_insts =
+                 runtime_malloc((uint64)module->import_func_count
+                                    * sizeof(WASMModuleInstanceCommon *),
+                                error_buf, error_buf_size))) {
+        goto fail;
+    }
+
     ret = wasm_runtime_sub_module_instantiate(
         (WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst,
         stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
@@ -1980,6 +1990,8 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
 #if WASM_ENABLE_MULTI_MODULE != 0
     wasm_runtime_sub_module_deinstantiate(
         (WASMModuleInstanceCommon *)module_inst);
+    if (extra->import_func_module_insts)
+        wasm_runtime_free(extra->import_func_module_insts);
 #endif
 
     if (module_inst->tables)
@@ -2835,10 +2847,6 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
     void *attachment;
     char buf[96];
     bool ret = false;
-#if WASM_ENABLE_MULTI_MODULE != 0
-    bh_list *sub_module_list_node = NULL;
-    const char *sub_inst_name = NULL;
-#endif
     bh_assert(func_idx < aot_module->import_func_count);
 
     import_func = aot_module->import_funcs + func_idx;
@@ -2863,20 +2871,10 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
     else if (!import_func->call_conv_raw) {
         signature = import_func->signature;
 #if WASM_ENABLE_MULTI_MODULE != 0
-        sub_module_list_node =
-            ((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list;
-        sub_module_list_node = bh_list_first_elem(sub_module_list_node);
-        while (sub_module_list_node) {
-            sub_inst_name =
-                ((AOTSubModInstNode *)sub_module_list_node)->module_name;
-            if (strcmp(sub_inst_name, import_func->module_name) == 0) {
-                exec_env = wasm_runtime_get_exec_env_singleton(
-                    (WASMModuleInstanceCommon *)((AOTSubModInstNode *)
-                                                     sub_module_list_node)
-                        ->module_inst);
-                break;
-            }
-            sub_module_list_node = bh_list_elem_next(sub_module_list_node);
+        WASMModuleInstanceCommon *sub_inst = NULL;
+        if ((sub_inst = ((AOTModuleInstanceExtra *)module_inst->e)
+                            ->import_func_module_insts[func_idx])) {
+            exec_env = wasm_runtime_get_exec_env_singleton(sub_inst);
         }
         if (exec_env == NULL) {
             wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst,

+ 1 - 0
core/iwasm/aot/aot_runtime.h

@@ -109,6 +109,7 @@ typedef struct AOTModuleInstanceExtra {
 #if WASM_ENABLE_MULTI_MODULE != 0
     bh_list sub_module_inst_list_head;
     bh_list *sub_module_inst_list;
+    WASMModuleInstanceCommon **import_func_module_insts;
 #endif
 } AOTModuleInstanceExtra;
 

+ 32 - 3
core/iwasm/aot/arch/aot_reloc_arm.c

@@ -14,33 +14,48 @@
 /* clang-format off */
 void __adddf3();
 void __addsf3();
+void __aeabi_d2f();
 void __aeabi_d2iz();
 void __aeabi_d2lz();
+void __aeabi_d2uiz();
 void __aeabi_d2ulz();
 void __aeabi_dadd();
+void __aeabi_dcmpeq();
 void __aeabi_dcmpge();
+void __aeabi_dcmpgt();
 void __aeabi_dcmple();
 void __aeabi_dcmplt();
 void __aeabi_dcmpun();
 void __aeabi_ddiv();
+void __aeabi_dmul();
+void __aeabi_dsub();
 void __aeabi_f2d();
 void __aeabi_f2iz();
 void __aeabi_f2lz();
 void __aeabi_f2ulz();
+void __aeabi_fadd();
+void __aeabi_fcmpeq();
 void __aeabi_fcmpge();
+void __aeabi_fcmpgt();
 void __aeabi_fcmple();
 void __aeabi_fcmplt();
 void __aeabi_fcmpun();
+void __aeabi_fdiv();
+void __aeabi_fmul();
+void __aeabi_fsub();
 void __aeabi_i2d();
+void __aeabi_i2f();
 void __aeabi_idiv();
 void __aeabi_idivmod();
 void __aeabi_l2d();
 void __aeabi_l2f();
 void __aeabi_ldivmod();
+void __aeabi_memclr();
 void __aeabi_memcpy();
 void __aeabi_memmove();
 void __aeabi_memset();
-void __aeabi_memclr();
+void __aeabi_ui2d();
+void __aeabi_ui2f();
 void __aeabi_uidiv();
 void __aeabi_uidivmod();
 void __aeabi_ul2d();
@@ -101,33 +116,48 @@ static SymbolMap target_sym_map[] = {
     REG_SYM(__adddf3),
     REG_SYM(__addsf3),
     /* clang-format on */
+    REG_SYM(__aeabi_d2f),
     REG_SYM(__aeabi_d2iz),
     REG_SYM(__aeabi_d2lz),
+    REG_SYM(__aeabi_d2uiz),
     REG_SYM(__aeabi_d2ulz),
     REG_SYM(__aeabi_dadd),
+    REG_SYM(__aeabi_dcmpeq),
     REG_SYM(__aeabi_dcmpge),
+    REG_SYM(__aeabi_dcmpgt),
     REG_SYM(__aeabi_dcmple),
     REG_SYM(__aeabi_dcmplt),
     REG_SYM(__aeabi_dcmpun),
     REG_SYM(__aeabi_ddiv),
+    REG_SYM(__aeabi_dmul),
+    REG_SYM(__aeabi_dsub),
     REG_SYM(__aeabi_f2d),
     REG_SYM(__aeabi_f2iz),
     REG_SYM(__aeabi_f2lz),
     REG_SYM(__aeabi_f2ulz),
+    REG_SYM(__aeabi_fadd),
+    REG_SYM(__aeabi_fcmpeq),
     REG_SYM(__aeabi_fcmpge),
+    REG_SYM(__aeabi_fcmpgt),
     REG_SYM(__aeabi_fcmple),
     REG_SYM(__aeabi_fcmplt),
     REG_SYM(__aeabi_fcmpun),
+    REG_SYM(__aeabi_fdiv),
+    REG_SYM(__aeabi_fmul),
+    REG_SYM(__aeabi_fsub),
     REG_SYM(__aeabi_i2d),
+    REG_SYM(__aeabi_i2f),
     REG_SYM(__aeabi_idiv),
     REG_SYM(__aeabi_idivmod),
     REG_SYM(__aeabi_l2d),
     REG_SYM(__aeabi_l2f),
     REG_SYM(__aeabi_ldivmod),
+    REG_SYM(__aeabi_memclr),
     REG_SYM(__aeabi_memcpy),
     REG_SYM(__aeabi_memmove),
     REG_SYM(__aeabi_memset),
-    REG_SYM(__aeabi_memclr),
+    REG_SYM(__aeabi_ui2d),
+    REG_SYM(__aeabi_ui2f),
     REG_SYM(__aeabi_uidiv),
     REG_SYM(__aeabi_uidivmod),
     REG_SYM(__aeabi_ul2d),
@@ -166,7 +196,6 @@ static SymbolMap target_sym_map[] = {
     REG_SYM(__moddi3),
     REG_SYM(__modsi3),
     REG_SYM(__muldf3),
-    REG_SYM(__muldf3),
     REG_SYM(__mulsf3),
     REG_SYM(__nedf2),
     REG_SYM(__nesf2),

+ 32 - 0
core/iwasm/common/wasm_loader_common.c

@@ -85,6 +85,21 @@ is_valid_value_type(uint8 type)
     return false;
 }
 
+bool
+is_valid_value_type_for_interpreter(uint8 value_type)
+{
+#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
+    /*
+     * Note: regardless of WASM_ENABLE_SIMD, our interpreters don't have
+     * SIMD implemented. It's safer to reject v128, especially for the
+     * fast interpreter.
+     */
+    if (value_type == VALUE_TYPE_V128)
+        return false;
+#endif
+    return is_valid_value_type(value_type);
+}
+
 bool
 is_valid_func_type(const WASMFuncType *func_type)
 {
@@ -96,3 +111,20 @@ is_valid_func_type(const WASMFuncType *func_type)
 
     return true;
 }
+
+/*
+ * Indices are represented as a u32.
+ */
+bool
+is_indices_overflow(uint32 import, uint32 other, char *error_buf,
+                    uint32 error_buf_size)
+{
+    if (import > UINT32_MAX - other) {
+        snprintf(error_buf, error_buf_size,
+                 "too many items in the index space(%" PRIu32 "+%" PRIu32 ").",
+                 import, other);
+        return true;
+    }
+
+    return false;
+}

+ 8 - 1
core/iwasm/common/wasm_loader_common.h

@@ -20,11 +20,18 @@ wasm_memory_check_flags(const uint8 mem_flag, char *error_buf,
 bool
 is_valid_value_type(uint8 value_tpye);
 
+bool
+is_valid_value_type_for_interpreter(uint8 value_tpye);
+
 bool
 is_valid_func_type(const WASMFuncType *func_type);
 
+bool
+is_indices_overflow(uint32 import, uint32 other, char *error_buf,
+                    uint32 error_buf_size);
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* end of _WASM_LOADER_COMMON_H */
+#endif /* end of _WASM_LOADER_COMMON_H */

+ 24 - 0
core/iwasm/common/wasm_memory.c

@@ -919,6 +919,30 @@ return_func:
     return ret;
 }
 
+bool
+wasm_runtime_enlarge_memory(WASMModuleInstanceCommon *module_inst,
+                            uint64 inc_page_count)
+{
+    if (inc_page_count > UINT32_MAX) {
+        return false;
+    }
+
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT) {
+        return aot_enlarge_memory((AOTModuleInstance *)module_inst,
+                                  inc_page_count);
+    }
+#endif
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode) {
+        return wasm_enlarge_memory((WASMModuleInstance *)module_inst,
+                                   inc_page_count);
+    }
+#endif
+
+    return false;
+}
+
 void
 wasm_runtime_set_enlarge_mem_error_callback(
     const enlarge_memory_error_callback_t callback, void *user_data)

+ 42 - 0
core/iwasm/common/wasm_runtime_common.c

@@ -871,6 +871,22 @@ get_package_type(const uint8 *buf, uint32 size)
     return Package_Type_Unknown;
 }
 
+PackageType
+wasm_runtime_get_file_package_type(const uint8 *buf, uint32 size)
+{
+    return get_package_type(buf, size);
+}
+
+PackageType
+wasm_runtime_get_module_package_type(WASMModuleCommon *module)
+{
+    if (!module) {
+        return Package_Type_Unknown;
+    }
+
+    return module->module_type;
+}
+
 #if WASM_ENABLE_AOT != 0
 static uint8 *
 align_ptr(const uint8 *p, uint32 b)
@@ -7325,6 +7341,32 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
             (WASMModuleInstance *)sub_module_inst;
         sub_module_inst_list_node->module_name =
             sub_module_list_node->module_name;
+
+#if WASM_ENABLE_AOT != 0
+        if (module_inst->module_type == Wasm_Module_AoT) {
+            AOTModuleInstance *aot_module_inst =
+                (AOTModuleInstance *)module_inst;
+            AOTModule *aot_module = (AOTModule *)module;
+            AOTModuleInstanceExtra *aot_extra =
+                (AOTModuleInstanceExtra *)aot_module_inst->e;
+            uint32 i;
+            AOTImportFunc *import_func;
+            for (i = 0; i < aot_module->import_func_count; i++) {
+                if (aot_extra->import_func_module_insts[i])
+                    continue;
+
+                import_func = &aot_module->import_funcs[i];
+                if (strcmp(sub_module_inst_list_node->module_name,
+                           import_func->module_name)
+                    == 0) {
+                    aot_extra->import_func_module_insts[i] =
+                        (WASMModuleInstanceCommon *)
+                            sub_module_inst_list_node->module_inst;
+                }
+            }
+        }
+#endif
+
         bh_list_status ret =
             bh_list_insert(sub_module_inst_list, sub_module_inst_list_node);
         bh_assert(BH_LIST_SUCCESS == ret);

+ 39 - 2
core/iwasm/include/wasm_export.h

@@ -81,8 +81,11 @@ typedef struct WASMTableType *wasm_table_type_t;
 struct WASMGlobalType;
 typedef struct WASMGlobalType *wasm_global_type_t;
 
+#ifndef WASM_MEMORY_T_DEFINED
+#define WASM_MEMORY_T_DEFINED
 struct WASMMemory;
 typedef struct WASMMemory WASMMemoryType;
+#endif
 typedef WASMMemoryType *wasm_memory_type_t;
 
 typedef struct wasm_import_t {
@@ -419,6 +422,28 @@ wasm_runtime_get_mem_alloc_info(mem_alloc_info_t *mem_alloc_info);
 WASM_RUNTIME_API_EXTERN package_type_t
 get_package_type(const uint8_t *buf, uint32_t size);
 
+/**
+ * Get the package type of a buffer (same as get_package_type).
+ *
+ * @param buf the package buffer
+ * @param size the package buffer size
+ *
+ * @return the package type, return Package_Type_Unknown if the type is unknown
+ */
+WASM_RUNTIME_API_EXTERN package_type_t
+wasm_runtime_get_file_package_type(const uint8_t *buf, uint32_t size);
+
+/**
+ * Get the package type of a module.
+ *
+ * @param module the module
+ *
+ * @return the package type, return Package_Type_Unknown if the type is
+ * unknown
+ */
+WASM_RUNTIME_API_EXTERN package_type_t
+wasm_runtime_get_module_package_type(wasm_module_t module);
+
 /**
  * Check whether a file is an AOT XIP (Execution In Place) file
  *
@@ -1202,7 +1227,7 @@ wasm_runtime_validate_native_addr(wasm_module_inst_t module_inst,
                                   void *native_ptr, uint64_t size);
 
 /**
- * Convert app address(relative address) to native address(absolute address)
+ * Convert app address (relative address) to native address (absolute address)
  *
  * Note that native addresses to module instance memory can be invalidated
  * on a memory growth. (Except shared memory, whose native addresses are
@@ -1218,7 +1243,7 @@ wasm_runtime_addr_app_to_native(wasm_module_inst_t module_inst,
                                 uint64_t app_offset);
 
 /**
- * Convert native address(absolute address) to app address(relative address)
+ * Convert native address (absolute address) to app address (relative address)
  *
  * @param module_inst the WASM module instance
  * @param native_ptr the native address
@@ -1842,6 +1867,18 @@ WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_is_import_global_linked(const char *module_name,
                                      const char *global_name);
 
+/**
+ * Enlarge the memory region for a module instance
+ *
+ * @param module_inst the module instance
+ * @param inc_page_count the number of pages to add
+ *
+ * @return true if success, false otherwise
+ */
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_enlarge_memory(wasm_module_inst_t module_inst,
+                            uint64_t inc_page_count);
+
 typedef enum {
     INTERNAL_ERROR,
     MAX_SIZE_REACHED,

+ 5 - 1
core/iwasm/interpreter/wasm.h

@@ -518,7 +518,11 @@ typedef struct WASMMemory {
     uint32 num_bytes_per_page;
     uint32 init_page_count;
     uint32 max_page_count;
-} WASMMemory, WASMMemoryType;
+} WASMMemory;
+#ifndef WASM_MEMORY_T_DEFINED
+#define WASM_MEMORY_T_DEFINED
+typedef struct WASMMemory WASMMemoryType;
+#endif
 
 typedef struct WASMTableImport {
     char *module_name;

+ 1 - 1
core/iwasm/interpreter/wasm_interp_classic.c

@@ -1424,7 +1424,7 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
 #define HANDLE_OP_END()                                            \
     os_mutex_lock(&exec_env->wait_lock);                           \
     if (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
-        && exec_env->current_status->step_count++ == 2) {          \
+        && exec_env->current_status->step_count++ == 1) {          \
         exec_env->current_status->step_count = 0;                  \
         SYNC_ALL_TO_FRAME();                                       \
         wasm_cluster_thread_waiting_run(exec_env);                 \

+ 88 - 34
core/iwasm/interpreter/wasm_loader.c

@@ -334,8 +334,10 @@ is_packed_type(uint8 type)
 static bool
 is_byte_a_type(uint8 type)
 {
-    return (is_valid_value_type(type) || (type == VALUE_TYPE_VOID)) ? true
-                                                                    : false;
+    return (is_valid_value_type_for_interpreter(type)
+            || (type == VALUE_TYPE_VOID))
+               ? true
+               : false;
 }
 
 #if WASM_ENABLE_SIMD != 0
@@ -1039,6 +1041,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
                         }
 
                         cur_value.type_index = type_idx;
+                        cur_value.data = NULL;
                         wasm_set_refheaptype_typeidx(
                             &cur_ref_type.ref_ht_typeidx, false, type_idx);
                         if (!push_const_expr_stack(
@@ -1442,7 +1445,7 @@ resolve_value_type(const uint8 **p_buf, const uint8 *buf_end,
     }
     else {
         /* type which can be represented by one byte */
-        if (!is_valid_value_type(type)
+        if (!is_valid_value_type_for_interpreter(type)
             && !(allow_packed_type && is_packed_type(type))) {
             set_error_buf(error_buf, error_buf_size, "type mismatch");
             return false;
@@ -1952,7 +1955,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
                 type->types[param_count + j] = read_uint8(p);
             }
             for (j = 0; j < param_count + result_count; j++) {
-                if (!is_valid_value_type(type->types[j])) {
+                if (!is_valid_value_type_for_interpreter(type->types[j])) {
                     set_error_buf(error_buf, error_buf_size,
                                   "unknown value type");
                     return false;
@@ -3048,7 +3051,7 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
     CHECK_BUF(p, p_end, 2);
     /* global type */
     declare_type = read_uint8(p);
-    if (!is_valid_value_type(declare_type)) {
+    if (!is_valid_value_type_for_interpreter(declare_type)) {
         set_error_buf(error_buf, error_buf_size, "type mismatch");
         return false;
     }
@@ -3627,6 +3630,10 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
         return false;
     }
 
+    if (is_indices_overflow(module->import_function_count, func_count,
+                            error_buf, error_buf_size))
+        return false;
+
     if (func_count) {
         module->function_count = func_count;
         total_size = sizeof(WASMFunction *) * (uint64)func_count;
@@ -3761,7 +3768,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
                 CHECK_BUF(p_code, buf_code_end, 1);
                 /* 0x7F/0x7E/0x7D/0x7C */
                 type = read_uint8(p_code);
-                if (!is_valid_value_type(type)) {
+                if (!is_valid_value_type_for_interpreter(type)) {
                     if (type == VALUE_TYPE_V128)
                         set_error_buf(error_buf, error_buf_size,
                                       "v128 value type requires simd feature");
@@ -4022,6 +4029,9 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
 #endif
 
     read_leb_uint32(p, p_end, global_count);
+    if (is_indices_overflow(module->import_global_count, global_count,
+                            error_buf, error_buf_size))
+        return false;
 
     module->global_count = 0;
     if (global_count) {
@@ -4038,7 +4048,7 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
             CHECK_BUF(p, p_end, 2);
             /* global type */
             global->type.val_type = read_uint8(p);
-            if (!is_valid_value_type(global->type.val_type)) {
+            if (!is_valid_value_type_for_interpreter(global->type.val_type)) {
                 set_error_buf(error_buf, error_buf_size, "type mismatch");
                 return false;
             }
@@ -4921,6 +4931,10 @@ load_tag_section(const uint8 *buf, const uint8 *buf_end, const uint8 *buf_code,
 
     /* get tag count */
     read_leb_uint32(p, p_end, section_tag_count);
+    if (is_indices_overflow(module->import_tag_count, section_tag_count,
+                            error_buf, error_buf_size))
+        return false;
+
     module->tag_count = section_tag_count;
 
     if (section_tag_count) {
@@ -9304,6 +9318,8 @@ wasm_loader_push_frame_offset(WASMLoaderContext *ctx, uint8 type,
                               bool disable_emit, int16 operand_offset,
                               char *error_buf, uint32 error_buf_size)
 {
+    uint32 cell_num_to_push, i;
+
     if (type == VALUE_TYPE_VOID)
         return true;
 
@@ -9330,21 +9346,24 @@ wasm_loader_push_frame_offset(WASMLoaderContext *ctx, uint8 type,
     if (is_32bit_type(type))
         return true;
 
-    if (ctx->p_code_compiled == NULL) {
-        if (!check_offset_push(ctx, error_buf, error_buf_size))
-            return false;
-    }
+    cell_num_to_push = wasm_value_type_cell_num(type) - 1;
+    for (i = 0; i < cell_num_to_push; i++) {
+        if (ctx->p_code_compiled == NULL) {
+            if (!check_offset_push(ctx, error_buf, error_buf_size))
+                return false;
+        }
 
-    ctx->frame_offset++;
-    if (!disable_emit) {
-        ctx->dynamic_offset++;
-        if (ctx->dynamic_offset > ctx->max_dynamic_offset) {
-            ctx->max_dynamic_offset = ctx->dynamic_offset;
-            if (ctx->max_dynamic_offset >= INT16_MAX) {
-                goto fail;
+        ctx->frame_offset++;
+        if (!disable_emit) {
+            ctx->dynamic_offset++;
+            if (ctx->dynamic_offset > ctx->max_dynamic_offset) {
+                ctx->max_dynamic_offset = ctx->dynamic_offset;
+                if (ctx->max_dynamic_offset >= INT16_MAX)
+                    goto fail;
             }
         }
     }
+
     return true;
 
 fail:
@@ -11185,10 +11204,15 @@ re_scan:
 
                 /* Pass parameters to block */
                 if (BLOCK_HAS_PARAM(block_type)) {
-                    for (i = 0; i < block_type.u.type->param_count; i++) {
+                    WASMFuncType *func_type = block_type.u.type;
+#if WASM_ENABLE_GC != 0
+                    WASMRefType *ref_type;
+                    uint32 j = 0;
+#endif
+                    for (i = 0; i < func_type->param_count; i++) {
 #if WASM_ENABLE_FAST_INTERP != 0
-                        uint32 cell_num = wasm_value_type_cell_num(
-                            block_type.u.type->types[i]);
+                        uint32 cell_num =
+                            wasm_value_type_cell_num(func_type->types[i]);
                         if (i >= available_params) {
                             /* If there isn't enough data on stack, push a dummy
                              * offset to keep the stack consistent with
@@ -11212,7 +11236,17 @@ re_scan:
                             loader_ctx->frame_offset += cell_num;
                         }
 #endif
-                        PUSH_TYPE(block_type.u.type->types[i]);
+#if WASM_ENABLE_GC != 0
+                        if (wasm_is_type_multi_byte_type(func_type->types[i])) {
+                            bh_assert(func_type->ref_type_maps[j].index == i);
+                            ref_type = func_type->ref_type_maps[j].ref_type;
+                            bh_memcpy_s(&wasm_ref_type, sizeof(WASMRefType),
+                                        ref_type,
+                                        wasm_reftype_struct_size(ref_type));
+                            j++;
+                        }
+#endif
+                        PUSH_TYPE(func_type->types[i]);
                     }
                 }
 
@@ -11340,6 +11374,7 @@ re_scan:
                 int32 available_stack_cell =
                     (int32)(loader_ctx->stack_cell_num
                             - cur_block->stack_cell_num);
+                int32 tti;
 
                 /* Check stack values match return types by comparing tag param
                  * types with stack cells */
@@ -11348,19 +11383,21 @@ re_scan:
                 WASMRefTypeMap *frame_reftype_map =
                     loader_ctx->frame_reftype_map;
                 uint32 frame_reftype_map_num = loader_ctx->reftype_map_num;
+
+                /* Temporarily set these values since they may be used in
+                   GET_LOCAL_REFTYPE(), remember they must be restored later */
                 param_reftype_maps = tag_type->ref_type_maps;
                 /* For tag_type function, it shouldn't have result_count = 0 */
                 param_reftype_map_count = tag_type->ref_type_map_count;
-                param_count = (int32)tag_type->param_count;
+                param_count = tag_type->param_count;
 #endif
 
-                for (int tti = (int32)tag_type->param_count - 1; tti >= 0;
-                     tti--) {
+                for (tti = (int32)tag_type->param_count - 1; tti >= 0; tti--) {
 #if WASM_ENABLE_GC != 0
                     local_type = tag_type->types[tti];
                     local_idx = tti;
                     /* Get the wasm_ref_type if the local_type is multibyte
-                     * type */
+                       type */
                     GET_LOCAL_REFTYPE();
 #endif
 
@@ -11390,6 +11427,13 @@ re_scan:
                         wasm_value_type_cell_num(tag_type->types[tti]);
                 }
 
+#if WASM_ENABLE_GC != 0
+                /* Restore the values */
+                param_reftype_maps = func->func_type->ref_type_maps;
+                param_reftype_map_count = func->func_type->ref_type_map_count;
+                param_count = func->func_type->param_count;
+#endif
+
                 /* throw is stack polymorphic */
                 (void)label_type;
                 RESET_STACK();
@@ -11481,10 +11525,6 @@ re_scan:
                     goto fail;
                 }
 
-                BlockType new_block_type;
-                new_block_type.is_value_type = false;
-                new_block_type.u.type = func_type;
-
                 /*
                  * replace frame_csp by LABEL_TYPE_CATCH
                  */
@@ -11494,10 +11534,24 @@ re_scan:
                  * CATCH Blocks */
                 RESET_STACK();
 
+#if WASM_ENABLE_GC != 0
+                WASMRefType *ref_type;
+                uint32 j = 0;
+#endif
+
                 /* push types on the stack according to caught type */
-                if (BLOCK_HAS_PARAM(new_block_type)) {
-                    for (i = 0; i < new_block_type.u.type->param_count; i++)
-                        PUSH_TYPE(new_block_type.u.type->types[i]);
+                for (i = 0; i < func_type->param_count; i++) {
+#if WASM_ENABLE_GC != 0
+                    if (wasm_is_type_multi_byte_type(func_type->types[i])) {
+                        bh_assert(func_type->ref_type_maps[j].index == i);
+                        ref_type = func_type->ref_type_maps[j].ref_type;
+                        bh_memcpy_s(&wasm_ref_type, sizeof(WASMRefType),
+                                    ref_type,
+                                    wasm_reftype_struct_size(ref_type));
+                        j++;
+                    }
+#endif
+                    PUSH_TYPE(func_type->types[i]);
                 }
                 break;
             }
@@ -12315,7 +12369,7 @@ re_scan:
 #if WASM_ENABLE_GC == 0
                 CHECK_BUF(p, p_end, 1);
                 type = read_uint8(p);
-                if (!is_valid_value_type(type)) {
+                if (!is_valid_value_type_for_interpreter(type)) {
                     set_error_buf(error_buf, error_buf_size,
                                   "unknown value type");
                     goto fail;

+ 25 - 14
core/iwasm/interpreter/wasm_mini_loader.c

@@ -91,7 +91,8 @@ is_64bit_type(uint8 type)
 static bool
 is_byte_a_type(uint8 type)
 {
-    return is_valid_value_type(type) || (type == VALUE_TYPE_VOID);
+    return is_valid_value_type_for_interpreter(type)
+           || (type == VALUE_TYPE_VOID);
 }
 
 static void
@@ -568,7 +569,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
                 type->types[param_count + j] = read_uint8(p);
             }
             for (j = 0; j < param_count + result_count; j++) {
-                bh_assert(is_valid_value_type(type->types[j]));
+                bh_assert(is_valid_value_type_for_interpreter(type->types[j]));
             }
 
             param_cell_num = wasm_get_cell_num(type->types, param_count);
@@ -1139,6 +1140,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
 
     bh_assert(func_count == code_count);
 
+    bh_assert(module->import_function_count <= UINT32_MAX - func_count);
+
     if (func_count) {
         module->function_count = func_count;
         total_size = sizeof(WASMFunction *) * (uint64)func_count;
@@ -1216,7 +1219,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
                 CHECK_BUF(p_code, buf_code_end, 1);
                 /* 0x7F/0x7E/0x7D/0x7C */
                 type = read_uint8(p_code);
-                bh_assert(is_valid_value_type(type));
+                bh_assert(is_valid_value_type_for_interpreter(type));
                 for (k = 0; k < sub_local_count; k++) {
                     func->local_types[local_type_index++] = type;
                 }
@@ -1321,6 +1324,8 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
 
     read_leb_uint32(p, p_end, global_count);
 
+    bh_assert(module->import_global_count <= UINT32_MAX - global_count);
+
     module->global_count = 0;
     if (global_count) {
         total_size = sizeof(WASMGlobal) * (uint64)global_count;
@@ -4865,6 +4870,8 @@ wasm_loader_push_frame_offset(WASMLoaderContext *ctx, uint8 type,
                               bool disable_emit, int16 operand_offset,
                               char *error_buf, uint32 error_buf_size)
 {
+    uint32 cell_num_to_push, i;
+
     if (type == VALUE_TYPE_VOID)
         return true;
 
@@ -4889,19 +4896,23 @@ wasm_loader_push_frame_offset(WASMLoaderContext *ctx, uint8 type,
     if (is_32bit_type(type))
         return true;
 
-    if (ctx->p_code_compiled == NULL) {
-        if (!check_offset_push(ctx, error_buf, error_buf_size))
-            return false;
-    }
+    cell_num_to_push = wasm_value_type_cell_num(type) - 1;
+    for (i = 0; i < cell_num_to_push; i++) {
+        if (ctx->p_code_compiled == NULL) {
+            if (!check_offset_push(ctx, error_buf, error_buf_size))
+                return false;
+        }
 
-    ctx->frame_offset++;
-    if (!disable_emit) {
-        ctx->dynamic_offset++;
-        if (ctx->dynamic_offset > ctx->max_dynamic_offset) {
-            ctx->max_dynamic_offset = ctx->dynamic_offset;
-            bh_assert(ctx->max_dynamic_offset < INT16_MAX);
+        ctx->frame_offset++;
+        if (!disable_emit) {
+            ctx->dynamic_offset++;
+            if (ctx->dynamic_offset > ctx->max_dynamic_offset) {
+                ctx->max_dynamic_offset = ctx->dynamic_offset;
+                bh_assert(ctx->max_dynamic_offset < INT16_MAX);
+            }
         }
     }
+
     return true;
 }
 
@@ -6818,7 +6829,7 @@ re_scan:
 
                 CHECK_BUF(p, p_end, 1);
                 ref_type = read_uint8(p);
-                if (!is_valid_value_type(ref_type)) {
+                if (!is_valid_value_type_for_interpreter(ref_type)) {
                     set_error_buf(error_buf, error_buf_size,
                                   "unknown value type");
                     goto fail;

+ 2 - 1
core/iwasm/libraries/wasi-nn/test/requirements.txt

@@ -1 +1,2 @@
-tensorflow==2.11.1
+tensorflow==2.11.1
+numpy==1.26.4

+ 1 - 1
test-tools/aot-analyzer/CMakeLists.txt

@@ -85,4 +85,4 @@ include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
 
 add_executable (aot-analyzer src/main.cc src/aot_file.cc src/binary_file.cc src/option_parser.cc src/wasm_file.cc ${UNCOMMON_SHARED_SOURCE})
 
-target_link_libraries (aot-analyzer vmlib -lm -ldl -lpthread -lrt)
+target_link_libraries (aot-analyzer vmlib -lm -ldl -lpthread)

+ 14 - 12
test-tools/aot-analyzer/src/main.cc

@@ -169,8 +169,8 @@ DumpInfo(AoTFile *aot)
            aot->GetExectuionMachineName(target_info.e_machine).c_str());
     printf("Exectuion version: %u\n", target_info.e_version);
     printf("Exectuion flags: %u\n", target_info.e_flags);
-    printf("Feature flags: %ld\n", target_info.feature_flags);
-    printf("Reserved: %ld\n", target_info.reserved);
+    printf("Feature flags: %" PRId64 "\n", target_info.feature_flags);
+    printf("Reserved: %" PRId64 "\n", target_info.reserved);
     printf("Arch: %s\n", target_info.arch);
 }
 
@@ -272,8 +272,8 @@ DumpDetails(AoTFile *aot)
         AOTImportMemory memory = import_memories[index];
         printf("    -[%u] num_bytes_per_page:%5u    init_page_count:%5u    "
                "max_page_count:%5u    module_name: %s    memory_name: %s\n",
-               index, memory.memory.num_bytes_per_page,
-               memory.memory.init_page_count, memory.memory.max_page_count,
+               index, memory.mem_type.num_bytes_per_page,
+               memory.mem_type.init_page_count, memory.mem_type.max_page_count,
                memory.module_name, memory.memory_name);
     }
     printf("\n");
@@ -285,14 +285,15 @@ DumpDetails(AoTFile *aot)
         printf("    -[%u] ", index);
         printf("elem_type: ");
 #if WASM_ENABLE_GC != 0
-        wasm_dump_value_type(table.elem_type, table.elem_ref_type);
+        wasm_dump_value_type(table.table_type.elem_type,
+                             table.table_type.elem_ref_type);
 #else
-        dump_value_type(table.elem_type);
+        dump_value_type(table.table_type.elem_type);
 #endif
         printf("    init_size:%5u    max_size:%5u    "
                "module_name: %s    table_name: %s\n",
                table.table_type.init_size, table.table_type.max_size,
-               table.module_name, table.table_type.name);
+               table.module_name, table.table_name);
     }
     printf("\n");
 
@@ -302,7 +303,7 @@ DumpDetails(AoTFile *aot)
         AOTImportGlobal global = import_globals[index];
         printf("    -[%u] ", index);
         printf("type: ");
-        dump_value_type(global.type);
+        dump_value_type(global.type.val_type);
         printf("    module_name: %s    global_name: %s\n", global.module_name,
                global.global_name);
     }
@@ -348,9 +349,10 @@ DumpDetails(AoTFile *aot)
         printf("  -[%u] ", index);
         printf("elem_type: ");
 #if WASM_ENABLE_GC != 0
-        wasm_dump_value_type(table.elem_type, table.elem_ref_type);
+        wasm_dump_value_type(table.table_type.elem_type,
+                             table.table_type.elem_ref_type);
 #else
-        dump_value_type(table.elem_type);
+        dump_value_type(table.table_type.elem_type);
 #endif
         printf("    init_size:%5u    max_size:%5u\n",
                table.table_type.init_size, table.table_type.max_size);
@@ -382,9 +384,9 @@ DumpDetails(AoTFile *aot)
         AOTGlobal global = globals[index];
         printf("  -[%u] ", index);
         printf("type: ");
-        dump_value_type(global.type);
+        dump_value_type(global.type.val_type);
         printf("    is_mutable: %d    size: %u    data_offset: %u\n",
-               global.is_mutable, global.size, global.data_offset);
+               global.type.is_mutable, global.size, global.data_offset);
     }
     printf("\n\n");
 

+ 7 - 3
tests/fuzz/wasm-mutator-fuzz/CMakeLists.txt

@@ -3,13 +3,17 @@
 
 cmake_minimum_required (VERSION 2.8)
 
+if (NOT DEFINED CMAKE_C_COMPILER)
+set (CMAKE_C_COMPILER "clang")
+endif ()
+if (NOT DEFINED CMAKE_CXX_COMPILER)
+set (CMAKE_CXX_COMPILER "clang++")
+endif ()
+
 project(wasm_mutator)
 
 set (CMAKE_BUILD_TYPE Debug)
 
-set (CMAKE_C_COMPILER "clang")
-set (CMAKE_CXX_COMPILER "clang++")
-
 string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
 
 # Reset default linker flags

+ 3 - 3
wamr-compiler/main.c

@@ -160,9 +160,9 @@ print_help()
     printf("  --enable-dump-call-stack  Enable stack trace feature\n");
     printf("  --enable-perf-profiling   Enable function performance profiling\n");
     printf("  --enable-memory-profiling Enable memory usage profiling\n");
-    printf("  --xip                     A shorthand of --enalbe-indirect-mode --disable-llvm-intrinsics\n");
-    printf("  --enable-indirect-mode    Enalbe call function through symbol table but not direct call\n");
-    printf("  --enable-gc               Enalbe GC (Garbage Collection) feature\n");
+    printf("  --xip                     A shorthand of --enable-indirect-mode --disable-llvm-intrinsics\n");
+    printf("  --enable-indirect-mode    Enable call function through symbol table but not direct call\n");
+    printf("  --enable-gc               Enable GC (Garbage Collection) feature\n");
     printf("  --disable-llvm-intrinsics Disable the LLVM built-in intrinsics\n");
     printf("  --enable-builtin-intrinsics=<flags>\n");
     printf("                            Enable the specified built-in intrinsics, it will override the default\n");