Browse Source

Merge branch main into dev/gc_refactor

Wenyong Huang 2 năm trước cách đây
mục cha
commit
348d82b923
45 tập tin đã thay đổi với 881 bổ sung436 xóa
  1. 31 9
      .github/workflows/nightly_run.yml
  2. 0 23
      CMakeLists.txt
  3. 2 0
      README.md
  4. 53 37
      core/iwasm/aot/aot_runtime.c
  5. 1 4
      core/iwasm/common/wasm_application.c
  6. 72 30
      core/iwasm/common/wasm_memory.c
  7. 4 0
      core/iwasm/common/wasm_memory.h
  8. 1 2
      core/iwasm/common/wasm_native.c
  9. 83 6
      core/iwasm/common/wasm_runtime_common.c
  10. 55 45
      core/iwasm/common/wasm_runtime_common.h
  11. 25 52
      core/iwasm/common/wasm_shared_memory.c
  12. 23 10
      core/iwasm/common/wasm_shared_memory.h
  13. 14 2
      core/iwasm/compilation/aot_emit_control.c
  14. 4 1
      core/iwasm/compilation/aot_emit_memory.c
  15. 14 18
      core/iwasm/compilation/aot_emit_numberic.c
  16. 15 10
      core/iwasm/compilation/aot_llvm_extra.cpp
  17. 10 10
      core/iwasm/compilation/simd/simd_bit_shifts.c
  18. 2 2
      core/iwasm/fast-jit/fe/jit_emit_compare.c
  19. 1 1
      core/iwasm/fast-jit/fe/jit_emit_control.c
  20. 49 0
      core/iwasm/fast-jit/fe/jit_emit_conversion.c
  21. 1 0
      core/iwasm/include/wasm_export.h
  22. 6 4
      core/iwasm/interpreter/wasm_interp_classic.c
  23. 21 6
      core/iwasm/interpreter/wasm_interp_fast.c
  24. 45 33
      core/iwasm/interpreter/wasm_loader.c
  25. 35 32
      core/iwasm/interpreter/wasm_mini_loader.c
  26. 48 37
      core/iwasm/interpreter/wasm_runtime.c
  27. 4 1
      core/iwasm/interpreter/wasm_runtime.h
  28. 2 2
      core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c
  29. 2 2
      core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h
  30. 18 8
      core/shared/platform/common/posix/posix_thread.c
  31. 60 0
      core/shared/utils/bh_atomic.h
  32. 1 1
      language-bindings/go/go.mod
  33. 3 11
      language-bindings/go/samples/build.sh
  34. 1 1
      language-bindings/go/samples/test.go
  35. 2 0
      language-bindings/go/wamr/instance.go
  36. 56 6
      product-mini/platforms/posix/main.c
  37. 38 4
      product-mini/platforms/windows/main.c
  38. 8 8
      samples/gui/wasm-apps/decrease/src/main.c
  39. 8 8
      samples/gui/wasm-apps/increase/src/main.c
  40. 3 2
      samples/multi-module/src/main.c
  41. 36 1
      tests/wamr-compiler/test_shift_negative_constants.wat
  42. 0 0
      tests/wamr-test-suites/spec-test-script/multi_module_aot_ignore_cases.patch
  43. 11 5
      tests/wamr-test-suites/test_wamr.sh
  44. 11 0
      tests/wamr-test-suites/tsan_suppressions.txt
  45. 2 2
      tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh

+ 31 - 9
.github/workflows/nightly_run.yml

@@ -49,10 +49,17 @@ jobs:
     with:
       os: "ubuntu-20.04"
       arch: "X86"
+  build_llvm_libraries_on_ubuntu_2204:
+    uses: ./.github/workflows/build_llvm_libraries.yml
+    with:
+      os: "ubuntu-22.04"
+      arch: "X86"
   
   build_wamrc:
     needs:
-      [build_llvm_libraries_on_ubuntu_2004]
+      [
+        build_llvm_libraries_on_ubuntu_2004,
+      ]
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
@@ -90,7 +97,9 @@ jobs:
 
   build_iwasm:
     needs:
-      [build_llvm_libraries_on_ubuntu_2004]
+      [
+        build_llvm_libraries_on_ubuntu_2004,
+      ]
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
@@ -497,14 +506,15 @@ jobs:
       [
         build_iwasm,
         build_llvm_libraries_on_ubuntu_2004,
+        build_llvm_libraries_on_ubuntu_2204,
         build_wamrc,
       ]
     runs-on: ${{ matrix.os }}
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-20.04]
-        sanitizer: ["", "ubsan", "asan"]
+        os: [ubuntu-20.04, ubuntu-22.04]
+        sanitizer: ["", "ubsan", "asan", "tsan"]
         running_mode:
           [
             "classic-interp",
@@ -530,11 +540,14 @@ jobs:
           - os: ubuntu-20.04
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
             ubuntu_version: "20.04"
+          - os: ubuntu-22.04
+            llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
+            ubuntu_version: "22.04"
 
         exclude:
           # uncompatiable modes and features
           - os: ubuntu-20.04
-            sanitizer: asan
+            sanitizer: tsan
           # asan works only for aot now
           - running_mode: "classic-interp"
             sanitizer: asan
@@ -546,6 +559,14 @@ jobs:
             sanitizer: asan
           - running_mode: "multi-tier-jit"
             sanitizer: asan
+          - running_mode: "classic-interp"
+            sanitizer: tsan
+          - running_mode: "jit"
+            sanitizer: tsan
+          - running_mode: "fast-jit"
+            sanitizer: tsan
+          - running_mode: "multi-tier-jit"
+            sanitizer: tsan
           # classic-interp and fast-interp don't support simd
           - running_mode: "classic-interp"
             test_option: $SIMD_TEST_OPTIONS
@@ -595,9 +616,10 @@ jobs:
            || matrix.test_option == '$WASI_TEST_OPTIONS')
           && matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit'
         run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV
-      
-      - name: set sanitizer
-        run: echo "WAMR_BUILD_SANITIZER=${{ matrix.sanitizer }}" >> $GITHUB_ENV
+
+      - name: set additional tsan options
+        run: echo "TSAN_OPTIONS=suppressions=$PWD/tsan_suppressions.txt" >> $GITHUB_ENV
+        working-directory: tests/wamr-test-suites
 
       #only download llvm libraries in jit and aot mode
       - name: Get LLVM libraries
@@ -638,7 +660,7 @@ jobs:
 
       - name: run tests
         timeout-minutes: 40
-        run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
+        run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} -T %{{matrix.sanitizer}}
         working-directory: ./tests/wamr-test-suites
 
       #only install x32 support libraries when to run x86_32 cases

+ 0 - 23
CMakeLists.txt

@@ -107,11 +107,6 @@ endif ()
 
 set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
-# Set the strip command based on the system (GNU or Clang)
-if (CMAKE_STRIP)
-    set (CMAKE_STRIP_FLAGS "--strip-all")
-endif ()
-
 include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
 
 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security -Wshadow -Wno-unused-parameter")
@@ -146,15 +141,6 @@ endif ()
 
 install (TARGETS iwasm_static ARCHIVE DESTINATION lib)
 
-# If it's a Release build, strip the static library
-if (CMAKE_STRIP AND CMAKE_BUILD_TYPE STREQUAL "Release")
-  # Strip static library
-  message (STATUS "Stripping static library after build!")
-  add_custom_command (TARGET iwasm_static POST_BUILD
-      COMMAND ${CMAKE_STRIP} ${CMAKE_STRIP_FLAGS} $<TARGET_FILE:iwasm_static>
-  )
-endif ()
-
 # SHARED LIBRARY
 add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE})
 set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm)
@@ -176,12 +162,3 @@ install (FILES
     ${WAMR_ROOT_DIR}/core/iwasm/include/wasm_export.h
     ${WAMR_ROOT_DIR}/core/iwasm/include/lib_export.h
     DESTINATION include)
-
-# If it's a Release build, strip the shared library
-if (CMAKE_STRIP AND CMAKE_BUILD_TYPE STREQUAL "Release")
-  # Strip shared library
-  message (STATUS "Stripping shared library after build!")
-  add_custom_command (TARGET iwasm_shared POST_BUILD
-      COMMAND ${CMAKE_STRIP} ${CMAKE_STRIP_FLAGS} $<TARGET_FILE:iwasm_shared>
-  )
-endif ()

+ 2 - 0
README.md

@@ -92,8 +92,10 @@ The current TSC members:
 - [lum1n0us](https://github.com/lum1n0us) - **Liang He**, <liang.he@intel.com>
 - [no1wudi](https://github.com/no1wudi) **Qi Huang**, <huangqi3@xiaomi.com>
 - [qinxk-inter](https://github.com/qinxk-inter) - **Xiaokang Qin**, <xiaokang.qxk@antgroup.com>
+- [ttrenner ](https://github.com/ttrenner) - **Trenner, Thomas**, <trenner.thomas@siemens.com>
 - [wei-tang](https://github.com/wei-tang) - **Wei Tang**, <tangwei.tang@antgroup.com>
 - [wenyongh](https://github.com/wenyongh) - **Wenyong Huang**, <wenyong.huang@intel.com>
+- [woodsmc](https://github.com/woodsmc) - **Woods, Chris**, <chris.woods@siemens.com>
 - [xujuntwt95329](https://github.com/xujuntwt95329) - **Jun Xu**, <Jun1.Xu@intel.com>
 - [xwang98](https://github.com/xwang98) - **Xin Wang**, <xin.wang@intel.com> (chair)
 - [yamt](https://github.com/yamt) - **Takashi Yamamoto**, <yamamoto@midokura.com>

+ 53 - 37
core/iwasm/aot/aot_runtime.c

@@ -7,6 +7,7 @@
 #include "bh_log.h"
 #include "mem_alloc.h"
 #include "../common/wasm_runtime_common.h"
+#include "../common/wasm_memory.h"
 #include "../interpreter/wasm_runtime.h"
 #if WASM_ENABLE_SHARED_MEMORY != 0
 #include "../common/wasm_shared_memory.h"
@@ -423,7 +424,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
     uint32 inc_page_count, aux_heap_base, global_idx;
     uint32 bytes_of_last_page, bytes_to_page_end;
     uint32 heap_offset = num_bytes_per_page * init_page_count;
-    uint64 total_size;
+    uint64 memory_data_size, max_memory_data_size;
     uint8 *p = NULL, *global_addr;
 #ifdef OS_ENABLE_HW_BOUND_CHECK
     uint8 *mapped_mem;
@@ -537,23 +538,34 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
                 module->aux_stack_size);
     LOG_VERBOSE("  heap offset: %u, heap size: %d\n", heap_offset, heap_size);
 
-    total_size = (uint64)num_bytes_per_page * init_page_count;
+    memory_data_size = (uint64)num_bytes_per_page * init_page_count;
+    max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
+    bh_assert(memory_data_size <= UINT32_MAX);
+    bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB);
+    (void)max_memory_data_size;
+
+#ifndef OS_ENABLE_HW_BOUND_CHECK
 #if WASM_ENABLE_SHARED_MEMORY != 0
     if (is_shared_memory) {
-        /* Allocate max page for shared memory */
-        total_size = (uint64)num_bytes_per_page * max_page_count;
+        /* Allocate maximum memory size when memory is shared */
+        if (max_memory_data_size > 0
+            && !(p = runtime_malloc(max_memory_data_size, error_buf,
+                                    error_buf_size))) {
+            return NULL;
+        }
     }
+    else
 #endif
-    bh_assert(total_size <= UINT32_MAX);
-
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-    /* Allocate memory */
-    if (total_size > 0
-        && !(p = runtime_malloc(total_size, error_buf, error_buf_size))) {
-        return NULL;
+    {
+        /* Allocate initial memory size when memory is not shared */
+        if (memory_data_size > 0
+            && !(p = runtime_malloc(memory_data_size, error_buf,
+                                    error_buf_size))) {
+            return NULL;
+        }
     }
-#else
-    total_size = (total_size + page_size - 1) & ~(page_size - 1);
+#else /* else of OS_ENABLE_HW_BOUND_CHECK */
+    memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1);
 
     /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
      *   ea = i + memarg.offset
@@ -567,37 +579,39 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
     }
 
 #ifdef BH_PLATFORM_WINDOWS
-    if (!os_mem_commit(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) {
+    if (!os_mem_commit(p, memory_data_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) {
         set_error_buf(error_buf, error_buf_size, "commit memory failed");
         os_munmap(mapped_mem, map_size);
         return NULL;
     }
 #endif
 
-    if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
+    if (os_mprotect(p, memory_data_size, MMAP_PROT_READ | MMAP_PROT_WRITE)
+        != 0) {
         set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
 #ifdef BH_PLATFORM_WINDOWS
-        os_mem_decommit(p, total_size);
+        os_mem_decommit(p, memory_data_size);
 #endif
         os_munmap(mapped_mem, map_size);
         return NULL;
     }
+
     /* Newly allocated pages are filled with zero by the OS, we don't fill it
      * again here */
-#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
-    if (total_size > UINT32_MAX)
-        total_size = UINT32_MAX;
+    if (memory_data_size > UINT32_MAX)
+        memory_data_size = UINT32_MAX;
+#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
     memory_inst->module_type = Wasm_Module_AoT;
     memory_inst->num_bytes_per_page = num_bytes_per_page;
     memory_inst->cur_page_count = init_page_count;
     memory_inst->max_page_count = max_page_count;
-    memory_inst->memory_data_size = (uint32)total_size;
+    memory_inst->memory_data_size = (uint32)memory_data_size;
 
     /* Init memory info */
     memory_inst->memory_data = p;
-    memory_inst->memory_data_end = p + (uint32)total_size;
+    memory_inst->memory_data_end = p + (uint32)memory_data_size;
 
     /* Initialize heap info */
     memory_inst->heap_data = p + heap_offset;
@@ -620,24 +634,13 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
         }
     }
 
-    if (total_size > 0) {
-#if UINTPTR_MAX == UINT64_MAX
-        memory_inst->mem_bound_check_1byte.u64 = total_size - 1;
-        memory_inst->mem_bound_check_2bytes.u64 = total_size - 2;
-        memory_inst->mem_bound_check_4bytes.u64 = total_size - 4;
-        memory_inst->mem_bound_check_8bytes.u64 = total_size - 8;
-        memory_inst->mem_bound_check_16bytes.u64 = total_size - 16;
-#else
-        memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1;
-        memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2;
-        memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4;
-        memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
-        memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
-#endif
+    if (memory_data_size > 0) {
+        wasm_runtime_set_mem_bound_check_bytes(memory_inst, memory_data_size);
     }
 
 #if WASM_ENABLE_SHARED_MEMORY != 0
     if (is_shared_memory) {
+        memory_inst->is_shared_memory = true;
         memory_inst->ref_count = 1;
     }
 #endif
@@ -654,7 +657,7 @@ fail1:
 #else
 #ifdef BH_PLATFORM_WINDOWS
     if (memory_inst->memory_data)
-        os_mem_decommit(p, total_size);
+        os_mem_decommit(p, memory_data_size);
 #endif
     os_munmap(mapped_mem, map_size);
 #endif
@@ -714,6 +717,10 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
         if (data_seg->is_passive)
             continue;
 #endif
+        if (parent != NULL)
+            /* Ignore setting memory init data if the memory has been
+               initialized */
+            continue;
 
         bh_assert(data_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
                   || data_seg->offset.init_expr_type
@@ -2135,6 +2142,13 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
 
     if (ptr) {
         uint8 *addr = memory_inst->memory_data + ptr;
+        uint8 *memory_data_end;
+
+        /* memory->memory_data_end may be changed in memory grow */
+        SHARED_MEMORY_LOCK(memory_inst);
+        memory_data_end = memory_inst->memory_data_end;
+        SHARED_MEMORY_UNLOCK(memory_inst);
+
         if (memory_inst->heap_handle && memory_inst->heap_data < addr
             && addr < memory_inst->heap_data_end) {
             mem_allocator_free(memory_inst->heap_handle, addr);
@@ -2142,7 +2156,7 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
         else if (module->malloc_func_index != (uint32)-1
                  && module->free_func_index != (uint32)-1
                  && memory_inst->memory_data <= addr
-                 && addr < memory_inst->memory_data_end) {
+                 && addr < memory_data_end) {
             AOTFunctionInstance *free_func;
             char *free_func_name;
 
@@ -2544,7 +2558,9 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
     maddr = wasm_runtime_addr_app_to_native(
         (WASMModuleInstanceCommon *)module_inst, dst);
 
+    SHARED_MEMORY_LOCK(memory_inst);
     bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
+    SHARED_MEMORY_UNLOCK(memory_inst);
     return true;
 }
 

+ 1 - 4
core/iwasm/common/wasm_application.c

@@ -323,7 +323,6 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
 #endif
     int32 i, p, module_type;
     uint64 total_size;
-    const char *exception;
     char buf[128];
 
     bh_assert(argc >= 0);
@@ -795,9 +794,7 @@ fail:
     }
 #endif
 
-    exception = wasm_runtime_get_exception(module_inst);
-    bh_assert(exception);
-    os_printf("%s\n", exception);
+    bh_assert(wasm_runtime_get_exception(module_inst));
     return false;
 }
 

+ 72 - 30
core/iwasm/common/wasm_memory.c

@@ -298,10 +298,15 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
         goto fail;
     }
 
+    SHARED_MEMORY_LOCK(memory_inst);
+
     if (app_offset + size <= memory_inst->memory_data_size) {
+        SHARED_MEMORY_UNLOCK(memory_inst);
         return true;
     }
 
+    SHARED_MEMORY_UNLOCK(memory_inst);
+
 fail:
     wasm_set_exception(module_inst, "out of bounds memory access");
     return false;
@@ -364,11 +369,16 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
         goto fail;
     }
 
+    SHARED_MEMORY_LOCK(memory_inst);
+
     if (memory_inst->memory_data <= addr
         && addr + size <= memory_inst->memory_data_end) {
+        SHARED_MEMORY_UNLOCK(memory_inst);
         return true;
     }
 
+    SHARED_MEMORY_UNLOCK(memory_inst);
+
 fail:
     wasm_set_exception(module_inst, "out of bounds memory access");
     return false;
@@ -393,20 +403,24 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
         return NULL;
     }
 
+    SHARED_MEMORY_LOCK(memory_inst);
+
     addr = memory_inst->memory_data + app_offset;
 
     if (bounds_checks) {
         if (memory_inst->memory_data <= addr
             && addr < memory_inst->memory_data_end) {
-
+            SHARED_MEMORY_UNLOCK(memory_inst);
             return addr;
         }
     }
     /* If bounds checks is disabled, return the address directly */
     else if (app_offset != 0) {
+        SHARED_MEMORY_UNLOCK(memory_inst);
         return addr;
     }
 
+    SHARED_MEMORY_UNLOCK(memory_inst);
     return NULL;
 }
 
@@ -418,6 +432,7 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
     WASMMemoryInstance *memory_inst;
     uint8 *addr = (uint8 *)native_ptr;
     bool bounds_checks;
+    uint32 ret;
 
     bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
               || module_inst_comm->module_type == Wasm_Module_AoT);
@@ -429,16 +444,24 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
         return 0;
     }
 
+    SHARED_MEMORY_LOCK(memory_inst);
+
     if (bounds_checks) {
         if (memory_inst->memory_data <= addr
-            && addr < memory_inst->memory_data_end)
-            return (uint32)(addr - memory_inst->memory_data);
+            && addr < memory_inst->memory_data_end) {
+            ret = (uint32)(addr - memory_inst->memory_data);
+            SHARED_MEMORY_UNLOCK(memory_inst);
+            return ret;
+        }
     }
     /* If bounds checks is disabled, return the offset directly */
     else if (addr != NULL) {
-        return (uint32)(addr - memory_inst->memory_data);
+        ret = (uint32)(addr - memory_inst->memory_data);
+        SHARED_MEMORY_UNLOCK(memory_inst);
+        return ret;
     }
 
+    SHARED_MEMORY_UNLOCK(memory_inst);
     return 0;
 }
 
@@ -459,6 +482,8 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
         return false;
     }
 
+    SHARED_MEMORY_LOCK(memory_inst);
+
     memory_data_size = memory_inst->memory_data_size;
 
     if (app_offset < memory_data_size) {
@@ -466,9 +491,11 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
             *p_app_start_offset = 0;
         if (p_app_end_offset)
             *p_app_end_offset = memory_data_size;
+        SHARED_MEMORY_UNLOCK(memory_inst);
         return true;
     }
 
+    SHARED_MEMORY_UNLOCK(memory_inst);
     return false;
 }
 
@@ -490,15 +517,19 @@ wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst_comm,
         return false;
     }
 
+    SHARED_MEMORY_LOCK(memory_inst);
+
     if (memory_inst->memory_data <= addr
         && addr < memory_inst->memory_data_end) {
         if (p_native_start_addr)
             *p_native_start_addr = memory_inst->memory_data;
         if (p_native_end_addr)
             *p_native_end_addr = memory_inst->memory_data_end;
+        SHARED_MEMORY_UNLOCK(memory_inst);
         return true;
     }
 
+    SHARED_MEMORY_UNLOCK(memory_inst);
     return false;
 }
 
@@ -512,7 +543,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
     bool bounds_checks;
 
     if (!memory_inst) {
-        goto fail;
+        wasm_set_exception(module_inst, "out of bounds memory access");
+        return false;
     }
 
     native_addr = memory_inst->memory_data + app_buf_addr;
@@ -529,6 +561,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
     /* No need to check the app_offset and buf_size if memory access
        boundary check with hardware trap is enabled */
 #ifndef OS_ENABLE_HW_BOUND_CHECK
+    SHARED_MEMORY_LOCK(memory_inst);
+
     if (app_buf_addr >= memory_inst->memory_data_size) {
         goto fail;
     }
@@ -549,14 +583,20 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
         if (str == str_end)
             goto fail;
     }
+
+    SHARED_MEMORY_UNLOCK(memory_inst);
 #endif
 
 success:
     *p_native_addr = (void *)native_addr;
     return true;
+
+#ifndef OS_ENABLE_HW_BOUND_CHECK
 fail:
+    SHARED_MEMORY_UNLOCK(memory_inst);
     wasm_set_exception(module_inst, "out of bounds memory access");
     return false;
+#endif
 }
 
 WASMMemoryInstance *
@@ -568,6 +608,27 @@ wasm_get_default_memory(WASMModuleInstance *module_inst)
         return NULL;
 }
 
+void
+wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
+                                       uint64 memory_data_size)
+{
+#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
+#if UINTPTR_MAX == UINT64_MAX
+    memory->mem_bound_check_1byte.u64 = memory_data_size - 1;
+    memory->mem_bound_check_2bytes.u64 = memory_data_size - 2;
+    memory->mem_bound_check_4bytes.u64 = memory_data_size - 4;
+    memory->mem_bound_check_8bytes.u64 = memory_data_size - 8;
+    memory->mem_bound_check_16bytes.u64 = memory_data_size - 16;
+#else
+    memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1;
+    memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2;
+    memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4;
+    memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8;
+    memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16;
+#endif
+#endif
+}
+
 #ifndef OS_ENABLE_HW_BOUND_CHECK
 bool
 wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
@@ -625,9 +686,10 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
         memory->num_bytes_per_page = num_bytes_per_page;
         memory->cur_page_count = total_page_count;
         memory->max_page_count = max_page_count;
-        /* No need to update memory->memory_data_size as it is
-           initialized with the maximum memory data size for
-           shared memory */
+        memory->memory_data_size = (uint32)total_size_new;
+        memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
+
+        wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
         return true;
     }
 #endif
@@ -679,21 +741,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
     memory->memory_data = memory_data_new;
     memory->memory_data_end = memory_data_new + (uint32)total_size_new;
 
-#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
-#if UINTPTR_MAX == UINT64_MAX
-    memory->mem_bound_check_1byte.u64 = total_size_new - 1;
-    memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
-    memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
-    memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
-    memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
-#else
-    memory->mem_bound_check_1byte.u32[0] = (uint32)total_size_new - 1;
-    memory->mem_bound_check_2bytes.u32[0] = (uint32)total_size_new - 2;
-    memory->mem_bound_check_4bytes.u32[0] = (uint32)total_size_new - 4;
-    memory->mem_bound_check_8bytes.u32[0] = (uint32)total_size_new - 8;
-    memory->mem_bound_check_16bytes.u32[0] = (uint32)total_size_new - 16;
-#endif
-#endif
+    wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
 
 #if defined(os_writegsbase)
     /* write base addr of linear memory to GS segment register */
@@ -799,13 +847,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
     memory->memory_data_size = (uint32)total_size_new;
     memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
 
-#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
-    memory->mem_bound_check_1byte.u64 = total_size_new - 1;
-    memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
-    memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
-    memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
-    memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
-#endif
+    wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
 
 return_func:
     if (!ret && enlarge_memory_error_cb) {

+ 4 - 0
core/iwasm/common/wasm_memory.h

@@ -24,6 +24,10 @@ wasm_runtime_memory_destroy();
 unsigned
 wasm_runtime_memory_pool_size();
 
+void
+wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
+                                       uint64 memory_data_size);
+
 void
 wasm_runtime_set_enlarge_mem_error_callback(
     const enlarge_memory_error_callback_t callback, void *user_data);

+ 1 - 2
core/iwasm/common/wasm_native.c

@@ -553,8 +553,7 @@ void
 wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
                           WASIContext *wasi_ctx)
 {
-    return wasm_native_set_context(module_inst_comm, g_wasi_context_key,
-                                   wasi_ctx);
+    wasm_native_set_context(module_inst_comm, g_wasi_context_key, wasi_ctx);
 }
 
 static void

+ 83 - 6
core/iwasm/common/wasm_runtime_common.c

@@ -3063,8 +3063,83 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
             goto fail;
         }
 
-        fd_table_insert_existing(curfds, wasm_fd, raw_fd);
-        fd_prestats_insert(prestats, dir_list[i], wasm_fd);
+        if (!fd_table_insert_existing(curfds, wasm_fd, raw_fd)
+            || !fd_prestats_insert(prestats, dir_list[i], wasm_fd)) {
+            if (error_buf)
+                snprintf(
+                    error_buf, error_buf_size,
+                    "error while pre-opening directory %s: insertion failed\n",
+                    dir_list[i]);
+            goto fail;
+        }
+    }
+
+    for (i = 0; i < map_dir_count; i++, wasm_fd++) {
+        char mapping_copy_buf[256];
+        char *mapping_copy = mapping_copy_buf;
+        char *map_mapped = NULL, *map_host = NULL;
+        const unsigned long max_len = strlen(map_dir_list[i]) * 2 + 3;
+
+        /* Allocation limit for runtime environments with reduced stack size */
+        if (max_len > 256) {
+            if (!(mapping_copy = wasm_runtime_malloc(max_len))) {
+                snprintf(error_buf, error_buf_size,
+                         "error while allocating for directory mapping\n");
+                goto fail;
+            }
+        }
+
+        bh_memcpy_s(mapping_copy, max_len, map_dir_list[i],
+                    (uint32)(strlen(map_dir_list[i]) + 1));
+        map_mapped = strtok(mapping_copy, "::");
+        map_host = strtok(NULL, "::");
+
+        if (!map_mapped || !map_host) {
+            if (error_buf)
+                snprintf(error_buf, error_buf_size,
+                         "error while pre-opening mapped directory: "
+                         "invalid map\n");
+            if (mapping_copy != mapping_copy_buf)
+                wasm_runtime_free(mapping_copy);
+            goto fail;
+        }
+
+        path = realpath(map_host, resolved_path);
+        if (!path) {
+            if (error_buf)
+                snprintf(error_buf, error_buf_size,
+                         "error while pre-opening mapped directory %s: %d\n",
+                         map_host, errno);
+            if (mapping_copy != mapping_copy_buf)
+                wasm_runtime_free(mapping_copy);
+            goto fail;
+        }
+
+        raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
+        if (raw_fd == -1) {
+            if (error_buf)
+                snprintf(error_buf, error_buf_size,
+                         "error while pre-opening mapped directory %s: %d\n",
+                         map_host, errno);
+            if (mapping_copy != mapping_copy_buf)
+                wasm_runtime_free(mapping_copy);
+            goto fail;
+        }
+
+        if (!fd_table_insert_existing(curfds, wasm_fd, raw_fd)
+            || !fd_prestats_insert(prestats, map_mapped, wasm_fd)) {
+            if (error_buf)
+                snprintf(error_buf, error_buf_size,
+                         "error while pre-opening mapped directory %s: "
+                         "insertion failed\n",
+                         dir_list[i]);
+            if (mapping_copy != mapping_copy_buf)
+                wasm_runtime_free(mapping_copy);
+            goto fail;
+        }
+
+        if (mapping_copy != mapping_copy_buf)
+            wasm_runtime_free(mapping_copy);
     }
 
     /* addr_pool(textual) -> apool */
@@ -4541,10 +4616,12 @@ static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative;
           || defined(BUILD_TARGET_RISCV64_LP64) */
 #endif /* end of defined(_WIN32) || defined(_WIN32_) */
 
-/* ASAN is not designed to work with custom stack unwind or other low-level \
- things. > Ignore a function that does some low-level magic. (e.g. walking \
- through the thread's stack bypassing the frame boundaries) */
-#if defined(__GNUC__)
+/*
+ * ASAN is not designed to work with custom stack unwind or other low-level
+ * things. Ignore a function that does some low-level magic. (e.g. walking
+ * through the thread's stack bypassing the frame boundaries)
+ */
+#if defined(__GNUC__) || defined(__clang__)
 __attribute__((no_sanitize_address))
 #endif
 bool

+ 55 - 45
core/iwasm/common/wasm_runtime_common.h

@@ -15,6 +15,7 @@
 #if WASM_ENABLE_GC != 0
 #include "gc/gc_object.h"
 #endif
+
 #if WASM_ENABLE_LIBC_WASI != 0
 #if WASM_ENABLE_UVWASI == 0
 #include "wasmtime_ssp.h"
@@ -52,15 +53,16 @@ extern "C" {
 
 /* For STORE opcodes */
 #define STORE_I64 PUT_I64_TO_ADDR
-#define STORE_U32(addr, value)               \
-    do {                                     \
-        *(uint32 *)(addr) = (uint32)(value); \
-    } while (0)
-#define STORE_U16(addr, value)               \
-    do {                                     \
-        *(uint16 *)(addr) = (uint16)(value); \
-    } while (0)
-
+static inline void
+STORE_U32(void *addr, uint32_t value)
+{
+    *(uint32_t *)(addr) = (uint32_t)(value);
+}
+static inline void
+STORE_U16(void *addr, uint16_t value)
+{
+    *(uint16_t *)(addr) = (uint16_t)(value);
+}
 /* For LOAD opcodes */
 #define LOAD_I64(addr) (*(int64 *)(addr))
 #define LOAD_F64(addr) (*(float64 *)(addr))
@@ -189,42 +191,42 @@ GET_REF_FROM_ADDR(uint32 *addr)
         }                                           \
     } while (0)
 
-#define STORE_U32(addr, value)                    \
-    do {                                          \
-        uintptr_t addr_ = (uintptr_t)(addr);      \
-        union {                                   \
-            uint32 val;                           \
-            uint16 u16[2];                        \
-            uint8 u8[4];                          \
-        } u;                                      \
-        if ((addr_ & (uintptr_t)3) == 0)          \
-            *(uint32 *)(addr) = (uint32)(value);  \
-        else {                                    \
-            u.val = (uint32)(value);              \
-            if ((addr_ & (uintptr_t)1) == 0) {    \
-                ((uint16 *)(addr))[0] = u.u16[0]; \
-                ((uint16 *)(addr))[1] = u.u16[1]; \
-            }                                     \
-            else {                                \
-                ((uint8 *)(addr))[0] = u.u8[0];   \
-                ((uint8 *)(addr))[1] = u.u8[1];   \
-                ((uint8 *)(addr))[2] = u.u8[2];   \
-                ((uint8 *)(addr))[3] = u.u8[3];   \
-            }                                     \
-        }                                         \
-    } while (0)
-
-#define STORE_U16(addr, value)          \
-    do {                                \
-        union {                         \
-            uint16 val;                 \
-            uint8 u8[2];                \
-        } u;                            \
-        u.val = (uint16)(value);        \
-        ((uint8 *)(addr))[0] = u.u8[0]; \
-        ((uint8 *)(addr))[1] = u.u8[1]; \
-    } while (0)
-
+static inline void
+STORE_U32(void *addr, uint32_t value)
+{
+    uintptr_t addr_ = (uintptr_t)(addr);
+    union {
+        uint32_t val;
+        uint16_t u16[2];
+        uint8_t u8[4];
+    } u;
+    if ((addr_ & (uintptr_t)3) == 0)
+        *(uint32_t *)(addr) = (uint32_t)(value);
+    else {
+        u.val = (uint32_t)(value);
+        if ((addr_ & (uintptr_t)1) == 0) {
+            ((uint16_t *)(addr))[0] = u.u16[0];
+            ((uint16_t *)(addr))[1] = u.u16[1];
+        }
+        else {
+            ((uint8_t *)(addr))[0] = u.u8[0];
+            ((uint8_t *)(addr))[1] = u.u8[1];
+            ((uint8_t *)(addr))[2] = u.u8[2];
+            ((uint8_t *)(addr))[3] = u.u8[3];
+        }
+    }
+}
+static inline void
+STORE_U16(void *addr, uint16_t value)
+{
+    union {
+        uint16_t val;
+        uint8_t u8[2];
+    } u;
+    u.val = (uint16_t)(value);
+    ((uint8_t *)(addr))[0] = u.u8[0];
+    ((uint8_t *)(addr))[1] = u.u8[1];
+}
 /* For LOAD opcodes */
 static inline int64
 LOAD_I64(void *addr)
@@ -340,6 +342,14 @@ LOAD_I16(void *addr)
 
 #endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
 
+#if WASM_ENABLE_SHARED_MEMORY != 0
+#define SHARED_MEMORY_LOCK(memory) shared_memory_lock(memory)
+#define SHARED_MEMORY_UNLOCK(memory) shared_memory_unlock(memory)
+#else
+#define SHARED_MEMORY_LOCK(memory) (void)0
+#define SHARED_MEMORY_UNLOCK(memory) (void)0
+#endif
+
 typedef struct WASMModuleCommon {
     /* Module type, for module loaded from WASM bytecode binary,
        this field is Wasm_Module_Bytecode, and this structure should

+ 25 - 52
core/iwasm/common/wasm_shared_memory.c

@@ -18,7 +18,7 @@
  * - If you care performance, it's better to make the interpreters
  *   use atomic ops.
  */
-static korp_mutex _shared_memory_lock;
+korp_mutex g_shared_memory_lock;
 
 /* clang-format off */
 enum {
@@ -55,13 +55,13 @@ destroy_wait_info(void *wait_info);
 bool
 wasm_shared_memory_init()
 {
-    if (os_mutex_init(&_shared_memory_lock) != 0)
+    if (os_mutex_init(&g_shared_memory_lock) != 0)
         return false;
     /* wait map not exists, create new map */
     if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash,
                                         (KeyEqualFunc)wait_address_equal, NULL,
                                         destroy_wait_info))) {
-        os_mutex_destroy(&_shared_memory_lock);
+        os_mutex_destroy(&g_shared_memory_lock);
         return false;
     }
     return true;
@@ -71,79 +71,47 @@ void
 wasm_shared_memory_destroy()
 {
     bh_hash_map_destroy(wait_map);
-    os_mutex_destroy(&_shared_memory_lock);
+    os_mutex_destroy(&g_shared_memory_lock);
 }
 
-uint32
+uint16
 shared_memory_inc_reference(WASMMemoryInstance *memory)
 {
     bh_assert(shared_memory_is_shared(memory));
-    uint32 old;
-#if BH_ATOMIC_32_IS_ATOMIC == 0
-    os_mutex_lock(&_shared_memory_lock);
+    uint16 old;
+#if BH_ATOMIC_16_IS_ATOMIC == 0
+    os_mutex_lock(&g_shared_memory_lock);
 #endif
-    old = BH_ATOMIC_32_FETCH_ADD(memory->ref_count, 1);
-#if BH_ATOMIC_32_IS_ATOMIC == 0
-    os_mutex_unlock(&_shared_memory_lock);
+    old = BH_ATOMIC_16_FETCH_ADD(memory->ref_count, 1);
+#if BH_ATOMIC_16_IS_ATOMIC == 0
+    os_mutex_unlock(&g_shared_memory_lock);
 #endif
     bh_assert(old >= 1);
-    bh_assert(old < UINT32_MAX);
+    bh_assert(old < UINT16_MAX);
     return old + 1;
 }
 
-uint32
+uint16
 shared_memory_dec_reference(WASMMemoryInstance *memory)
 {
     bh_assert(shared_memory_is_shared(memory));
-    uint32 old;
-#if BH_ATOMIC_32_IS_ATOMIC == 0
-    os_mutex_lock(&_shared_memory_lock);
+    uint16 old;
+#if BH_ATOMIC_16_IS_ATOMIC == 0
+    os_mutex_lock(&g_shared_memory_lock);
 #endif
-    old = BH_ATOMIC_32_FETCH_SUB(memory->ref_count, 1);
-#if BH_ATOMIC_32_IS_ATOMIC == 0
-    os_mutex_unlock(&_shared_memory_lock);
+    old = BH_ATOMIC_16_FETCH_SUB(memory->ref_count, 1);
+#if BH_ATOMIC_16_IS_ATOMIC == 0
+    os_mutex_unlock(&g_shared_memory_lock);
 #endif
     bh_assert(old > 0);
     return old - 1;
 }
 
-bool
-shared_memory_is_shared(WASMMemoryInstance *memory)
-{
-    uint32 old;
-#if BH_ATOMIC_32_IS_ATOMIC == 0
-    os_mutex_lock(&_shared_memory_lock);
-#endif
-    old = BH_ATOMIC_32_LOAD(memory->ref_count);
-#if BH_ATOMIC_32_IS_ATOMIC == 0
-    os_mutex_unlock(&_shared_memory_lock);
-#endif
-    return old > 0;
-}
-
 static korp_mutex *
 shared_memory_get_lock_pointer(WASMMemoryInstance *memory)
 {
     bh_assert(memory != NULL);
-    return &_shared_memory_lock;
-}
-
-void
-shared_memory_lock(WASMMemoryInstance *memory)
-{
-    /*
-     * Note: exception logic is currently abusing this lock.
-     * cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407
-     */
-    bh_assert(memory != NULL);
-    os_mutex_lock(&_shared_memory_lock);
-}
-
-void
-shared_memory_unlock(WASMMemoryInstance *memory)
-{
-    bh_assert(memory != NULL);
-    os_mutex_unlock(&_shared_memory_lock);
+    return &g_shared_memory_lock;
 }
 
 /* Atomics wait && notify APIs */
@@ -301,12 +269,15 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
         return -1;
     }
 
+    shared_memory_lock(module_inst->memories[0]);
     if ((uint8 *)address < module_inst->memories[0]->memory_data
         || (uint8 *)address + (wait64 ? 8 : 4)
                > module_inst->memories[0]->memory_data_end) {
+        shared_memory_unlock(module_inst->memories[0]);
         wasm_runtime_set_exception(module, "out of bounds memory access");
         return -1;
     }
+    shared_memory_unlock(module_inst->memories[0]);
 
 #if WASM_ENABLE_THREAD_MGR != 0
     exec_env =
@@ -423,9 +394,11 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
     bh_assert(module->module_type == Wasm_Module_Bytecode
               || module->module_type == Wasm_Module_AoT);
 
+    shared_memory_lock(module_inst->memories[0]);
     out_of_bounds =
         ((uint8 *)address < module_inst->memories[0]->memory_data
          || (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end);
+    shared_memory_unlock(module_inst->memories[0]);
 
     if (out_of_bounds) {
         wasm_runtime_set_exception(module, "out of bounds memory access");

+ 23 - 10
core/iwasm/common/wasm_shared_memory.h

@@ -14,26 +14,39 @@
 extern "C" {
 #endif
 
+extern korp_mutex g_shared_memory_lock;
+
 bool
 wasm_shared_memory_init();
 
 void
 wasm_shared_memory_destroy();
 
-uint32
+uint16
 shared_memory_inc_reference(WASMMemoryInstance *memory);
 
-uint32
+uint16
 shared_memory_dec_reference(WASMMemoryInstance *memory);
 
-bool
-shared_memory_is_shared(WASMMemoryInstance *memory);
-
-void
-shared_memory_lock(WASMMemoryInstance *memory);
-
-void
-shared_memory_unlock(WASMMemoryInstance *memory);
+#define shared_memory_is_shared(memory) memory->is_shared_memory
+
+#define shared_memory_lock(memory)                                            \
+    do {                                                                      \
+        /*                                                                    \
+         * Note: exception logic is currently abusing this lock.              \
+         * cf.                                                                \
+         * https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407 \
+         */                                                                   \
+        bh_assert(memory != NULL);                                            \
+        if (memory->is_shared_memory)                                         \
+            os_mutex_lock(&g_shared_memory_lock);                             \
+    } while (0)
+
+#define shared_memory_unlock(memory)                \
+    do {                                            \
+        if (memory->is_shared_memory)               \
+            os_mutex_unlock(&g_shared_memory_lock); \
+    } while (0)
 
 uint32
 wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,

+ 14 - 2
core/iwasm/compilation/aot_emit_control.c

@@ -396,7 +396,9 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
         for (i = 0; i < block->param_count; i++) {
             param_index = block->param_count - 1 - i;
             POP(value, block->param_types[param_index]);
-            ADD_TO_PARAM_PHIS(block, value, param_index);
+            if (block->llvm_entry_block)
+                /* Only add incoming phis if the entry block was created */
+                ADD_TO_PARAM_PHIS(block, value, param_index);
             if (block->label_type == LABEL_TYPE_IF
                 && !block->skip_wasm_code_else) {
                 if (block->llvm_else_block) {
@@ -421,7 +423,17 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
 
     /* Push param phis to the new block */
     for (i = 0; i < block->param_count; i++) {
-        PUSH(block->param_phis[i], block->param_types[i]);
+        if (block->llvm_entry_block)
+            /* Push param phis if the entry basic block was created */
+            PUSH(block->param_phis[i], block->param_types[i]);
+        else {
+            bh_assert(block->label_type == LABEL_TYPE_IF
+                      && block->llvm_else_block && block->else_param_phis
+                      && !block->skip_wasm_code_else);
+            /* Push else param phis if we start to translate the
+               else branch */
+            PUSH(block->else_param_phis[i], block->param_types[i]);
+        }
     }
 
     return true;

+ 4 - 1
core/iwasm/compilation/aot_emit_memory.c

@@ -157,7 +157,10 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 
         if (mem_offset + bytes <= mem_data_size) {
             /* inside memory space */
-            offset1 = I32_CONST((uint32)mem_offset);
+            if (comp_ctx->pointer_size == sizeof(uint64))
+                offset1 = I64_CONST((uint32)mem_offset);
+            else
+                offset1 = I32_CONST((uint32)mem_offset);
             CHECK_LLVM_CONST(offset1);
             if (!enable_segue) {
                 if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder,

+ 14 - 18
core/iwasm/compilation/aot_emit_numberic.c

@@ -171,15 +171,6 @@
         right = shift_count_mask;                                      \
     } while (0)
 
-static bool
-is_shift_count_mask_needed(AOTCompContext *comp_ctx, LLVMValueRef left,
-                           LLVMValueRef right)
-{
-    return (strcmp(comp_ctx->target_arch, "x86_64") != 0
-            && strcmp(comp_ctx->target_arch, "i386") != 0)
-           || (LLVMIsEfficientConstInt(left) && LLVMIsEfficientConstInt(right));
-}
-
 /* Call llvm constrained floating-point intrinsic */
 static LLVMValueRef
 call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
@@ -737,8 +728,7 @@ compile_int_shl(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
 {
     LLVMValueRef res;
 
-    if (is_shift_count_mask_needed(comp_ctx, left, right))
-        SHIFT_COUNT_MASK;
+    SHIFT_COUNT_MASK;
 
     /* Build shl */
     LLVM_BUILD_OP(Shl, left, right, res, "shl", NULL);
@@ -752,8 +742,7 @@ compile_int_shr_s(AOTCompContext *comp_ctx, LLVMValueRef left,
 {
     LLVMValueRef res;
 
-    if (is_shift_count_mask_needed(comp_ctx, left, right))
-        SHIFT_COUNT_MASK;
+    SHIFT_COUNT_MASK;
 
     /* Build shl */
     LLVM_BUILD_OP(AShr, left, right, res, "shr_s", NULL);
@@ -767,8 +756,7 @@ compile_int_shr_u(AOTCompContext *comp_ctx, LLVMValueRef left,
 {
     LLVMValueRef res;
 
-    if (is_shift_count_mask_needed(comp_ctx, left, right))
-        SHIFT_COUNT_MASK;
+    SHIFT_COUNT_MASK;
 
     /* Build shl */
     LLVM_BUILD_OP(LShr, left, right, res, "shr_u", NULL);
@@ -789,17 +777,25 @@ compile_int_rot(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
     if (IS_CONST_ZERO(right))
         return left;
 
-    /* Calculate (bits - shif_count) */
+    /* Calculate (bits - shift_count) */
     LLVM_BUILD_OP(Sub, is_i32 ? I32_32 : I64_64, right, bits_minus_shift_count,
                   "bits_minus_shift_count", NULL);
+    /* Calculate (bits - shift_count) & mask */
+    bits_minus_shift_count =
+        LLVMBuildAnd(comp_ctx->builder, bits_minus_shift_count,
+                     is_i32 ? I32_31 : I64_63, "bits_minus_shift_count_and");
+    if (!bits_minus_shift_count) {
+        aot_set_last_error("llvm build and failed.");
+        return NULL;
+    }
 
     if (is_rotl) {
-        /* left<<count | left>>(BITS-count) */
+        /* (left << count) | (left >> ((BITS - count) & mask)) */
         LLVM_BUILD_OP(Shl, left, right, tmp_l, "tmp_l", NULL);
         LLVM_BUILD_OP(LShr, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
     }
     else {
-        /* left>>count | left<<(BITS-count) */
+        /* (left >> count) | (left << ((BITS - count) & mask)) */
         LLVM_BUILD_OP(LShr, left, right, tmp_l, "tmp_l", NULL);
         LLVM_BUILD_OP(Shl, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
     }

+ 15 - 10
core/iwasm/compilation/aot_llvm_extra.cpp

@@ -343,18 +343,23 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
             ExitOnErr(PB.parsePassPipeline(MPM, comp_ctx->llvm_passes));
         }
 
-        if (!disable_llvm_lto) {
-            /* Apply LTO for AOT mode */
-            if (comp_ctx->comp_data->func_count >= 10
-                || comp_ctx->enable_llvm_pgo || comp_ctx->use_prof_file)
-                /* Add the pre-link optimizations if the func count
-                   is large enough or PGO is enabled */
-                MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(OL));
-            else
-                MPM.addPass(PB.buildLTODefaultPipeline(OL, NULL));
+        if (OptimizationLevel::O0 == OL) {
+            MPM.addPass(PB.buildO0DefaultPipeline(OL));
         }
         else {
-            MPM.addPass(PB.buildPerModuleDefaultPipeline(OL));
+            if (!disable_llvm_lto) {
+                /* Apply LTO for AOT mode */
+                if (comp_ctx->comp_data->func_count >= 10
+                    || comp_ctx->enable_llvm_pgo || comp_ctx->use_prof_file)
+                    /* Add the pre-link optimizations if the func count
+                       is large enough or PGO is enabled */
+                    MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(OL));
+                else
+                    MPM.addPass(PB.buildLTODefaultPipeline(OL, NULL));
+            }
+            else {
+                MPM.addPass(PB.buildPerModuleDefaultPipeline(OL));
+            }
         }
 
         /* Run specific passes for AOT indirect mode in last since general

+ 10 - 10
core/iwasm/compilation/simd/simd_bit_shifts.c

@@ -30,11 +30,11 @@ simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                             LLVM_CONST(i16x8_vec_zero),
                             LLVM_CONST(i32x4_vec_zero),
                             LLVM_CONST(i64x2_vec_zero) };
-    LLVMValueRef lane_bits[] = {
-        LLVM_CONST(i32_eight),
-        LLVMConstInt(I32_TYPE, 16, true),
-        LLVMConstInt(I32_TYPE, 32, true),
-        LLVMConstInt(I32_TYPE, 64, true),
+    LLVMValueRef lane_shift_masks[] = {
+        LLVMConstInt(I32_TYPE, 7, true),
+        LLVMConstInt(I32_TYPE, 15, true),
+        LLVMConstInt(I32_TYPE, 31, true),
+        LLVMConstInt(I32_TYPE, 63, true),
     };
 
     POP_I32(offset);
@@ -44,11 +44,11 @@ simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
         return false;
     }
 
-    /* offset mod LaneBits */
-    if (!lane_bits[itype]
-        || !(offset = LLVMBuildSRem(comp_ctx->builder, offset, lane_bits[itype],
-                                    "offset_fix"))) {
-        HANDLE_FAILURE("LLVMBuildSRem");
+    /* offset = offset & shift_mask */
+    if (!lane_shift_masks[itype]
+        || !(offset = LLVMBuildAnd(comp_ctx->builder, offset,
+                                   lane_shift_masks[itype], "offset_fix"))) {
+        HANDLE_FAILURE("LLVMBuildAnd");
         return false;
     }
 

+ 2 - 2
core/iwasm/fast-jit/fe/jit_emit_compare.c

@@ -227,7 +227,7 @@ jit_compile_op_f32_compare(JitCompContext *cc, FloatCond cond)
     POP_F32(rhs);
     POP_F32(lhs);
 
-    if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) {
+    if (jit_reg_is_const(lhs) && jit_reg_is_const(rhs)) {
         float32 lvalue = jit_cc_get_const_F32(cc, lhs);
         float32 rvalue = jit_cc_get_const_F32(cc, rhs);
 
@@ -290,7 +290,7 @@ jit_compile_op_f64_compare(JitCompContext *cc, FloatCond cond)
     POP_F64(rhs);
     POP_F64(lhs);
 
-    if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) {
+    if (jit_reg_is_const(lhs) && jit_reg_is_const(rhs)) {
         float64 lvalue = jit_cc_get_const_F64(cc, lhs);
         float64 rvalue = jit_cc_get_const_F64(cc, rhs);
 

+ 1 - 1
core/iwasm/fast-jit/fe/jit_emit_control.c

@@ -808,7 +808,7 @@ jit_compile_op_block(JitCompContext *cc, uint8 **p_frame_ip,
     else if (label_type == LABEL_TYPE_IF) {
         POP_I32(value);
 
-        if (!jit_reg_is_const_val(value)) {
+        if (!jit_reg_is_const(value)) {
             /* Compare value is not constant, create condition br IR */
 
             /* Create entry block */

+ 49 - 0
core/iwasm/fast-jit/fe/jit_emit_conversion.c

@@ -192,6 +192,55 @@ jit_compile_check_value_range(JitCompContext *cc, JitReg value, JitReg min_fp,
 
     bh_assert(JIT_REG_KIND_F32 == kind || JIT_REG_KIND_F64 == kind);
 
+    if (JIT_REG_KIND_F32 == kind && jit_reg_is_const(value)) {
+        /* value is an f32 const */
+        float value_f32_const = jit_cc_get_const_F32(cc, value);
+        float min_fp_f32_const = jit_cc_get_const_F32(cc, min_fp);
+        float max_fp_f32_const = jit_cc_get_const_F32(cc, max_fp);
+
+        if (isnan(value_f32_const)) {
+            /* throw exception if value is nan */
+            if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER,
+                                    JIT_OP_JMP, 0, NULL))
+                goto fail;
+        }
+
+        if (value_f32_const <= min_fp_f32_const
+            || value_f32_const >= max_fp_f32_const) {
+            /* throw exception if value is out of range */
+            if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_JMP, 0,
+                                    NULL))
+                goto fail;
+        }
+
+        /* value is in range, do nothing */
+        return true;
+    }
+    else if (JIT_REG_KIND_F64 == kind && jit_reg_is_const(value)) {
+        /* value is an f64 const */
+        double value_f64_const = jit_cc_get_const_F64(cc, value);
+        double min_fp_f64_const = jit_cc_get_const_F64(cc, min_fp);
+        double max_fp_f64_const = jit_cc_get_const_F64(cc, max_fp);
+
+        if (isnan(value_f64_const)) {
+            /* throw exception if value is nan */
+            if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER,
+                                    JIT_OP_JMP, 0, NULL))
+                goto fail;
+        }
+
+        if (value_f64_const <= min_fp_f64_const
+            || value_f64_const >= max_fp_f64_const) {
+            /* throw exception if value is out of range */
+            if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_JMP, 0,
+                                    NULL))
+                goto fail;
+        }
+
+        /* value is in range, do nothing */
+        return true;
+    }
+
     /* If value is NaN, throw exception */
     if (JIT_REG_KIND_F32 == kind)
         emit_ret = jit_emit_callnative(cc, local_isnanf, nan_ret, &value, 1);

+ 1 - 0
core/iwasm/include/wasm_export.h

@@ -426,6 +426,7 @@ wasm_runtime_get_module_hash(wasm_module_t module);
  * @param dir_list      The list of directories to preopen. (real path)
  * @param dir_count     The number of elements in dir_list.
  * @param map_dir_list  The list of directories to preopen. (mapped path)
+ *                      Format for each map entry: <guest-path>::<host-path>
  * @param map_dir_count The number of elements in map_dir_list.
  *                      If map_dir_count is smaller than dir_count,
  *                      mapped path is assumed to be same as the

+ 6 - 4
core/iwasm/interpreter/wasm_interp_classic.c

@@ -5885,10 +5885,12 @@ wasm_interp_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap)
 #endif
 
 #if WASM_ENABLE_FAST_JIT != 0
-/* ASAN is not designed to work with custom stack unwind or other low-level \
- things. > Ignore a function that does some low-level magic. (e.g. walking \
- through the thread's stack bypassing the frame boundaries) */
-#if defined(__GNUC__)
+/*
+ * ASAN is not designed to work with custom stack unwind or other low-level
+ * things. Ignore a function that does some low-level magic. (e.g. walking
+ * through the thread's stack bypassing the frame boundaries)
+ */
+#if defined(__GNUC__) || defined(__clang__)
 __attribute__((no_sanitize_address))
 #endif
 static void

+ 21 - 6
core/iwasm/interpreter/wasm_interp_fast.c

@@ -1390,12 +1390,27 @@ wasm_interp_dump_op_count()
         goto *p_label_addr;                            \
     } while (0)
 #else
-#define FETCH_OPCODE_AND_DISPATCH()                                 \
-    do {                                                            \
-        const void *p_label_addr = label_base + *(int16 *)frame_ip; \
-        frame_ip += sizeof(int16);                                  \
-        goto *p_label_addr;                                         \
+#if UINTPTR_MAX == UINT64_MAX
+#define FETCH_OPCODE_AND_DISPATCH()                                       \
+    do {                                                                  \
+        const void *p_label_addr;                                         \
+        bh_assert(((uintptr_t)frame_ip & 1) == 0);                        \
+        /* int32 relative offset was emitted in 64-bit target */          \
+        p_label_addr = label_base + (int32)LOAD_U32_WITH_2U16S(frame_ip); \
+        frame_ip += sizeof(int32);                                        \
+        goto *p_label_addr;                                               \
     } while (0)
+#else
+#define FETCH_OPCODE_AND_DISPATCH()                                      \
+    do {                                                                 \
+        const void *p_label_addr;                                        \
+        bh_assert(((uintptr_t)frame_ip & 1) == 0);                       \
+        /* uint32 label address was emitted in 32-bit target */          \
+        p_label_addr = (void *)(uintptr_t)LOAD_U32_WITH_2U16S(frame_ip); \
+        frame_ip += sizeof(int32);                                       \
+        goto *p_label_addr;                                              \
+    } while (0)
+#endif
 #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
 #define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
 
@@ -1445,7 +1460,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
     register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
     register uint32 *frame_lp = NULL;          /* cache of frame->lp */
 #if WASM_ENABLE_LABELS_AS_VALUES != 0
-#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
+#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 && UINTPTR_MAX == UINT64_MAX
     /* cache of label base addr */
     register uint8 *label_base = &&HANDLE_WASM_OP_UNREACHABLE;
 #endif

+ 45 - 33
core/iwasm/interpreter/wasm_loader.c

@@ -2309,7 +2309,15 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
         return false;
     }
     if (memory->flags > 1) {
-        set_error_buf(error_buf, error_buf_size, "integer too large");
+        if (memory->flags & 2) {
+            set_error_buf(error_buf, error_buf_size,
+                          "shared memory flag was found, "
+                          "please enable shared memory, lib-pthread "
+                          "or lib-wasi-threads");
+        }
+        else {
+            set_error_buf(error_buf, error_buf_size, "invalid memory flags");
+        }
         return false;
     }
 #else
@@ -7249,21 +7257,27 @@ fail:
         LOG_OP("\ndelete last op\n");                           \
     } while (0)
 #else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
+#if UINTPTR_MAX == UINT64_MAX
 #define emit_label(opcode)                                                     \
     do {                                                                       \
         int32 offset =                                                         \
             (int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \
-        if (!(offset >= INT16_MIN && offset < INT16_MAX)) {                    \
-            set_error_buf(error_buf, error_buf_size,                           \
-                          "pre-compiled label offset out of range");           \
-            goto fail;                                                         \
-        }                                                                      \
-        wasm_loader_emit_int16(loader_ctx, offset);                            \
+        /* emit int32 relative offset in 64-bit target */                      \
+        wasm_loader_emit_uint32(loader_ctx, offset);                           \
         LOG_OP("\nemit_op [%02x]\t", opcode);                                  \
     } while (0)
+#else
+#define emit_label(opcode)                                           \
+    do {                                                             \
+        uint32 label_addr = (uint32)(uintptr_t)handle_table[opcode]; \
+        /* emit uint32 label address in 32-bit target */             \
+        wasm_loader_emit_uint32(loader_ctx, label_addr);             \
+        LOG_OP("\nemit_op [%02x]\t", opcode);                        \
+    } while (0)
+#endif
 #define skip_label()                                           \
     do {                                                       \
-        wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); \
+        wasm_loader_emit_backspace(loader_ctx, sizeof(int32)); \
         LOG_OP("\ndelete last op\n");                          \
     } while (0)
 #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
@@ -7600,12 +7614,6 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
     (void)error_buf;
     (void)error_buf_size;
     return true;
-#if WASM_ENABLE_LABELS_AS_VALUES != 0
-#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
-fail:
-    return false;
-#endif
-#endif
 }
 
 static bool
@@ -10131,6 +10139,9 @@ re_scan:
                 uint8 ref_type;
                 BranchBlock *cur_block = loader_ctx->frame_csp - 1;
                 int32 available_stack_cell;
+#if WASM_ENABLE_FAST_INTERP != 0
+                uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
+#endif
 
                 POP_I32();
 
@@ -10159,26 +10170,26 @@ re_scan:
 #if WASM_ENABLE_FAST_INTERP != 0
                             if (loader_ctx->p_code_compiled) {
                                 uint8 opcode_tmp = WASM_OP_SELECT_64;
-                                uint8 *p_code_compiled_tmp =
-                                    loader_ctx->p_code_compiled - 2;
 #if WASM_ENABLE_LABELS_AS_VALUES != 0
 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
                                 *(void **)(p_code_compiled_tmp
                                            - sizeof(void *)) =
                                     handle_table[opcode_tmp];
 #else
+#if UINTPTR_MAX == UINT64_MAX
+                                /* emit int32 relative offset in 64-bit target
+                                 */
                                 int32 offset =
                                     (int32)((uint8 *)handle_table[opcode_tmp]
                                             - (uint8 *)handle_table[0]);
-                                if (!(offset >= INT16_MIN
-                                      && offset < INT16_MAX)) {
-                                    set_error_buf(error_buf, error_buf_size,
-                                                  "pre-compiled label offset "
-                                                  "out of range");
-                                    goto fail;
-                                }
-                                *(int16 *)(p_code_compiled_tmp
-                                           - sizeof(int16)) = (int16)offset;
+                                *(int32 *)(p_code_compiled_tmp
+                                           - sizeof(int32)) = offset;
+#else
+                                /* emit uint32 label address in 32-bit target */
+                                *(uint32 *)(p_code_compiled_tmp
+                                            - sizeof(uint32)) =
+                                    (uint32)(uintptr_t)handle_table[opcode_tmp];
+#endif
 #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
 #else  /* else of WASM_ENABLE_LABELS_AS_VALUES */
 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
@@ -10307,16 +10318,17 @@ re_scan:
                         *(void **)(p_code_compiled_tmp - sizeof(void *)) =
                             handle_table[opcode_tmp];
 #else
+#if UINTPTR_MAX == UINT64_MAX
+                        /* emit int32 relative offset in 64-bit target */
                         int32 offset = (int32)((uint8 *)handle_table[opcode_tmp]
                                                - (uint8 *)handle_table[0]);
-                        if (!(offset >= INT16_MIN && offset < INT16_MAX)) {
-                            set_error_buf(
-                                error_buf, error_buf_size,
-                                "pre-compiled label offset out of range");
-                            goto fail;
-                        }
-                        *(int16 *)(p_code_compiled_tmp - sizeof(int16)) =
-                            (int16)offset;
+                        *(int32 *)(p_code_compiled_tmp - sizeof(int32)) =
+                            offset;
+#else
+                        /* emit uint32 label address in 32-bit target */
+                        *(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) =
+                            (uint32)(uintptr_t)handle_table[opcode_tmp];
+#endif
 #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
 #else  /* else of WASM_ENABLE_LABELS_AS_VALUES */
 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0

+ 35 - 32
core/iwasm/interpreter/wasm_mini_loader.c

@@ -4018,21 +4018,27 @@ wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf,
         LOG_OP("\ndelete last op\n");                           \
     } while (0)
 #else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
+#if UINTPTR_MAX == UINT64_MAX
 #define emit_label(opcode)                                                     \
     do {                                                                       \
         int32 offset =                                                         \
             (int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \
-        if (!(offset >= INT16_MIN && offset < INT16_MAX)) {                    \
-            set_error_buf(error_buf, error_buf_size,                           \
-                          "pre-compiled label offset out of range");           \
-            goto fail;                                                         \
-        }                                                                      \
-        wasm_loader_emit_int16(loader_ctx, offset);                            \
+        /* emit int32 relative offset in 64-bit target */                      \
+        wasm_loader_emit_uint32(loader_ctx, offset);                           \
         LOG_OP("\nemit_op [%02x]\t", opcode);                                  \
     } while (0)
+#else
+#define emit_label(opcode)                                           \
+    do {                                                             \
+        uint32 label_addr = (uint32)(uintptr_t)handle_table[opcode]; \
+        /* emit uint32 label address in 32-bit target */             \
+        wasm_loader_emit_uint32(loader_ctx, label_addr);             \
+        LOG_OP("\nemit_op [%02x]\t", opcode);                        \
+    } while (0)
+#endif
 #define skip_label()                                           \
     do {                                                       \
-        wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); \
+        wasm_loader_emit_backspace(loader_ctx, sizeof(int32)); \
         LOG_OP("\ndelete last op\n");                          \
     } while (0)
 #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
@@ -4360,13 +4366,6 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
     }
 
     return true;
-
-#if WASM_ENABLE_LABELS_AS_VALUES != 0
-#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
-fail:
-    return false;
-#endif
-#endif
 }
 
 static bool
@@ -6164,6 +6163,9 @@ re_scan:
                 uint8 ref_type;
                 BranchBlock *cur_block = loader_ctx->frame_csp - 1;
                 int32 available_stack_cell;
+#if WASM_ENABLE_FAST_INTERP != 0
+                uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
+#endif
 
                 POP_I32();
 
@@ -6186,26 +6188,26 @@ re_scan:
 #if WASM_ENABLE_FAST_INTERP != 0
                             if (loader_ctx->p_code_compiled) {
                                 uint8 opcode_tmp = WASM_OP_SELECT_64;
-                                uint8 *p_code_compiled_tmp =
-                                    loader_ctx->p_code_compiled - 2;
 #if WASM_ENABLE_LABELS_AS_VALUES != 0
 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
                                 *(void **)(p_code_compiled_tmp
                                            - sizeof(void *)) =
                                     handle_table[opcode_tmp];
 #else
+#if UINTPTR_MAX == UINT64_MAX
+                                /* emit int32 relative offset in 64-bit target
+                                 */
                                 int32 offset =
                                     (int32)((uint8 *)handle_table[opcode_tmp]
                                             - (uint8 *)handle_table[0]);
-                                if (!(offset >= INT16_MIN
-                                      && offset < INT16_MAX)) {
-                                    set_error_buf(error_buf, error_buf_size,
-                                                  "pre-compiled label offset "
-                                                  "out of range");
-                                    goto fail;
-                                }
-                                *(int16 *)(p_code_compiled_tmp
-                                           - sizeof(int16)) = (int16)offset;
+                                *(int32 *)(p_code_compiled_tmp
+                                           - sizeof(int32)) = offset;
+#else
+                                /* emit uint32 label address in 32-bit target */
+                                *(uint32 *)(p_code_compiled_tmp
+                                            - sizeof(uint32)) =
+                                    (uint32)(uintptr_t)handle_table[opcode_tmp];
+#endif
 #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
 #else  /* else of WASM_ENABLE_LABELS_AS_VALUES */
 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
@@ -6281,15 +6283,16 @@ re_scan:
                     *(void **)(p_code_compiled_tmp - sizeof(void *)) =
                         handle_table[opcode_tmp];
 #else
+#if UINTPTR_MAX == UINT64_MAX
+                    /* emit int32 relative offset in 64-bit target */
                     int32 offset = (int32)((uint8 *)handle_table[opcode_tmp]
                                            - (uint8 *)handle_table[0]);
-                    if (!(offset >= INT16_MIN && offset < INT16_MAX)) {
-                        set_error_buf(error_buf, error_buf_size,
-                                      "pre-compiled label offset out of range");
-                        goto fail;
-                    }
-                    *(int16 *)(p_code_compiled_tmp - sizeof(int16)) =
-                        (int16)offset;
+                    *(int32 *)(p_code_compiled_tmp - sizeof(int32)) = offset;
+#else
+                    /* emit uint32 label address in 32-bit target */
+                    *(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) =
+                        (uint32)(uintptr_t)handle_table[opcode_tmp];
+#endif
 #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
 #else  /* else of WASM_ENABLE_LABELS_AS_VALUES */
 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0

+ 48 - 37
core/iwasm/interpreter/wasm_runtime.c

@@ -10,6 +10,7 @@
 #include "bh_log.h"
 #include "mem_alloc.h"
 #include "../common/wasm_runtime_common.h"
+#include "../common/wasm_memory.h"
 #if WASM_ENABLE_GC != 0
 #include "../common/gc/gc_object.h"
 #endif
@@ -170,7 +171,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
                    char *error_buf, uint32 error_buf_size)
 {
     WASMModule *module = module_inst->module;
-    uint64 memory_data_size;
+    uint64 memory_data_size, max_memory_data_size;
     uint32 heap_offset = num_bytes_per_page * init_page_count;
     uint32 inc_page_count, aux_heap_base, global_idx;
     uint32 bytes_of_last_page, bytes_to_page_end;
@@ -285,22 +286,33 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
     LOG_VERBOSE("  heap offset: %u, heap size: %d\n", heap_offset, heap_size);
 
     memory_data_size = (uint64)num_bytes_per_page * init_page_count;
+    max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
+    bh_assert(memory_data_size <= UINT32_MAX);
+    bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB);
+    (void)max_memory_data_size;
+
+    bh_assert(memory != NULL);
+#ifndef OS_ENABLE_HW_BOUND_CHECK
 #if WASM_ENABLE_SHARED_MEMORY != 0
     if (is_shared_memory) {
-        /* Allocate max page for shared memory */
-        memory_data_size = (uint64)num_bytes_per_page * max_page_count;
+        /* Allocate maximum memory size when memory is shared */
+        if (max_memory_data_size > 0
+            && !(memory->memory_data = runtime_malloc(
+                     max_memory_data_size, error_buf, error_buf_size))) {
+            goto fail1;
+        }
     }
+    else
 #endif
-    bh_assert(memory_data_size <= 4 * (uint64)BH_GB);
-
-    bh_assert(memory != NULL);
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-    if (memory_data_size > 0
-        && !(memory->memory_data =
-                 runtime_malloc(memory_data_size, error_buf, error_buf_size))) {
-        goto fail1;
+    {
+        /* Allocate initial memory size when memory is not shared */
+        if (memory_data_size > 0
+            && !(memory->memory_data = runtime_malloc(
+                     memory_data_size, error_buf, error_buf_size))) {
+            goto fail1;
+        }
     }
-#else
+#else /* else of OS_ENABLE_HW_BOUND_CHECK */
     memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1);
 
     /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
@@ -329,12 +341,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
         set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
         goto fail2;
     }
+
     /* Newly allocated pages are filled with zero by the OS, we don't fill it
      * again here */
-#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
     if (memory_data_size > UINT32_MAX)
-        memory_data_size = (uint32)memory_data_size;
+        memory_data_size = UINT32_MAX;
+#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
     memory->module_type = Wasm_Module_Bytecode;
     memory->num_bytes_per_page = num_bytes_per_page;
@@ -362,26 +375,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
         }
     }
 
-#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0
     if (memory_data_size > 0) {
-#if UINTPTR_MAX == UINT64_MAX
-        memory->mem_bound_check_1byte.u64 = memory_data_size - 1;
-        memory->mem_bound_check_2bytes.u64 = memory_data_size - 2;
-        memory->mem_bound_check_4bytes.u64 = memory_data_size - 4;
-        memory->mem_bound_check_8bytes.u64 = memory_data_size - 8;
-        memory->mem_bound_check_16bytes.u64 = memory_data_size - 16;
-#else
-        memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1;
-        memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2;
-        memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4;
-        memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8;
-        memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16;
-#endif
+        wasm_runtime_set_mem_bound_check_bytes(memory, memory_data_size);
     }
-#endif
 
 #if WASM_ENABLE_SHARED_MEMORY != 0
     if (is_shared_memory) {
+        memory->is_shared_memory = true;
         memory->ref_count = 1;
     }
 #endif
@@ -2020,6 +2020,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
         if (data_seg->is_passive)
             continue;
 #endif
+        if (is_sub_inst)
+            /* Ignore setting memory init data if the memory has been
+               initialized */
+            continue;
 
         /* has check it in loader */
         memory = module_inst->memories[data_seg->memory_index];
@@ -2785,15 +2789,20 @@ void
 wasm_module_free_internal(WASMModuleInstance *module_inst,
                           WASMExecEnv *exec_env, uint32 ptr)
 {
-    if (ptr) {
-        WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
-        uint8 *addr;
+    WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
 
-        if (!memory) {
-            return;
-        }
+    if (!memory) {
+        return;
+    }
+
+    if (ptr) {
+        uint8 *addr = memory->memory_data + ptr;
+        uint8 *memory_data_end;
 
-        addr = memory->memory_data + ptr;
+        /* memory->memory_data_end may be changed in memory grow */
+        SHARED_MEMORY_LOCK(memory);
+        memory_data_end = memory->memory_data_end;
+        SHARED_MEMORY_UNLOCK(memory);
 
         if (memory->heap_handle && memory->heap_data <= addr
             && addr < memory->heap_data_end) {
@@ -2801,7 +2810,7 @@ wasm_module_free_internal(WASMModuleInstance *module_inst,
         }
         else if (module_inst->e->malloc_function
                  && module_inst->e->free_function && memory->memory_data <= addr
-                 && addr < memory->memory_data_end) {
+                 && addr < memory_data_end) {
             execute_free_function(module_inst, exec_env,
                                   module_inst->e->free_function, ptr);
         }
@@ -3523,7 +3532,9 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
     maddr = wasm_runtime_addr_app_to_native(
         (WASMModuleInstanceCommon *)module_inst, dst);
 
+    SHARED_MEMORY_LOCK(memory_inst);
     bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
+    SHARED_MEMORY_UNLOCK(memory_inst);
     return true;
 }
 

+ 4 - 1
core/iwasm/interpreter/wasm_runtime.h

@@ -91,8 +91,11 @@ typedef union {
 struct WASMMemoryInstance {
     /* Module type */
     uint32 module_type;
+
+    bool is_shared_memory;
+
     /* Shared memory flag */
-    bh_atomic_32_t ref_count; /* 0: non-shared, > 0: reference count */
+    bh_atomic_16_t ref_count; /* 0: non-shared, > 0: reference count */
 
     /* Number bytes per page */
     uint32 num_bytes_per_page;

+ 2 - 2
core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c

@@ -3169,8 +3169,8 @@ wasi_ssp_sock_open(wasm_exec_env_t exec_env, struct fd_table *curfds,
     bool is_tcp = SOCKET_DGRAM == socktype ? false : true;
     bool is_ipv4 = INET6 == af ? false : true;
     int ret;
-    __wasi_filetype_t wasi_type;
-    __wasi_rights_t max_base, max_inheriting;
+    __wasi_filetype_t wasi_type = __WASI_FILETYPE_UNKNOWN;
+    __wasi_rights_t max_base = 0, max_inheriting = 0;
     __wasi_errno_t error;
 
     (void)poolfd;

+ 2 - 2
core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h

@@ -26,8 +26,8 @@
 
 // On Linux, prefer to use getrandom, though it isn't available in
 // GLIBC before 2.25.
-#if (defined(__linux__) || defined(ESP_PLATFORM)) \
-    && (!defined(__GLIBC__) || __GLIBC__ > 2      \
+#if (defined(__linux__) || defined(ESP_PLATFORM) || defined(__COSMOPOLITAN__)) \
+    && (!defined(__GLIBC__) || __GLIBC__ > 2                                   \
         || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
 #define CONFIG_HAS_GETRANDOM 1
 #else

+ 18 - 8
core/shared/platform/common/posix/posix_thread.c

@@ -441,8 +441,14 @@ static os_thread_local_attribute bool thread_signal_inited = false;
 /* The signal alternate stack base addr */
 static os_thread_local_attribute uint8 *sigalt_stack_base_addr;
 
+/*
+ * ASAN is not designed to work with custom stack unwind or other low-level
+ * things. Ignore a function that does some low-level magic. (e.g. walking
+ * through the thread's stack bypassing the frame boundaries)
+ */
 #if defined(__clang__)
 #pragma clang optimize off
+__attribute__((no_sanitize_address))
 #elif defined(__GNUC__)
 #pragma GCC push_options
 #pragma GCC optimize("O0")
@@ -503,10 +509,12 @@ destroy_stack_guard_pages()
 }
 #endif /* end of WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 */
 
-/* ASAN is not designed to work with custom stack unwind or other low-level \
- things. > Ignore a function that does some low-level magic. (e.g. walking \
- through the thread's stack bypassing the frame boundaries) */
-#if defined(__GNUC__)
+/*
+ * ASAN is not designed to work with custom stack unwind or other low-level
+ * things. Ignore a function that does some low-level magic. (e.g. walking
+ * through the thread's stack bypassing the frame boundaries)
+ */
+#if defined(__GNUC__) || defined(__clang__)
 __attribute__((no_sanitize_address))
 #endif
 static void
@@ -523,10 +531,12 @@ mask_signals(int how)
 static struct sigaction prev_sig_act_SIGSEGV;
 static struct sigaction prev_sig_act_SIGBUS;
 
-/* ASAN is not designed to work with custom stack unwind or other low-level \
- things. > Ignore a function that does some low-level magic. (e.g. walking \
- through the thread's stack bypassing the frame boundaries) */
-#if defined(__GNUC__)
+/*
+ * ASAN is not designed to work with custom stack unwind or other low-level
+ * things. Ignore a function that does some low-level magic. (e.g. walking
+ * through the thread's stack bypassing the frame boundaries)
+ */
+#if defined(__GNUC__) || defined(__clang__)
 __attribute__((no_sanitize_address))
 #endif
 static void

+ 60 - 0
core/shared/utils/bh_atomic.h

@@ -45,6 +45,7 @@ extern "C" {
  */
 
 typedef uint32 bh_atomic_32_t;
+typedef uint16 bh_atomic_16_t;
 
 #if defined(__GNUC_PREREQ)
 #if __GNUC_PREREQ(4, 7)
@@ -59,6 +60,7 @@ typedef uint32 bh_atomic_32_t;
 #if defined(CLANG_GCC_HAS_ATOMIC_BUILTIN)
 #define BH_ATOMIC_32_IS_ATOMIC 1
 #define BH_ATOMIC_32_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST)
+#define BH_ATOMIC_32_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST)
 #define BH_ATOMIC_32_FETCH_OR(v, val) \
     __atomic_fetch_or(&(v), (val), __ATOMIC_SEQ_CST)
 #define BH_ATOMIC_32_FETCH_AND(v, val) \
@@ -67,13 +69,33 @@ typedef uint32 bh_atomic_32_t;
     __atomic_fetch_add(&(v), (val), __ATOMIC_SEQ_CST)
 #define BH_ATOMIC_32_FETCH_SUB(v, val) \
     __atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST)
+
+#define BH_ATOMIC_16_IS_ATOMIC 1
+#define BH_ATOMIC_16_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST)
+#define BH_ATOMIC_16_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST)
+#define BH_ATOMIC_16_FETCH_OR(v, val) \
+    __atomic_fetch_or(&(v), (val), __ATOMIC_SEQ_CST)
+#define BH_ATOMIC_16_FETCH_AND(v, val) \
+    __atomic_fetch_and(&(v), (val), __ATOMIC_SEQ_CST)
+#define BH_ATOMIC_16_FETCH_ADD(v, val) \
+    __atomic_fetch_add(&(v), (val), __ATOMIC_SEQ_CST)
+#define BH_ATOMIC_16_FETCH_SUB(v, val) \
+    __atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST)
 #else /* else of defined(CLANG_GCC_HAS_ATOMIC_BUILTIN) */
 #define BH_ATOMIC_32_LOAD(v) (v)
+#define BH_ATOMIC_32_STORE(v, val) (v) = val
 #define BH_ATOMIC_32_FETCH_OR(v, val) nonatomic_32_fetch_or(&(v), val)
 #define BH_ATOMIC_32_FETCH_AND(v, val) nonatomic_32_fetch_and(&(v), val)
 #define BH_ATOMIC_32_FETCH_ADD(v, val) nonatomic_32_fetch_add(&(v), val)
 #define BH_ATOMIC_32_FETCH_SUB(v, val) nonatomic_32_fetch_sub(&(v), val)
 
+#define BH_ATOMIC_16_LOAD(v) (v)
+#define BH_ATOMIC_16_STORE(v) (v) = val
+#define BH_ATOMIC_16_FETCH_OR(v, val) nonatomic_16_fetch_or(&(v), val)
+#define BH_ATOMIC_16_FETCH_AND(v, val) nonatomic_16_fetch_and(&(v), val)
+#define BH_ATOMIC_16_FETCH_ADD(v, val) nonatomic_16_fetch_add(&(v), val)
+#define BH_ATOMIC_16_FETCH_SUB(v, val) nonatomic_16_fetch_sub(&(v), val)
+
 static inline uint32
 nonatomic_32_fetch_or(bh_atomic_32_t *p, uint32 val)
 {
@@ -106,6 +128,38 @@ nonatomic_32_fetch_sub(bh_atomic_32_t *p, uint32 val)
     return old;
 }
 
+static inline uint16
+nonatomic_16_fetch_or(bh_atomic_16_t *p, uint16 val)
+{
+    uint16 old = *p;
+    *p |= val;
+    return old;
+}
+
+static inline uint16
+nonatomic_16_fetch_and(bh_atomic_16_t *p, uint16 val)
+{
+    uint16 old = *p;
+    *p &= val;
+    return old;
+}
+
+static inline uint16
+nonatomic_16_fetch_add(bh_atomic_16_t *p, uint16 val)
+{
+    uint16 old = *p;
+    *p += val;
+    return old;
+}
+
+static inline uint16
+nonatomic_16_fetch_sub(bh_atomic_16_t *p, uint16 val)
+{
+    uint16 old = *p;
+    *p -= val;
+    return old;
+}
+
 /* The flag can be defined by the user if the platform
    supports atomic access to uint32 aligned memory. */
 #ifdef WASM_UINT32_IS_ATOMIC
@@ -114,6 +168,12 @@ nonatomic_32_fetch_sub(bh_atomic_32_t *p, uint32 val)
 #define BH_ATOMIC_32_IS_ATOMIC 0
 #endif /* WASM_UINT32_IS_ATOMIC */
 
+#ifdef WASM_UINT16_IS_ATOMIC
+#define BH_ATOMIC_16_IS_ATOMIC 1
+#else /* else of WASM_UINT16_IS_ATOMIC */
+#define BH_ATOMIC_16_IS_ATOMIC 0
+#endif /* WASM_UINT16_IS_ATOMIC */
+
 #endif
 
 #ifdef __cplusplus

+ 1 - 1
language-bindings/go/go.mod

@@ -1,4 +1,4 @@
-module gitlab.alipay-inc.com/TNT_Runtime/ant-runtime/bindings/go
+module github.com/bytecodealliance/wasm-micro-runtime/language-bindings/go
 
 go 1.15
 

+ 3 - 11
language-bindings/go/samples/build.sh

@@ -3,19 +3,11 @@
 # Copyright (C) 2019 Intel Corporation.  All rights reserved.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-PLATFORM=$(uname -s | tr A-Z a-z)
 CUR_DIR=$PWD
-WAMR_DIR=$PWD/../../..
-WAMR_GO_DIR=$PWD/../wamr
 
-cp -a ${WAMR_DIR}/core/iwasm/include/*.h ${WAMR_GO_DIR}/packaged/include
-
-mkdir -p build && cd build
-cmake ${WAMR_DIR}/product-mini/platforms/${PLATFORM} \
-    -DWAMR_BUILD_LIB_PTHREAD=1 -DWAMR_BUILD_DUMP_CALL_STACK=1 \
-    -DWAMR_BUILD_MEMORY_PROFILING=1
-make -j ${nproc}
-cp -a libvmlib.a ${WAMR_GO_DIR}/packaged/lib/${PLATFORM}-amd64
+pushd ${CUR_DIR}/.. > /dev/null 2>&1
+./build.sh
+popd > /dev/null 2>& 1
 
 cd ${CUR_DIR}
 rm -f test

+ 1 - 1
language-bindings/go/samples/test.go

@@ -6,7 +6,7 @@
 package main
 
 import (
-    "gitlab.alipay-inc.com/TNT_Runtime/ant-runtime/bindings/go/wamr"
+    "github.com/bytecodealliance/wasm-micro-runtime/language-bindings/go/wamr"
     "fmt"
 )
 

+ 2 - 0
language-bindings/go/wamr/instance.go

@@ -272,7 +272,9 @@ func (self *Instance) CallFuncV(funcName string,
     for i = 0; i < result_count; i++ {
         switch result_types[i] {
             case C.WASM_I32:
+                fallthrough
             case C.WASM_FUNCREF:
+                fallthrough
             case C.WASM_ANYREF:
                 i32 := (int32)(argv[argc])
                 results[i] = i32

+ 56 - 6
product-mini/platforms/posix/main.c

@@ -79,6 +79,9 @@ print_help()
     printf("  --dir=<dir>              Grant wasi access to the given host directories\n");
     printf("                           to the program, for example:\n");
     printf("                             --dir=<dir1> --dir=<dir2>\n");
+    printf("  --map-dir=<guest::host>  Grant wasi access to the given host directories\n");
+    printf("                           to the program at a specific guest path, for example:\n");
+    printf("                             --map-dir=<guest-path1::host-path1> --map-dir=<guest-path2::host-path2>\n");
     printf("  --addr-pool=<addrs>      Grant wasi access to the given network addresses in\n");
     printf("                           CIRD notation to the program, seperated with ',',\n");
     printf("                           for example:\n");
@@ -439,7 +442,7 @@ module_reader_callback(package_type_t module_type, const char *module_name,
     const char *format = "%s/%s%s";
     int sz = strlen(module_search_path) + strlen("/") + strlen(module_name)
              + strlen(file_format) + 1;
-    char *wasm_file_name = BH_MALLOC(sz);
+    char *wasm_file_name = wasm_runtime_malloc(sz);
     if (!wasm_file_name) {
         return false;
     }
@@ -465,7 +468,37 @@ moudle_destroyer(uint8 *buffer, uint32 size)
 
 #if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
 static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
+#else
+static void *
+malloc_func(
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
+#endif
+    unsigned int size)
+{
+    return malloc(size);
+}
+
+static void *
+realloc_func(
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
+#endif
+    void *ptr, unsigned int size)
+{
+    return realloc(ptr, size);
+}
+
+static void
+free_func(
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
 #endif
+    void *ptr)
+{
+    free(ptr);
+}
+#endif /* end of WASM_ENABLE_GLOBAL_HEAP_POOL */
 
 #if WASM_ENABLE_STATIC_PGO != 0
 static void
@@ -580,6 +613,8 @@ main(int argc, char *argv[])
 #if WASM_ENABLE_LIBC_WASI != 0
     const char *dir_list[8] = { NULL };
     uint32 dir_list_size = 0;
+    const char *map_dir_list[8] = { NULL };
+    uint32 map_dir_list_size = 0;
     const char *env_list[8] = { NULL };
     uint32 env_list_size = 0;
     const char *addr_pool[8] = { NULL };
@@ -725,6 +760,16 @@ main(int argc, char *argv[])
             }
             dir_list[dir_list_size++] = argv[0] + 6;
         }
+        else if (!strncmp(argv[0], "--map-dir=", 10)) {
+            if (argv[0][10] == '\0')
+                return print_help();
+            if (map_dir_list_size >= sizeof(map_dir_list) / sizeof(char *)) {
+                printf("Only allow max map dir number %d\n",
+                       (int)(sizeof(map_dir_list) / sizeof(char *)));
+                return 1;
+            }
+            map_dir_list[map_dir_list_size++] = argv[0] + 10;
+        }
         else if (!strncmp(argv[0], "--env=", 6)) {
             char *tmp_env;
 
@@ -860,9 +905,13 @@ main(int argc, char *argv[])
     init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
 #else
     init_args.mem_alloc_type = Alloc_With_Allocator;
-    init_args.mem_alloc_option.allocator.malloc_func = malloc;
-    init_args.mem_alloc_option.allocator.realloc_func = realloc;
-    init_args.mem_alloc_option.allocator.free_func = free;
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    /* Set user data for the allocator is needed */
+    /* init_args.mem_alloc_option.allocator.user_data = user_data; */
+#endif
+    init_args.mem_alloc_option.allocator.malloc_func = malloc_func;
+    init_args.mem_alloc_option.allocator.realloc_func = realloc_func;
+    init_args.mem_alloc_option.allocator.free_func = free_func;
 #endif
 
 #if WASM_ENABLE_FAST_JIT != 0
@@ -938,8 +987,9 @@ main(int argc, char *argv[])
     }
 
 #if WASM_ENABLE_LIBC_WASI != 0
-    wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size, NULL, 0,
-                               env_list, env_list_size, argv, argc);
+    wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size,
+                               map_dir_list, map_dir_list_size, env_list,
+                               env_list_size, argv, argc);
 
     wasm_runtime_set_wasi_addr_pool(wasm_module, addr_pool, addr_pool_size);
     wasm_runtime_set_wasi_ns_lookup_pool(wasm_module, ns_lookup_pool,

+ 38 - 4
product-mini/platforms/windows/main.c

@@ -191,7 +191,37 @@ validate_env_str(char *env)
 
 #if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
 static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
+#else
+static void *
+malloc_func(
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
 #endif
+    unsigned int size)
+{
+    return malloc(size);
+}
+
+static void *
+realloc_func(
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
+#endif
+    void *ptr, unsigned int size)
+{
+    return realloc(ptr, size);
+}
+
+static void
+free_func(
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
+#endif
+    void *ptr)
+{
+    free(ptr);
+}
+#endif /* end of WASM_ENABLE_GLOBAL_HEAP_POOL */
 
 #if WASM_ENABLE_MULTI_MODULE != 0
 static char *
@@ -219,7 +249,7 @@ module_reader_callback(package_type_t module_type, const char *module_name,
     const char *format = "%s/%s%s";
     int sz = strlen(module_search_path) + strlen("/") + strlen(module_name)
              + strlen(file_format) + 1;
-    char *wasm_file_name = BH_MALLOC(sz);
+    char *wasm_file_name = wasm_runtime_malloc(sz);
     if (!wasm_file_name) {
         return false;
     }
@@ -450,9 +480,13 @@ main(int argc, char *argv[])
     init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
 #else
     init_args.mem_alloc_type = Alloc_With_Allocator;
-    init_args.mem_alloc_option.allocator.malloc_func = malloc;
-    init_args.mem_alloc_option.allocator.realloc_func = realloc;
-    init_args.mem_alloc_option.allocator.free_func = free;
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    /* Set user data for the allocator is needed */
+    /* init_args.mem_alloc_option.allocator.user_data = user_data; */
+#endif
+    init_args.mem_alloc_option.allocator.malloc_func = malloc_func;
+    init_args.mem_alloc_option.allocator.realloc_func = realloc_func;
+    init_args.mem_alloc_option.allocator.free_func = free_func;
 #endif
 
 #if WASM_ENABLE_JIT != 0

+ 8 - 8
samples/gui/wasm-apps/decrease/src/main.c

@@ -46,14 +46,14 @@ on_init()
     count_label = lv_label_create(NULL, NULL);
     lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0);
 
-    btn1 = lv_btn_create(
-        NULL, NULL); /*Create a button on the currently loaded screen*/
-    lv_obj_set_event_cb(
-        btn1,
-        btn_event_cb); /*Set function to be called when the button is released*/
-    lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align below the label*/
+    /* Create a button on the currently loaded screen */
+    btn1 = lv_btn_create(NULL, NULL);
+    /* Set function to be called when the button is released */
+    lv_obj_set_event_cb(btn1, (lv_event_cb_t)btn_event_cb);
+    /* Align below the label */
+    lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0);
 
-    /*Create a label on the button*/
+    /* Create a label on the button */
     lv_obj_t *btn_label = lv_label_create(btn1, NULL);
     lv_label_set_text(btn_label, "Click --");
 
@@ -61,7 +61,7 @@ on_init()
     lv_label_set_text(label_count1, "100");
     lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
 
-    /* set up a timer */
+    /* Set up a timer */
     user_timer_t timer;
     timer = api_timer_create(10, true, false, timer1_update);
     if (timer)

+ 8 - 8
samples/gui/wasm-apps/increase/src/main.c

@@ -46,14 +46,14 @@ on_init()
     count_label = lv_label_create(NULL, NULL);
     lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0);
 
-    btn1 = lv_btn_create(
-        NULL, NULL); /*Create a button on the currently loaded screen*/
-    lv_obj_set_event_cb(
-        btn1,
-        btn_event_cb); /*Set function to be called when the button is released*/
-    lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align below the label*/
+    /* Create a button on the current loaded screen */
+    btn1 = lv_btn_create(NULL, NULL);
+    /* Set function to be called when the button is released */
+    lv_obj_set_event_cb(btn1, (lv_event_cb_t)btn_event_cb);
+    /* Align below the label */
+    lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0);
 
-    /*Create a label on the button*/
+    /* Create a label on the button */
     lv_obj_t *btn_label = lv_label_create(btn1, NULL);
     lv_label_set_text(btn_label, "Click ++");
 
@@ -61,7 +61,7 @@ on_init()
     lv_label_set_text(label_count1, "1");
     lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
 
-    /* set up a timer */
+    /* Set up a timer */
     user_timer_t timer;
     timer = api_timer_create(10, true, false, timer1_update);
     if (timer)

+ 3 - 2
samples/multi-module/src/main.c

@@ -11,7 +11,7 @@ static bool
 module_reader_callback(package_type_t module_type, const char *module_name,
                        uint8 **p_buffer, uint32 *p_size)
 {
-    char *file_format;
+    char *file_format = NULL;
 #if WASM_ENABLE_INTERP != 0
     if (module_type == Wasm_Module_Bytecode)
         file_format = ".wasm";
@@ -21,10 +21,11 @@ module_reader_callback(package_type_t module_type, const char *module_name,
         file_format = ".aot";
 
 #endif
+    bh_assert(file_format != NULL);
     const char *format = "%s/%s%s";
     int sz = strlen(module_search_path) + strlen("/") + strlen(module_name)
              + strlen(file_format) + 1;
-    char *wasm_file_name = BH_MALLOC(sz);
+    char *wasm_file_name = wasm_runtime_malloc(sz);
     if (!wasm_file_name) {
         return false;
     }

+ 36 - 1
tests/wamr-compiler/test_shift_negative_constants.wat

@@ -7,6 +7,7 @@
 ;; any problems. See: https://github.com/bytecodealliance/wasm-micro-runtime/pull/2619
 (module
   (memory (export "memory") 1 1)
+
   (func $assert_eq (param i32 i32)
     (i32.ne (local.get 0) (local.get 1))
     if
@@ -23,7 +24,7 @@
 
   (func $i32_shr_s
     (call $assert_eq
-      (i32.shr_u (i32.const 32) (i32.const -30))
+      (i32.shr_s (i32.const 32) (i32.const -30))
       (i32.const 8)
     )
   )
@@ -35,9 +36,43 @@
     )
   )
 
+  (func $const_ret (result i32)
+    i32.const -5
+  )
+
+  ;; *_func_call tests validate the potential LLVM optimizations
+  ;; where the right parameter of the shift operation is an
+  ;; indirect constant value.
+  (func $i32_shr_u_func_call
+    (call $assert_eq
+      (i32.shr_u (i32.const -1) (call $const_ret))
+      (i32.const 31)
+    )
+  )
+
+  (func $i32_shr_s_func_call
+    (call $assert_eq
+      (i32.shr_s
+        (i32.const 1073741824) ;; 2^30
+        (call $const_ret)
+      )
+      (i32.const 8)
+    )
+  )
+
+  (func $i32_shl_func_call
+    (call $assert_eq
+      (i32.shl (i32.const -1) (call $const_ret))
+      (i32.const -134217728)
+    )
+  )
+
   (func (export "_start")
     call $i32_shr_u
     call $i32_shr_s
     call $i32_shl
+    call $i32_shr_u_func_call
+    call $i32_shr_s_func_call
+    call $i32_shl_func_call
   )
 )

+ 0 - 0
tests/wamr-test-suites/spec-test-script/muti_module_aot_ignore_cases.patch → tests/wamr-test-suites/spec-test-script/multi_module_aot_ignore_cases.patch


+ 11 - 5
tests/wamr-test-suites/test_wamr.sh

@@ -32,6 +32,7 @@ function help()
     echo "-F set the firmware path used by qemu"
     echo "-C enable code coverage collect"
     echo "-j set the platform to test"
+    echo "-T set sanitizer to use in tests(ubsan|tsan|asan)"
 }
 
 OPT_PARSED=""
@@ -59,7 +60,7 @@ QEMU_FIRMWARE=""
 # prod/testsuite-all branch
 WASI_TESTSUITE_COMMIT="ee807fc551978490bf1c277059aabfa1e589a6c2"
 
-while getopts ":s:cabgvt:m:MCpSXxwPGQF:j:" opt
+while getopts ":s:cabgvt:m:MCpSXxwPGQF:j:T:" opt
 do
     OPT_PARSED="TRUE"
     case $opt in
@@ -165,9 +166,14 @@ do
         echo "test platform " ${OPTARG}
         PLATFORM=${OPTARG}
         ;;
+        T)
+        echo "sanitizer is " ${OPTARG}
+        WAMR_BUILD_SANITIZER=${OPTARG}
+        ;;
         ?)
         help
-        exit 1;;
+        exit 1
+        ;;
     esac
 done
 
@@ -386,7 +392,7 @@ function spec_test()
         git apply ../../spec-test-script/simd_ignore_cases.patch
     fi
     if [[ ${ENABLE_MULTI_MODULE} == 1 && $1 == 'aot'  ]]; then
-        git apply ../../spec-test-script/muti_module_aot_ignore_cases.patch
+        git apply ../../spec-test-script/multi_module_aot_ignore_cases.patch
     fi
 
     # udpate thread cases
@@ -553,7 +559,7 @@ function wasi_certification_test()
     cd wasi-testsuite
     git reset --hard ${WASI_TESTSUITE_COMMIT}
 
-    bash ../../wasi-test-script/run_wasi_tests.sh $1 $TARGET \
+    TSAN_OPTIONS=${TSAN_OPTIONS} bash ../../wasi-test-script/run_wasi_tests.sh $1 $TARGET \
         | tee -a ${REPORT_DIR}/wasi_test_report.txt
     ret=${PIPESTATUS[0]}
 
@@ -948,4 +954,4 @@ fi
 echo -e "Test finish. Reports are under ${REPORT_DIR}"
 DEBUG set +xv pipefail
 echo "TEST SUCCESSFUL"
-exit 0
+exit 0

+ 11 - 0
tests/wamr-test-suites/tsan_suppressions.txt

@@ -0,0 +1,11 @@
+# Proposing to accept this risk for now. It might be wasi-libc related.
+# https://github.com/bytecodealliance/wasm-micro-runtime/pull/1963#issuecomment-1455342931
+race:STORE_U32
+
+
+# https://github.com/bytecodealliance/wasm-micro-runtime/issues/2680
+race:execute_post_instantiate_functions
+
+# Suppressing signal-unsafe inside of a signal for AOT mode 
+# see https://github.com/bytecodealliance/wasm-micro-runtime/issues/2248#issuecomment-1630189656
+signal:*

+ 2 - 2
tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh

@@ -67,7 +67,7 @@ if [[ $MODE != "aot" ]];then
     python3 -m pip install -r test-runner/requirements.txt
 
     export TEST_RUNTIME_EXE="${IWASM_CMD}"
-    python3 ${THIS_DIR}/pipe.py | python3 test-runner/wasi_test_runner.py \
+    python3 ${THIS_DIR}/pipe.py | TSAN_OPTIONS=${TSAN_OPTIONS} python3 test-runner/wasi_test_runner.py \
             -r adapters/wasm-micro-runtime.py \
             -t \
                 ${C_TESTS} \
@@ -79,7 +79,7 @@ if [[ $MODE != "aot" ]];then
 
     ret=${PIPESTATUS[1]}
 
-    TEST_RUNTIME_EXE="${IWASM_CMD_STRESS}" python3 test-runner/wasi_test_runner.py \
+    TEST_RUNTIME_EXE="${IWASM_CMD_STRESS}" TSAN_OPTIONS=${TSAN_OPTIONS}  python3 test-runner/wasi_test_runner.py \
             -r adapters/wasm-micro-runtime.py \
             -t \
                 ${THREAD_STRESS_TESTS}