Explorar o código

Merge branch main into dev/thread_suspension

Wenyong Huang %!s(int64=2) %!d(string=hai) anos
pai
achega
e88166dbf8
Modificáronse 100 ficheiros con 3636 adicións e 1562 borrados
  1. 1 1
      .github/workflows/build_docker_images.yml
  2. 2 2
      .github/workflows/build_iwasm_release.yml
  3. 5 5
      .github/workflows/build_llvm_libraries.yml
  4. 2 2
      .github/workflows/build_wamr_lldb.yml
  5. 1 1
      .github/workflows/build_wamr_sdk.yml
  6. 1 1
      .github/workflows/build_wamr_vscode_ext.yml
  7. 2 2
      .github/workflows/build_wamrc.yml
  8. 1 1
      .github/workflows/coding_guidelines.yml
  9. 25 19
      .github/workflows/compilation_on_android_ubuntu.yml
  10. 58 20
      .github/workflows/compilation_on_macos.yml
  11. 6 6
      .github/workflows/compilation_on_nuttx.yml
  12. 6 6
      .github/workflows/compilation_on_sgx.yml
  13. 2 2
      .github/workflows/compilation_on_windows.yml
  14. 1 1
      .github/workflows/create_tag.yml
  15. 1 1
      .github/workflows/hadolint_dockerfiles.yml
  16. 19 11
      .github/workflows/nightly_run.yml
  17. 1 1
      .github/workflows/release_process.yml
  18. 1 1
      .github/workflows/reuse_latest_release_binaries.yml
  19. 8 8
      .github/workflows/spec_test_on_nuttx.yml
  20. 2 2
      README.md
  21. 76 0
      RELEASE_NOTES.md
  22. 62 38
      build-scripts/config_common.cmake
  23. 24 1
      core/config.h
  24. 22 11
      core/iwasm/aot/aot_loader.c
  25. 109 117
      core/iwasm/aot/aot_runtime.c
  26. 9 0
      core/iwasm/aot/aot_runtime.h
  27. 9 8
      core/iwasm/aot/arch/aot_reloc_x86_64.c
  28. 15 4
      core/iwasm/aot/debug/elf_parser.c
  29. 1 1
      core/iwasm/common/wasm_application.c
  30. 24 16
      core/iwasm/common/wasm_c_api.c
  31. 188 138
      core/iwasm/common/wasm_memory.c
  32. 8 0
      core/iwasm/common/wasm_memory.h
  33. 388 447
      core/iwasm/common/wasm_native.c
  34. 42 2
      core/iwasm/common/wasm_runtime_common.c
  35. 0 10
      core/iwasm/common/wasm_runtime_common.h
  36. 3 2
      core/iwasm/common/wasm_shared_memory.c
  37. 2 0
      core/iwasm/common/wasm_suspend_flags.h
  38. 16 5
      core/iwasm/compilation/aot_compiler.c
  39. 44 10
      core/iwasm/compilation/aot_emit_aot_file.c
  40. 0 6
      core/iwasm/compilation/aot_llvm.c
  41. 1 1
      core/iwasm/compilation/aot_llvm_extra2.cpp
  42. 1 1
      core/iwasm/compilation/aot_llvm_extra2.h
  43. 20 4
      core/iwasm/compilation/debug/dwarf_extractor.cpp
  44. 2 3
      core/iwasm/fast-jit/fe/jit_emit_control.c
  45. 11 11
      core/iwasm/fast-jit/fe/jit_emit_table.c
  46. 11 7
      core/iwasm/fast-jit/jit_frontend.c
  47. 10 10
      core/iwasm/include/wasm_c_api.h
  48. 23 0
      core/iwasm/include/wasm_export.h
  49. 67 0
      core/iwasm/interpreter/wasm.h
  50. 8 0
      core/iwasm/interpreter/wasm_interp.h
  51. 552 47
      core/iwasm/interpreter/wasm_interp_classic.c
  52. 44 32
      core/iwasm/interpreter/wasm_interp_fast.c
  53. 695 79
      core/iwasm/interpreter/wasm_loader.c
  54. 106 66
      core/iwasm/interpreter/wasm_mini_loader.c
  55. 25 14
      core/iwasm/interpreter/wasm_opcode.h
  56. 306 160
      core/iwasm/interpreter/wasm_runtime.c
  57. 58 0
      core/iwasm/interpreter/wasm_runtime.h
  58. 12 2
      core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c
  59. 49 3
      core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c
  60. 101 93
      core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c
  61. 21 0
      core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.c
  62. 7 1
      core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.h
  63. 1 1
      core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/locking.h
  64. 21 12
      core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c
  65. 1 1
      core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h
  66. 70 60
      core/iwasm/libraries/thread-mgr/thread_manager.c
  67. 8 1
      core/shared/platform/alios/alios_time.c
  68. 2 2
      core/shared/platform/android/platform_internal.h
  69. 1 1
      core/shared/platform/common/freertos/freertos_thread.c
  70. 8 1
      core/shared/platform/common/freertos/freertos_time.c
  71. 12 0
      core/shared/platform/common/memory/mremap.c
  72. 4 0
      core/shared/platform/common/memory/platform_api_memory.cmake
  73. 15 0
      core/shared/platform/common/posix/platform_api_posix.cmake
  74. 1 0
      core/shared/platform/common/posix/posix_blocking_op.c
  75. 2 0
      core/shared/platform/common/posix/posix_clock.c
  76. 2 0
      core/shared/platform/common/posix/posix_file.c
  77. 29 14
      core/shared/platform/common/posix/posix_memmap.c
  78. 2 2
      core/shared/platform/common/posix/posix_socket.c
  79. 4 0
      core/shared/platform/common/posix/posix_thread.c
  80. 12 1
      core/shared/platform/common/posix/posix_time.c
  81. 9 2
      core/shared/platform/cosmopolitan/platform_internal.h
  82. 2 2
      core/shared/platform/darwin/platform_internal.h
  83. 3 0
      core/shared/platform/darwin/shared_platform.cmake
  84. 8 1
      core/shared/platform/esp-idf/espidf_platform.c
  85. 2 2
      core/shared/platform/freebsd/platform_internal.h
  86. 13 2
      core/shared/platform/include/platform_api_vmcore.h
  87. 2 0
      core/shared/platform/linux-sgx/platform_internal.h
  88. 16 1
      core/shared/platform/linux-sgx/sgx_time.c
  89. 3 0
      core/shared/platform/linux-sgx/shared_platform.cmake
  90. 2 2
      core/shared/platform/linux/platform_internal.h
  91. 16 1
      core/shared/platform/nuttx/nuttx_platform.c
  92. 2 0
      core/shared/platform/nuttx/platform_internal.h
  93. 2 1
      core/shared/platform/nuttx/shared_platform.cmake
  94. 11 4
      core/shared/platform/riot/riot_time.c
  95. 8 1
      core/shared/platform/rt-thread/rtt_platform.c
  96. 2 2
      core/shared/platform/vxworks/platform_internal.h
  97. 3 0
      core/shared/platform/windows/shared_platform.cmake
  98. 4 0
      core/shared/platform/windows/win_socket.c
  99. 8 1
      core/shared/platform/windows/win_time.c
  100. 8 1
      core/shared/platform/zephyr/zephyr_time.c

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

@@ -21,7 +21,7 @@ jobs:
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Build and save Docker image(wasm-debug-server:${{ inputs.ver_num }}) to tar file
         run: |

+ 2 - 2
.github/workflows/build_iwasm_release.yml

@@ -35,11 +35,11 @@ jobs:
   build:
     runs-on: ${{ inputs.runner }}
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: get cached LLVM libraries
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin

+ 5 - 5
.github/workflows/build_llvm_libraries.yml

@@ -31,7 +31,7 @@ jobs:
 
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: install dependencies
         run: /usr/bin/env python3 -m pip install -r requirements.txt
@@ -52,7 +52,7 @@ jobs:
 
       - name: Cache LLVM libraries
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -62,7 +62,7 @@ jobs:
             ./core/deps/llvm/build/share
           key: ${{ steps.create_lib_cache_key.outputs.key}}
 
-      - uses: actions/cache@v3
+      - uses: actions/cache@v4
         with:
           path: ~/.ccache
           key: 0-ccache-${{ inputs.os }}-${{ steps.get_last_commit.outputs.last_commit }}
@@ -70,7 +70,7 @@ jobs:
             0-ccache-${{ inputs.os }}
         if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && inputs.os == 'ubuntu-20.04'
 
-      - uses: actions/cache@v3
+      - uses: actions/cache@v4
         with:
           path: ~/.cache/ccache
           key: 0-ccache-${{ inputs.os }}-${{ steps.get_last_commit.outputs.last_commit }}
@@ -82,7 +82,7 @@ jobs:
       - run: sudo apt install -y ccache ninja-build
         if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && startsWith(inputs.os, 'ubuntu') && inputs.container_image == ''
 
-      - uses: actions/cache@v3
+      - uses: actions/cache@v4
         with:
           path: ~/Library/Caches/ccache
           key: 0-ccache-${{ inputs.os }}-${{ steps.get_last_commit.outputs.last_commit }}

+ 2 - 2
.github/workflows/build_wamr_lldb.yml

@@ -47,7 +47,7 @@ jobs:
       PYTHON_UBUNTU_STANDALONE_BUILD: https://github.com/indygreg/python-build-standalone/releases/download/20230507/cpython-3.10.11+20230507-x86_64-unknown-linux-gnu-install_only.tar.gz
       PYTHON_MACOS_STANDALONE_BUILD: https://github.com/indygreg/python-build-standalone/releases/download/20230507/cpython-3.10.11+20230507-x86_64-apple-darwin-install_only.tar.gz
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         run: |
@@ -60,7 +60,7 @@ jobs:
 
       - name: Cache build
         id: lldb_build_cache
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm-project/build/bin

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

@@ -35,7 +35,7 @@ jobs:
   build:
     runs-on: ${{ inputs.runner }}
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         run: |

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

@@ -18,7 +18,7 @@ jobs:
   build:
     runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: Use Node.js 16.x
         uses: actions/setup-node@v3

+ 2 - 2
.github/workflows/build_wamrc.yml

@@ -35,11 +35,11 @@ jobs:
   build:
     runs-on: ${{ inputs.runner }}
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: get cached LLVM libraries
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin

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

@@ -19,7 +19,7 @@ jobs:
     runs-on: ubuntu-20.04
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           fetch-depth: 0
 

+ 25 - 19
.github/workflows/compilation_on_android_ubuntu.yml

@@ -85,13 +85,13 @@ jobs:
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       # since jobs.id can't contain the dot character
       # it is hard to use `format` to assemble the cache key
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -213,13 +213,13 @@ jobs:
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       # only download llvm cache when needed
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
         if: endsWith(matrix.make_options_run_mode, '_JIT_BUILD_OPTIONS')
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -284,12 +284,12 @@ jobs:
 
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
         if: (!endsWith(matrix.make_options, '_INTERP_BUILD_OPTIONS'))
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -322,7 +322,7 @@ jobs:
         run: |
           VERBOSE=1
           cmake -S . -B build ${{ matrix.make_options }}
-          cmake --build build --config Release --parallel 4
+          cmake --build build --config Debug --parallel 4
           ctest --test-dir build --output-on-failure
         working-directory: samples/wasm-c-api
 
@@ -350,7 +350,7 @@ jobs:
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         run: |
@@ -367,7 +367,7 @@ jobs:
           sudo mv wabt-1.0.31 wabt
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -393,7 +393,7 @@ jobs:
           cd samples/file
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./src/iwasm -f wasm-app/file.wasm -d .
 
       - name: Build Sample [multi-thread]
@@ -401,7 +401,7 @@ jobs:
           cd samples/multi-thread
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./iwasm wasm-apps/test.wasm
 
       - name: Build Sample [multi-module]
@@ -409,7 +409,7 @@ jobs:
           cd samples/multi-module
           mkdir build && cd build
           cmake .. -DWAMR_BUILD_AOT=1
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./multi_module mC.wasm
           ./multi_module mC.aot
 
@@ -418,7 +418,7 @@ jobs:
           cd samples/spawn-thread
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./spawn_thread
 
       - name: Build Sample [ref-types]
@@ -426,7 +426,7 @@ jobs:
           cd samples/ref-types
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./hello
 
       - name: Build Sample [simple]
@@ -441,7 +441,7 @@ jobs:
           cd samples/wasi-threads
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./iwasm wasm-apps/no_pthread.wasm
 
       - name: Build Sample [shared-module]
@@ -450,6 +450,12 @@ jobs:
           ./build.sh
           ./run.sh
 
+      - name: Build Sample [terminate]
+        run: |
+          cd samples/terminate
+          ./build.sh
+          ./run.sh
+
   test:
     needs:
       [
@@ -513,7 +519,7 @@ jobs:
             test_option: $SIMD_TEST_OPTIONS
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         if: matrix.test_option == '$WASI_TEST_OPTIONS'
@@ -548,7 +554,7 @@ jobs:
       - name: Get LLVM libraries
         if: env.USE_LLVM == 'true'
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -610,7 +616,7 @@ jobs:
 
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: install dependencies
         run: |
@@ -629,7 +635,7 @@ jobs:
 
       - name: Cache LLDB
         id: cache-lldb
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         env:
           cache-name: cache-lldb-vscode
         with:

+ 58 - 20
.github/workflows/compilation_on_macos.yml

@@ -1,7 +1,7 @@
 # Copyright (C) 2019 Intel Corporation.  All rights reserved.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-name: compilation on macos-latest
+name: compilation on macos
 
 on:
   # will be triggered on PR events
@@ -55,27 +55,32 @@ env:
   LLVM_EAGER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0"
 
 jobs:
-  build_llvm_libraries:
+  build_llvm_libraries_on_intel_macos:
     uses: ./.github/workflows/build_llvm_libraries.yml
     with:
       os: "macos-latest"
       arch: "X86"
+  build_llvm_libraries_on_arm_macos:
+    uses: ./.github/workflows/build_llvm_libraries.yml
+    with:
+      os: "macos-14"
+      arch: "AArch64 ARM"
 
   build_wamrc:
-    needs: [build_llvm_libraries]
+    needs: [build_llvm_libraries_on_intel_macos]
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
         include:
           - os: macos-latest
-            llvm_cache_key: ${{ needs.build_llvm_libraries.outputs.cache_key }}
+            llvm_cache_key: ${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -97,7 +102,7 @@ jobs:
         working-directory: wamr-compiler
 
   build_iwasm:
-    needs: [build_llvm_libraries]
+    needs: [build_llvm_libraries_on_intel_macos]
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
@@ -171,16 +176,16 @@ jobs:
             make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
         include:
           - os: macos-latest
-            llvm_cache_key: ${{ needs.build_llvm_libraries.outputs.cache_key }}
+            llvm_cache_key: ${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       # only download llvm cache when needed
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
         if: endsWith(matrix.make_options_run_mode, '_JIT_BUILD_OPTIONS')
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -226,7 +231,7 @@ jobs:
           ]
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: download and install wabt
         run: |
@@ -243,11 +248,11 @@ jobs:
         working-directory: samples/wasm-c-api
 
   build_samples_others:
-    needs: [build_iwasm, build_wamrc]
+    needs: [build_iwasm, build_wamrc, build_llvm_libraries_on_intel_macos, build_llvm_libraries_on_arm_macos]
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
-        os: [macos-latest]
+        os: [macos-latest, macos-14]
         wasi_sdk_release:
           [
             "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-macos.tar.gz",
@@ -256,9 +261,14 @@ jobs:
           [
             "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-macos-12.tar.gz",
           ]
+        include:
+          - os: macos-latest
+            llvm_cache_key: ${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}
+          - os: macos-14
+            llvm_cache_key: ${{ needs.build_llvm_libraries_on_arm_macos.outputs.cache_key }}
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         run: |
@@ -285,7 +295,7 @@ jobs:
           cd samples/file
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./src/iwasm -f wasm-app/file.wasm -d .
 
       - name: Build Sample [multi-thread]
@@ -293,7 +303,7 @@ jobs:
           cd samples/multi-thread
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./iwasm wasm-apps/test.wasm
 
       - name: Build Sample [multi-module]
@@ -301,7 +311,7 @@ jobs:
           cd samples/multi-module
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./multi_module mC.wasm
 
       - name: Build Sample [spawn-thread]
@@ -309,7 +319,7 @@ jobs:
           cd samples/spawn-thread
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./spawn_thread
 
       - name: Build Sample [ref-types]
@@ -317,19 +327,47 @@ jobs:
           cd samples/ref-types
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./hello
 
+      - name: Get LLVM libraries
+        id: retrieve_llvm_libs
+        uses: actions/cache@v4
+        with:
+          path: |
+            ./core/deps/llvm/build/bin
+            ./core/deps/llvm/build/include
+            ./core/deps/llvm/build/lib
+            ./core/deps/llvm/build/libexec
+            ./core/deps/llvm/build/share
+          key: ${{ matrix.llvm_cache_key }}
+
+      - name: Build wamrc
+        run: |
+          mkdir build && cd build
+          cmake ..
+          cmake --build . --config Release --parallel 4
+        working-directory: wamr-compiler
+        
       - name: Build Sample [wasi-threads]
         run: |
           cd samples/wasi-threads
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           ./iwasm wasm-apps/no_pthread.wasm
 
+          ../../../wamr-compiler/build/wamrc --size-level=0 --enable-multi-thread -o wasm-apps/no_pthread.aot wasm-apps/no_pthread.wasm
+          ./iwasm wasm-apps/no_pthread.aot
+
       - name: Build Sample [shared-module]
         run: |
           cd samples/shared-module
           ./build.sh
           ./run.sh
+
+      - name: Build Sample [terminate]
+        run: |
+          cd samples/terminate
+          ./build.sh
+          ./run.sh

+ 6 - 6
.github/workflows/compilation_on_nuttx.yml

@@ -52,7 +52,7 @@ jobs:
   build_iwasm_on_nuttx:
     runs-on: ubuntu-latest
     container:
-      image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:4b4cbf0b70512e61ada9cdcb76b97e90ad478b85e4d0774d05a95fa32caa8c39
+      image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:d9261eacf6c6ebe656c571757751c803e8f04c3ae9b820320a5ea5dd57b7205a
 
     strategy:
       matrix:
@@ -87,21 +87,21 @@ jobs:
 
     steps:
       - name: Checkout NuttX
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           repository: apache/incubator-nuttx
-          ref: releases/12.3
+          ref: releases/12.4
           path: nuttx
 
       - name: Checkout NuttX Apps
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           repository: apache/incubator-nuttx-apps
-          ref: releases/12.3
+          ref: releases/12.4
           path: apps
 
       - name: Checkout WAMR
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           repository: ${{ github.repository }}
           path: apps/interpreters/wamr/wamr

+ 6 - 6
.github/workflows/compilation_on_sgx.yml

@@ -119,7 +119,7 @@ jobs:
           source /opt/intel/sgxsdk/environment
 
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Build iwasm
         run: |
@@ -165,7 +165,7 @@ jobs:
 
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         run: |
@@ -221,7 +221,7 @@ jobs:
       - name: Get LLVM libraries
         if: matrix.iwasm_make_options_run_mode == '$AOT_BUILD_OPTIONS'
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -246,7 +246,7 @@ jobs:
           cd samples/file
           mkdir build && cd build
           cmake ..
-          cmake --build . --config Release --parallel 4
+          cmake --build . --config Debug --parallel 4
           cp wasm-app/file.wasm `pwd`/../../../product-mini/platforms/${{ matrix.platform }}/enclave-sample
 
       - name: Test Sample [file] in non-aot mode
@@ -290,12 +290,12 @@ jobs:
 
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Get LLVM libraries
         if: matrix.running_mode == 'aot'
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin

+ 2 - 2
.github/workflows/compilation_on_windows.yml

@@ -74,7 +74,7 @@ jobs:
           "-DWAMR_BUILD_LIBC_UVWASI=0 -DWAMR_BUILD_LIBC_WASI=1"
         ]
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: clone uvwasi library
         if: ${{ !contains(matrix.build_options, '-DWAMR_BUILD_LIBC_UVWASI=0') }}
@@ -108,7 +108,7 @@ jobs:
           ]
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         if: matrix.test_option == '$WASI_TEST_OPTIONS'

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

@@ -24,7 +24,7 @@ jobs:
       new_tag: ${{ steps.preparation.outputs.new_tag }}
 
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
         # Full git history is needed to get a proper list of commits and tags
         with:
           fetch-depth: 0

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

@@ -34,7 +34,7 @@ jobs:
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       # on default, hadolint will fail on warnings and errors
       - name: Run hadolint on dockerfiles

+ 19 - 11
.github/workflows/nightly_run.yml

@@ -68,13 +68,13 @@ jobs:
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}  
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       # since jobs.id can't contain the dot character
       # it is hard to use `format` to assemble the cache key
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -199,13 +199,13 @@ jobs:
 
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       # only download llvm cache when needed
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
         if: endsWith(matrix.make_options_run_mode, '_JIT_BUILD_OPTIONS')
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -347,12 +347,12 @@ jobs:
             sanitizer: asan
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
         if: (!endsWith(matrix.make_options, '_INTERP_BUILD_OPTIONS'))
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -383,7 +383,9 @@ jobs:
       - name: Build Sample [wasm-c-api]
         run: |
           VERBOSE=1
-          cmake -S . -B build ${{ matrix.make_options }} -D WAMR_BUILD_SANITIZER="${{matrix.sanitizer}}"
+          cmake -S . -B build ${{ matrix.make_options }} \
+                -D WAMR_BUILD_SANITIZER="${{matrix.sanitizer}}" \
+                -D WAMR_BUILD_QUICK_AOT_ENTRY=0
           cmake --build build --config Release --parallel 4
           ctest --test-dir build --output-on-failure
         working-directory: samples/wasm-c-api
@@ -412,7 +414,7 @@ jobs:
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         run: |
@@ -429,7 +431,7 @@ jobs:
 
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin
@@ -507,6 +509,12 @@ jobs:
           cd samples/shared-module
           ./build.sh
           ./run.sh
+
+      - name: Build Sample [terminate]
+        run: |
+          cd samples/terminate
+          ./build.sh
+          ./run.sh
   test:
     needs:
       [
@@ -593,7 +601,7 @@ jobs:
             test_option: $SIMD_TEST_OPTIONS
     steps:
       - name: checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: download and install wasi-sdk
         if: matrix.test_option == '$WASI_TEST_OPTIONS'
@@ -631,7 +639,7 @@ jobs:
       - name: Get LLVM libraries
         if: env.USE_LLVM == 'true'
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin

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

@@ -28,7 +28,7 @@ jobs:
     outputs:
       upload_url: ${{ steps.create_release.outputs.upload_url }}
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: prepare the release note
         run: |

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

@@ -28,7 +28,7 @@ jobs:
     outputs:
       result: ${{ steps.try_reuse.outputs.result }}
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
         # Full git history is needed to get a proper list of commits and tags
         with:
           fetch-depth: 0

+ 8 - 8
.github/workflows/spec_test_on_nuttx.yml

@@ -28,13 +28,13 @@ jobs:
     with:
       os: "ubuntu-22.04"
       arch: "ARM RISCV AArch64"
-      container_image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:4b4cbf0b70512e61ada9cdcb76b97e90ad478b85e4d0774d05a95fa32caa8c39
+      container_image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:d9261eacf6c6ebe656c571757751c803e8f04c3ae9b820320a5ea5dd57b7205a
 
   spec_test_on_qemu:
     runs-on: ubuntu-latest
     needs: [build_llvm_libraries]
     container:
-      image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:4b4cbf0b70512e61ada9cdcb76b97e90ad478b85e4d0774d05a95fa32caa8c39
+      image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:d9261eacf6c6ebe656c571757751c803e8f04c3ae9b820320a5ea5dd57b7205a
     strategy:
       matrix:
         target_config: [
@@ -96,21 +96,21 @@ jobs:
 
     steps:
       - name: Checkout NuttX
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           repository: apache/incubator-nuttx
-          ref: releases/12.3
+          ref: releases/12.4
           path: nuttx
 
       - name: Checkout NuttX Apps
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           repository: apache/incubator-nuttx-apps
-          ref: releases/12.3
+          ref: releases/12.4
           path: apps
 
       - name: Checkout WAMR
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           repository: ${{ github.repository }}
           path: apps/interpreters/wamr/wamr
@@ -118,7 +118,7 @@ jobs:
       - name: Get LLVM libraries
         if: contains(matrix.wamr_test_option.mode, 'aot')
         id: retrieve_llvm_libs
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         with:
           path: |
             ./core/deps/llvm/build/bin

+ 2 - 2
README.md

@@ -75,9 +75,9 @@ The following platforms are supported, click each link below for how to build iw
 - [Blog: The WAMR memory model](https://bytecodealliance.github.io/wamr.dev/blog/the-wamr-memory-model/)
 - [Blog: Understand WAMR heaps](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-heaps/) and [stacks](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-stacks/)
 - [Blog: Introduction to WAMR running modes](https://bytecodealliance.github.io/wamr.dev/blog/introduction-to-wamr-running-modes/)
-- [Memory usage tunning](./doc/memory_tune.md): the memory model and how to tune the memory usage
+- [Memory usage tuning](./doc/memory_tune.md): the memory model and how to tune the memory usage
 - [Memory usage profiling](./doc/build_wamr.md#enable-memory-profiling-experiment): how to profile the memory usage
-- [Performance tunning](./doc/perf_tune.md): how to tune the performance
+- [Performance tuning](./doc/perf_tune.md): how to tune the performance
 - [Benchmarks](./tests/benchmarks): checkout these links for how to run the benchmarks: [PolyBench](./tests/benchmarks/polybench), [CoreMark](./tests/benchmarks/coremark), [Sightglass](./tests/benchmarks/sightglass), [JetStream2](./tests/benchmarks/jetstream)
 - [Performance and footprint data](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Performance): the performance and footprint data
 

+ 76 - 0
RELEASE_NOTES.md

@@ -1,3 +1,79 @@
+## WAMR-1.3.2
+
+### Breaking Changes
+
+### New Features
+- Implement Exception Handling for classic interpreter (#3096)
+  - Use `cmake -DWAMR_BUILD_EXCE_HANDLING=1/0` option to enable/disable
+    the feature, and by default it is disabled
+  - It is still in highly experimental stage
+
+### Bug Fixes
+- Fix build errors when initializing wasm_val_t values with macros (#3007)
+- fix(wasm-c-api): Do not clone stack frames if there's no trap (#3008)
+- classic-interp: Handle SIMD opcode when JIT is enabled (#3046)
+- fast-interp: Fix dynamic offset error issue in else branch (#3058)
+- wasm_cluster_destroy_spawned_exec_env: Avoid "invalid exec env" trap (#3068)
+- thread-mgr: Fix locking problems around aux stack allocation (#3073)
+- cosmopolitan: Update compiler and update platform_internal.h (#3079)
+- wasi: Apply wasm_runtime_begin_blocking_op to poll as well (#3080)
+- Fix memory/table segment checks in memory.init/table.init (#3081)
+- perf profiling: Adjust the calculation of execution time (#3089)
+- aot: Fix LLVMSetTailCallKind check (#3099)
+- fast-interp: Fix stack recovery for else branch (#3100)
+- fast-interp: Fix frame_offset pop order (#3101)
+- Fix AOT compilation on MacOS (#3102)
+- fast-interp: Fix block with parameter in polymorphic stack issue (#3112)
+- Fix read and validation of misc/simd/atomic sub opcodes (#3115)
+
+### Enhancements
+- Clear compilation warning and dead code (#3002)
+- aot debug: Try to use a bit more appropriate file names (#3000)
+- Increase default app thread stack size (#3010)
+- Rename rwlock_init to avoid conflict (#3016)
+- nuttx: Use larger alignment for os_mmap and comment why (#3017)
+- Allow using mmap for shared memory if hw bound check is disabled (#3029)
+- Don't redefine D_INO if already defined (#3036)
+- Enhancements on wasm function execution time statistic (#2985)
+- wamr-compiler: Fix non-x86{_64} host builds (#3037)
+- Disable quick aot entry for interp and fast-jit (#3039)
+- nuttx: Add option to enable quick aot entry (#3040)
+- Set CONFIG_HAS_CAP_ENTER to support posix file api for freertos (#3041)
+- Revert "Enable MAP_32BIT for macOS (#2992)" (#3032)
+- Enable quick aot entry when hw bound check is disabled (#3044)
+- Do not inherit WASM_SUSPEND_FLAG_BLOCKING from the parent thread (#3051)
+- wasm_runtime_begin_blocking_op: A comment about usage expectation (#3056)
+- Check arguments before calling bh_hash_map_find (#3055)
+- Fix aot large model (--size-level=0) with LLVM 18 (#3057)
+- Add flag to control Winsocket initialization (#3060)
+- nuttx: If STACK_GUARD_SIZE is not set, leave it to config.h (#2927)
+- Enhance setting write gs base with cmake variable (#3066)
+- aot_reloc_x86_64.c: Suggest to try --size-level=0 as well (#3067)
+- Fix some issues reported by CodeQL (#3064)
+- Remove a lot of "unused parameter" warnings (#3075)
+- Forward log and log level to custom bh_log callback (#3070)
+- Fix inconsistent code style in aot_loader.c (#3082)
+- freertos: Thread exit more common (#3094)
+- Fix windows build error and compilation warnings (#3095)
+
+### Others
+- Fix nightly-run CI failure (#3014)
+- Build samples in debug mode (#3019)
+- Remove deprecated tests in language-bindings python (#3018)
+- Avoid unused thread_id warning and recompile multi-module sample (#3033)
+- samples/terminate: Add a sample to demonstrate wasm_runtime_terminate (#3043)
+- Bump NuttX version to 12.4.x in CI (#3047)
+- perf_tune.md: Add refine the calling processes between host and wasm (#3065)
+- build_wamr.md: Update the document (#3074)
+- Fix download link for wasi-sdk (#3077)
+- README.md: Fix typo tunning to tuning (#3078)
+- Update outdated reference link in multi_module.md (#3092)
+- Add comments to suppress warning from clang-tidy (#3088)
+- CI: Update version of checkout to suppress warnings (#3093)
+- test_wamr.sh: Allow using test script on different platforms (#3098)
+
+---
+
 ## WAMR-1.3.1
 
 ### Breaking Changes

+ 62 - 38
build-scripts/config_common.cmake

@@ -329,9 +329,17 @@ if (WAMR_BUILD_REF_TYPES EQUAL 1)
 else ()
   message ("     Reference types disabled")
 endif ()
+if (WAMR_BUILD_EXCE_HANDLING EQUAL 1)
+  add_definitions (-DWASM_ENABLE_EXCE_HANDLING=1)
+  add_definitions (-DWASM_ENABLE_TAGS=1)
+  message ("     Exception Handling enabled")
+endif ()
 if (DEFINED WAMR_BH_VPRINTF)
   add_definitions (-DBH_VPRINTF=${WAMR_BH_VPRINTF})
 endif ()
+if (DEFINED WAMR_BH_LOG)
+  add_definitions (-DBH_LOG=${WAMR_BH_LOG})
+endif ()
 if (WAMR_DISABLE_APP_ENTRY EQUAL 1)
   message ("     WAMR application entry functions excluded")
 endif ()
@@ -415,32 +423,49 @@ if (WAMR_BUILD_STATIC_PGO EQUAL 1)
   add_definitions (-DWASM_ENABLE_STATIC_PGO=1)
   message ("     AOT static PGO enabled")
 endif ()
-if (WAMR_DISABLE_WRITE_GS_BASE EQUAL 1)
-  add_definitions (-DWASM_DISABLE_WRITE_GS_BASE=1)
-  message ("     Write linear memory base addr to x86 GS register disabled")
-elseif (WAMR_BUILD_TARGET STREQUAL "X86_64"
-        AND WAMR_BUILD_PLATFORM STREQUAL "linux")
-  set (TEST_WRGSBASE_SOURCE "${CMAKE_BINARY_DIR}/test_wrgsbase.c")
-  file (WRITE "${TEST_WRGSBASE_SOURCE}" "
-  #include <stdio.h>
-  #include <stdint.h>
-  int main() {
-      uint64_t value;
-      asm volatile (\"wrgsbase %0\" : : \"r\"(value));
-      printf(\"WRGSBASE instruction is available.\\n\");
-      return 0;
-  }")
-  # Try to compile and run the test program
-  try_run (TEST_WRGSBASE_RESULT
-    TEST_WRGSBASE_COMPILED
-    ${CMAKE_BINARY_DIR}/test_wrgsbase
-    SOURCES ${TEST_WRGSBASE_SOURCE}
-    CMAKE_FLAGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-  )
-  #message("${TEST_WRGSBASE_COMPILED}, ${TEST_WRGSBASE_RESULT}")
-  if (NOT TEST_WRGSBASE_RESULT EQUAL 0)
+if (WAMR_BUILD_TARGET STREQUAL "X86_64"
+    AND WAMR_BUILD_PLATFORM STREQUAL "linux")
+  if (WAMR_DISABLE_WRITE_GS_BASE EQUAL 1)
+    # disabled by user
+    set (DISABLE_WRITE_GS_BASE 1)
+  elseif (WAMR_DISABLE_WRITE_GS_BASE EQUAL 0)
+    # enabled by user
+    set (DISABLE_WRITE_GS_BASE 0)
+  elseif (CMAKE_CROSSCOMPILING)
+    # disabled in cross compilation environment
+    set (DISABLE_WRITE_GS_BASE 1)
+  else ()
+    # auto-detected by the compiler
+    set (TEST_WRGSBASE_SOURCE "${CMAKE_BINARY_DIR}/test_wrgsbase.c")
+    file (WRITE "${TEST_WRGSBASE_SOURCE}" "
+    #include <stdio.h>
+    #include <stdint.h>
+    int main() {
+        uint64_t value;
+        asm volatile (\"wrgsbase %0\" : : \"r\"(value));
+        printf(\"WRGSBASE instruction is available.\\n\");
+        return 0;
+    }")
+    # Try to compile and run the test program
+    try_run (TEST_WRGSBASE_RESULT
+      TEST_WRGSBASE_COMPILED
+      ${CMAKE_BINARY_DIR}/test_wrgsbase
+      SOURCES ${TEST_WRGSBASE_SOURCE}
+      CMAKE_FLAGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
+    )
+    #message("${TEST_WRGSBASE_COMPILED}, ${TEST_WRGSBASE_RESULT}")
+    if (TEST_WRGSBASE_RESULT EQUAL 0)
+      set (DISABLE_WRITE_GS_BASE 0)
+    else ()
+      set (DISABLE_WRITE_GS_BASE 1)
+    endif ()
+  endif ()
+  if (DISABLE_WRITE_GS_BASE EQUAL 1)
     add_definitions (-DWASM_DISABLE_WRITE_GS_BASE=1)
     message ("     Write linear memory base addr to x86 GS register disabled")
+  else ()
+    add_definitions (-DWASM_DISABLE_WRITE_GS_BASE=0)
+    message ("     Write linear memory base addr to x86 GS register enabled")
   endif ()
 endif ()
 if (WAMR_CONFIGUABLE_BOUNDS_CHECKS EQUAL 1)
@@ -451,20 +476,19 @@ if (WAMR_BUILD_LINUX_PERF EQUAL 1)
   add_definitions (-DWASM_ENABLE_LINUX_PERF=1)
   message ("     Linux perf support enabled")
 endif ()
-if (NOT DEFINED WAMR_BUILD_QUICK_AOT_ENTRY)
-  # Enable quick aot/jit entries by default
-  set (WAMR_BUILD_QUICK_AOT_ENTRY 1)
-endif ()
-if (WAMR_BUILD_QUICK_AOT_ENTRY EQUAL 1)
-  add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=1)
-  message ("     Quick AOT/JIT entries enabled")
+if (WAMR_BUILD_AOT EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1)
+  if (NOT DEFINED WAMR_BUILD_QUICK_AOT_ENTRY)
+    # Enable quick aot/jit entries by default
+    set (WAMR_BUILD_QUICK_AOT_ENTRY 1)
+  endif ()
+  if (WAMR_BUILD_QUICK_AOT_ENTRY EQUAL 1)
+    add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=1)
+    message ("     Quick AOT/JIT entries enabled")
+  else ()
+    add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=0)
+    message ("     Quick AOT/JIT entries disabled")
+  endif ()
 else ()
+  # Disable quick aot/jit entries for interp and fast-jit
   add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=0)
-  message ("     Quick AOT/JIT entries disabled")
-endif ()
-
-if (APPLE)
-  # On recent macOS versions, by default, the size of page zero is 4GB.
-  # Shrink it to make MAP_32BIT mmap can work.
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-pagezero_size,0x4000")
 endif ()

+ 24 - 1
core/config.h

@@ -188,6 +188,10 @@
 #define WASM_ENABLE_APP_FRAMEWORK 0
 #endif
 
+#ifndef WASM_HAVE_MREMAP
+#define WASM_HAVE_MREMAP 0
+#endif
+
 /* Bulk memory operation */
 #ifndef WASM_ENABLE_BULK_MEMORY
 #define WASM_ENABLE_BULK_MEMORY 0
@@ -231,6 +235,17 @@
 #define WASM_ENABLE_LOG 1
 #endif
 
+/* When this flag is set, WAMR will not automatically
+ * initialize sockets on Windows platforms. The host
+ * application is responsible for calling WSAStartup()
+ * before executing WAMR code that uses sockets, and
+ * calling WSACleanup() after.
+ * This flag passes control of socket initialization from
+ * WAMR to the host application. */
+#ifndef WASM_ENABLE_HOST_SOCKET_INIT
+#define WASM_ENABLE_HOST_SOCKET_INIT 0
+#endif
+
 #ifndef WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS
 #if defined(BUILD_TARGET_X86_32) || defined(BUILD_TARGET_X86_64) \
     || defined(BUILD_TARGET_AARCH64)
@@ -397,7 +412,7 @@
 #define APP_THREAD_STACK_SIZE_DEFAULT (64 * 1024)
 #define APP_THREAD_STACK_SIZE_MIN (48 * 1024)
 #else
-#define APP_THREAD_STACK_SIZE_DEFAULT (64 * 1024)
+#define APP_THREAD_STACK_SIZE_DEFAULT (128 * 1024)
 #define APP_THREAD_STACK_SIZE_MIN (24 * 1024)
 #endif
 #endif /* end of !(defined(APP_THREAD_STACK_SIZE_DEFAULT) \
@@ -446,6 +461,14 @@
 #define WASM_ENABLE_REF_TYPES 0
 #endif
 
+#ifndef WASM_ENABLE_EXCE_HANDLING
+#define WASM_ENABLE_EXCE_HANDLING 0
+#endif
+
+#ifndef WASM_ENABLE_TAGS
+#define WASM_ENABLE_TAGS 0
+#endif
+
 #ifndef WASM_ENABLE_SGX_IPFS
 #define WASM_ENABLE_SGX_IPFS 0
 #endif

+ 22 - 11
core/iwasm/aot/aot_loader.c

@@ -66,15 +66,15 @@ exchange_uint32(uint8 *p_data)
 }
 
 static void
-exchange_uint64(uint8 *pData)
+exchange_uint64(uint8 *p_data)
 {
     uint32 value;
 
-    value = *(uint32 *)pData;
-    *(uint32 *)pData = *(uint32 *)(pData + 4);
-    *(uint32 *)(pData + 4) = value;
-    exchange_uint32(pData);
-    exchange_uint32(pData + 4);
+    value = *(uint32 *)p_data;
+    *(uint32 *)p_data = *(uint32 *)(p_data + 4);
+    *(uint32 *)(p_data + 4) = value;
+    exchange_uint32(p_data);
+    exchange_uint32(p_data + 4);
 }
 
 static union {
@@ -214,6 +214,8 @@ GET_U16_FROM_ADDR(const uint8 *p)
         p += sizeof(type);                              \
     } while (0)
 
+/* NOLINTBEGIN, disable lint for this region with clang-tidy */
+
 #define read_byte_array(p, p_end, addr, len) \
     do {                                     \
         CHECK_BUF(p, p_end, len);            \
@@ -236,6 +238,8 @@ GET_U16_FROM_ADDR(const uint8 *p)
 #define read_uint32(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint32)
 #define read_uint64(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint64)
 
+/* NOLINTEND */
+
 /* Legal values for bin_type */
 #define BIN_TYPE_ELF32L 0 /* 32-bit little endian */
 #define BIN_TYPE_ELF32B 1 /* 32-bit big endian */
@@ -1975,6 +1979,12 @@ str2uint64(const char *buf, uint64 *p_res)
 
 #define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative offset to GOT */
 
+static bool
+is_text_section(const char *section_name)
+{
+    return !strcmp(section_name, ".text") || !strcmp(section_name, ".ltext");
+}
+
 static bool
 do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
                    char *error_buf, uint32 error_buf_size)
@@ -2063,7 +2073,7 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
             symbol_addr = module->func_ptrs[func_index];
         }
 #endif
-        else if (!strcmp(symbol, ".text")) {
+        else if (is_text_section(symbol)) {
             symbol_addr = module->code;
         }
         else if (!strcmp(symbol, ".data") || !strcmp(symbol, ".sdata")
@@ -2235,7 +2245,7 @@ do_data_relocation(AOTModule *module, AOTRelocationGroup *group,
 
     for (i = 0; i < group->relocation_count; i++, relocation++) {
         symbol = relocation->symbol_name;
-        if (!strcmp(symbol, ".text")) {
+        if (is_text_section(symbol)) {
             symbol_addr = module->code;
         }
 #if WASM_ENABLE_STATIC_PGO != 0
@@ -2696,6 +2706,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
 
         if (!strcmp(group->section_name, ".rel.text")
             || !strcmp(group->section_name, ".rela.text")
+            || !strcmp(group->section_name, ".rel.ltext")
+            || !strcmp(group->section_name, ".rela.ltext")
             || !strcmp(group->section_name, ".rela.literal")
 #ifdef BH_PLATFORM_WINDOWS
             || !strcmp(group->section_name, ".text")
@@ -3126,8 +3138,7 @@ resolve_execute_mode(const uint8 *buf, uint32 size, bool *p_mode,
     p += 8;
     while (p < p_end) {
         read_uint32(p, p_end, section_type);
-        if (section_type <= AOT_SECTION_TYPE_SIGANATURE
-            || section_type == AOT_SECTION_TYPE_TARGET_INFO) {
+        if (section_type <= AOT_SECTION_TYPE_SIGANATURE) {
             read_uint32(p, p_end, section_size);
             CHECK_BUF(p, p_end, section_size);
             if (section_type == AOT_SECTION_TYPE_TARGET_INFO) {
@@ -3142,7 +3153,7 @@ resolve_execute_mode(const uint8 *buf, uint32 size, bool *p_mode,
                 break;
             }
         }
-        else if (section_type > AOT_SECTION_TYPE_SIGANATURE) {
+        else { /* section_type > AOT_SECTION_TYPE_SIGANATURE */
             set_error_buf(error_buf, error_buf_size,
                           "resolve execute mode failed");
             break;

+ 109 - 117
core/iwasm/aot/aot_runtime.c

@@ -361,16 +361,7 @@ memories_deinstantiate(AOTModuleInstance *module_inst)
             }
 
             if (memory_inst->memory_data) {
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-                wasm_runtime_free(memory_inst->memory_data);
-#else
-#ifdef BH_PLATFORM_WINDOWS
-                os_mem_decommit(memory_inst->memory_data,
-                                memory_inst->num_bytes_per_page
-                                    * memory_inst->cur_page_count);
-#endif
-                os_munmap(memory_inst->memory_data, 8 * (uint64)BH_GB);
-#endif
+                wasm_deallocate_linear_memory(memory_inst);
             }
         }
     }
@@ -392,15 +383,10 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
     uint32 heap_offset = num_bytes_per_page * init_page_count;
     uint64 memory_data_size, max_memory_data_size;
     uint8 *p = NULL, *global_addr;
-#ifdef OS_ENABLE_HW_BOUND_CHECK
-    uint8 *mapped_mem;
-    uint64 map_size = 8 * (uint64)BH_GB;
-    uint64 page_size = os_getpagesize();
-#endif
 
+    bool is_shared_memory = false;
 #if WASM_ENABLE_SHARED_MEMORY != 0
-    bool is_shared_memory = memory->memory_flags & 0x02 ? true : false;
-
+    is_shared_memory = memory->memory_flags & 0x02 ? true : false;
     /* Shared memory */
     if (is_shared_memory && parent != NULL) {
         AOTMemoryInstance *shared_memory_instance;
@@ -510,71 +496,19 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
                 module->aux_stack_size);
     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;
 
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-#if WASM_ENABLE_SHARED_MEMORY != 0
-    if (is_shared_memory) {
-        /* 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
-    {
-        /* 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 /* 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
-     * both i and memarg.offset are u32 in range 0 to 4G
-     * so the range of ea is 0 to 8G
-     */
-    if (!(p = mapped_mem = os_mmap(NULL, map_size, MMAP_PROT_NONE,
-                                   MMAP_MAP_NONE, os_get_invalid_handle()))) {
-        set_error_buf(error_buf, error_buf_size, "mmap memory failed");
-        return NULL;
-    }
-
-#ifdef BH_PLATFORM_WINDOWS
-    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, 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, memory_data_size);
-#endif
-        os_munmap(mapped_mem, map_size);
+    if (wasm_allocate_linear_memory(&p, is_shared_memory, num_bytes_per_page,
+                                    init_page_count, max_page_count,
+                                    &memory_data_size)
+        != BHT_OK) {
+        set_error_buf(error_buf, error_buf_size,
+                      "allocate linear memory failed");
         return NULL;
     }
 
-    /* Newly allocated pages are filled with zero by the OS, we don't fill it
-     * again here */
-
-    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;
@@ -623,17 +557,8 @@ fail2:
     if (heap_size > 0)
         wasm_runtime_free(memory_inst->heap_handle);
 fail1:
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-    if (memory_inst->memory_data)
-        wasm_runtime_free(memory_inst->memory_data);
-#else
-#ifdef BH_PLATFORM_WINDOWS
-    if (memory_inst->memory_data)
-        os_mem_decommit(p, memory_data_size);
-#endif
-    os_munmap(mapped_mem, map_size);
-#endif
-    memory_inst->memory_data = NULL;
+    wasm_deallocate_linear_memory(memory_inst);
+
     return NULL;
 }
 
@@ -1186,6 +1111,10 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
                           "failed to allocate bitmaps");
             goto fail;
         }
+        for (i = 0; i < module->mem_init_data_count; i++) {
+            if (!module->mem_init_data_list[i]->is_passive)
+                bh_bitmap_set_bit(common->data_dropped, i);
+        }
     }
 #endif
 #if WASM_ENABLE_REF_TYPES != 0
@@ -1197,6 +1126,10 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
                           "failed to allocate bitmaps");
             goto fail;
         }
+        for (i = 0; i < module->table_init_data_count; i++) {
+            if (wasm_elem_is_active(module->table_init_data_list[i]->mode))
+                bh_bitmap_set_bit(common->elem_dropped, i);
+        }
     }
 #endif
 
@@ -1433,14 +1366,10 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
 #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
         /* Quick call if the quick aot entry is registered */
         if (!signature && func_type->quick_aot_entry) {
-            void (*invoke_native)(
-                void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-                uint32 *argv_ret) = func_type->quick_aot_entry;
-            invoke_native(func_ptr,
-                          func_type->result_count > 0
-                              ? func_type->types[func_type->param_count]
-                              : VALUE_TYPE_VOID,
-                          exec_env, argv, argv_ret);
+            void (*invoke_native)(void *func_ptr, void *exec_env, uint32 *argv,
+                                  uint32 *argv_ret) =
+                func_type->quick_aot_entry;
+            invoke_native(func_ptr, exec_env, argv, argv_ret);
             ret = !aot_copy_exception(module_inst, NULL);
         }
         else
@@ -1477,9 +1406,28 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
     (void)jmpbuf_node_pop;
     return ret;
 }
-#define invoke_native_internal invoke_native_with_hw_bound_check
+#define invoke_native_internal invoke_native_with_hw_bound_check /* NOLINT */
 #else /* else of OS_ENABLE_HW_BOUND_CHECK */
-#define invoke_native_internal wasm_runtime_invoke_native
+static inline bool
+invoke_native_internal(WASMExecEnv *exec_env, void *func_ptr,
+                       const WASMType *func_type, const char *signature,
+                       void *attachment, uint32 *argv, uint32 argc,
+                       uint32 *argv_ret)
+{
+#if WASM_ENABLE_QUICK_AOT_ENTRY != 0
+    /* Quick call if the quick aot entry is registered */
+    if (!signature && func_type->quick_aot_entry) {
+        AOTModuleInstance *module_inst =
+            (AOTModuleInstance *)exec_env->module_inst;
+        void (*invoke_native)(void *func_ptr, void *exec_env, uint32 *argv,
+                              uint32 *argv_ret) = func_type->quick_aot_entry;
+        invoke_native(func_ptr, exec_env, argv, argv_ret);
+        return !aot_copy_exception(module_inst, NULL);
+    }
+#endif
+    return wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature,
+                                      attachment, argv, argc, argv_ret);
+}
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
 bool
@@ -2613,6 +2561,7 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
 {
     AOTTableInstance *tbl_inst;
     AOTTableInitData *tbl_seg;
+    uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
     const AOTModule *module = (AOTModule *)module_inst->module;
 
     tbl_inst = module_inst->tables[tbl_idx];
@@ -2621,32 +2570,28 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
     tbl_seg = module->table_init_data_list[tbl_seg_idx];
     bh_assert(tbl_seg);
 
-    if (offset_len_out_of_bounds(src_offset, length, tbl_seg->func_index_count)
-        || offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
-        aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
-        return;
-    }
-
-    if (!length) {
-        return;
-    }
-
-    if (bh_bitmap_get_bit(
+    if (!bh_bitmap_get_bit(
             ((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
             tbl_seg_idx)) {
+        /* table segment isn't dropped */
+        tbl_seg_elems = tbl_seg->func_indexes;
+        tbl_seg_len = tbl_seg->func_index_count;
+    }
+
+    if (offset_len_out_of_bounds(src_offset, length, tbl_seg_len)
+        || offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
         aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
         return;
     }
 
-    if (!wasm_elem_is_passive(tbl_seg->mode)) {
-        aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
+    if (!length) {
         return;
     }
 
     bh_memcpy_s((uint8 *)tbl_inst + offsetof(AOTTableInstance, elems)
                     + dst_offset * sizeof(uint32),
                 (tbl_inst->cur_size - dst_offset) * sizeof(uint32),
-                tbl_seg->func_indexes + src_offset, length * sizeof(uint32));
+                tbl_seg_elems + src_offset, length * sizeof(uint32));
 }
 
 void
@@ -2814,7 +2759,7 @@ aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
     }
 
 #if WASM_ENABLE_PERF_PROFILING != 0
-    frame->time_started = os_time_get_boot_microsecond();
+    frame->time_started = os_time_thread_cputime_us();
     frame->func_perf_prof_info = func_perf_prof;
 #endif
 
@@ -2832,9 +2777,13 @@ aot_free_frame(WASMExecEnv *exec_env)
     AOTFrame *prev_frame = cur_frame->prev_frame;
 
 #if WASM_ENABLE_PERF_PROFILING != 0
-    cur_frame->func_perf_prof_info->total_exec_time +=
-        os_time_get_boot_microsecond() - cur_frame->time_started;
+    uint64 elapsed = os_time_thread_cputime_us() - cur_frame->time_started;
+    cur_frame->func_perf_prof_info->total_exec_time += elapsed;
     cur_frame->func_perf_prof_info->total_exec_cnt++;
+
+    /* parent function */
+    if (prev_frame)
+        prev_frame->func_perf_prof_info->children_exec_time += elapsed;
 #endif
 
     wasm_exec_env_free_wasm_frame(exec_env, cur_frame);
@@ -2971,22 +2920,65 @@ aot_dump_perf_profiling(const AOTModuleInstance *module_inst)
 
     os_printf("Performance profiler data:\n");
     for (i = 0; i < total_func_count; i++, perf_prof++) {
+        if (perf_prof->total_exec_cnt == 0)
+            continue;
+
         func_name = get_func_name_from_index(module_inst, i);
 
         if (func_name)
             os_printf(
                 "  func %s, execution time: %.3f ms, execution count: %" PRIu32
-                " times\n",
+                " times, children execution time: %.3f ms\n",
                 func_name, perf_prof->total_exec_time / 1000.0f,
-                perf_prof->total_exec_cnt);
+                perf_prof->total_exec_cnt,
+                perf_prof->children_exec_time / 1000.0f);
         else
             os_printf("  func %" PRIu32
                       ", execution time: %.3f ms, execution count: %" PRIu32
-                      " times\n",
+                      " times, children execution time: %.3f ms\n",
                       i, perf_prof->total_exec_time / 1000.0f,
-                      perf_prof->total_exec_cnt);
+                      perf_prof->total_exec_cnt,
+                      perf_prof->children_exec_time / 1000.0f);
     }
 }
+
+double
+aot_summarize_wasm_execute_time(const AOTModuleInstance *inst)
+{
+    double ret = 0;
+
+    AOTModule *module = (AOTModule *)inst->module;
+    uint32 total_func_count = module->import_func_count + module->func_count, i;
+
+    for (i = 0; i < total_func_count; i++) {
+        AOTFuncPerfProfInfo *perf_prof =
+            (AOTFuncPerfProfInfo *)inst->func_perf_profilings + i;
+        ret += (perf_prof->total_exec_time - perf_prof->children_exec_time)
+               / 1000.0f;
+    }
+
+    return ret;
+}
+
+double
+aot_get_wasm_func_exec_time(const AOTModuleInstance *inst,
+                            const char *func_name)
+{
+    AOTModule *module = (AOTModule *)inst->module;
+    uint32 total_func_count = module->import_func_count + module->func_count, i;
+
+    for (i = 0; i < total_func_count; i++) {
+        const char *name_in_wasm = get_func_name_from_index(inst, i);
+        if (name_in_wasm && strcmp(func_name, name_in_wasm) == 0) {
+            AOTFuncPerfProfInfo *perf_prof =
+                (AOTFuncPerfProfInfo *)inst->func_perf_profilings + i;
+            return (perf_prof->total_exec_time - perf_prof->children_exec_time)
+                   / 1000.0f;
+        }
+    }
+
+    return -1.0;
+}
 #endif /* end of WASM_ENABLE_PERF_PROFILING */
 
 #if WASM_ENABLE_STATIC_PGO != 0

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

@@ -286,6 +286,8 @@ typedef struct AOTFuncPerfProfInfo {
     uint64 total_exec_time;
     /* total execution count */
     uint32 total_exec_cnt;
+    /* children execution time */
+    uint64 children_exec_time;
 } AOTFuncPerfProfInfo;
 
 /* AOT auxiliary call stack */
@@ -613,6 +615,13 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len);
 void
 aot_dump_perf_profiling(const AOTModuleInstance *module_inst);
 
+double
+aot_summarize_wasm_execute_time(const AOTModuleInstance *inst);
+
+double
+aot_get_wasm_func_exec_time(const AOTModuleInstance *inst,
+                            const char *func_name);
+
 const uint8 *
 aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len);
 

+ 9 - 8
core/iwasm/aot/arch/aot_reloc_x86_64.c

@@ -163,7 +163,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
                     error_buf, error_buf_size,
                     "AOT module load failed: "
                     "relocation truncated to fit R_X86_64_PC32 failed. "
-                    "Try using wamrc with --size-level=1 option.");
+                    "Try using wamrc with --size-level=1 or 0 option.");
                 return false;
             }
 
@@ -196,7 +196,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
                 snprintf(buf, sizeof(buf),
                          "AOT module load failed: "
                          "relocation truncated to fit %s failed. "
-                         "Try using wamrc with --size-level=1 option.",
+                         "Try using wamrc with --size-level=1 or 0 option.",
                          reloc_type == R_X86_64_32 ? "R_X86_64_32"
                                                    : "R_X86_64_32S");
                 set_error_buf(error_buf, error_buf_size, buf);
@@ -236,15 +236,16 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
             target_addr -= sizeof(int32);
 #endif
             if ((int32)target_addr != target_addr) {
-                set_error_buf(error_buf, error_buf_size,
-                              "AOT module load failed: "
-                              "relocation truncated to fit "
+                set_error_buf(
+                    error_buf, error_buf_size,
+                    "AOT module load failed: "
+                    "relocation truncated to fit "
 #if !defined(BH_PLATFORM_WINDOWS)
-                              "R_X86_64_PLT32 failed. "
+                    "R_X86_64_PLT32 failed. "
 #else
-                              "IMAGE_REL_AMD64_32 failed."
+                    "IMAGE_REL_AMD64_32 failed."
 #endif
-                              "Try using wamrc with --size-level=1 option.");
+                    "Try using wamrc with --size-level=1 or 0 option.");
                 return false;
             }
             *(int32 *)(target_section_addr + reloc_offset) = (int32)target_addr;

+ 15 - 4
core/iwasm/aot/debug/elf_parser.c

@@ -100,6 +100,12 @@ get_section64(Elf64_Ehdr *eh, Elf64_Shdr *section_header)
     return buf + section_header->sh_offset;
 }
 
+static bool
+is_text_section(const char *section_name)
+{
+    return !strcmp(section_name, ".text") || !strcmp(section_name, ".ltext");
+}
+
 bool
 get_text_section(void *buf, uint64_t *offset, uint64_t *size)
 {
@@ -107,6 +113,7 @@ get_text_section(void *buf, uint64_t *offset, uint64_t *size)
     uint32 i;
     char *sh_str;
 
+    /* Assumption: Only one of .text or .ltext is non-empty. */
     if (is64Bit(buf)) {
         Elf64_Ehdr *eh = (Elf64_Ehdr *)buf;
         Elf64_Shdr **sh_table =
@@ -115,14 +122,16 @@ get_text_section(void *buf, uint64_t *offset, uint64_t *size)
             read_section_header_table64(eh, sh_table);
             sh_str = get_section64(eh, sh_table[eh->e_shstrndx]);
             for (i = 0; i < eh->e_shnum; i++) {
-                if (!strcmp(sh_str + sh_table[i]->sh_name, ".text")) {
+                if (is_text_section(sh_str + sh_table[i]->sh_name)) {
                     *offset = sh_table[i]->sh_offset;
                     *size = sh_table[i]->sh_size;
                     sh_table[i]->sh_addr =
                         (Elf64_Addr)(uintptr_t)((char *)buf
                                                 + sh_table[i]->sh_offset);
                     ret = true;
-                    break;
+                    if (*size > 0) {
+                        break;
+                    }
                 }
             }
             wasm_runtime_free(sh_table);
@@ -136,14 +145,16 @@ get_text_section(void *buf, uint64_t *offset, uint64_t *size)
             read_section_header_table(eh, sh_table);
             sh_str = get_section(eh, sh_table[eh->e_shstrndx]);
             for (i = 0; i < eh->e_shnum; i++) {
-                if (!strcmp(sh_str + sh_table[i]->sh_name, ".text")) {
+                if (is_text_section(sh_str + sh_table[i]->sh_name)) {
                     *offset = sh_table[i]->sh_offset;
                     *size = sh_table[i]->sh_size;
                     sh_table[i]->sh_addr =
                         (Elf32_Addr)(uintptr_t)((char *)buf
                                                 + sh_table[i]->sh_offset);
                     ret = true;
-                    break;
+                    if (*size > 0) {
+                        break;
+                    }
                 }
             }
             wasm_runtime_free(sh_table);

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

@@ -46,7 +46,7 @@ static union {
     char b;
 } __ue = { .a = 1 };
 
-#define is_little_endian() (__ue.b == 1)
+#define is_little_endian() (__ue.b == 1) /* NOLINT */
 
 /**
  * Implementation of wasm_application_execute_main()

+ 24 - 16
core/iwasm/common/wasm_c_api.c

@@ -1924,16 +1924,18 @@ wasm_frame_func_offset(const wasm_frame_t *frame)
 void
 wasm_frame_vec_clone_internal(Vector *src, Vector *out)
 {
-    bh_assert(src->num_elems != 0 && src->data);
-
-    bh_vector_destroy(out);
-    if (!bh_vector_init(out, src->num_elems, sizeof(WASMCApiFrame), false)) {
+    if (src->num_elems == 0) {
         bh_vector_destroy(out);
         return;
     }
 
-    bh_memcpy_s(out->data, src->num_elems * sizeof(WASMCApiFrame), src->data,
-                src->num_elems * sizeof(WASMCApiFrame));
+    if (!bh_vector_destroy(out)
+        || !bh_vector_init(out, src->num_elems, sizeof(WASMCApiFrame), false)) {
+        return;
+    }
+
+    bh_memcpy_s(out->data, (uint32)(src->num_elems * sizeof(WASMCApiFrame)),
+                src->data, (uint32)(src->num_elems * sizeof(WASMCApiFrame)));
     out->num_elems = src->num_elems;
 }
 
@@ -2292,7 +2294,7 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
         (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size,
         error_buf, (uint32)sizeof(error_buf));
     if (!(module_ex->module_comm_rt)) {
-        LOG_ERROR(error_buf);
+        LOG_ERROR("%s", error_buf);
         goto free_vec;
     }
 
@@ -2365,7 +2367,7 @@ wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary)
     }
     else {
         ret = false;
-        LOG_VERBOSE(error_buf);
+        LOG_VERBOSE("%s", error_buf);
     }
 
     return ret;
@@ -2960,8 +2962,10 @@ wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type,
     if (!(func->type = wasm_functype_copy(type))) {
         goto failed;
     }
-    func->param_count = func->type->params->num_elems;
-    func->result_count = func->type->results->num_elems;
+    /* func type's param_count and result_count were checked in
+       loader and are no larger than UINT16_MAX */
+    func->param_count = (uint16)func->type->params->num_elems;
+    func->result_count = (uint16)func->type->results->num_elems;
 
     RETURN_OBJ(func, wasm_func_delete)
 }
@@ -2992,8 +2996,10 @@ wasm_func_new_with_env_basic(wasm_store_t *store, const wasm_functype_t *type,
     if (!(func->type = wasm_functype_copy(type))) {
         goto failed;
     }
-    func->param_count = func->type->params->num_elems;
-    func->result_count = func->type->results->num_elems;
+    /* func type's param_count and result_count were checked in
+       loader and are no larger than UINT16_MAX */
+    func->param_count = (uint16)func->type->params->num_elems;
+    func->result_count = (uint16)func->type->results->num_elems;
 
     RETURN_OBJ(func, wasm_func_delete)
 }
@@ -3083,8 +3089,10 @@ wasm_func_new_internal(wasm_store_t *store, uint16 func_idx_rt,
     if (!func->type) {
         goto failed;
     }
-    func->param_count = func->type->params->num_elems;
-    func->result_count = func->type->results->num_elems;
+    /* func type's param_count and result_count were checked in
+       loader and are no larger than UINT16_MAX */
+    func->param_count = (uint16)func->type->params->num_elems;
+    func->result_count = (uint16)func->type->results->num_elems;
 
     /* will add name information when processing "exports" */
     func->store = store;
@@ -3357,7 +3365,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
     wasm_runtime_set_exception(func->inst_comm_rt, NULL);
     if (!wasm_runtime_call_wasm(exec_env, func_comm_rt, argc, argv)) {
         if (wasm_runtime_get_exception(func->inst_comm_rt)) {
-            LOG_DEBUG(wasm_runtime_get_exception(func->inst_comm_rt));
+            LOG_DEBUG("%s", wasm_runtime_get_exception(func->inst_comm_rt));
             goto failed;
         }
     }
@@ -5042,7 +5050,7 @@ failed:
         *trap = wasm_trap_new(store, &message);
         wasm_byte_vec_delete(&message);
     }
-    LOG_DEBUG(error_buf);
+    LOG_DEBUG("%s", error_buf);
     wasm_instance_delete_internal(instance);
     return NULL;
 }

+ 188 - 138
core/iwasm/common/wasm_memory.c

@@ -42,6 +42,14 @@ static void (*free_func)(void *ptr) = NULL;
 
 static unsigned int global_pool_size;
 
+static uint32
+align_as_and_cast(uint64 size, uint64 alignment)
+{
+    uint64 aligned_size = (size + alignment - 1) & ~(alignment - 1);
+
+    return aligned_size > UINT32_MAX ? UINT32_MAX : (uint32)aligned_size;
+}
+
 static bool
 wasm_memory_init_with_pool(void *mem, unsigned int bytes)
 {
@@ -629,147 +637,70 @@ wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
 #endif
 }
 
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-bool
-wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
+static void
+wasm_munmap_linear_memory(void *mapped_mem, uint64 commit_size, uint64 map_size)
 {
-    WASMMemoryInstance *memory = wasm_get_default_memory(module);
-    uint8 *memory_data_old, *memory_data_new, *heap_data_old;
-    uint32 num_bytes_per_page, heap_size, total_size_old = 0;
-    uint32 cur_page_count, max_page_count, total_page_count;
-    uint64 total_size_new;
-    bool ret = true;
-    enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR;
-
-    if (!memory) {
-        ret = false;
-        goto return_func;
-    }
-
-    heap_data_old = memory->heap_data;
-    heap_size = (uint32)(memory->heap_data_end - memory->heap_data);
-
-    memory_data_old = memory->memory_data;
-    total_size_old = memory->memory_data_size;
+#ifdef BH_PLATFORM_WINDOWS
+    os_mem_decommit(mapped_mem, commit_size);
+#else
+    (void)commit_size;
+#endif
+    os_munmap(mapped_mem, map_size);
+}
 
-    num_bytes_per_page = memory->num_bytes_per_page;
-    cur_page_count = memory->cur_page_count;
-    max_page_count = memory->max_page_count;
-    total_page_count = inc_page_count + cur_page_count;
-    total_size_new = num_bytes_per_page * (uint64)total_page_count;
+static void *
+wasm_mremap_linear_memory(void *mapped_mem, uint64 old_size, uint64 new_size,
+                          uint64 commit_size)
+{
+    void *new_mem;
 
-    if (inc_page_count <= 0)
-        /* No need to enlarge memory */
-        return true;
+    bh_assert(new_size > 0);
+    bh_assert(new_size > old_size);
 
-    if (total_page_count < cur_page_count) { /* integer overflow */
-        ret = false;
-        goto return_func;
+    if (mapped_mem) {
+        new_mem = os_mremap(mapped_mem, old_size, new_size);
     }
-
-    if (total_page_count > max_page_count) {
-        failure_reason = MAX_SIZE_REACHED;
-        ret = false;
-        goto return_func;
+    else {
+        new_mem = os_mmap(NULL, new_size, MMAP_PROT_NONE, MMAP_MAP_NONE,
+                          os_get_invalid_handle());
     }
-
-    bh_assert(total_size_new <= 4 * (uint64)BH_GB);
-    if (total_size_new > UINT32_MAX) {
-        /* Resize to 1 page with size 4G-1 */
-        num_bytes_per_page = UINT32_MAX;
-        total_page_count = max_page_count = 1;
-        total_size_new = UINT32_MAX;
+    if (!new_mem) {
+        return NULL;
     }
 
-#if WASM_ENABLE_SHARED_MEMORY != 0
-    if (shared_memory_is_shared(memory)) {
-        memory->num_bytes_per_page = num_bytes_per_page;
-        memory->cur_page_count = total_page_count;
-        memory->max_page_count = max_page_count;
-        SET_LINEAR_MEMORY_SIZE(memory, (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;
+#ifdef BH_PLATFORM_WINDOWS
+    if (commit_size > 0
+        && !os_mem_commit(new_mem, commit_size,
+                          MMAP_PROT_READ | MMAP_PROT_WRITE)) {
+        os_munmap(new_mem, new_size);
+        return NULL;
     }
 #endif
 
-    if (heap_size > 0) {
-        if (mem_allocator_is_heap_corrupted(memory->heap_handle)) {
-            wasm_runtime_show_app_heap_corrupted_prompt();
-            ret = false;
-            goto return_func;
-        }
-    }
-
-    if (!(memory_data_new =
-              wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
-        if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
-            ret = false;
-            goto return_func;
-        }
-        if (memory_data_old) {
-            bh_memcpy_s(memory_data_new, (uint32)total_size_new,
-                        memory_data_old, total_size_old);
-            wasm_runtime_free(memory_data_old);
-        }
-    }
-
-    memset(memory_data_new + total_size_old, 0,
-           (uint32)total_size_new - total_size_old);
-
-    if (heap_size > 0) {
-        if (mem_allocator_migrate(memory->heap_handle,
-                                  (char *)heap_data_old
-                                      + (memory_data_new - memory_data_old),
-                                  heap_size)
-            != 0) {
-            /* Don't return here as memory->memory_data is obsolete and
-               must be updated to be correctly used later. */
-            ret = false;
-        }
+    if (os_mprotect(new_mem, commit_size, MMAP_PROT_READ | MMAP_PROT_WRITE)
+        != 0) {
+        wasm_munmap_linear_memory(new_mem, new_size, new_size);
+        return NULL;
     }
 
-    memory->heap_data = memory_data_new + (heap_data_old - memory_data_old);
-    memory->heap_data_end = memory->heap_data + heap_size;
-
-    memory->num_bytes_per_page = num_bytes_per_page;
-    memory->cur_page_count = total_page_count;
-    memory->max_page_count = max_page_count;
-    memory->memory_data_size = (uint32)total_size_new;
-
-    memory->memory_data = memory_data_new;
-    memory->memory_data_end = memory_data_new + (uint32)total_size_new;
-
-    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 */
-    os_writegsbase(memory_data_new);
-#endif
-
-return_func:
-    if (!ret && enlarge_memory_error_cb) {
-        WASMExecEnv *exec_env =
-            wasm_runtime_get_cur_exec_env((WASMModuleInstanceCommon *)module);
-        bh_assert(exec_env);
-        enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
-                                failure_reason,
-                                (WASMModuleInstanceCommon *)module, exec_env,
-                                enlarge_memory_error_user_data);
-    }
+    return new_mem;
+}
 
-    return ret;
+static void *
+wasm_mmap_linear_memory(uint64_t map_size, uint64 commit_size)
+{
+    return wasm_mremap_linear_memory(NULL, 0, map_size, commit_size);
 }
-#else
+
 bool
 wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
 {
     WASMMemoryInstance *memory = wasm_get_default_memory(module);
-    uint32 num_bytes_per_page, total_size_old = 0;
+    uint8 *memory_data_old, *memory_data_new, *heap_data_old;
+    uint32 num_bytes_per_page, heap_size, total_size_old = 0;
     uint32 cur_page_count, max_page_count, total_page_count;
     uint64 total_size_new;
-    bool ret = true;
+    bool ret = true, full_size_mmaped;
     enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR;
 
     if (!memory) {
@@ -777,10 +708,23 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
         goto return_func;
     }
 
+#ifdef OS_ENABLE_HW_BOUND_CHECK
+    full_size_mmaped = true;
+#elif WASM_ENABLE_SHARED_MEMORY != 0
+    full_size_mmaped = shared_memory_is_shared(memory);
+#else
+    full_size_mmaped = false;
+#endif
+
+    memory_data_old = memory->memory_data;
+    total_size_old = memory->memory_data_size;
+
+    heap_data_old = memory->heap_data;
+    heap_size = (uint32)(memory->heap_data_end - memory->heap_data);
+
     num_bytes_per_page = memory->num_bytes_per_page;
     cur_page_count = memory->cur_page_count;
     max_page_count = memory->max_page_count;
-    total_size_old = num_bytes_per_page * cur_page_count;
     total_page_count = inc_page_count + cur_page_count;
     total_size_new = num_bytes_per_page * (uint64)total_page_count;
 
@@ -807,29 +751,64 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
         total_size_new = UINT32_MAX;
     }
 
+    if (full_size_mmaped) {
 #ifdef BH_PLATFORM_WINDOWS
-    if (!os_mem_commit(memory->memory_data_end,
-                       (uint32)total_size_new - total_size_old,
-                       MMAP_PROT_READ | MMAP_PROT_WRITE)) {
-        ret = false;
-        goto return_func;
-    }
+        if (!os_mem_commit(memory->memory_data_end,
+                           (uint32)total_size_new - total_size_old,
+                           MMAP_PROT_READ | MMAP_PROT_WRITE)) {
+            ret = false;
+            goto return_func;
+        }
 #endif
 
-    if (os_mprotect(memory->memory_data_end,
-                    (uint32)total_size_new - total_size_old,
-                    MMAP_PROT_READ | MMAP_PROT_WRITE)
-        != 0) {
+        if (os_mprotect(memory->memory_data_end,
+                        (uint32)total_size_new - total_size_old,
+                        MMAP_PROT_READ | MMAP_PROT_WRITE)
+            != 0) {
 #ifdef BH_PLATFORM_WINDOWS
-        os_mem_decommit(memory->memory_data_end,
-                        (uint32)total_size_new - total_size_old);
+            os_mem_decommit(memory->memory_data_end,
+                            (uint32)total_size_new - total_size_old);
 #endif
-        ret = false;
-        goto return_func;
+            ret = false;
+            goto return_func;
+        }
     }
+    else {
+        if (heap_size > 0) {
+            if (mem_allocator_is_heap_corrupted(memory->heap_handle)) {
+                wasm_runtime_show_app_heap_corrupted_prompt();
+                ret = false;
+                goto return_func;
+            }
+        }
+
+        if (!(memory_data_new = wasm_mremap_linear_memory(
+                  memory_data_old, total_size_old, (uint32)total_size_new,
+                  (uint32)total_size_new))) {
+            ret = false;
+            goto return_func;
+        }
 
-    /* The increased pages are filled with zero by the OS when os_mmap,
-       no need to memset it again here */
+        if (heap_size > 0) {
+            if (mem_allocator_migrate(memory->heap_handle,
+                                      (char *)heap_data_old
+                                          + (memory_data_new - memory_data_old),
+                                      heap_size)
+                != 0) {
+                /* Don't return here as memory->memory_data is obsolete and
+                must be updated to be correctly used later. */
+                ret = false;
+            }
+        }
+
+        memory->heap_data = memory_data_new + (heap_data_old - memory_data_old);
+        memory->heap_data_end = memory->heap_data + heap_size;
+        memory->memory_data = memory_data_new;
+#if defined(os_writegsbase)
+        /* write base addr of linear memory to GS segment register */
+        os_writegsbase(memory_data_new);
+#endif
+    }
 
     memory->num_bytes_per_page = num_bytes_per_page;
     memory->cur_page_count = total_page_count;
@@ -852,7 +831,6 @@ return_func:
 
     return ret;
 }
-#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
 void
 wasm_runtime_set_enlarge_mem_error_callback(
@@ -879,3 +857,75 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
 
     return ret;
 }
+
+void
+wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst)
+{
+    uint64 map_size;
+
+    bh_assert(memory_inst);
+    bh_assert(memory_inst->memory_data);
+
+#ifndef OS_ENABLE_HW_BOUND_CHECK
+#if WASM_ENABLE_SHARED_MEMORY != 0
+    if (shared_memory_is_shared(memory_inst)) {
+        map_size = (uint64)memory_inst->num_bytes_per_page
+                   * memory_inst->max_page_count;
+    }
+    else
+#endif
+    {
+        map_size = (uint64)memory_inst->num_bytes_per_page
+                   * memory_inst->cur_page_count;
+    }
+#else
+    map_size = 8 * (uint64)BH_GB;
+#endif
+    wasm_munmap_linear_memory(memory_inst->memory_data,
+                              memory_inst->memory_data_size, map_size);
+    memory_inst->memory_data = NULL;
+}
+
+int
+wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
+                            uint64 num_bytes_per_page, uint64 init_page_count,
+                            uint64 max_page_count, uint64 *memory_data_size)
+{
+    uint64 map_size, page_size;
+
+    bh_assert(data);
+    bh_assert(memory_data_size);
+
+#ifndef OS_ENABLE_HW_BOUND_CHECK
+#if WASM_ENABLE_SHARED_MEMORY != 0
+    if (is_shared_memory) {
+        /* Allocate maximum memory size when memory is shared */
+        map_size = max_page_count * num_bytes_per_page;
+    }
+    else
+#endif
+    {
+        map_size = init_page_count * num_bytes_per_page;
+    }
+#else  /* else of OS_ENABLE_HW_BOUND_CHECK */
+    /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
+     *   ea = i + memarg.offset
+     * both i and memarg.offset are u32 in range 0 to 4G
+     * so the range of ea is 0 to 8G
+     */
+    map_size = 8 * (uint64)BH_GB;
+#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
+
+    page_size = os_getpagesize();
+    *memory_data_size = init_page_count * num_bytes_per_page;
+    bh_assert(*memory_data_size <= UINT32_MAX);
+    align_as_and_cast(*memory_data_size, page_size);
+
+    if (map_size > 0) {
+        if (!(*data = wasm_mmap_linear_memory(map_size, *memory_data_size))) {
+            return BHT_ERROR;
+        }
+    }
+
+    return BHT_OK;
+}

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

@@ -42,6 +42,14 @@ void
 wasm_runtime_set_enlarge_mem_error_callback(
     const enlarge_memory_error_callback_t callback, void *user_data);
 
+void
+wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst);
+
+int
+wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
+                            uint64 num_bytes_per_page, uint64 init_page_count,
+                            uint64 max_page_count, uint64 *memory_data_size);
+
 #ifdef __cplusplus
 }
 #endif

+ 388 - 447
core/iwasm/common/wasm_native.c

@@ -194,7 +194,7 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
 {
     NativeSymbolsNode *node, *node_next;
     const char *signature = NULL;
-    void *func_ptr = NULL, *attachment;
+    void *func_ptr = NULL, *attachment = NULL;
 
     node = g_native_symbols_list;
     while (node) {
@@ -618,819 +618,760 @@ wasm_native_destroy()
 
 #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
 static void
-invoke_no_args_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-                 uint32 *argv_ret)
+invoke_no_args_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
+    void (*native_code)(WASMExecEnv *) = func_ptr;
     native_code(exec_env);
 }
 static void
-invoke_no_args_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-                 uint32 *argv_ret)
+invoke_no_args_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *) = func_ptr;
     argv_ret[0] = native_code(exec_env);
 }
 static void
-invoke_no_args_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-                 uint32 *argv_ret)
+invoke_no_args_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env);
+    int64 (*native_code)(WASMExecEnv *) = func_ptr;
+    int64 ret = native_code(exec_env);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_i_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-           uint32 *argv_ret)
+invoke_i_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
+    void (*native_code)(WASMExecEnv *, int32) = func_ptr;
     native_code(exec_env, argv[0]);
 }
 static void
-invoke_i_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-           uint32 *argv_ret)
+invoke_i_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *, int32) = func_ptr;
     argv_ret[0] = native_code(exec_env, argv[0]);
 }
 static void
-invoke_i_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-           uint32 *argv_ret)
+invoke_i_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0]);
+    int64 (*native_code)(WASMExecEnv *, int32) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_I_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-           uint32 *argv_ret)
+invoke_I_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv));
+    void (*native_code)(WASMExecEnv *, int64) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv));
 }
 static void
-invoke_I_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-           uint32 *argv_ret)
+invoke_I_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv));
+    int32 (*native_code)(WASMExecEnv *, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv));
 }
 static void
-invoke_I_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-           uint32 *argv_ret)
+invoke_I_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv));
+    int64 (*native_code)(WASMExecEnv *, int64) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_ii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_ii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
+    void (*native_code)(WASMExecEnv *, int32, int32) = func_ptr;
     native_code(exec_env, argv[0], argv[1]);
 }
 static void
-invoke_ii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_ii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *, int32, int32) = func_ptr;
     argv_ret[0] = native_code(exec_env, argv[0], argv[1]);
 }
 static void
-invoke_ii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_ii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], argv[1]);
+    int64 (*native_code)(WASMExecEnv *, int32, int32) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0], argv[1]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iI_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_iI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1));
+    void (*native_code)(WASMExecEnv *, int32, int64) = func_ptr;
+    native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1));
 }
 static void
-invoke_iI_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_iI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1));
+    int32 (*native_code)(WASMExecEnv *, int32, int64) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1));
 }
 static void
-invoke_iI_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_iI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1));
+    int64 (*native_code)(WASMExecEnv *, int32, int64) = func_ptr;
+    int64 ret =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_Ii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_Ii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2]);
+    void (*native_code)(WASMExecEnv *, int64, int32) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2]);
 }
 static void
-invoke_Ii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_Ii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2]);
+    int32 (*native_code)(WASMExecEnv *, int64, int32) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2]);
 }
 static void
-invoke_Ii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_Ii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2]);
+    int64 (*native_code)(WASMExecEnv *, int64, int32) = func_ptr;
+    int64 ret =
+        native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_II_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_II_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2));
+    void (*native_code)(WASMExecEnv *, int64, int64) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                GET_I64_FROM_ADDR((uint32 *)argv + 2));
 }
 static void
-invoke_II_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_II_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                              GET_I64_FROM_ADDR(argv + 2));
+    int32 (*native_code)(WASMExecEnv *, int64, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2));
 }
 static void
-invoke_II_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-            uint32 *argv_ret)
+invoke_II_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                             GET_I64_FROM_ADDR(argv + 2));
+    int64 (*native_code)(WASMExecEnv *, int64, int64) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
+    void (*native_code)(WASMExecEnv *, int32, int32, int32) = func_ptr;
     native_code(exec_env, argv[0], argv[1], argv[2]);
 }
 static void
-invoke_iii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *, int32, int32, int32) = func_ptr;
     argv_ret[0] = native_code(exec_env, argv[0], argv[1], argv[2]);
 }
 static void
-invoke_iii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], argv[1], argv[2]);
+    int64 (*native_code)(WASMExecEnv *, int32, int32, int32) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0], argv[1], argv[2]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iiI_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], argv[1], GET_I64_FROM_ADDR(argv + 2));
+    void (*native_code)(WASMExecEnv *, int32, int32, int64) = func_ptr;
+    native_code(exec_env, argv[0], argv[1],
+                GET_I64_FROM_ADDR((uint32 *)argv + 2));
 }
 static void
-invoke_iiI_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] =
-        native_code(exec_env, argv[0], argv[1], GET_I64_FROM_ADDR(argv + 2));
+    int32 (*native_code)(WASMExecEnv *, int32, int32, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, argv[0], argv[1],
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2));
 }
 static void
-invoke_iiI_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret =
-        native_code(exec_env, argv[0], argv[1], GET_I64_FROM_ADDR(argv + 2));
+    int64 (*native_code)(WASMExecEnv *, int32, int32, int64) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0], argv[1],
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iIi_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1), argv[3]);
+    void (*native_code)(WASMExecEnv *, int32, int64, int32) = func_ptr;
+    native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                argv[3]);
 }
 static void
-invoke_iIi_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] =
-        native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1), argv[3]);
+    int32 (*native_code)(WASMExecEnv *, int32, int64, int32) = func_ptr;
+    argv_ret[0] = native_code(exec_env, argv[0],
+                              GET_I64_FROM_ADDR((uint32 *)argv + 1), argv[3]);
 }
 static void
-invoke_iIi_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret =
-        native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1), argv[3]);
+    int64 (*native_code)(WASMExecEnv *, int32, int64, int32) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0],
+                            GET_I64_FROM_ADDR((uint32 *)argv + 1), argv[3]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iII_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                GET_I64_FROM_ADDR(argv + 3));
+    void (*native_code)(WASMExecEnv *, int32, int64, int64) = func_ptr;
+    native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                GET_I64_FROM_ADDR((uint32 *)argv + 3));
 }
 static void
-invoke_iII_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                              GET_I64_FROM_ADDR(argv + 3));
+    int32 (*native_code)(WASMExecEnv *, int32, int64, int64) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 3));
 }
 static void
-invoke_iII_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_iII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                             GET_I64_FROM_ADDR(argv + 3));
+    int64 (*native_code)(WASMExecEnv *, int32, int64, int64) = func_ptr;
+    int64 ret =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 3));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_Iii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_Iii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2], argv[3]);
+    void (*native_code)(WASMExecEnv *, int64, int32, int32) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2], argv[3]);
 }
 static void
-invoke_Iii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_Iii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] =
-        native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2], argv[3]);
+    int32 (*native_code)(WASMExecEnv *, int64, int32, int32) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              argv[2], argv[3]);
 }
 static void
-invoke_Iii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_Iii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret =
-        native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2], argv[3]);
+    int64 (*native_code)(WASMExecEnv *, int64, int32, int32) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            argv[2], argv[3]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IiI_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_IiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                GET_I64_FROM_ADDR(argv + 3));
+    void (*native_code)(WASMExecEnv *, int64, int32, int64) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
+                GET_I64_FROM_ADDR((uint32 *)argv + 3));
 }
 static void
-invoke_IiI_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_IiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                              GET_I64_FROM_ADDR(argv + 3));
+    int32 (*native_code)(WASMExecEnv *, int64, int32, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              argv[2], GET_I64_FROM_ADDR((uint32 *)argv + 3));
 }
 static void
-invoke_IiI_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_IiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                             GET_I64_FROM_ADDR(argv + 3));
+    int64 (*native_code)(WASMExecEnv *, int64, int32, int64) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            argv[2], GET_I64_FROM_ADDR((uint32 *)argv + 3));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IIi_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_IIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2),
-                argv[4]);
+    void (*native_code)(WASMExecEnv *, int64, int64, int32) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
 }
 static void
-invoke_IIi_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_IIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                              GET_I64_FROM_ADDR(argv + 2), argv[4]);
+    int32 (*native_code)(WASMExecEnv *, int64, int64, int32) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
 }
 static void
-invoke_IIi_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_IIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                             GET_I64_FROM_ADDR(argv + 2), argv[4]);
+    int64 (*native_code)(WASMExecEnv *, int64, int64, int32) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_III_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_III_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2),
-                GET_I64_FROM_ADDR(argv + 4));
+    void (*native_code)(WASMExecEnv *, int64, int64, int64) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                GET_I64_FROM_ADDR((uint32 *)argv + 4));
 }
 static void
-invoke_III_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_III_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] =
-        native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                    GET_I64_FROM_ADDR(argv + 2), GET_I64_FROM_ADDR(argv + 4));
+    int32 (*native_code)(WASMExecEnv *, int64, int64, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 4));
 }
 static void
-invoke_III_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-             uint32 *argv_ret)
+invoke_III_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret =
-        native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                    GET_I64_FROM_ADDR(argv + 2), GET_I64_FROM_ADDR(argv + 4));
+    int64 (*native_code)(WASMExecEnv *, int64, int64, int64) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 4));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iiii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
+    void (*native_code)(WASMExecEnv *, int32, int32, int32, int32) = func_ptr;
     native_code(exec_env, argv[0], argv[1], argv[2], argv[3]);
 }
 static void
-invoke_iiii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *, int32, int32, int32, int32) = func_ptr;
     argv_ret[0] = native_code(exec_env, argv[0], argv[1], argv[2], argv[3]);
 }
 static void
-invoke_iiii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], argv[1], argv[2], argv[3]);
+    int64 (*native_code)(WASMExecEnv *, int32, int32, int32, int32) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0], argv[1], argv[2], argv[3]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iiiI_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
+    void (*native_code)(WASMExecEnv *, int32, int32, int32, int64) = func_ptr;
     native_code(exec_env, argv[0], argv[1], argv[2],
-                GET_I64_FROM_ADDR(argv + 3));
+                GET_I64_FROM_ADDR((uint32 *)argv + 3));
 }
 static void
-invoke_iiiI_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *, int32, int32, int32, int64) = func_ptr;
     argv_ret[0] = native_code(exec_env, argv[0], argv[1], argv[2],
-                              GET_I64_FROM_ADDR(argv + 3));
+                              GET_I64_FROM_ADDR((uint32 *)argv + 3));
 }
 static void
-invoke_iiiI_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], argv[1], argv[2],
-                             GET_I64_FROM_ADDR(argv + 3));
+    int64 (*native_code)(WASMExecEnv *, int32, int32, int32, int64) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0], argv[1], argv[2],
+                            GET_I64_FROM_ADDR((uint32 *)argv + 3));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iiIi_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], argv[1], GET_I64_FROM_ADDR(argv + 2),
-                argv[4]);
+    void (*native_code)(WASMExecEnv *, int32, int32, int64, int32) = func_ptr;
+    native_code(exec_env, argv[0], argv[1],
+                GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
 }
 static void
-invoke_iiIi_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *, int32, int32, int64, int32) = func_ptr;
     argv_ret[0] = native_code(exec_env, argv[0], argv[1],
-                              GET_I64_FROM_ADDR(argv + 2), argv[4]);
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
 }
 static void
-invoke_iiIi_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], argv[1],
-                             GET_I64_FROM_ADDR(argv + 2), argv[4]);
+    int64 (*native_code)(WASMExecEnv *, int32, int32, int64, int32) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0], argv[1],
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iiII_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], argv[1], GET_I64_FROM_ADDR(argv + 2),
-                GET_I64_FROM_ADDR(argv + 4));
+    void (*native_code)(WASMExecEnv *, int32, int32, int64, int64) = func_ptr;
+    native_code(exec_env, argv[0], argv[1],
+                GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                GET_I64_FROM_ADDR((uint32 *)argv + 4));
 }
 static void
-invoke_iiII_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] =
-        native_code(exec_env, argv[0], argv[1], GET_I64_FROM_ADDR(argv + 2),
-                    GET_I64_FROM_ADDR(argv + 4));
+    int32 (*native_code)(WASMExecEnv *, int32, int32, int64, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, argv[0], argv[1],
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 4));
 }
 static void
-invoke_iiII_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iiII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret =
-        native_code(exec_env, argv[0], argv[1], GET_I64_FROM_ADDR(argv + 2),
-                    GET_I64_FROM_ADDR(argv + 4));
+    int64 (*native_code)(WASMExecEnv *, int32, int32, int64, int64) = func_ptr;
+    int64 ret = native_code(exec_env, argv[0], argv[1],
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 4));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iIii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1), argv[3],
-                argv[4]);
+    void (*native_code)(WASMExecEnv *, int32, int64, int32, int32) = func_ptr;
+    native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                argv[3], argv[4]);
 }
 static void
-invoke_iIii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                              argv[3], argv[4]);
+    int32 (*native_code)(WASMExecEnv *, int32, int64, int32, int32) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    argv[3], argv[4]);
 }
 static void
-invoke_iIii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                             argv[3], argv[4]);
+    int64 (*native_code)(WASMExecEnv *, int32, int64, int32, int32) = func_ptr;
+    int64 ret =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    argv[3], argv[4]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iIiI_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1), argv[3],
-                GET_I64_FROM_ADDR(argv + 4));
+    void (*native_code)(WASMExecEnv *, int32, int64, int32, int64) = func_ptr;
+    native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
 }
 static void
-invoke_iIiI_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                              argv[3], GET_I64_FROM_ADDR(argv + 4));
+    int32 (*native_code)(WASMExecEnv *, int32, int64, int32, int64) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
 }
 static void
-invoke_iIiI_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                             argv[3], GET_I64_FROM_ADDR(argv + 4));
+    int64 (*native_code)(WASMExecEnv *, int32, int64, int32, int64) = func_ptr;
+    int64 ret =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iIIi_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                GET_I64_FROM_ADDR(argv + 3), argv[5]);
+    void (*native_code)(WASMExecEnv *, int32, int64, int64, int32) = func_ptr;
+    native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
 }
 static void
-invoke_iIIi_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                              GET_I64_FROM_ADDR(argv + 3), argv[5]);
+    int32 (*native_code)(WASMExecEnv *, int32, int64, int64, int32) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
 }
 static void
-invoke_iIIi_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                             GET_I64_FROM_ADDR(argv + 3), argv[5]);
+    int64 (*native_code)(WASMExecEnv *, int32, int64, int64, int32) = func_ptr;
+    int64 ret =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iIII_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                GET_I64_FROM_ADDR(argv + 3), GET_I64_FROM_ADDR(argv + 5));
+    void (*native_code)(WASMExecEnv *, int32, int64, int64, int64) = func_ptr;
+    native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                GET_I64_FROM_ADDR((uint32 *)argv + 3),
+                GET_I64_FROM_ADDR((uint32 *)argv + 5));
 }
 static void
-invoke_iIII_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *, int32, int64, int64, int64) = func_ptr;
     argv_ret[0] =
-        native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                    GET_I64_FROM_ADDR(argv + 3), GET_I64_FROM_ADDR(argv + 5));
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 3),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 5));
 }
 static void
-invoke_iIII_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_iIII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret =
-        native_code(exec_env, argv[0], GET_I64_FROM_ADDR(argv + 1),
-                    GET_I64_FROM_ADDR(argv + 3), GET_I64_FROM_ADDR(argv + 5));
+    int64 (*native_code)(WASMExecEnv *, int32, int64, int64, int64) = func_ptr;
+    int64 ret =
+        native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 3),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 5));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_Iiii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_Iiii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2], argv[3], argv[4]);
+    void (*native_code)(WASMExecEnv *, int64, int32, int32, int32) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2], argv[3],
+                argv[4]);
 }
 static void
-invoke_Iiii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_Iiii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                              argv[3], argv[4]);
+    int32 (*native_code)(WASMExecEnv *, int64, int32, int32, int32) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              argv[2], argv[3], argv[4]);
 }
 static void
-invoke_Iiii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_Iiii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                             argv[3], argv[4]);
+    int64 (*native_code)(WASMExecEnv *, int64, int32, int32, int32) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            argv[2], argv[3], argv[4]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IiiI_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2], argv[3],
-                GET_I64_FROM_ADDR(argv + 4));
+    void (*native_code)(WASMExecEnv *, int64, int32, int32, int64) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2], argv[3],
+                GET_I64_FROM_ADDR((uint32 *)argv + 4));
 }
 
 static void
-invoke_IiiI_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                              argv[3], GET_I64_FROM_ADDR(argv + 4));
+    int32 (*native_code)(WASMExecEnv *, int64, int32, int32, int64) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
+                    argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
 }
 
 static void
-invoke_IiiI_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                             argv[3], GET_I64_FROM_ADDR(argv + 4));
+    int64 (*native_code)(WASMExecEnv *, int64, int32, int32, int64) = func_ptr;
+    int64 ret =
+        native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
+                    argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IiIi_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                GET_I64_FROM_ADDR(argv + 3), argv[5]);
+    void (*native_code)(WASMExecEnv *, int64, int32, int64, int32) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
+                GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
 }
 static void
-invoke_IiIi_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                              GET_I64_FROM_ADDR(argv + 3), argv[5]);
+    int32 (*native_code)(WASMExecEnv *, int64, int32, int64, int32) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
+                    GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
 }
 static void
-invoke_IiIi_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                             GET_I64_FROM_ADDR(argv + 3), argv[5]);
+    int64 (*native_code)(WASMExecEnv *, int64, int32, int64, int32) = func_ptr;
+    int64 ret =
+        native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
+                    GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IiII_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                GET_I64_FROM_ADDR(argv + 3), GET_I64_FROM_ADDR(argv + 5));
+    void (*native_code)(WASMExecEnv *, int64, int32, int64, int64) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
+                GET_I64_FROM_ADDR((uint32 *)argv + 3),
+                GET_I64_FROM_ADDR((uint32 *)argv + 5));
 }
 static void
-invoke_IiII_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] =
-        native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                    GET_I64_FROM_ADDR(argv + 3), GET_I64_FROM_ADDR(argv + 5));
+    int32 (*native_code)(WASMExecEnv *, int64, int32, int64, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              argv[2], GET_I64_FROM_ADDR((uint32 *)argv + 3),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 5));
 }
 static void
-invoke_IiII_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IiII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret =
-        native_code(exec_env, GET_I64_FROM_ADDR(argv), argv[2],
-                    GET_I64_FROM_ADDR(argv + 3), GET_I64_FROM_ADDR(argv + 5));
+    int64 (*native_code)(WASMExecEnv *, int64, int32, int64, int64) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            argv[2], GET_I64_FROM_ADDR((uint32 *)argv + 3),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 5));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IIii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2),
-                argv[4], argv[5]);
+    void (*native_code)(WASMExecEnv *, int64, int64, int32, int32) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4], argv[5]);
 }
 static void
-invoke_IIii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                              GET_I64_FROM_ADDR(argv + 2), argv[4], argv[5]);
+    int32 (*native_code)(WASMExecEnv *, int64, int64, int32, int32) = func_ptr;
+    argv_ret[0] =
+        native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4], argv[5]);
 }
 static void
-invoke_IIii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                             GET_I64_FROM_ADDR(argv + 2), argv[4], argv[5]);
+    int64 (*native_code)(WASMExecEnv *, int64, int64, int32, int32) = func_ptr;
+    int64 ret =
+        native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                    GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4], argv[5]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IIiI_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2),
-                argv[4], GET_I64_FROM_ADDR(argv + 5));
+    void (*native_code)(WASMExecEnv *, int64, int64, int32, int64) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4],
+                GET_I64_FROM_ADDR((uint32 *)argv + 5));
 }
 static void
-invoke_IIiI_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                              GET_I64_FROM_ADDR(argv + 2), argv[4],
-                              GET_I64_FROM_ADDR(argv + 5));
+    int32 (*native_code)(WASMExecEnv *, int64, int64, int32, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4],
+                              GET_I64_FROM_ADDR((uint32 *)argv + 5));
 }
 static void
-invoke_IIiI_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                             GET_I64_FROM_ADDR(argv + 2), argv[4],
-                             GET_I64_FROM_ADDR(argv + 5));
+    int64 (*native_code)(WASMExecEnv *, int64, int64, int32, int64) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4],
+                            GET_I64_FROM_ADDR((uint32 *)argv + 5));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IIIi_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2),
-                GET_I64_FROM_ADDR(argv + 4), argv[6]);
+    void (*native_code)(WASMExecEnv *, int64, int64, int64, int32) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                GET_I64_FROM_ADDR((uint32 *)argv + 4), argv[6]);
 }
 static void
-invoke_IIIi_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                              GET_I64_FROM_ADDR(argv + 2),
-                              GET_I64_FROM_ADDR(argv + 4), argv[6]);
+    int32 (*native_code)(WASMExecEnv *, int64, int64, int64, int32) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 4), argv[6]);
 }
 static void
-invoke_IIIi_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(exec_env, GET_I64_FROM_ADDR(argv),
-                             GET_I64_FROM_ADDR(argv + 2),
-                             GET_I64_FROM_ADDR(argv + 4), argv[6]);
+    int64 (*native_code)(WASMExecEnv *, int64, int64, int64, int32) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 4), argv[6]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_IIII_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
-    native_code(exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2),
-                GET_I64_FROM_ADDR(argv + 4), GET_I64_FROM_ADDR(argv + 6));
+    void (*native_code)(WASMExecEnv *, int64, int64, int64, int64) = func_ptr;
+    native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                GET_I64_FROM_ADDR((uint32 *)argv + 4),
+                GET_I64_FROM_ADDR((uint32 *)argv + 6));
 }
 static void
-invoke_IIII_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
-    argv_ret[0] = native_code(
-        exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2),
-        GET_I64_FROM_ADDR(argv + 4), GET_I64_FROM_ADDR(argv + 6));
+    int32 (*native_code)(WASMExecEnv *, int64, int64, int64, int64) = func_ptr;
+    argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 4),
+                              GET_I64_FROM_ADDR((uint32 *)argv + 6));
 }
 static void
-invoke_IIII_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-              uint32 *argv_ret)
+invoke_IIII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret = native_code(
-        exec_env, GET_I64_FROM_ADDR(argv), GET_I64_FROM_ADDR(argv + 2),
-        GET_I64_FROM_ADDR(argv + 4), GET_I64_FROM_ADDR(argv + 6));
+    int64 (*native_code)(WASMExecEnv *, int64, int64, int64, int64) = func_ptr;
+    int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 2),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 4),
+                            GET_I64_FROM_ADDR((uint32 *)argv + 6));
     PUT_I64_TO_ADDR(argv_ret, ret);
 }
 
 static void
-invoke_iiiii_v(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-               uint32 *argv_ret)
+invoke_iiiii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    void (*native_code)() = func_ptr;
+    void (*native_code)(WASMExecEnv *, int32, int32, int32, int32, int32) =
+        func_ptr;
     native_code(exec_env, argv[0], argv[1], argv[2], argv[3], argv[4]);
 }
 static void
-invoke_iiiii_i(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-               uint32 *argv_ret)
+invoke_iiiii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint32 (*native_code)() = func_ptr;
+    int32 (*native_code)(WASMExecEnv *, int32, int32, int32, int32, int32) =
+        func_ptr;
     argv_ret[0] =
         native_code(exec_env, argv[0], argv[1], argv[2], argv[3], argv[4]);
 }
 static void
-invoke_iiiii_I(void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-               uint32 *argv_ret)
+invoke_iiiii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
 {
-    uint64 (*native_code)() = func_ptr;
-    uint64 ret =
+    int64 (*native_code)(WASMExecEnv *, int32, int32, int32, int32, int32) =
+        func_ptr;
+    int64 ret =
         native_code(exec_env, argv[0], argv[1], argv[2], argv[3], argv[4]);
     PUT_I64_TO_ADDR(argv_ret, ret);
 }

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

@@ -785,6 +785,7 @@ align_ptr(const uint8 *p, uint32 b)
             return false;                                    \
     } while (0)
 
+/* NOLINTNEXTLINE */
 #define read_uint16(p, p_end, res)                 \
     do {                                           \
         p = (uint8 *)align_ptr(p, sizeof(uint16)); \
@@ -793,6 +794,7 @@ align_ptr(const uint8 *p, uint32 b)
         p += sizeof(uint16);                       \
     } while (0)
 
+/* NOLINTNEXTLINE */
 #define read_uint32(p, p_end, res)                 \
     do {                                           \
         p = (uint8 *)align_ptr(p, sizeof(uint32)); \
@@ -1702,8 +1704,43 @@ wasm_runtime_dump_perf_profiling(WASMModuleInstanceCommon *module_inst)
     }
 #endif
 }
+
+double
+wasm_runtime_sum_wasm_exec_time(WASMModuleInstanceCommon *inst)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (inst->module_type == Wasm_Module_Bytecode)
+        return wasm_summarize_wasm_execute_time((WASMModuleInstance *)inst);
 #endif
 
+#if WASM_ENABLE_AOT != 0
+    if (inst->module_type == Wasm_Module_AoT)
+        return aot_summarize_wasm_execute_time((AOTModuleInstance *)inst);
+#endif
+
+    return 0.0;
+}
+
+double
+wasm_runtime_get_wasm_func_exec_time(WASMModuleInstanceCommon *inst,
+                                     const char *func_name)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (inst->module_type == Wasm_Module_Bytecode)
+        return wasm_get_wasm_func_exec_time((WASMModuleInstance *)inst,
+                                            func_name);
+#endif
+
+#if WASM_ENABLE_AOT != 0
+    if (inst->module_type == Wasm_Module_AoT)
+        return aot_get_wasm_func_exec_time((AOTModuleInstance *)inst,
+                                           func_name);
+#endif
+
+    return 0.0;
+}
+#endif /* WASM_ENABLE_PERF_PROFILING != 0 */
+
 WASMModuleInstanceCommon *
 wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
 {
@@ -2905,7 +2942,8 @@ copy_string_array(const char *array[], uint32 array_size, char **buf_ptr,
     /* We add +1 to generate null-terminated array of strings */
     total_size = sizeof(char *) * ((uint64)array_size + 1);
     if (total_size >= UINT32_MAX
-        || (total_size > 0 && !(list = wasm_runtime_malloc((uint32)total_size)))
+        /* total_size must be larger than 0, don' check it again */
+        || !(list = wasm_runtime_malloc((uint32)total_size))
         || buf_size >= UINT32_MAX
         || (buf_size > 0 && !(buf = wasm_runtime_malloc((uint32)buf_size)))) {
 
@@ -3536,7 +3574,7 @@ static union {
     char b;
 } __ue = { .a = 1 };
 
-#define is_little_endian() (__ue.b == 1)
+#define is_little_endian() (__ue.b == 1) /* NOLINT */
 
 bool
 wasm_runtime_register_natives(const char *module_name,
@@ -4445,6 +4483,7 @@ typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint64 *, uint64);
 typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint64 *, uint64);
 typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint64 *, uint64);
 
+/* NOLINTBEGIN */
 static volatile Float64FuncPtr invokeNative_Float64 =
     (Float64FuncPtr)(uintptr_t)invokeNative;
 static volatile Float32FuncPtr invokeNative_Float32 =
@@ -4460,6 +4499,7 @@ static volatile VoidFuncPtr invokeNative_Void =
 typedef v128 (*V128FuncPtr)(GenericFunctionPointer, uint64 *, uint64);
 static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative;
 #endif
+/* NOLINTEND */
 
 #if defined(_WIN32) || defined(_WIN32_)
 #define MAX_REG_FLOATS 4

+ 0 - 10
core/iwasm/common/wasm_runtime_common.h

@@ -416,16 +416,6 @@ typedef struct WASMRegisteredModule {
 } WASMRegisteredModule;
 #endif
 
-typedef struct WASMMemoryInstanceCommon {
-    uint32 module_type;
-
-    /* The following uint8[1] member is a dummy just to indicate
-       some module_type dependent members follow.
-       Typically it should be accessed by casting to the corresponding
-       actual module_type dependent structure, not via this member. */
-    uint8 memory_inst_data[1];
-} WASMMemoryInstanceCommon;
-
 typedef package_type_t PackageType;
 typedef wasm_section_t WASMSection, AOTSection;
 

+ 3 - 2
core/iwasm/common/wasm_shared_memory.c

@@ -176,8 +176,9 @@ acquire_wait_info(void *address, AtomicWaitNode *wait_node)
     AtomicWaitInfo *wait_info = NULL;
     bh_list_status ret;
 
-    if (address)
-        wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address);
+    bh_assert(address != NULL);
+
+    wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address);
 
     if (!wait_node) {
         return wait_info;

+ 2 - 0
core/iwasm/common/wasm_suspend_flags.h

@@ -35,6 +35,8 @@ typedef union WASMSuspendFlags {
 #define WASM_SUSPEND_FLAGS_FETCH_AND(s_flags, val) \
     BH_ATOMIC_32_FETCH_AND(s_flags.flags, val)
 
+#define WASM_SUSPEND_FLAG_INHERIT_MASK (~WASM_SUSPEND_FLAG_BLOCKING)
+
 #if WASM_SUSPEND_FLAGS_IS_ATOMIC != 0
 #define WASM_SUSPEND_FLAGS_LOCK(lock) (void)0
 #define WASM_SUSPEND_FLAGS_UNLOCK(lock) (void)0

+ 16 - 5
core/iwasm/compilation/aot_compiler.c

@@ -1050,7 +1050,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
                 uint32 opcode1;
 
                 read_leb_uint32(frame_ip, frame_ip_end, opcode1);
-                opcode = (uint32)opcode1;
+                /* opcode1 was checked in loader and is no larger than
+                   UINT8_MAX */
+                opcode = (uint8)opcode1;
 
 #if WASM_ENABLE_BULK_MEMORY != 0
                 if (WASM_OP_MEMORY_INIT <= opcode
@@ -1211,10 +1213,13 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
             case WASM_OP_ATOMIC_PREFIX:
             {
                 uint8 bin_op, op_type;
+                uint32 opcode1;
+
+                read_leb_uint32(frame_ip, frame_ip_end, opcode1);
+                /* opcode1 was checked in loader and is no larger than
+                   UINT8_MAX */
+                opcode = (uint8)opcode1;
 
-                if (frame_ip < frame_ip_end) {
-                    opcode = *frame_ip++;
-                }
                 if (opcode != WASM_OP_ATOMIC_FENCE) {
                     read_leb_uint32(frame_ip, frame_ip_end, align);
                     read_leb_uint32(frame_ip, frame_ip_end, offset);
@@ -1364,11 +1369,17 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
 #if WASM_ENABLE_SIMD != 0
             case WASM_OP_SIMD_PREFIX:
             {
+                uint32 opcode1;
+
                 if (!comp_ctx->enable_simd) {
                     goto unsupport_simd;
                 }
 
-                opcode = *frame_ip++;
+                read_leb_uint32(frame_ip, frame_ip_end, opcode1);
+                /* opcode1 was checked in loader and is no larger than
+                   UINT8_MAX */
+                opcode = (uint8)opcode1;
+
                 /* follow the order of enum WASMSimdEXTOpcode in
                    wasm_opcode.h */
                 switch (opcode) {

+ 44 - 10
core/iwasm/compilation/aot_emit_aot_file.c

@@ -25,6 +25,7 @@
         }                                                  \
     } while (0)
 
+#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
 static bool
 check_utf8_str(const uint8 *str, uint32 len)
 {
@@ -89,6 +90,7 @@ check_utf8_str(const uint8 *str, uint32 len)
     }
     return (p == p_end);
 }
+#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
 
 /* Internal function in object file */
 typedef struct AOTObjectFunc {
@@ -652,7 +654,8 @@ get_relocations_size(AOTObjectData *obj_data,
         /* ignore the relocations to aot_func_internal#n in text section
            for windows platform since they will be applied in
            aot_emit_text_section */
-        if (!strcmp(relocation_group->section_name, ".text")
+        if ((!strcmp(relocation_group->section_name, ".text")
+             || !strcmp(relocation_group->section_name, ".ltext"))
             && !strncmp(relocation->symbol_name, AOT_FUNC_INTERNAL_PREFIX,
                         strlen(AOT_FUNC_INTERNAL_PREFIX))
             && ((!strncmp(obj_data->comp_ctx->target_arch, "x86_64", 6)
@@ -1111,6 +1114,7 @@ static union {
         EMIT_BUF(s, str_len);                         \
     } while (0)
 
+#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
 static bool
 read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
          uint64 *p_result)
@@ -1309,6 +1313,7 @@ get_name_section_size(AOTCompData *comp_data)
 fail:
     return 0;
 }
+#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
 
 static uint32
 get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
@@ -1815,7 +1820,8 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
         for (i = 0; i < obj_data->relocation_group_count;
              i++, relocation_group++) {
             /* relocation in text section */
-            if (!strcmp(relocation_group->section_name, ".text")) {
+            if ((!strcmp(relocation_group->section_name, ".text")
+                 || !strcmp(relocation_group->section_name, ".ltext"))) {
                 relocation = relocation_group->relocations;
                 relocation_count = relocation_group->relocation_count;
                 for (j = 0; j < relocation_count; j++) {
@@ -2065,6 +2071,7 @@ aot_emit_native_symbol(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
     return true;
 }
 
+#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
 static bool
 aot_emit_name_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
                       AOTCompData *comp_data, AOTCompContext *comp_ctx)
@@ -2090,6 +2097,7 @@ aot_emit_name_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
     LOG_DEBUG("emit name section");
     return true;
 }
+#endif
 
 static bool
 aot_emit_custom_sections(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
@@ -2374,17 +2382,19 @@ aot_resolve_text(AOTObjectData *obj_data)
         while (
             !LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
             if ((name = (char *)LLVMGetSectionName(sec_itr))) {
-                if (!strcmp(name, ".text")) {
+                if (!strcmp(name, ".text") || !strcmp(name, ".ltext")) {
                     obj_data->text = (char *)LLVMGetSectionContents(sec_itr);
                     obj_data->text_size = (uint32)LLVMGetSectionSize(sec_itr);
                 }
-                else if (!strcmp(name, ".text.unlikely.")) {
+                else if (!strcmp(name, ".text.unlikely.")
+                         || !strcmp(name, ".ltext.unlikely.")) {
                     obj_data->text_unlikely =
                         (char *)LLVMGetSectionContents(sec_itr);
                     obj_data->text_unlikely_size =
                         (uint32)LLVMGetSectionSize(sec_itr);
                 }
-                else if (!strcmp(name, ".text.hot.")) {
+                else if (!strcmp(name, ".text.hot.")
+                         || !strcmp(name, ".ltext.hot.")) {
                     obj_data->text_hot =
                         (char *)LLVMGetSectionContents(sec_itr);
                     obj_data->text_hot_size =
@@ -2903,11 +2913,13 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
                     (char *)LLVMGetSectionName(contain_section);
                 LLVMDisposeSectionIterator(contain_section);
 
-                if (!strcmp(contain_section_name, ".text.unlikely.")) {
+                if (!strcmp(contain_section_name, ".text.unlikely.")
+                    || !strcmp(contain_section_name, ".ltext.unlikely.")) {
                     func->text_offset = align_uint(obj_data->text_size, 4)
                                         + LLVMGetSymbolAddress(sym_itr);
                 }
-                else if (!strcmp(contain_section_name, ".text.hot.")) {
+                else if (!strcmp(contain_section_name, ".text.hot.")
+                         || !strcmp(contain_section_name, ".ltext.hot.")) {
                     func->text_offset =
                         align_uint(obj_data->text_size, 4)
                         + align_uint(obj_data->text_unlikely_size, 4)
@@ -2939,12 +2951,14 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
                     (char *)LLVMGetSectionName(contain_section);
                 LLVMDisposeSectionIterator(contain_section);
 
-                if (!strcmp(contain_section_name, ".text.unlikely.")) {
+                if (!strcmp(contain_section_name, ".text.unlikely.")
+                    || !strcmp(contain_section_name, ".ltext.unlikely.")) {
                     func->text_offset_of_aot_func_internal =
                         align_uint(obj_data->text_size, 4)
                         + LLVMGetSymbolAddress(sym_itr);
                 }
-                else if (!strcmp(contain_section_name, ".text.hot.")) {
+                else if (!strcmp(contain_section_name, ".text.hot.")
+                         || !strcmp(contain_section_name, ".ltext.hot.")) {
                     func->text_offset_of_aot_func_internal =
                         align_uint(obj_data->text_size, 4)
                         + align_uint(obj_data->text_unlikely_size, 4)
@@ -3205,6 +3219,12 @@ is_relocation_section_name(AOTObjectData *obj_data, char *section_name)
             || !strcmp(section_name, ".rel.text.unlikely.")
             || !strcmp(section_name, ".rela.text.hot.")
             || !strcmp(section_name, ".rel.text.hot.")
+            || !strcmp(section_name, ".rela.ltext")
+            || !strcmp(section_name, ".rel.ltext")
+            || !strcmp(section_name, ".rela.ltext.unlikely.")
+            || !strcmp(section_name, ".rel.ltext.unlikely.")
+            || !strcmp(section_name, ".rela.ltext.hot.")
+            || !strcmp(section_name, ".rel.ltext.hot.")
             || !strcmp(section_name, ".rela.literal")
             || !strcmp(section_name, ".rela.data")
             || !strcmp(section_name, ".rel.data")
@@ -3243,7 +3263,9 @@ static bool
 is_readonly_section(const char *name)
 {
     return !strcmp(name, ".rel.text") || !strcmp(name, ".rela.text")
-           || !strcmp(name, ".rela.literal") || !strcmp(name, ".text");
+           || !strcmp(name, ".rel.ltext") || !strcmp(name, ".rela.ltext")
+           || !strcmp(name, ".rela.literal") || !strcmp(name, ".text")
+           || !strcmp(name, ".ltext");
 }
 
 static bool
@@ -3336,12 +3358,24 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
                 || !strcmp(relocation_group->section_name, ".rela.text.hot.")) {
                 relocation_group->section_name = ".rela.text";
             }
+            else if (!strcmp(relocation_group->section_name,
+                             ".rela.ltext.unlikely.")
+                     || !strcmp(relocation_group->section_name,
+                                ".rela.ltext.hot.")) {
+                relocation_group->section_name = ".rela.ltext";
+            }
             else if (!strcmp(relocation_group->section_name,
                              ".rel.text.unlikely.")
                      || !strcmp(relocation_group->section_name,
                                 ".rel.text.hot.")) {
                 relocation_group->section_name = ".rel.text";
             }
+            else if (!strcmp(relocation_group->section_name,
+                             ".rel.ltext.unlikely.")
+                     || !strcmp(relocation_group->section_name,
+                                ".rel.ltext.hot.")) {
+                relocation_group->section_name = ".rel.ltext";
+            }
 
             /*
              * Relocations in read-only sections are problematic,

+ 0 - 6
core/iwasm/compilation/aot_llvm.c

@@ -533,18 +533,12 @@ aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
     }
     wasm_runtime_free(params);
     params = NULL;
-
-#if LLVM_VERSION_MAJOR < 17
     if (aot_target_precheck_can_use_musttail(comp_ctx)) {
         LLVMSetTailCallKind(retval, LLVMTailCallKindMustTail);
     }
     else {
         LLVMSetTailCallKind(retval, LLVMTailCallKindTail);
     }
-#else
-    LLVMSetTailCall(retval, true);
-#endif
-
     if (ret_type == VOID_TYPE) {
         if (!LLVMBuildRetVoid(b)) {
             goto fail;

+ 1 - 1
core/iwasm/compilation/aot_llvm_extra2.cpp

@@ -163,7 +163,7 @@ LLVMCreateTargetMachineWithOpts(LLVMTargetRef ctarget, const char *triple,
 }
 
 /* https://reviews.llvm.org/D153107 */
-#if LLVM_VERSION_MAJOR < 17
+#if LLVM_VERSION_MAJOR < 18
 using namespace llvm;
 
 LLVMTailCallKind

+ 1 - 1
core/iwasm/compilation/aot_llvm_extra2.h

@@ -17,7 +17,7 @@ LLVMCreateTargetMachineWithOpts(LLVMTargetRef ctarget, const char *triple,
                                 const char *StackUsageOutput);
 
 /* https://reviews.llvm.org/D153107 */
-#if LLVM_VERSION_MAJOR < 17
+#if LLVM_VERSION_MAJOR < 18
 typedef enum {
     LLVMTailCallKindNone = 0,
     LLVMTailCallKindTail = 1,

+ 20 - 4
core/iwasm/compilation/debug/dwarf_extractor.cpp

@@ -133,9 +133,10 @@ dwarf_gen_file_info(const AOTCompContext *comp_ctx)
         file_name = filespec.GetFilename();
         dir_name = filespec.GetDirectory();
         if (file_name || dir_name) {
-            file_info = LLVMDIBuilderCreateFile(comp_ctx->debug_builder,
-                                                file_name, strlen(file_name),
-                                                dir_name, strlen(dir_name));
+            file_info = LLVMDIBuilderCreateFile(
+                comp_ctx->debug_builder, file_name,
+                file_name ? strlen(file_name) : 0, dir_name,
+                dir_name ? strlen(dir_name) : 0);
         }
     }
     return file_info;
@@ -298,7 +299,7 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
         return NULL;
 
     LLVMDIBuilderRef DIB = comp_ctx->debug_builder;
-    LLVMMetadataRef File = comp_ctx->debug_file;
+    LLVMMetadataRef File = comp_ctx->debug_file; /* a fallback */
 
     LLVMMetadataRef ParamTypes[num_function_args + 1];
 
@@ -315,6 +316,21 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
         }
     }
 
+    auto compile_unit = sc.GetCompileUnit();
+    auto file_spec = compile_unit.GetFileSpec();
+    const char *file_name = file_spec.GetFilename();
+    const char *dir_name = file_spec.GetDirectory();
+    LLVMMetadataRef file_info = NULL;
+    if (file_name || dir_name) {
+        file_info =
+            LLVMDIBuilderCreateFile(comp_ctx->debug_builder, file_name,
+                                    file_name ? strlen(file_name) : 0, dir_name,
+                                    dir_name ? strlen(dir_name) : 0);
+    }
+    if (file_info) {
+        File = file_info;
+    }
+
     LLVMMetadataRef FunctionTy = LLVMDIBuilderCreateSubroutineType(
         DIB, File, ParamTypes, num_function_args + 1, LLVMDIFlagZero);
 

+ 2 - 3
core/iwasm/fast-jit/fe/jit_emit_control.c

@@ -396,9 +396,8 @@ handle_func_return(JitCompContext *cc, JitBlock *block)
 #endif
 
 #if WASM_ENABLE_PERF_PROFILING != 0
-    /* time_end = os_time_get_boot_microsecond() */
-    if (!jit_emit_callnative(cc, os_time_get_boot_microsecond, time_end, NULL,
-                             0)) {
+    /* time_end = os_time_get_boot_us() */
+    if (!jit_emit_callnative(cc, os_time_get_boot_us, time_end, NULL, 0)) {
         return false;
     }
     /* time_start = cur_frame->time_started */

+ 11 - 11
core/iwasm/fast-jit/fe/jit_emit_table.c

@@ -88,17 +88,21 @@ fail:
 }
 
 static int
-wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx,
+wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 seg_idx,
                 uint32 dst_offset, uint32 len, uint32 src_offset)
 {
     WASMTableInstance *tbl;
     uint32 tbl_sz;
-    WASMTableSeg *elem;
-    uint32 elem_len;
+    WASMTableSeg *tbl_seg = inst->module->table_segments + seg_idx;
+    uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
 
-    elem = inst->module->table_segments + elem_idx;
-    elem_len = elem->function_count;
-    if (offset_len_out_of_bounds(src_offset, len, elem_len))
+    if (!bh_bitmap_get_bit(inst->e->common.elem_dropped, seg_idx)) {
+        /* table segment isn't dropped */
+        tbl_seg_elems = tbl_seg->func_indexes;
+        tbl_seg_len = tbl_seg->function_count;
+    }
+
+    if (offset_len_out_of_bounds(src_offset, len, tbl_seg_len))
         goto out_of_bounds;
 
     tbl = inst->tables[tbl_idx];
@@ -109,14 +113,10 @@ wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx,
     if (!len)
         return 0;
 
-    if (bh_bitmap_get_bit(inst->e->common.elem_dropped, elem_idx))
-        goto out_of_bounds;
-
     bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems)
                     + dst_offset * sizeof(uint32),
                 (uint32)((tbl_sz - dst_offset) * sizeof(uint32)),
-                elem->func_indexes + src_offset,
-                (uint32)(len * sizeof(uint32)));
+                tbl_seg_elems + src_offset, (uint32)(len * sizeof(uint32)));
 
     return 0;
 out_of_bounds:

+ 11 - 7
core/iwasm/fast-jit/jit_frontend.c

@@ -1157,11 +1157,10 @@ init_func_translation(JitCompContext *cc)
     func_inst = jit_cc_new_reg_ptr(cc);
 #if WASM_ENABLE_PERF_PROFILING != 0
     time_started = jit_cc_new_reg_I64(cc);
-    /* Call os_time_get_boot_microsecond() to get time_started firstly
+    /* Call os_time_get_boot_us() to get time_started firstly
        as there is stack frame switching below, calling native in them
        may cause register spilling work inproperly */
-    if (!jit_emit_callnative(cc, os_time_get_boot_microsecond, time_started,
-                             NULL, 0)) {
+    if (!jit_emit_callnative(cc, os_time_get_boot_us, time_started, NULL, 0)) {
         return NULL;
     }
 #endif
@@ -2258,7 +2257,9 @@ jit_compile_func(JitCompContext *cc)
                 uint32 opcode1;
 
                 read_leb_uint32(frame_ip, frame_ip_end, opcode1);
-                opcode = (uint32)opcode1;
+                /* opcode1 was checked in loader and is no larger than
+                   UINT8_MAX */
+                opcode = (uint8)opcode1;
 
                 switch (opcode) {
                     case WASM_OP_I32_TRUNC_SAT_S_F32:
@@ -2397,10 +2398,13 @@ jit_compile_func(JitCompContext *cc)
             case WASM_OP_ATOMIC_PREFIX:
             {
                 uint8 bin_op, op_type;
+                uint32 opcode1;
+
+                read_leb_uint32(frame_ip, frame_ip_end, opcode1);
+                /* opcode1 was checked in loader and is no larger than
+                   UINT8_MAX */
+                opcode = (uint8)opcode1;
 
-                if (frame_ip < frame_ip_end) {
-                    opcode = *frame_ip++;
-                }
                 if (opcode != WASM_OP_ATOMIC_FENCE) {
                     read_leb_uint32(frame_ip, frame_ip_end, align);
                     read_leb_uint32(frame_ip, frame_ip_end, offset);

+ 10 - 10
core/iwasm/include/wasm_c_api.h

@@ -22,12 +22,12 @@
 #endif
 
 #if defined(__GNUC__) || defined(__clang__)
-#define DEPRECATED __attribute__((deprecated))
+#define WASM_API_DEPRECATED __attribute__((deprecated))
 #elif defined(_MSC_VER)
-#define DEPRECATED __declspec(deprecated)
+#define WASM_API_DEPRECATED __declspec(deprecated)
 #else
 #pragma message("WARNING: You need to implement DEPRECATED for this compiler")
-#define DEPRECATED
+#define WASM_API_DEPRECATED
 #endif
 
 #ifdef __cplusplus
@@ -231,7 +231,7 @@ WASM_DECLARE_OWN(engine)
  */
 WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(void);
 WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(wasm_config_t*);
-DEPRECATED WASM_API_EXTERN own wasm_engine_t *
+WASM_API_DEPRECATED WASM_API_EXTERN own wasm_engine_t *
 wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts);
 
 // Store
@@ -828,12 +828,12 @@ static inline void* wasm_val_ptr(const wasm_val_t* val) {
 #endif
 }
 
-#define WASM_I32_VAL(i) {.kind = WASM_I32, .of = {.i32 = i}}
-#define WASM_I64_VAL(i) {.kind = WASM_I64, .of = {.i64 = i}}
-#define WASM_F32_VAL(z) {.kind = WASM_F32, .of = {.f32 = z}}
-#define WASM_F64_VAL(z) {.kind = WASM_F64, .of = {.f64 = z}}
-#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .of = {.ref = r}}
-#define WASM_INIT_VAL {.kind = WASM_ANYREF, .of = {.ref = NULL}}
+#define WASM_I32_VAL(i) {.kind = WASM_I32, .__paddings = {0}, .of = {.i32 = i}}
+#define WASM_I64_VAL(i) {.kind = WASM_I64, .__paddings = {0}, .of = {.i64 = i}}
+#define WASM_F32_VAL(z) {.kind = WASM_F32, .__paddings = {0}, .of = {.f32 = z}}
+#define WASM_F64_VAL(z) {.kind = WASM_F64, .__paddings = {0}, .of = {.f64 = z}}
+#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .__paddings = {0}, .of = {.ref = r}}
+#define WASM_INIT_VAL {.kind = WASM_ANYREF, .__paddings = {0}, .of = {.ref = NULL}}
 
 #define KILOBYTE(n) ((n) * 1024)
 

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

@@ -1274,6 +1274,26 @@ wasm_runtime_dump_mem_consumption(wasm_exec_env_t exec_env);
 WASM_RUNTIME_API_EXTERN void
 wasm_runtime_dump_perf_profiling(wasm_module_inst_t module_inst);
 
+/**
+ * Return total wasm functions' execution time in ms
+ *
+ * @param module_inst the WASM module instance to profile
+ */
+WASM_RUNTIME_API_EXTERN double
+wasm_runtime_sum_wasm_exec_time(wasm_module_inst_t module_inst);
+
+/**
+ * Return execution time in ms of a given wasm funciton with
+*  func_name. If the function is not found, return 0.
+ *
+ * @param module_inst the WASM module instance to profile
+ * @param func_name could be an export name or a name in the
+ *                  name section
+ */
+WASM_RUNTIME_API_EXTERN double
+wasm_runtime_get_wasm_func_exec_time(wasm_module_inst_t inst,
+                                     const char *func_name);
+
 /* wasm thread callback function type */
 typedef void *(*wasm_thread_callback_t)(wasm_exec_env_t, void *);
 /* wasm thread type */
@@ -1587,6 +1607,9 @@ wasm_runtime_get_context(wasm_module_inst_t inst, void *key);
  * host functions. It wraps an operation which possibly blocks for long
  * to prepare for async termination.
  *
+ * For simplicity, we recommend to wrap only the very minimum piece of
+ * the code with this. Ideally, just a single system call.
+ *
  * eg.
  *
  *   if (!wasm_runtime_begin_blocking_op(exec_env)) {

+ 67 - 0
core/iwasm/interpreter/wasm.h

@@ -65,6 +65,9 @@ extern "C" {
 #if WASM_ENABLE_BULK_MEMORY != 0
 #define SECTION_TYPE_DATACOUNT 12
 #endif
+#if WASM_ENABLE_TAGS != 0
+#define SECTION_TYPE_TAG 13
+#endif
 
 #define SUB_SECTION_TYPE_MODULE 0
 #define SUB_SECTION_TYPE_FUNC 1
@@ -74,20 +77,34 @@ extern "C" {
 #define IMPORT_KIND_TABLE 1
 #define IMPORT_KIND_MEMORY 2
 #define IMPORT_KIND_GLOBAL 3
+#if WASM_ENABLE_TAGS != 0
+#define IMPORT_KIND_TAG 4
+#endif
 
 #define EXPORT_KIND_FUNC 0
 #define EXPORT_KIND_TABLE 1
 #define EXPORT_KIND_MEMORY 2
 #define EXPORT_KIND_GLOBAL 3
+#if WASM_ENABLE_TAGS != 0
+#define EXPORT_KIND_TAG 4
+#endif
 
 #define LABEL_TYPE_BLOCK 0
 #define LABEL_TYPE_LOOP 1
 #define LABEL_TYPE_IF 2
 #define LABEL_TYPE_FUNCTION 3
+#if WASM_ENABLE_EXCE_HANDLING != 0
+#define LABEL_TYPE_TRY 4
+#define LABEL_TYPE_CATCH 5
+#define LABEL_TYPE_CATCH_ALL 6
+#endif
 
 typedef struct WASMModule WASMModule;
 typedef struct WASMFunction WASMFunction;
 typedef struct WASMGlobal WASMGlobal;
+#if WASM_ENABLE_TAGS != 0
+typedef struct WASMTag WASMTag;
+#endif
 
 typedef union V128 {
     int8 i8x16[16];
@@ -201,6 +218,24 @@ typedef struct WASMFunctionImport {
     bool call_conv_wasm_c_api;
 } WASMFunctionImport;
 
+#if WASM_ENABLE_TAGS != 0
+typedef struct WASMTagImport {
+    char *module_name;
+    char *field_name;
+    uint8 attribute; /* the type of the tag (numerical) */
+    uint32 type;     /* the type of the catch function (numerical)*/
+    WASMType *tag_type;
+    void *tag_ptr_linked;
+
+#if WASM_ENABLE_MULTI_MODULE != 0
+    /* imported tag  pointer after linked */
+    WASMModule *import_module;
+    WASMTag *import_tag_linked;
+    uint32 import_tag_index_linked;
+#endif
+} WASMTagImport;
+#endif
+
 typedef struct WASMGlobalImport {
     char *module_name;
     char *field_name;
@@ -227,6 +262,9 @@ typedef struct WASMImport {
         WASMFunctionImport function;
         WASMTableImport table;
         WASMMemoryImport memory;
+#if WASM_ENABLE_TAGS != 0
+        WASMTagImport tag;
+#endif
         WASMGlobalImport global;
         struct {
             char *module_name;
@@ -265,6 +303,10 @@ struct WASMFunction {
     uint32 const_cell_num;
 #endif
 
+#if WASM_ENABLE_EXCE_HANDLING != 0
+    uint32 exception_handler_count;
+#endif
+
 #if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
     || WASM_ENABLE_WAMR_COMPILER != 0
     /* Whether function has opcode memory.grow */
@@ -294,6 +336,14 @@ struct WASMFunction {
 #endif
 };
 
+#if WASM_ENABLE_TAGS != 0
+struct WASMTag {
+    uint8 attribute; /* the attribute property of the tag (expected to be 0) */
+    uint32 type; /* the type of the tag (expected valid inden in type table) */
+    WASMType *tag_type;
+};
+#endif
+
 struct WASMGlobal {
     uint8 type;
     bool is_mutable;
@@ -420,6 +470,9 @@ struct WASMModule {
     uint32 function_count;
     uint32 table_count;
     uint32 memory_count;
+#if WASM_ENABLE_TAGS != 0
+    uint32 tag_count;
+#endif
     uint32 global_count;
     uint32 export_count;
     uint32 table_seg_count;
@@ -433,11 +486,17 @@ struct WASMModule {
     uint32 import_function_count;
     uint32 import_table_count;
     uint32 import_memory_count;
+#if WASM_ENABLE_TAGS != 0
+    uint32 import_tag_count;
+#endif
     uint32 import_global_count;
 
     WASMImport *import_functions;
     WASMImport *import_tables;
     WASMImport *import_memories;
+#if WASM_ENABLE_TAGS != 0
+    WASMImport *import_tags;
+#endif
     WASMImport *import_globals;
 
     WASMType **types;
@@ -445,6 +504,9 @@ struct WASMModule {
     WASMFunction **functions;
     WASMTable *tables;
     WASMMemory *memories;
+#if WASM_ENABLE_TAGS != 0
+    WASMTag **tags;
+#endif
     WASMGlobal *globals;
     WASMExport *exports;
     WASMTableSeg *table_segments;
@@ -628,6 +690,11 @@ typedef struct WASMBranchBlock {
     uint8 *target_addr;
     uint32 *frame_sp;
     uint32 cell_num;
+#if WASM_ENABLE_EXCE_HANDLING != 0
+    /* in exception handling, label_type needs to be stored to lookup exception
+     * handlers */
+    uint8 label_type;
+#endif
 } WASMBranchBlock;
 
 /**

+ 8 - 0
core/iwasm/interpreter/wasm_interp.h

@@ -34,6 +34,14 @@ typedef struct WASMInterpFrame {
     uint64 time_started;
 #endif
 
+#if WASM_ENABLE_EXCE_HANDLING != 0
+    /* set to true if the callee returns an exception rather than
+     * result values on the stack
+     */
+    bool exception_raised;
+    uint32 tag_index;
+#endif
+
 #if WASM_ENABLE_FAST_INTERP != 0
     /* Return offset of the first return value of current frame,
        the callee will put return values here continuously */

+ 552 - 47
core/iwasm/interpreter/wasm_interp_classic.c

@@ -340,10 +340,19 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
         frame_sp += 2;                    \
     } while (0)
 
+/* in exception handling, label_type needs to be stored to lookup exception
+ * handlers */
+
+#if WASM_ENABLE_EXCE_HANDLING != 0
+#define SET_LABEL_TYPE(_label_type) frame_csp->label_type = _label_type
+#else
+#define SET_LABEL_TYPE(_label_type) (void)0
+#endif
+
 #define PUSH_CSP(_label_type, param_cell_num, cell_num, _target_addr) \
     do {                                                              \
         bh_assert(frame_csp < frame->csp_boundary);                   \
-        /* frame_csp->label_type = _label_type; */                    \
+        SET_LABEL_TYPE(_label_type);                                  \
         frame_csp->cell_num = cell_num;                               \
         frame_csp->begin_addr = frame_ip;                             \
         frame_csp->target_addr = _target_addr;                        \
@@ -394,6 +403,18 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
         frame_sp -= n; \
     } while (0)
 
+#if WASM_ENABLE_EXCE_HANDLING != 0
+/* unwind the CSP to a given label and optionally modify the labeltype  */
+#define UNWIND_CSP(N, T)                                                   \
+    do {                                                                   \
+        /* unwind to function frame  */                                    \
+        frame_csp -= N;                                                    \
+        /* drop handlers and values pushd in try block */                  \
+        frame_sp = (frame_csp - 1)->frame_sp;                              \
+        (frame_csp - 1)->label_type = T ? T : (frame_csp - 1)->label_type; \
+    } while (0)
+#endif
+
 #define SYNC_ALL_TO_FRAME()     \
     do {                        \
         frame->sp = frame_sp;   \
@@ -852,7 +873,7 @@ ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
     if (frame) {
         frame->prev_frame = prev_frame;
 #if WASM_ENABLE_PERF_PROFILING != 0
-        frame->time_started = os_time_get_boot_microsecond();
+        frame->time_started = os_time_thread_cputime_us();
 #endif
     }
     else {
@@ -868,9 +889,13 @@ FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *frame)
 {
 #if WASM_ENABLE_PERF_PROFILING != 0
     if (frame->function) {
-        frame->function->total_exec_time +=
-            os_time_get_boot_microsecond() - frame->time_started;
+        WASMInterpFrame *prev_frame = frame->prev_frame;
+        uint64 elapsed = os_time_thread_cputime_us() - frame->time_started;
+        frame->function->total_exec_time += elapsed;
         frame->function->total_exec_cnt++;
+
+        if (prev_frame && prev_frame->function)
+            prev_frame->function->children_exec_time += elapsed;
     }
 #endif
     wasm_exec_env_free_wasm_frame(exec_env, frame);
@@ -1181,6 +1206,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
     uint32 local_idx, local_offset, global_idx;
     uint8 local_type, *global_addr;
     uint32 cache_index, type_index, param_cell_num, cell_num;
+#if WASM_ENABLE_EXCE_HANDLING != 0
+    int32_t exception_tag_index;
+#endif
     uint8 value_type;
 #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
@@ -1223,6 +1251,390 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
             HANDLE_OP(WASM_OP_NOP) { HANDLE_OP_END(); }
 
+#if WASM_ENABLE_EXCE_HANDLING != 0
+
+            HANDLE_OP(WASM_OP_RETHROW)
+            {
+                int32_t relative_depth;
+                read_leb_int32(frame_ip, frame_ip_end, relative_depth);
+
+                /* No frame found with exception handler; validation should
+                 * catch it */
+                bh_assert(frame_csp >= frame->csp_bottom + relative_depth);
+
+                /* go up the frame stack */
+                WASMBranchBlock *tgtframe = (frame_csp - 1) - relative_depth;
+
+                bh_assert(tgtframe->label_type == LABEL_TYPE_CATCH
+                          || tgtframe->label_type == LABEL_TYPE_CATCH_ALL);
+
+                /* tgtframe points to the frame containing a thrown
+                 * exception */
+
+                uint32 *tgtframe_sp = tgtframe->frame_sp;
+
+                /* frame sp of tgtframe points to catched exception */
+                exception_tag_index = *((uint32 *)tgtframe_sp);
+                tgtframe_sp++;
+
+                /* get tag type */
+                uint8 tag_type_index =
+                    module->module->tags[exception_tag_index]->type;
+                uint32 cell_num_to_copy =
+                    wasm_types[tag_type_index]->param_cell_num;
+
+                /* move exception parameters (if there are any) onto top
+                 * of stack */
+                if (cell_num_to_copy > 0) {
+                    word_copy(frame_sp, tgtframe_sp - cell_num_to_copy,
+                              cell_num_to_copy);
+                }
+
+                frame_sp += cell_num_to_copy;
+                goto find_a_catch_handler;
+            }
+
+            HANDLE_OP(WASM_OP_THROW)
+            {
+                read_leb_int32(frame_ip, frame_ip_end, exception_tag_index);
+
+            /* landing pad for the rethrow ? */
+            find_a_catch_handler:
+            {
+                WASMType *tag_type = NULL;
+                uint32 cell_num_to_copy = 0;
+                if (IS_INVALID_TAGINDEX(exception_tag_index)) {
+                    /*
+                     * invalid exception index,
+                     * generated if a submodule throws an exception
+                     * that has not been imported here
+                     *
+                     * This should result in a branch to the CATCH_ALL block,
+                     * if there is one
+                     */
+                    tag_type = NULL;
+                    cell_num_to_copy = 0;
+                }
+                else {
+                    if (module->e->tags[exception_tag_index].is_import_tag) {
+                        tag_type = module->e->tags[exception_tag_index]
+                                       .u.tag_import->tag_type;
+                    }
+                    else {
+                        tag_type = module->e->tags[exception_tag_index]
+                                       .u.tag->tag_type;
+                    }
+                    cell_num_to_copy = tag_type->param_cell_num;
+                }
+
+                /* browse through frame stack */
+                uint32 relative_depth = 0;
+                do {
+                    POP_CSP_CHECK_OVERFLOW(relative_depth - 1);
+                    WASMBranchBlock *tgtframe = frame_csp - relative_depth - 1;
+
+                    switch (tgtframe->label_type) {
+                        case LABEL_TYPE_BLOCK:
+                        case LABEL_TYPE_IF:
+                        case LABEL_TYPE_LOOP:
+                        case LABEL_TYPE_CATCH:
+                        case LABEL_TYPE_CATCH_ALL:
+                            /*
+                             * skip that blocks in search
+                             * BLOCK, IF and LOOP do not contain handlers and
+                             * cannot catch exceptions.
+                             * blocks marked as CATCH or
+                             * CATCH_ALL did already caugth an exception and can
+                             * only be a target for RETHROW, but cannot catch an
+                             * exception again
+                             */
+                            break;
+                        case LABEL_TYPE_TRY:
+                        {
+                            uint32 handler_number = 0;
+                            uint8 **handlers = (uint8 **)tgtframe->frame_sp;
+                            uint8 *handler = NULL;
+                            while ((handler = handlers[handler_number]) != 0) {
+                                uint8 handler_opcode = *handler;
+                                uint8 *target_addr =
+                                    handler
+                                    + 1; /* first instruction or leb-immediate
+                                            behind the handler opcode */
+                                switch (handler_opcode) {
+                                    case WASM_OP_CATCH:
+                                    {
+                                        int32 lookup_index = 0;
+                                        /* read the tag_index and advance
+                                         * target_addr to the first instruction
+                                         * in the block */
+                                        read_leb_int32(target_addr, 0,
+                                                       lookup_index);
+
+                                        if (exception_tag_index
+                                            == lookup_index) {
+                                            /* set ip */
+                                            frame_ip = target_addr;
+                                            /* save frame_sp (points to
+                                             * exception values) */
+                                            uint32 *frame_sp_old = frame_sp;
+
+                                            UNWIND_CSP(relative_depth,
+                                                       LABEL_TYPE_CATCH);
+
+                                            /* push exception_tag_index and
+                                             * exception values for rethrow */
+                                            PUSH_I32(exception_tag_index);
+                                            if (cell_num_to_copy > 0) {
+                                                word_copy(
+                                                    frame_sp,
+                                                    frame_sp_old
+                                                        - cell_num_to_copy,
+                                                    cell_num_to_copy);
+                                                frame_sp += cell_num_to_copy;
+                                                /* push exception values for
+                                                 * catch
+                                                 */
+                                                word_copy(
+                                                    frame_sp,
+                                                    frame_sp_old
+                                                        - cell_num_to_copy,
+                                                    cell_num_to_copy);
+                                                frame_sp += cell_num_to_copy;
+                                            }
+
+                                            /* advance to handler */
+                                            HANDLE_OP_END();
+                                        }
+                                        break;
+                                    }
+                                    case WASM_OP_DELEGATE:
+                                    {
+                                        int32 lookup_depth = 0;
+                                        /* read the depth */
+                                        read_leb_int32(target_addr, 0,
+                                                       lookup_depth);
+
+                                        /* save frame_sp (points to exception
+                                         * values) */
+                                        uint32 *frame_sp_old = frame_sp;
+
+                                        UNWIND_CSP(relative_depth,
+                                                   LABEL_TYPE_CATCH);
+
+                                        /* leave the block (the delegate is
+                                         * technically not inside the frame) */
+                                        frame_csp--;
+
+                                        /* unwind to delegated frame */
+                                        frame_csp -= lookup_depth;
+
+                                        /* push exception values for catch */
+                                        if (cell_num_to_copy > 0) {
+                                            word_copy(frame_sp,
+                                                      frame_sp_old
+                                                          - cell_num_to_copy,
+                                                      cell_num_to_copy);
+                                            frame_sp += cell_num_to_copy;
+                                        }
+
+                                        /* tag_index is already stored in
+                                         * exception_tag_index */
+                                        goto find_a_catch_handler;
+                                    }
+                                    case WASM_OP_CATCH_ALL:
+                                    {
+                                        /* no immediate */
+                                        /* save frame_sp (points to exception
+                                         * values) */
+                                        uint32 *frame_sp_old = frame_sp;
+                                        /* set ip */
+                                        frame_ip = target_addr;
+
+                                        UNWIND_CSP(relative_depth,
+                                                   LABEL_TYPE_CATCH_ALL);
+
+                                        /* push exception_tag_index and
+                                         * exception values for rethrow */
+                                        PUSH_I32(exception_tag_index);
+                                        if (cell_num_to_copy > 0) {
+                                            word_copy(frame_sp,
+                                                      frame_sp_old
+                                                          - cell_num_to_copy,
+                                                      cell_num_to_copy);
+                                            frame_sp += cell_num_to_copy;
+                                        }
+                                        /* catch_all has no exception values */
+
+                                        /* advance to handler */
+                                        HANDLE_OP_END();
+                                    }
+                                    default:
+                                        wasm_set_exception(
+                                            module, "WASM_OP_THROW found "
+                                                    "unexpected handler type");
+                                        goto got_exception;
+                                }
+                                handler_number++;
+                            }
+                            /* exception not catched in this frame */
+                            break;
+                        }
+                        case LABEL_TYPE_FUNCTION:
+                        {
+                            /* save frame_sp (points to exception values) */
+                            uint32 *frame_sp_old = frame_sp;
+
+                            UNWIND_CSP(relative_depth, LABEL_TYPE_FUNCTION);
+                            /* push exception values for catch
+                             * The values are copied to the CALLER FRAME
+                             * (prev_frame->sp) same behvior ad WASM_OP_RETURN
+                             */
+                            if (cell_num_to_copy > 0) {
+                                word_copy(prev_frame->sp,
+                                          frame_sp_old - cell_num_to_copy,
+                                          cell_num_to_copy);
+                                prev_frame->sp += cell_num_to_copy;
+                            }
+                            *((int32 *)(prev_frame->sp)) = exception_tag_index;
+                            prev_frame->sp++;
+
+                            /* mark frame as raised exception */
+                            wasm_set_exception(module,
+                                               "uncaught wasm exception");
+
+                            /* end of function, treat as WASM_OP_RETURN */
+                            goto return_func;
+                        }
+                        default:
+                            wasm_set_exception(
+                                module,
+                                "unexpected or invalid label in THROW or "
+                                "RETHROW when searching a catch handler");
+                            goto got_exception;
+                    }
+
+                    relative_depth++;
+
+                } while (1);
+            }
+
+                /* something went wrong. normally, we should always find the
+                 * func label. if not, stop the interpreter */
+                wasm_set_exception(
+                    module, "WASM_OP_THROW hit the bottom of the frame stack");
+                goto got_exception;
+            }
+
+            HANDLE_OP(EXT_OP_TRY)
+            {
+                /* read the blocktype */
+                read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                param_cell_num = wasm_types[type_index]->param_cell_num;
+                cell_num = wasm_types[type_index]->ret_cell_num;
+                goto handle_op_try;
+            }
+
+            HANDLE_OP(WASM_OP_TRY)
+            {
+                value_type = *frame_ip++;
+                param_cell_num = 0;
+                cell_num = wasm_value_type_cell_num(value_type);
+
+            handle_op_try:
+
+                cache_index = ((uintptr_t)frame_ip)
+                              & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
+                cache_items = exec_env->block_addr_cache[cache_index];
+                if (cache_items[0].start_addr == frame_ip) {
+                    cache_items[0].start_addr = 0;
+                }
+                if (cache_items[1].start_addr == frame_ip) {
+                    cache_items[1].start_addr = 0;
+                }
+
+                /* start at the first opcode following the try and its blocktype
+                 */
+                uint8 *lookup_cursor = frame_ip;
+                uint8 handler_opcode = WASM_OP_UNREACHABLE;
+
+                /* target_addr filled in when END or DELEGATE is found */
+                PUSH_CSP(LABEL_TYPE_TRY, param_cell_num, cell_num, 0);
+
+                /* reset to begin of block */
+                lookup_cursor = frame_ip;
+                do {
+                    /* lookup the next CATCH, CATCH_ALL or END for this TRY */
+                    if (!wasm_loader_find_block_addr(
+                            exec_env, (BlockAddr *)exec_env->block_addr_cache,
+                            lookup_cursor, (uint8 *)-1, LABEL_TYPE_TRY,
+                            &else_addr, &end_addr)) {
+                        /* something went wrong */
+                        wasm_set_exception(module, "find block address failed");
+                        goto got_exception;
+                    }
+
+                    /* place cursor for continuation past opcode */
+                    lookup_cursor = end_addr + 1;
+
+                    /* end_addr points to CATCH, CATCH_ALL, DELEGATE or END */
+                    handler_opcode = *end_addr;
+                    switch (handler_opcode) {
+                        case WASM_OP_CATCH:
+                            skip_leb(lookup_cursor); /* skip tag_index */
+                            PUSH_I64(end_addr);
+                            break;
+                        case WASM_OP_CATCH_ALL:
+                            PUSH_I64(end_addr);
+                            break;
+                        case WASM_OP_DELEGATE:
+                            skip_leb(lookup_cursor); /* skip depth */
+                            PUSH_I64(end_addr);
+                            /* patch target_addr */
+                            (frame_csp - 1)->target_addr = lookup_cursor;
+                            break;
+                        case WASM_OP_END:
+                            PUSH_I64(0);
+                            /* patch target_addr */
+                            (frame_csp - 1)->target_addr = end_addr;
+                            break;
+                        default:
+                            /* something went wrong */
+                            wasm_set_exception(module,
+                                               "find block address returned an "
+                                               "unexpected opcode");
+                            goto got_exception;
+                    }
+                    /* ... search until the returned address is the END of the
+                     * TRY block */
+                } while (handler_opcode != WASM_OP_END
+                         && handler_opcode != WASM_OP_DELEGATE);
+                /* handler setup on stack complete */
+
+                HANDLE_OP_END();
+            }
+            HANDLE_OP(WASM_OP_CATCH)
+            {
+                /* skip the tag_index */
+                skip_leb(frame_ip);
+                /* leave the frame */
+                POP_CSP_N(0);
+                HANDLE_OP_END();
+            }
+            HANDLE_OP(WASM_OP_CATCH_ALL)
+            {
+                /* leave the frame */
+                POP_CSP_N(0);
+                HANDLE_OP_END();
+            }
+            HANDLE_OP(WASM_OP_DELEGATE)
+            {
+                /* skip the delegate depth */
+                skip_leb(frame_ip);
+                /* leave the frame like WASM_OP_END */
+                POP_CSP();
+                HANDLE_OP_END();
+            }
+#endif
             HANDLE_OP(EXT_OP_BLOCK)
             {
                 read_leb_uint32(frame_ip, frame_ip_end, type_index);
@@ -3096,6 +3508,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                 uint32 opcode1;
 
                 read_leb_uint32(frame_ip, frame_ip_end, opcode1);
+                /* opcode1 was checked in loader and is no larger than
+                   UINT8_MAX */
                 opcode = (uint8)opcode1;
 
                 switch (opcode) {
@@ -3254,6 +3668,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         uint32 tbl_idx, elem_idx;
                         uint32 n, s, d;
                         WASMTableInstance *tbl_inst;
+                        uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
 
                         read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
                         bh_assert(elem_idx < module->module->table_seg_count);
@@ -3267,10 +3682,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         s = (uint32)POP_I32();
                         d = (uint32)POP_I32();
 
-                        if (offset_len_out_of_bounds(
-                                s, n,
+                        if (!bh_bitmap_get_bit(module->e->common.elem_dropped,
+                                               elem_idx)) {
+                            /* table segment isn't dropped */
+                            tbl_seg_elems =
                                 module->module->table_segments[elem_idx]
-                                    .function_count)
+                                    .func_indexes;
+                            tbl_seg_len =
+                                module->module->table_segments[elem_idx]
+                                    .function_count;
+                        }
+
+                        if (offset_len_out_of_bounds(s, n, tbl_seg_len)
                             || offset_len_out_of_bounds(d, n,
                                                         tbl_inst->cur_size)) {
                             wasm_set_exception(module,
@@ -3282,30 +3705,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                             break;
                         }
 
-                        if (bh_bitmap_get_bit(module->e->common.elem_dropped,
-                                              elem_idx)) {
-                            wasm_set_exception(module,
-                                               "out of bounds table access");
-                            goto got_exception;
-                        }
-
-                        if (!wasm_elem_is_passive(
-                                module->module->table_segments[elem_idx]
-                                    .mode)) {
-                            wasm_set_exception(module,
-                                               "out of bounds table access");
-                            goto got_exception;
-                        }
-
                         bh_memcpy_s(
                             (uint8 *)tbl_inst
                                 + offsetof(WASMTableInstance, elems)
                                 + d * sizeof(uint32),
                             (uint32)((tbl_inst->cur_size - d) * sizeof(uint32)),
-                            module->module->table_segments[elem_idx]
-                                    .func_indexes
-                                + s,
-                            (uint32)(n * sizeof(uint32)));
+                            tbl_seg_elems + s, (uint32)(n * sizeof(uint32)));
 
                         break;
                     }
@@ -3436,9 +3841,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #if WASM_ENABLE_SHARED_MEMORY != 0
             HANDLE_OP(WASM_OP_ATOMIC_PREFIX)
             {
-                uint32 offset = 0, align, addr;
+                uint32 offset = 0, align = 0, addr;
+                uint32 opcode1;
 
-                opcode = *frame_ip++;
+                read_leb_uint32(frame_ip, frame_ip_end, opcode1);
+                /* opcode1 was checked in loader and is no larger than
+                   UINT8_MAX */
+                opcode = (uint8)opcode1;
 
                 if (opcode != WASM_OP_ATOMIC_FENCE) {
                     read_leb_uint32(frame_ip, frame_ip_end, align);
@@ -3816,10 +4225,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #endif
 
 #if WASM_ENABLE_LABELS_AS_VALUES != 0
-        HANDLE_OP(WASM_OP_UNUSED_0x06)
-        HANDLE_OP(WASM_OP_UNUSED_0x07)
-        HANDLE_OP(WASM_OP_UNUSED_0x08)
-        HANDLE_OP(WASM_OP_UNUSED_0x09)
         HANDLE_OP(WASM_OP_UNUSED_0x0a)
 #if WASM_ENABLE_TAIL_CALL == 0
         HANDLE_OP(WASM_OP_RETURN_CALL)
@@ -3835,13 +4240,26 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
         HANDLE_OP(WASM_OP_REF_NULL)
         HANDLE_OP(WASM_OP_REF_IS_NULL)
         HANDLE_OP(WASM_OP_REF_FUNC)
+#endif
+#if WASM_ENABLE_EXCE_HANDLING == 0
+        HANDLE_OP(WASM_OP_TRY)
+        HANDLE_OP(WASM_OP_CATCH)
+        HANDLE_OP(WASM_OP_THROW)
+        HANDLE_OP(WASM_OP_RETHROW)
+        HANDLE_OP(WASM_OP_DELEGATE)
+        HANDLE_OP(WASM_OP_CATCH_ALL)
+        HANDLE_OP(EXT_OP_TRY)
+#endif
+#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_SIMD != 0
+        /* SIMD isn't supported by interpreter, but when JIT is
+           enabled, `iwasm --interp <wasm_file>` may be run to
+           trigger the SIMD opcode in interpreter */
+        HANDLE_OP(WASM_OP_SIMD_PREFIX)
 #endif
         HANDLE_OP(WASM_OP_UNUSED_0x14)
         HANDLE_OP(WASM_OP_UNUSED_0x15)
         HANDLE_OP(WASM_OP_UNUSED_0x16)
         HANDLE_OP(WASM_OP_UNUSED_0x17)
-        HANDLE_OP(WASM_OP_UNUSED_0x18)
-        HANDLE_OP(WASM_OP_UNUSED_0x19)
         HANDLE_OP(WASM_OP_UNUSED_0x27)
         /* Used by fast interpreter */
         HANDLE_OP(EXT_OP_SET_LOCAL_FAST_I64)
@@ -3892,6 +4310,50 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             if (cur_func->import_func_inst) {
                 wasm_interp_call_func_import(module, exec_env, cur_func,
                                              prev_frame);
+#if WASM_ENABLE_EXCE_HANDLING != 0
+                char uncaught_exception[128] = { 0 };
+                bool has_exception =
+                    wasm_copy_exception(module, uncaught_exception);
+                if (has_exception
+                    && strstr(uncaught_exception, "uncaught wasm exception")) {
+                    /* fix framesp */
+                    UPDATE_ALL_FROM_FRAME();
+
+                    uint32 import_exception;
+                    /* initialize imported exception index to be invalid */
+                    SET_INVALID_TAGINDEX(import_exception);
+
+                    /* pull external exception */
+                    uint32 ext_exception = POP_I32();
+
+                    /* external function came back with an exception or trap */
+                    /* lookup exception in import tags */
+                    WASMTagInstance *tag = module->e->tags;
+                    for (uint32 t = 0; t < module->module->import_tag_count;
+                         tag++, t++) {
+
+                        /* compare the module and the external index with the
+                         * imort tag data */
+                        if ((cur_func->u.func_import->import_module
+                             == tag->u.tag_import->import_module)
+                            && (ext_exception
+                                == tag->u.tag_import
+                                       ->import_tag_index_linked)) {
+                            /* set the import_exception to the import tag */
+                            import_exception = t;
+                            break;
+                        }
+                    }
+                    /*
+                     * excange the thrown exception (index valid in submodule)
+                     * with the imported exception index (valid in this module)
+                     * if the module did not import the exception,
+                     * that results in a "INVALID_TAGINDEX", that triggers
+                     * an CATCH_ALL block, if there is one.
+                     */
+                    PUSH_I32(import_exception);
+                }
+#endif
             }
             else
 #endif
@@ -3912,19 +4374,58 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             if (memory)
                 linear_mem_size = get_linear_mem_size();
 #endif
-            if (wasm_copy_exception(module, NULL))
+            if (wasm_copy_exception(module, NULL)) {
+#if WASM_ENABLE_EXCE_HANDLING != 0
+                /* the caller raised an exception */
+                char uncaught_exception[128] = { 0 };
+                bool has_exception =
+                    wasm_copy_exception(module, uncaught_exception);
+
+                /* libc_builtin signaled a "exception thrown by stdc++" trap */
+                if (has_exception
+                    && strstr(uncaught_exception,
+                              "exception thrown by stdc++")) {
+                    wasm_set_exception(module, NULL);
+
+                    /* setup internal c++ rethrow */
+                    exception_tag_index = 0;
+                    goto find_a_catch_handler;
+                }
+
+                /* when throw hits the end of a function it signalles with a
+                 * "uncaught wasm exception" trap */
+                if (has_exception
+                    && strstr(uncaught_exception, "uncaught wasm exception")) {
+                    wasm_set_exception(module, NULL);
+                    exception_tag_index = POP_I32();
+
+                    /* rethrow the exception into that frame */
+                    goto find_a_catch_handler;
+                }
+#endif
                 goto got_exception;
+            }
         }
         else {
             WASMFunction *cur_wasm_func = cur_func->u.func;
             WASMType *func_type;
+            uint32 max_stack_cell_num = cur_wasm_func->max_stack_cell_num;
+
+#if WASM_ENABLE_EXCE_HANDLING != 0
+            /* account for exception handlers */
+            /* bundle them here */
+            uint32 eh_size =
+                cur_wasm_func->exception_handler_count * sizeof(uint8 *);
+            max_stack_cell_num += eh_size;
+#endif
 
             func_type = cur_wasm_func->func_type;
 
             all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num
-                           + cur_wasm_func->max_stack_cell_num
+                           + max_stack_cell_num
                            + cur_wasm_func->max_block_num
                                  * (uint32)sizeof(WASMBranchBlock) / 4;
+
             /* param_cell_num, local_cell_num, max_stack_cell_num and
                max_block_num are all no larger than UINT16_MAX (checked
                in loader), all_cell_num must be smaller than 1MB */
@@ -3944,8 +4445,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
             frame_sp = frame->sp_bottom =
                 frame_lp + cur_func->param_cell_num + cur_func->local_cell_num;
-            frame->sp_boundary =
-                frame->sp_bottom + cur_wasm_func->max_stack_cell_num;
+            frame->sp_boundary = frame->sp_bottom + max_stack_cell_num;
 
             frame_csp = frame->csp_bottom =
                 (WASMBranchBlock *)frame->sp_boundary;
@@ -3973,11 +4473,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
         FREE_FRAME(exec_env, frame);
         wasm_exec_env_set_cur_frame(exec_env, prev_frame);
 
-        if (!prev_frame->ip)
+        if (!prev_frame->ip) {
             /* Called from native. */
             return;
+        }
 
         RECOVER_CONTEXT(prev_frame);
+#if WASM_ENABLE_EXCE_HANDLING != 0
+        if (wasm_get_exception(module)) {
+            wasm_set_exception(module, NULL);
+            exception_tag_index = POP_I32();
+            goto find_a_catch_handler;
+        }
+#endif
         HANDLE_OP_END();
     }
 
@@ -4199,14 +4707,11 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
 #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
         /* Quick call if the quick jit entry is registered */
         if (func_type->quick_aot_entry) {
-            void (*invoke_native)(
-                void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
-                uint32 *argv_ret) = func_type->quick_aot_entry;
-            invoke_native(module_inst->func_ptrs[func_idx],
-                          func_type->result_count > 0
-                              ? func_type->types[func_type->param_count]
-                              : VALUE_TYPE_VOID,
-                          exec_env, argv, argv);
+            void (*invoke_native)(void *func_ptr, void *exec_env, uint32 *argv,
+                                  uint32 *argv_ret) =
+                func_type->quick_aot_entry;
+            invoke_native(module_inst->func_ptrs[func_idx], exec_env, argv,
+                          argv);
             ret = !wasm_copy_exception(module_inst, NULL);
         }
         else

+ 44 - 32
core/iwasm/interpreter/wasm_interp_fast.c

@@ -887,7 +887,7 @@ ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
     if (frame) {
         frame->prev_frame = prev_frame;
 #if WASM_ENABLE_PERF_PROFILING != 0
-        frame->time_started = os_time_get_boot_microsecond();
+        frame->time_started = os_time_thread_cputime_us();
 #endif
     }
     else {
@@ -903,9 +903,13 @@ FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *frame)
 {
 #if WASM_ENABLE_PERF_PROFILING != 0
     if (frame->function) {
-        frame->function->total_exec_time +=
-            os_time_get_boot_microsecond() - frame->time_started;
+        WASMInterpFrame *prev_frame = frame->prev_frame;
+        uint64 elapsed = os_time_thread_cputime_us() - frame->time_started;
+        frame->function->total_exec_time += elapsed;
         frame->function->total_exec_cnt++;
+
+        if (prev_frame && prev_frame->function)
+            prev_frame->function->children_exec_time += elapsed;
     }
 #endif
     wasm_exec_env_free_wasm_frame(exec_env, frame);
@@ -1447,6 +1451,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                 goto call_func_from_interp;
             }
 
+#if WASM_ENABLE_EXCE_HANDLING != 0
+            HANDLE_OP(WASM_OP_TRY)
+            HANDLE_OP(WASM_OP_CATCH)
+            HANDLE_OP(WASM_OP_THROW)
+            HANDLE_OP(WASM_OP_RETHROW)
+            HANDLE_OP(WASM_OP_DELEGATE)
+            HANDLE_OP(WASM_OP_CATCH_ALL)
+            HANDLE_OP(EXT_OP_TRY)
+            {
+                wasm_set_exception(module, "unsupported opcode");
+                goto got_exception;
+            }
+#endif
+
             /* parametric instructions */
             HANDLE_OP(WASM_OP_SELECT)
             {
@@ -3031,7 +3049,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                             data = NULL;
                         }
                         else {
-
                             seg_len =
                                 (uint64)module->module->data_segments[segment]
                                     ->data_length;
@@ -3114,6 +3131,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         uint32 tbl_idx, elem_idx;
                         uint32 n, s, d;
                         WASMTableInstance *tbl_inst;
+                        uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
 
                         elem_idx = read_uint32(frame_ip);
                         bh_assert(elem_idx < module->module->table_seg_count);
@@ -3127,10 +3145,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         s = (uint32)POP_I32();
                         d = (uint32)POP_I32();
 
-                        if (offset_len_out_of_bounds(
-                                s, n,
+                        if (!bh_bitmap_get_bit(module->e->common.elem_dropped,
+                                               elem_idx)) {
+                            /* table segment isn't dropped */
+                            tbl_seg_elems =
+                                module->module->table_segments[elem_idx]
+                                    .func_indexes;
+                            tbl_seg_len =
                                 module->module->table_segments[elem_idx]
-                                    .function_count)
+                                    .function_count;
+                        }
+
+                        if (offset_len_out_of_bounds(s, n, tbl_seg_len)
                             || offset_len_out_of_bounds(d, n,
                                                         tbl_inst->cur_size)) {
                             wasm_set_exception(module,
@@ -3142,30 +3168,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                             break;
                         }
 
-                        if (bh_bitmap_get_bit(module->e->common.elem_dropped,
-                                              elem_idx)) {
-                            wasm_set_exception(module,
-                                               "out of bounds table access");
-                            goto got_exception;
-                        }
-
-                        if (!wasm_elem_is_passive(
-                                module->module->table_segments[elem_idx]
-                                    .mode)) {
-                            wasm_set_exception(module,
-                                               "out of bounds table access");
-                            goto got_exception;
-                        }
-
                         bh_memcpy_s(
                             (uint8 *)tbl_inst
                                 + offsetof(WASMTableInstance, elems)
                                 + d * sizeof(uint32),
                             (uint32)((tbl_inst->cur_size - d) * sizeof(uint32)),
-                            module->module->table_segments[elem_idx]
-                                    .func_indexes
-                                + s,
-                            (uint32)(n * sizeof(uint32)));
+                            tbl_seg_elems + s, (uint32)(n * sizeof(uint32)));
                         break;
                     }
                     case WASM_OP_ELEM_DROP:
@@ -3690,10 +3698,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #endif
 
 #if WASM_ENABLE_LABELS_AS_VALUES != 0
-        HANDLE_OP(WASM_OP_UNUSED_0x06)
-        HANDLE_OP(WASM_OP_UNUSED_0x07)
-        HANDLE_OP(WASM_OP_UNUSED_0x08)
-        HANDLE_OP(WASM_OP_UNUSED_0x09)
         HANDLE_OP(WASM_OP_UNUSED_0x0a)
 #if WASM_ENABLE_TAIL_CALL == 0
         HANDLE_OP(WASM_OP_RETURN_CALL)
@@ -3708,6 +3712,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
         HANDLE_OP(WASM_OP_REF_NULL)
         HANDLE_OP(WASM_OP_REF_IS_NULL)
         HANDLE_OP(WASM_OP_REF_FUNC)
+#endif
+#if WASM_ENABLE_EXCE_HANDLING == 0
+        /* if exception handling is disabled, these opcodes issue a trap */
+        HANDLE_OP(WASM_OP_TRY)
+        HANDLE_OP(WASM_OP_CATCH)
+        HANDLE_OP(WASM_OP_THROW)
+        HANDLE_OP(WASM_OP_RETHROW)
+        HANDLE_OP(WASM_OP_DELEGATE)
+        HANDLE_OP(WASM_OP_CATCH_ALL)
+        HANDLE_OP(EXT_OP_TRY)
 #endif
         /* SELECT_T is converted to SELECT or SELECT_64 */
         HANDLE_OP(WASM_OP_SELECT_T)
@@ -3715,8 +3729,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
         HANDLE_OP(WASM_OP_UNUSED_0x15)
         HANDLE_OP(WASM_OP_UNUSED_0x16)
         HANDLE_OP(WASM_OP_UNUSED_0x17)
-        HANDLE_OP(WASM_OP_UNUSED_0x18)
-        HANDLE_OP(WASM_OP_UNUSED_0x19)
         HANDLE_OP(WASM_OP_UNUSED_0x27)
         /* optimized op code */
         HANDLE_OP(WASM_OP_F32_STORE)

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 695 - 79
core/iwasm/interpreter/wasm_loader.c


+ 106 - 66
core/iwasm/interpreter/wasm_mini_loader.c

@@ -3259,6 +3259,17 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
                 u8 = read_uint8(p); /* 0x00 */
                 break;
 
+#if WASM_ENABLE_EXCE_HANDLING != 0
+            case WASM_OP_TRY:
+            case WASM_OP_CATCH:
+            case WASM_OP_THROW:
+            case WASM_OP_RETHROW:
+            case WASM_OP_DELEGATE:
+            case WASM_OP_CATCH_ALL:
+                /* TODO */
+                return false;
+#endif
+
             case WASM_OP_DROP:
             case WASM_OP_SELECT:
             case WASM_OP_DROP_64:
@@ -3481,8 +3492,11 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
                 uint32 opcode1;
 
                 read_leb_uint32(p, p_end, opcode1);
+                /* opcode1 was checked in wasm_loader_prepare_bytecode and
+                   is no larger than UINT8_MAX */
+                opcode = (uint8)opcode1;
 
-                switch (opcode1) {
+                switch (opcode) {
                     case WASM_OP_I32_TRUNC_SAT_S_F32:
                     case WASM_OP_I32_TRUNC_SAT_U_F32:
                     case WASM_OP_I32_TRUNC_SAT_S_F64:
@@ -3538,8 +3552,14 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
 #if WASM_ENABLE_SHARED_MEMORY != 0
             case WASM_OP_ATOMIC_PREFIX:
             {
-                /* atomic_op (1 u8) + memarg (2 u32_leb) */
-                opcode = read_uint8(p);
+                uint32 opcode1;
+
+                /* atomic_op (u32_leb) + memarg (2 u32_leb) */
+                read_leb_uint32(p, p_end, opcode1);
+                /* opcode1 was checked in wasm_loader_prepare_bytecode and
+                   is no larger than UINT8_MAX */
+                opcode = (uint8)opcode1;
+
                 if (opcode != WASM_OP_ATOMIC_FENCE) {
                     skip_leb_uint32(p, p_end); /* align */
                     skip_leb_uint32(p, p_end); /* offset */
@@ -3603,6 +3623,8 @@ typedef struct BranchBlock {
     /* This is used to store available param num for if/else branch, so the else
      * opcode can know how many parameters should be copied to the stack */
     uint32 available_param_num;
+    /* This is used to recover dynamic offset for else branch */
+    uint16 start_dynamic_offset;
 #endif
 
     /* Indicate the operand stack is in polymorphic state.
@@ -5352,18 +5374,15 @@ fail:
  * 1) POP original parameter out;
  * 2) Push and copy original values to dynamic space.
  * The copy instruction format:
- *   Part a: available param count
+ *   Part a: param count
  *   Part b: all param total cell num
  *   Part c: each param's cell_num, src offset and dst offset
  *   Part d: each param's src offset
  *   Part e: each param's dst offset
- * Note: if the stack is in polymorphic state, the actual copied parameters may
- * be fewer than the defined number in block type
  */
 static bool
 copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
-                             uint32 *p_available_param_count, char *error_buf,
-                             uint32 error_buf_size)
+                             char *error_buf, uint32 error_buf_size)
 {
     bool ret = false;
     int16 *frame_offset = NULL;
@@ -5375,91 +5394,72 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
     BlockType *block_type = &block->block_type;
     WASMType *wasm_type = block_type->u.type;
     uint32 param_count = block_type->u.type->param_count;
-    uint32 available_param_count = 0;
     int16 condition_offset = 0;
     bool disable_emit = false;
     int16 operand_offset = 0;
-    uint64 size;
-
-    if (is_if_block)
-        condition_offset = *loader_ctx->frame_offset;
-
-    /* POP original parameter out */
-    for (i = 0; i < param_count; i++) {
-        int32 available_stack_cell =
-            (int32)(loader_ctx->stack_cell_num - block->stack_cell_num);
 
-        if (available_stack_cell <= 0 && block->is_stack_polymorphic)
-            break;
-
-        POP_OFFSET_TYPE(wasm_type->types[param_count - i - 1]);
-        wasm_loader_emit_backspace(loader_ctx, sizeof(int16));
-    }
-    available_param_count = i;
-
-    size =
-        (uint64)available_param_count * (sizeof(*cells) + sizeof(*src_offsets));
+    uint64 size = (uint64)param_count * (sizeof(*cells) + sizeof(*src_offsets));
+    bh_assert(size > 0);
 
     /* For if block, we also need copy the condition operand offset. */
     if (is_if_block)
         size += sizeof(*cells) + sizeof(*src_offsets);
 
     /* Allocate memory for the emit data */
-    if ((size > 0)
-        && !(emit_data = loader_malloc(size, error_buf, error_buf_size)))
+    if (!(emit_data = loader_malloc(size, error_buf, error_buf_size)))
         return false;
 
     cells = emit_data;
     src_offsets = (int16 *)(cells + param_count);
 
+    if (is_if_block)
+        condition_offset = *loader_ctx->frame_offset;
+
+    /* POP original parameter out */
+    for (i = 0; i < param_count; i++) {
+        POP_OFFSET_TYPE(wasm_type->types[param_count - i - 1]);
+        wasm_loader_emit_backspace(loader_ctx, sizeof(int16));
+    }
     frame_offset = loader_ctx->frame_offset;
 
     /* Get each param's cell num and src offset */
-    for (i = 0; i < available_param_count; i++) {
+    for (i = 0; i < param_count; i++) {
         cell = (uint8)wasm_value_type_cell_num(wasm_type->types[i]);
         cells[i] = cell;
         src_offsets[i] = *frame_offset;
         frame_offset += cell;
     }
-
     /* emit copy instruction */
     emit_label(EXT_OP_COPY_STACK_VALUES);
     /* Part a) */
-    emit_uint32(loader_ctx, is_if_block ? available_param_count + 1
-                                        : available_param_count);
+    emit_uint32(loader_ctx, is_if_block ? param_count + 1 : param_count);
     /* Part b) */
     emit_uint32(loader_ctx, is_if_block ? wasm_type->param_cell_num + 1
                                         : wasm_type->param_cell_num);
     /* Part c) */
-    for (i = 0; i < available_param_count; i++)
+    for (i = 0; i < param_count; i++)
         emit_byte(loader_ctx, cells[i]);
     if (is_if_block)
         emit_byte(loader_ctx, 1);
 
     /* Part d) */
-    for (i = 0; i < available_param_count; i++)
+    for (i = 0; i < param_count; i++)
         emit_operand(loader_ctx, src_offsets[i]);
     if (is_if_block)
         emit_operand(loader_ctx, condition_offset);
 
     /* Part e) */
     /* Push to dynamic space. The push will emit the dst offset. */
-    for (i = 0; i < available_param_count; i++)
+    for (i = 0; i < param_count; i++)
         PUSH_OFFSET_TYPE(wasm_type->types[i]);
     if (is_if_block)
         PUSH_OFFSET_TYPE(VALUE_TYPE_I32);
 
-    if (p_available_param_count) {
-        *p_available_param_count = available_param_count;
-    }
-
     ret = true;
 
 fail:
     /* Free the emit data */
-    if (emit_data) {
-        wasm_runtime_free(emit_data);
-    }
+    wasm_runtime_free(emit_data);
 
     return ret;
 }
@@ -5661,6 +5661,7 @@ re_scan:
 
                     BranchBlock *cur_block = loader_ctx->frame_csp - 1;
 #if WASM_ENABLE_FAST_INTERP != 0
+                    uint32 cell_num;
                     available_params = block_type.u.type->param_count;
 #endif
                     for (i = 0; i < block_type.u.type->param_count; i++) {
@@ -5678,6 +5679,13 @@ re_scan:
 
                         POP_TYPE(
                             wasm_type->types[wasm_type->param_count - i - 1]);
+#if WASM_ENABLE_FAST_INTERP != 0
+                        /* decrease the frame_offset pointer accordingly to keep
+                         * consistent with frame_ref stack */
+                        cell_num = wasm_value_type_cell_num(
+                            wasm_type->types[wasm_type->param_count - i - 1]);
+                        loader_ctx->frame_offset -= cell_num;
+#endif
                     }
                 }
 
@@ -5687,12 +5695,26 @@ re_scan:
                 /* Pass parameters to block */
                 if (BLOCK_HAS_PARAM(block_type)) {
                     for (i = 0; i < block_type.u.type->param_count; i++) {
-                        PUSH_TYPE(block_type.u.type->types[i]);
 #if WASM_ENABLE_FAST_INTERP != 0
+                        uint32 cell_num = wasm_value_type_cell_num(
+                            block_type.u.type->types[i]);
                         if (i >= available_params) {
-                            PUSH_OFFSET_TYPE(block_type.u.type->types[i]);
+                            /* If there isn't enough data on stack, push a dummy
+                             * offset to keep the stack consistent with
+                             * frame_ref.
+                             * Since the stack is already in polymorphic state,
+                             * the opcode will not be executed, so the dummy
+                             * offset won't cause any error */
+                            *loader_ctx->frame_offset++ = 0;
+                            if (cell_num > 1) {
+                                *loader_ctx->frame_offset++ = 0;
+                            }
+                        }
+                        else {
+                            loader_ctx->frame_offset += cell_num;
                         }
 #endif
+                        PUSH_TYPE(block_type.u.type->types[i]);
                     }
                 }
 
@@ -5701,9 +5723,8 @@ re_scan:
                     skip_label();
                     if (BLOCK_HAS_PARAM(block_type)) {
                         /* Make sure params are in dynamic space */
-                        if (!copy_params_to_dynamic_space(loader_ctx, false,
-                                                          NULL, error_buf,
-                                                          error_buf_size))
+                        if (!copy_params_to_dynamic_space(
+                                loader_ctx, false, error_buf, error_buf_size))
                             goto fail;
                     }
                     if (opcode == WASM_OP_LOOP) {
@@ -5730,17 +5751,21 @@ re_scan:
                      * recover them before entering else branch.
                      *
                      */
-                    if (if_condition_available && BLOCK_HAS_PARAM(block_type)) {
+                    if (BLOCK_HAS_PARAM(block_type)) {
                         uint64 size;
 
-                        /* skip the if condition operand offset */
-                        wasm_loader_emit_backspace(loader_ctx, sizeof(int16));
+                        /* In polymorphic state, there may be no if condition on
+                         * the stack, so the offset may not emitted */
+                        if (if_condition_available) {
+                            /* skip the if condition operand offset */
+                            wasm_loader_emit_backspace(loader_ctx,
+                                                       sizeof(int16));
+                        }
                         /* skip the if label */
                         skip_label();
                         /* Emit a copy instruction */
                         if (!copy_params_to_dynamic_space(
-                                loader_ctx, true, &block->available_param_num,
-                                error_buf, error_buf_size))
+                                loader_ctx, true, error_buf, error_buf_size))
                             goto fail;
 
                         /* Emit the if instruction */
@@ -5761,9 +5786,8 @@ re_scan:
                                         - size / sizeof(int16),
                                     (uint32)size);
                     }
-                    else {
-                        block->available_param_num = 0;
-                    }
+
+                    block->start_dynamic_offset = loader_ctx->dynamic_offset;
 
                     emit_empty_label_addr_and_frame_ip(PATCH_ELSE);
                     emit_empty_label_addr_and_frame_ip(PATCH_END);
@@ -5807,12 +5831,13 @@ re_scan:
 
 #if WASM_ENABLE_FAST_INTERP != 0
                 /* Recover top param_count values of frame_offset stack */
-                if (block->available_param_num) {
+                if (BLOCK_HAS_PARAM((block_type))) {
                     uint32 size;
-                    size = sizeof(int16) * block->available_param_num;
+                    size = sizeof(int16) * block_type.u.type->param_cell_num;
                     bh_memcpy_s(loader_ctx->frame_offset, size,
                                 block->param_frame_offsets, size);
                     loader_ctx->frame_offset += (size / sizeof(int16));
+                    loader_ctx->dynamic_offset = block->start_dynamic_offset;
                 }
 #endif
 
@@ -5999,11 +6024,11 @@ re_scan:
                      idx--) {
                     ret_type = *(func->func_type->types
                                  + func->func_type->param_count + idx);
-                    POP_TYPE(ret_type);
 #if WASM_ENABLE_FAST_INTERP != 0
                     /* emit the offset after return opcode */
                     POP_OFFSET_TYPE(ret_type);
 #endif
+                    POP_TYPE(ret_type);
                 }
 
                 RESET_STACK();
@@ -6042,10 +6067,10 @@ re_scan:
                 if (func_type->param_count > 0) {
                     for (idx = (int32)(func_type->param_count - 1); idx >= 0;
                          idx--) {
-                        POP_TYPE(func_type->types[idx]);
 #if WASM_ENABLE_FAST_INTERP != 0
                         POP_OFFSET_TYPE(func_type->types[idx]);
 #endif
+                        POP_TYPE(func_type->types[idx]);
                     }
                 }
 
@@ -6123,10 +6148,10 @@ re_scan:
                 if (func_type->param_count > 0) {
                     for (idx = (int32)(func_type->param_count - 1); idx >= 0;
                          idx--) {
-                        POP_TYPE(func_type->types[idx]);
 #if WASM_ENABLE_FAST_INTERP != 0
                         POP_OFFSET_TYPE(func_type->types[idx]);
 #endif
+                        POP_TYPE(func_type->types[idx]);
                     }
                 }
 
@@ -6164,6 +6189,18 @@ re_scan:
                 break;
             }
 
+#if WASM_ENABLE_EXCE_HANDLING != 0
+            case WASM_OP_TRY:
+            case WASM_OP_CATCH:
+            case WASM_OP_THROW:
+            case WASM_OP_RETHROW:
+            case WASM_OP_DELEGATE:
+            case WASM_OP_CATCH_ALL:
+                /* TODO */
+                set_error_buf(error_buf, error_buf_size, "unsupported opcode");
+                goto fail;
+#endif
+
             case WASM_OP_DROP:
             {
                 BranchBlock *cur_block = loader_ctx->frame_csp - 1;
@@ -7436,11 +7473,14 @@ re_scan:
 #if WASM_ENABLE_SHARED_MEMORY != 0
             case WASM_OP_ATOMIC_PREFIX:
             {
-                opcode = read_uint8(p);
+                uint32 opcode1;
+
+                read_leb_uint32(p, p_end, opcode1);
+
 #if WASM_ENABLE_FAST_INTERP != 0
-                emit_byte(loader_ctx, opcode);
+                emit_byte(loader_ctx, opcode1);
 #endif
-                if (opcode != WASM_OP_ATOMIC_FENCE) {
+                if (opcode1 != WASM_OP_ATOMIC_FENCE) {
                     CHECK_MEMORY();
                     read_leb_uint32(p, p_end, align);      /* align */
                     read_leb_uint32(p, p_end, mem_offset); /* offset */
@@ -7451,7 +7491,7 @@ re_scan:
 #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
                 func->has_memory_operations = true;
 #endif
-                switch (opcode) {
+                switch (opcode1) {
                     case WASM_OP_ATOMIC_NOTIFY:
                         POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
                         break;

+ 25 - 14
core/iwasm/interpreter/wasm_opcode.h

@@ -20,11 +20,10 @@ typedef enum WASMOpcode {
     WASM_OP_LOOP = 0x03,        /* loop */
     WASM_OP_IF = 0x04,          /* if */
     WASM_OP_ELSE = 0x05,        /* else */
-
-    WASM_OP_UNUSED_0x06 = 0x06,
-    WASM_OP_UNUSED_0x07 = 0x07,
-    WASM_OP_UNUSED_0x08 = 0x08,
-    WASM_OP_UNUSED_0x09 = 0x09,
+    WASM_OP_TRY = 0x06,         /* try */
+    WASM_OP_CATCH = 0x07,       /* catch* */
+    WASM_OP_THROW = 0x08,       /* throw of a try catch */
+    WASM_OP_RETHROW = 0x09,     /* rethrow of a try catch */
     WASM_OP_UNUSED_0x0a = 0x0a,
 
     WASM_OP_END = 0x0b,                  /* end */
@@ -41,8 +40,9 @@ typedef enum WASMOpcode {
     WASM_OP_UNUSED_0x15 = 0x15,
     WASM_OP_UNUSED_0x16 = 0x16,
     WASM_OP_UNUSED_0x17 = 0x17,
-    WASM_OP_UNUSED_0x18 = 0x18,
-    WASM_OP_UNUSED_0x19 = 0x19,
+
+    WASM_OP_DELEGATE = 0x18,  /* delegate block of the try catch*/
+    WASM_OP_CATCH_ALL = 0x19, /* a catch_all handler in a try block */
 
     /* parametric instructions */
     WASM_OP_DROP = 0x1a,     /* drop */
@@ -268,8 +268,10 @@ typedef enum WASMOpcode {
     EXT_OP_IF = 0xd5,             /* if with blocktype */
     EXT_OP_BR_TABLE_CACHE = 0xd6, /* br_table from cache */
 
+    EXT_OP_TRY = 0xd7, /* try block with blocktype */
+
 #if WASM_ENABLE_DEBUG_INTERP != 0
-    DEBUG_OP_BREAK = 0xd7, /* debug break point */
+    DEBUG_OP_BREAK = 0xd8, /* debug break point */
 #endif
 
     /* Post-MVP extend op prefix */
@@ -683,6 +685,13 @@ typedef enum WASMAtomicEXTOpcode {
 
 #define SET_GOTO_TABLE_ELEM(opcode) [opcode] = HANDLE_OPCODE(opcode)
 
+#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_SIMD != 0
+#define SET_GOTO_TABLE_SIMD_PREFIX_ELEM() \
+    SET_GOTO_TABLE_ELEM(WASM_OP_SIMD_PREFIX),
+#else
+#define SET_GOTO_TABLE_SIMD_PREFIX_ELEM()
+#endif
+
 /*
  * Macro used to generate computed goto tables for the C interpreter.
  */
@@ -696,10 +705,10 @@ typedef enum WASMAtomicEXTOpcode {
         HANDLE_OPCODE(WASM_OP_LOOP),                 /* 0x03 */ \
         HANDLE_OPCODE(WASM_OP_IF),                   /* 0x04 */ \
         HANDLE_OPCODE(WASM_OP_ELSE),                 /* 0x05 */ \
-        HANDLE_OPCODE(WASM_OP_UNUSED_0x06),          /* 0x06 */ \
-        HANDLE_OPCODE(WASM_OP_UNUSED_0x07),          /* 0x07 */ \
-        HANDLE_OPCODE(WASM_OP_UNUSED_0x08),          /* 0x08 */ \
-        HANDLE_OPCODE(WASM_OP_UNUSED_0x09),          /* 0x09 */ \
+        HANDLE_OPCODE(WASM_OP_TRY),                  /* 0x06 */ \
+        HANDLE_OPCODE(WASM_OP_CATCH),                /* 0x07 */ \
+        HANDLE_OPCODE(WASM_OP_THROW),                /* 0x08 */ \
+        HANDLE_OPCODE(WASM_OP_RETHROW),              /* 0x09 */ \
         HANDLE_OPCODE(WASM_OP_UNUSED_0x0a),          /* 0x0a */ \
         HANDLE_OPCODE(WASM_OP_END),                  /* 0x0b */ \
         HANDLE_OPCODE(WASM_OP_BR),                   /* 0x0c */ \
@@ -714,8 +723,8 @@ typedef enum WASMAtomicEXTOpcode {
         HANDLE_OPCODE(WASM_OP_UNUSED_0x15),          /* 0x15 */ \
         HANDLE_OPCODE(WASM_OP_UNUSED_0x16),          /* 0x16 */ \
         HANDLE_OPCODE(WASM_OP_UNUSED_0x17),          /* 0x17 */ \
-        HANDLE_OPCODE(WASM_OP_UNUSED_0x18),          /* 0x18 */ \
-        HANDLE_OPCODE(WASM_OP_UNUSED_0x19),          /* 0x19 */ \
+        HANDLE_OPCODE(WASM_OP_DELEGATE),             /* 0x18 */ \
+        HANDLE_OPCODE(WASM_OP_CATCH_ALL),            /* 0x19 */ \
         HANDLE_OPCODE(WASM_OP_DROP),                 /* 0x1a */ \
         HANDLE_OPCODE(WASM_OP_SELECT),               /* 0x1b */ \
         HANDLE_OPCODE(WASM_OP_SELECT_T),             /* 0x1c */ \
@@ -905,7 +914,9 @@ typedef enum WASMAtomicEXTOpcode {
         HANDLE_OPCODE(EXT_OP_LOOP),                  /* 0xd4 */ \
         HANDLE_OPCODE(EXT_OP_IF),                    /* 0xd5 */ \
         HANDLE_OPCODE(EXT_OP_BR_TABLE_CACHE),        /* 0xd6 */ \
+        HANDLE_OPCODE(EXT_OP_TRY),                   /* 0xd7 */ \
         SET_GOTO_TABLE_ELEM(WASM_OP_MISC_PREFIX),    /* 0xfc */ \
+        SET_GOTO_TABLE_SIMD_PREFIX_ELEM()            /* 0xfd */ \
         SET_GOTO_TABLE_ELEM(WASM_OP_ATOMIC_PREFIX),  /* 0xfe */ \
         DEF_DEBUG_BREAK_HANDLE()                                \
     };

+ 306 - 160
core/iwasm/interpreter/wasm_runtime.c

@@ -141,17 +141,7 @@ memories_deinstantiate(WASMModuleInstance *module_inst,
                     memories[i]->heap_handle = NULL;
                 }
                 if (memories[i]->memory_data) {
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-                    wasm_runtime_free(memories[i]->memory_data);
-#else
-#ifdef BH_PLATFORM_WINDOWS
-                    os_mem_decommit(memories[i]->memory_data,
-                                    memories[i]->num_bytes_per_page
-                                        * memories[i]->cur_page_count);
-#endif
-                    os_munmap((uint8 *)memories[i]->memory_data,
-                              8 * (uint64)BH_GB);
-#endif
+                    wasm_deallocate_linear_memory(memories[i]);
                 }
             }
         }
@@ -173,14 +163,10 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
     uint32 inc_page_count, aux_heap_base, global_idx;
     uint32 bytes_of_last_page, bytes_to_page_end;
     uint8 *global_addr;
-#ifdef OS_ENABLE_HW_BOUND_CHECK
-    uint8 *mapped_mem;
-    uint64 map_size = 8 * (uint64)BH_GB;
-    uint64 page_size = os_getpagesize();
-#endif
 
+    bool is_shared_memory = false;
 #if WASM_ENABLE_SHARED_MEMORY != 0
-    bool is_shared_memory = flags & 0x02 ? true : false;
+    is_shared_memory = flags & 0x02 ? true : false;
 
     /* shared memory */
     if (is_shared_memory && parent != NULL) {
@@ -189,6 +175,10 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
         shared_memory_inc_reference(memory);
         return memory;
     }
+#else
+    (void)parent;
+    (void)memory_idx;
+    (void)flags;
 #endif /* end of WASM_ENABLE_SHARED_MEMORY */
 
     if (heap_size > 0 && module_inst->module->malloc_function != (uint32)-1
@@ -288,72 +278,21 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
                 num_bytes_per_page, init_page_count, max_page_count);
     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 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
-    {
-        /* 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 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
-     * both i and memarg.offset are u32 in range 0 to 4G
-     * so the range of ea is 0 to 8G
-     */
-    if (!(memory->memory_data = mapped_mem =
-              os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE,
-                      os_get_invalid_handle()))) {
-        set_error_buf(error_buf, error_buf_size, "mmap memory failed");
-        goto fail1;
-    }
-
-#ifdef BH_PLATFORM_WINDOWS
-    if (memory_data_size > 0
-        && !os_mem_commit(mapped_mem, 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);
-        goto fail1;
-    }
-#endif
 
-    if (os_mprotect(mapped_mem, memory_data_size,
-                    MMAP_PROT_READ | MMAP_PROT_WRITE)
-        != 0) {
-        set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
-        goto fail2;
+    if (wasm_allocate_linear_memory(&memory->memory_data, is_shared_memory,
+                                    num_bytes_per_page, init_page_count,
+                                    max_page_count, &memory_data_size)
+        != BHT_OK) {
+        set_error_buf(error_buf, error_buf_size,
+                      "allocate linear memory failed");
+        return NULL;
     }
 
-    /* Newly allocated pages are filled with zero by the OS, we don't fill it
-     * again here */
-
-    if (memory_data_size > UINT32_MAX)
-        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;
     memory->cur_page_count = init_page_count;
@@ -370,13 +309,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
 
         if (!(memory->heap_handle = runtime_malloc(
                   (uint64)heap_struct_size, error_buf, error_buf_size))) {
-            goto fail2;
+            goto fail1;
         }
         if (!mem_allocator_create_with_struct_and_pool(
                 memory->heap_handle, heap_struct_size, memory->heap_data,
                 heap_size)) {
             set_error_buf(error_buf, error_buf_size, "init app heap failed");
-            goto fail3;
+            goto fail2;
         }
     }
 
@@ -394,20 +333,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
     LOG_VERBOSE("Memory instantiate success.");
     return memory;
 
-fail3:
+fail2:
     if (heap_size > 0)
         wasm_runtime_free(memory->heap_handle);
-fail2:
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-    if (memory->memory_data)
-        wasm_runtime_free(memory->memory_data);
-#else
-#ifdef BH_PLATFORM_WINDOWS
-    os_mem_decommit(mapped_mem, memory_data_size);
-#endif
-    os_munmap(mapped_mem, map_size);
-#endif
 fail1:
+    if (memory->memory_data)
+        wasm_deallocate_linear_memory(memory);
+
     return NULL;
 }
 
@@ -639,7 +571,7 @@ fail:
  * Destroy function instances.
  */
 static void
-functions_deinstantiate(WASMFunctionInstance *functions, uint32 count)
+functions_deinstantiate(WASMFunctionInstance *functions)
 {
     if (functions) {
         wasm_runtime_free(functions);
@@ -738,6 +670,101 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
     return functions;
 }
 
+#if WASM_ENABLE_TAGS != 0
+/**
+ * Destroy tags instances.
+ */
+static void
+tags_deinstantiate(WASMTagInstance *tags, void **import_tag_ptrs)
+{
+    if (tags) {
+        wasm_runtime_free(tags);
+    }
+    if (import_tag_ptrs) {
+        wasm_runtime_free(import_tag_ptrs);
+    }
+}
+
+/**
+ * Instantiate tags in a module.
+ */
+static WASMTagInstance *
+tags_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
+                 char *error_buf, uint32 error_buf_size)
+{
+    WASMImport *import;
+    uint32 i, tag_count = module->import_tag_count + module->tag_count;
+    uint64 total_size = sizeof(WASMTagInstance) * (uint64)tag_count;
+    WASMTagInstance *tags, *tag;
+
+    if (!(tags = runtime_malloc(total_size, error_buf, error_buf_size))) {
+        return NULL;
+    }
+
+    total_size = sizeof(void *) * (uint64)module->import_tag_count;
+    if (total_size > 0
+        && !(module_inst->e->import_tag_ptrs =
+                 runtime_malloc(total_size, error_buf, error_buf_size))) {
+        wasm_runtime_free(tags);
+        return NULL;
+    }
+
+    /* instantiate tags from import section */
+    tag = tags;
+    import = module->import_tags;
+    for (i = 0; i < module->import_tag_count; i++, import++) {
+        tag->is_import_tag = true;
+        tag->u.tag_import = &import->u.tag;
+        tag->type = import->u.tag.type;
+        tag->attribute = import->u.tag.attribute;
+#if WASM_ENABLE_MULTI_MODULE != 0
+        if (import->u.tag.import_module) {
+            if (!(tag->import_module_inst = get_sub_module_inst(
+                      module_inst, import->u.tag.import_module))) {
+                set_error_buf(error_buf, error_buf_size, "unknown tag");
+                goto fail;
+            }
+
+            if (!(tag->import_tag_inst =
+                      wasm_lookup_tag(tag->import_module_inst,
+                                      import->u.tag.field_name, NULL))) {
+                set_error_buf(error_buf, error_buf_size, "unknown tag");
+                goto fail;
+            }
+
+            /* Copy the imported tag to current instance */
+            module_inst->e->import_tag_ptrs[i] =
+                tag->u.tag_import->import_tag_linked;
+        }
+#endif
+        tag++;
+    }
+
+    /* instantiate tags from tag section */
+    for (i = 0; i < module->tag_count; i++) {
+        tag->is_import_tag = false;
+        tag->type = module->tags[i]->type;
+        tag->u.tag = module->tags[i];
+
+#if WASM_ENABLE_FAST_INTERP != 0
+        /* tag->const_cell_num = function->u.func->const_cell_num; */
+#endif
+        tag++;
+    }
+    bh_assert((uint32)(tag - tags) == tag_count);
+
+    return tags;
+
+#if WASM_ENABLE_MULTI_MODULE != 0
+fail:
+    tags_deinstantiate(tags, module_inst->e->import_tag_ptrs);
+    /* clean up */
+    module_inst->e->import_tag_ptrs = NULL;
+    return NULL;
+#endif
+}
+#endif
+
 /**
  * Destroy global instances.
  */
@@ -937,6 +964,52 @@ export_functions_instantiate(const WASMModule *module,
     return export_funcs;
 }
 
+#if WASM_ENABLE_TAGS != 0
+/**
+ * Destroy export function instances.
+ */
+static void
+export_tags_deinstantiate(WASMExportTagInstance *tags)
+{
+    if (tags)
+        wasm_runtime_free(tags);
+}
+
+/**
+ * Instantiate export functions in a module.
+ */
+static WASMExportTagInstance *
+export_tags_instantiate(const WASMModule *module,
+                        WASMModuleInstance *module_inst,
+                        uint32 export_tag_count, char *error_buf,
+                        uint32 error_buf_size)
+{
+    WASMExportTagInstance *export_tags, *export_tag;
+    WASMExport *export = module->exports;
+    uint32 i;
+    uint64 total_size =
+        sizeof(WASMExportTagInstance) * (uint64)export_tag_count;
+
+    if (!(export_tag = export_tags =
+              runtime_malloc(total_size, error_buf, error_buf_size))) {
+        return NULL;
+    }
+
+    for (i = 0; i < module->export_count; i++, export ++)
+        if (export->kind == EXPORT_KIND_TAG) {
+            export_tag->name = export->name;
+
+            bh_assert(module_inst->e->tags);
+
+            export_tag->tag = &module_inst->e->tags[export->index];
+            export_tag++;
+        }
+
+    bh_assert((uint32)(export_tag - export_tags) == export_tag_count);
+    return export_tags;
+}
+#endif
+
 #if WASM_ENABLE_MULTI_MODULE != 0
 static void
 export_globals_deinstantiate(WASMExportGlobInstance *globals)
@@ -1426,6 +1499,7 @@ set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode,
 
 #if !(WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \
       && WASM_ENABLE_LAZY_JIT != 0) /* No possible multi-tier JIT */
+    (void)first_time_set;
     module_inst->e->running_mode = running_mode;
 
     if (running_mode == Mode_Interp) {
@@ -1676,6 +1750,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
                           "failed to allocate bitmaps");
             goto fail;
         }
+        for (i = 0; i < module->data_seg_count; i++) {
+            if (!module->data_segments[i]->is_passive)
+                bh_bitmap_set_bit(module_inst->e->common.data_dropped, i);
+        }
     }
 #endif
 #if WASM_ENABLE_REF_TYPES != 0
@@ -1688,6 +1766,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
                           "failed to allocate bitmaps");
             goto fail;
         }
+        for (i = 0; i < module->table_seg_count; i++) {
+            if (wasm_elem_is_active(module->table_segments[i].mode))
+                bh_bitmap_set_bit(module_inst->e->common.elem_dropped, i);
+        }
     }
 #endif
 
@@ -1718,6 +1800,9 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
     module_inst->table_count = module->import_table_count + module->table_count;
     module_inst->e->function_count =
         module->import_function_count + module->function_count;
+#if WASM_ENABLE_TAGS != 0
+    module_inst->e->tag_count = module->import_tag_count + module->tag_count;
+#endif
 
     /* export */
     module_inst->export_func_count = get_export_count(module, EXPORT_KIND_FUNC);
@@ -1726,11 +1811,15 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
         get_export_count(module, EXPORT_KIND_TABLE);
     module_inst->export_memory_count =
         get_export_count(module, EXPORT_KIND_MEMORY);
+#if WASM_ENABLE_TAGS != 0
+    module_inst->e->export_tag_count =
+        get_export_count(module, EXPORT_KIND_TAG);
+#endif
     module_inst->export_global_count =
         get_export_count(module, EXPORT_KIND_GLOBAL);
 #endif
 
-    /* Instantiate memories/tables/functions */
+    /* Instantiate memories/tables/functions/tags */
     if ((module_inst->memory_count > 0
          && !(module_inst->memories =
                   memories_instantiate(module, module_inst, parent, heap_size,
@@ -1746,6 +1835,15 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
             && !(module_inst->export_functions = export_functions_instantiate(
                      module, module_inst, module_inst->export_func_count,
                      error_buf, error_buf_size)))
+#if WASM_ENABLE_TAGS != 0
+        || (module_inst->e->tag_count > 0
+            && !(module_inst->e->tags = tags_instantiate(
+                     module, module_inst, error_buf, error_buf_size)))
+        || (module_inst->e->export_tag_count > 0
+            && !(module_inst->e->export_tags = export_tags_instantiate(
+                     module, module_inst, module_inst->e->export_tag_count,
+                     error_buf, error_buf_size)))
+#endif
 #if WASM_ENABLE_MULTI_MODULE != 0
         || (module_inst->export_global_count > 0
             && !(module_inst->export_globals = export_globals_instantiate(
@@ -1763,7 +1861,6 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
     ) {
         goto fail;
     }
-
     if (global_count > 0) {
         /* Initialize the global data */
         global_data = module_inst->global_data;
@@ -2184,10 +2281,16 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
     }
 
     tables_deinstantiate(module_inst);
-    functions_deinstantiate(module_inst->e->functions,
-                            module_inst->e->function_count);
+    functions_deinstantiate(module_inst->e->functions);
+#if WASM_ENABLE_TAGS != 0
+    tags_deinstantiate(module_inst->e->tags, module_inst->e->import_tag_ptrs);
+#endif
     globals_deinstantiate(module_inst->e->globals);
     export_functions_deinstantiate(module_inst->export_functions);
+#if WASM_ENABLE_TAGS != 0
+    export_tags_deinstantiate(module_inst->e->export_tags);
+#endif
+
 #if WASM_ENABLE_MULTI_MODULE != 0
     export_globals_deinstantiate(module_inst->export_globals);
 #endif
@@ -2268,6 +2371,21 @@ wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name)
     (void)module_inst->export_tables;
     return module_inst->tables[0];
 }
+
+#if WASM_ENABLE_TAGS != 0
+WASMTagInstance *
+wasm_lookup_tag(const WASMModuleInstance *module_inst, const char *name,
+                const char *signature)
+{
+    uint32 i;
+    for (i = 0; i < module_inst->e->export_tag_count; i++)
+        if (!strcmp(module_inst->e->export_tags[i].name, name))
+            return module_inst->e->export_tags[i].tag;
+    (void)signature;
+    return NULL;
+}
+#endif
+
 #endif
 
 #ifdef OS_ENABLE_HW_BOUND_CHECK
@@ -2398,53 +2516,103 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
     return !wasm_copy_exception(module_inst, NULL);
 }
 
+#if WASM_ENABLE_PERF_PROFILING != 0 || WASM_ENABLE_DUMP_CALL_STACK != 0
+/* look for the function name */
+static char *
+get_func_name_from_index(const WASMModuleInstance *inst, uint32 func_index)
+{
+    char *func_name = NULL;
+    WASMFunctionInstance *func_inst = inst->e->functions + func_index;
+
+    if (func_inst->is_import_func) {
+        func_name = func_inst->u.func_import->field_name;
+    }
+    else {
+#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
+        func_name = func_inst->u.func->field_name;
+#endif
+        /* if custom name section is not generated,
+            search symbols from export table */
+        if (!func_name) {
+            unsigned j;
+            for (j = 0; j < inst->export_func_count; j++) {
+                WASMExportFuncInstance *export_func =
+                    inst->export_functions + j;
+                if (export_func->function == func_inst) {
+                    func_name = export_func->name;
+                    break;
+                }
+            }
+        }
+    }
+
+    return func_name;
+}
+#endif /*WASM_ENABLE_PERF_PROFILING != 0 || WASM_ENABLE_DUMP_CALL_STACK != 0*/
+
 #if WASM_ENABLE_PERF_PROFILING != 0
 void
 wasm_dump_perf_profiling(const WASMModuleInstance *module_inst)
 {
-    WASMExportFuncInstance *export_func;
     WASMFunctionInstance *func_inst;
     char *func_name;
-    uint32 i, j;
+    uint32 i;
 
     os_printf("Performance profiler data:\n");
     for (i = 0; i < module_inst->e->function_count; i++) {
         func_inst = module_inst->e->functions + i;
-        if (func_inst->is_import_func) {
-            func_name = func_inst->u.func_import->field_name;
-        }
-#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
-        else if (func_inst->u.func->field_name) {
-            func_name = func_inst->u.func->field_name;
-        }
-#endif
-        else {
-            func_name = NULL;
-            for (j = 0; j < module_inst->export_func_count; j++) {
-                export_func = module_inst->export_functions + j;
-                if (export_func->function == func_inst) {
-                    func_name = export_func->name;
-                    break;
-                }
-            }
-        }
 
+        if (func_inst->total_exec_cnt == 0)
+            continue;
+
+        func_name = get_func_name_from_index(module_inst, i);
         if (func_name)
             os_printf(
                 "  func %s, execution time: %.3f ms, execution count: %" PRIu32
-                " times\n",
-                func_name,
-                module_inst->e->functions[i].total_exec_time / 1000.0f,
-                module_inst->e->functions[i].total_exec_cnt);
+                " times, children execution time: %.3f ms\n",
+                func_name, func_inst->total_exec_time / 1000.0f,
+                func_inst->total_exec_cnt,
+                func_inst->children_exec_time / 1000.0f);
         else
             os_printf("  func %" PRIu32
                       ", execution time: %.3f ms, execution count: %" PRIu32
-                      " times\n",
-                      i, module_inst->e->functions[i].total_exec_time / 1000.0f,
-                      module_inst->e->functions[i].total_exec_cnt);
+                      " times, children execution time: %.3f ms\n",
+                      i, func_inst->total_exec_time / 1000.0f,
+                      func_inst->total_exec_cnt,
+                      func_inst->children_exec_time / 1000.0f);
     }
 }
-#endif
+
+double
+wasm_summarize_wasm_execute_time(const WASMModuleInstance *inst)
+{
+    double ret = 0;
+
+    unsigned i;
+    for (i = 0; i < inst->e->function_count; i++) {
+        WASMFunctionInstance *func = inst->e->functions + i;
+        ret += (func->total_exec_time - func->children_exec_time) / 1000.0f;
+    }
+
+    return ret;
+}
+
+double
+wasm_get_wasm_func_exec_time(const WASMModuleInstance *inst,
+                             const char *func_name)
+{
+    unsigned i;
+    for (i = 0; i < inst->e->function_count; i++) {
+        char *name_in_wasm = get_func_name_from_index(inst, i);
+        if (name_in_wasm && strcmp(name_in_wasm, func_name) == 0) {
+            WASMFunctionInstance *func = inst->e->functions + i;
+            return (func->total_exec_time - func->children_exec_time) / 1000.0f;
+        }
+    }
+
+    return -1.0;
+}
+#endif /*WASM_ENABLE_PERF_PROFILING != 0*/
 
 uint32
 wasm_module_malloc_internal(WASMModuleInstance *module_inst,
@@ -2939,29 +3107,7 @@ wasm_interp_create_call_stack(struct WASMExecEnv *exec_env)
             frame.func_offset = (uint32)(cur_frame->ip - func_code_base);
         }
 
-        /* look for the function name */
-        if (func_inst->is_import_func) {
-            func_name = func_inst->u.func_import->field_name;
-        }
-        else {
-#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
-            func_name = func_inst->u.func->field_name;
-#endif
-            /* if custom name section is not generated,
-                search symbols from export table */
-            if (!func_name) {
-                uint32 i;
-                for (i = 0; i < module_inst->export_func_count; i++) {
-                    WASMExportFuncInstance *export_func =
-                        module_inst->export_functions + i;
-                    if (export_func->function == func_inst) {
-                        func_name = export_func->name;
-                        break;
-                    }
-                }
-            }
-        }
-
+        func_name = get_func_name_from_index(module_inst, frame.func_index);
         frame.func_name_wp = func_name;
 
         if (!bh_vector_append(module_inst->frames, &frame)) {
@@ -3256,6 +3402,7 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
 {
     WASMTableInstance *tbl_inst;
     WASMTableSeg *tbl_seg;
+    uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
 
     bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
 
@@ -3265,31 +3412,26 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
     bh_assert(tbl_inst);
     bh_assert(tbl_seg);
 
-    if (offset_len_out_of_bounds(src_offset, length, tbl_seg->function_count)
-        || offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
-        jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
-        return;
-    }
-
-    if (!length) {
-        return;
+    if (!bh_bitmap_get_bit(module_inst->e->common.elem_dropped, tbl_seg_idx)) {
+        /* table segment isn't dropped */
+        tbl_seg_elems = tbl_seg->func_indexes;
+        tbl_seg_len = tbl_seg->function_count;
     }
 
-    if (bh_bitmap_get_bit(module_inst->e->common.elem_dropped, tbl_seg_idx)) {
+    if (offset_len_out_of_bounds(src_offset, length, tbl_seg_len)
+        || offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
         jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
         return;
     }
 
-    if (!wasm_elem_is_passive(tbl_seg->mode)) {
-        jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
+    if (!length) {
         return;
     }
 
     bh_memcpy_s((uint8 *)tbl_inst + offsetof(WASMTableInstance, elems)
                     + dst_offset * sizeof(uint32),
                 (uint32)sizeof(uint32) * (tbl_inst->cur_size - dst_offset),
-                tbl_seg->func_indexes + src_offset,
-                (uint32)(length * sizeof(uint32)));
+                tbl_seg_elems + src_offset, (uint32)(length * sizeof(uint32)));
 }
 
 void
@@ -3408,7 +3550,7 @@ llvm_jit_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
     frame->ip = NULL;
     frame->sp = frame->lp;
 #if WASM_ENABLE_PERF_PROFILING != 0
-    frame->time_started = os_time_get_boot_microsecond();
+    frame->time_started = os_time_thread_cputime_us();
 #endif
     frame->prev_frame = wasm_exec_env_get_cur_frame(exec_env);
     wasm_exec_env_set_cur_frame(exec_env, frame);
@@ -3429,9 +3571,13 @@ llvm_jit_free_frame(WASMExecEnv *exec_env)
 
 #if WASM_ENABLE_PERF_PROFILING != 0
     if (frame->function) {
-        frame->function->total_exec_time +=
-            os_time_get_boot_microsecond() - frame->time_started;
+        uint64 elapsed = os_time_thread_cputime_us() - frame->time_started;
+        frame->function->total_exec_time += elapsed;
         frame->function->total_exec_cnt++;
+
+        /* parent function */
+        if (prev_frame)
+            prev_frame->function->children_exec_time += elapsed;
     }
 #endif
     wasm_exec_env_free_wasm_frame(exec_env, frame);

+ 58 - 0
core/iwasm/interpreter/wasm_runtime.h

@@ -28,6 +28,9 @@ typedef struct WASMFunctionInstance WASMFunctionInstance;
 typedef struct WASMMemoryInstance WASMMemoryInstance;
 typedef struct WASMTableInstance WASMTableInstance;
 typedef struct WASMGlobalInstance WASMGlobalInstance;
+#if WASM_ENABLE_TAGS != 0
+typedef struct WASMTagInstance WASMTagInstance;
+#endif
 
 /**
  * When LLVM JIT, WAMR compiler or AOT is enabled, we should ensure that
@@ -186,9 +189,35 @@ struct WASMFunctionInstance {
     uint64 total_exec_time;
     /* total execution count */
     uint32 total_exec_cnt;
+    /* children execution time */
+    uint64 children_exec_time;
 #endif
 };
 
+#if WASM_ENABLE_TAGS != 0
+struct WASMTagInstance {
+    bool is_import_tag;
+    /* tag attribute */
+    uint8 attribute;
+    /* tag type index */
+    uint32 type;
+    union {
+        WASMTagImport *tag_import;
+        WASMTag *tag;
+    } u;
+
+#if WASM_ENABLE_MULTI_MODULE != 0
+    WASMModuleInstance *import_module_inst;
+    WASMTagInstance *import_tag_inst;
+#endif
+};
+#endif
+
+#if WASM_ENABLE_EXCE_HANDLING != 0
+#define INVALID_TAGINDEX ((uint32)0xFFFFFFFF)
+#define SET_INVALID_TAGINDEX(tag) (tag = INVALID_TAGINDEX)
+#define IS_INVALID_TAGINDEX(tag) ((tag & INVALID_TAGINDEX) == INVALID_TAGINDEX)
+#endif
 typedef struct WASMExportFuncInstance {
     char *name;
     WASMFunctionInstance *function;
@@ -209,6 +238,13 @@ typedef struct WASMExportMemInstance {
     WASMMemoryInstance *memory;
 } WASMExportMemInstance;
 
+#if WASM_ENABLE_TAGS != 0
+typedef struct WASMExportTagInstance {
+    char *name;
+    WASMTagInstance *tag;
+} WASMExportTagInstance;
+#endif
+
 /* wasm-c-api import function info */
 typedef struct CApiFuncImport {
     /* host func pointer after linked */
@@ -261,6 +297,14 @@ typedef struct WASMModuleInstanceExtra {
     WASMTableInstance **table_insts_linked;
 #endif
 
+#if WASM_ENABLE_TAGS != 0
+    uint32 tag_count;
+    uint32 export_tag_count;
+    WASMTagInstance *tags;
+    WASMExportTagInstance *export_tags;
+    void **import_tag_ptrs;
+#endif
+
 #if WASM_ENABLE_MEMORY_PROFILING != 0
     uint32 max_aux_stack_used;
 #endif
@@ -432,6 +476,13 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
 void
 wasm_dump_perf_profiling(const WASMModuleInstance *module_inst);
 
+double
+wasm_summarize_wasm_execute_time(const WASMModuleInstance *inst);
+
+double
+wasm_get_wasm_func_exec_time(const WASMModuleInstance *inst,
+                             const char *func_name);
+
 void
 wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst);
 
@@ -452,6 +503,13 @@ wasm_lookup_memory(const WASMModuleInstance *module_inst, const char *name);
 
 WASMTableInstance *
 wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name);
+
+#if WASM_ENABLE_TAGS != 0
+WASMTagInstance *
+wasm_lookup_tag(const WASMModuleInstance *module_inst, const char *name,
+                const char *signature);
+#endif
+
 #endif
 
 bool

+ 12 - 2
core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c

@@ -468,7 +468,7 @@ get_thread_info(wasm_exec_env_t exec_env, uint32 handle)
     WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
     ClusterInfoNode *info = get_cluster_info(cluster);
 
-    if (!info) {
+    if (!info || !handle) {
         return NULL;
     }
 
@@ -1145,6 +1145,10 @@ sem_open_wrapper(wasm_exec_env_t exec_env, const char *name, int32 oflags,
      * For Unix like system, it's dedicated for multiple processes.
      */
 
+    if (!name) { /* avoid passing NULL to bh_hash_map_find and os_sem_open */
+        return -1;
+    }
+
     if ((info_node = bh_hash_map_find(sem_info_map, (void *)name))) {
         return info_node->handle;
     }
@@ -1277,7 +1281,13 @@ sem_unlink_wrapper(wasm_exec_env_t exec_env, const char *name)
     (void)exec_env;
     int32 ret_val;
 
-    ThreadInfoNode *info_node = bh_hash_map_find(sem_info_map, (void *)name);
+    ThreadInfoNode *info_node;
+
+    if (!name) { /* avoid passing NULL to bh_hash_map_find */
+        return -1;
+    }
+
+    info_node = bh_hash_map_find(sem_info_map, (void *)name);
     if (!info_node || info_node->type != T_SEM)
         return -1;
 

+ 49 - 3
core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c

@@ -473,12 +473,16 @@ snprintf_wrapper(wasm_exec_env_t exec_env, char *str, uint32 size,
 static int
 puts_wrapper(wasm_exec_env_t exec_env, const char *str)
 {
+    (void)exec_env;
+
     return os_printf("%s\n", str);
 }
 
 static int
 putchar_wrapper(wasm_exec_env_t exec_env, int c)
 {
+    (void)exec_env;
+
     os_printf("%c", c);
     return 1;
 }
@@ -585,6 +589,8 @@ strchr_wrapper(wasm_exec_env_t exec_env, const char *s, int32 c)
 static int32
 strcmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2)
 {
+    (void)exec_env;
+
     /* s1 and s2 have been checked by runtime */
     return strcmp(s1, s2);
 }
@@ -641,6 +647,8 @@ strncpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src,
 static uint32
 strlen_wrapper(wasm_exec_env_t exec_env, const char *s)
 {
+    (void)exec_env;
+
     /* s has been checked by runtime */
     return (uint32)strlen(s);
 }
@@ -693,6 +701,7 @@ free_wrapper(wasm_exec_env_t exec_env, void *ptr)
 static int32
 atoi_wrapper(wasm_exec_env_t exec_env, const char *s)
 {
+    (void)exec_env;
     /* s has been checked by runtime */
     return atoi(s);
 }
@@ -757,6 +766,8 @@ static int32
 strncasecmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
                     uint32 n)
 {
+    (void)exec_env;
+
     /* s1 and s2 have been checked by runtime */
     return strncasecmp(s1, s2, n);
 }
@@ -764,6 +775,8 @@ strncasecmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
 static uint32
 strspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *accept)
 {
+    (void)exec_env;
+
     /* s and accept have been checked by runtime */
     return (uint32)strspn(s, accept);
 }
@@ -771,6 +784,8 @@ strspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *accept)
 static uint32
 strcspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *reject)
 {
+    (void)exec_env;
+
     /* s and reject have been checked by runtime */
     return (uint32)strcspn(s, reject);
 }
@@ -787,60 +802,80 @@ strstr_wrapper(wasm_exec_env_t exec_env, const char *s, const char *find)
 static int32
 isupper_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return isupper(c);
 }
 
 static int32
 isalpha_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return isalpha(c);
 }
 
 static int32
 isspace_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return isspace(c);
 }
 
 static int32
 isgraph_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return isgraph(c);
 }
 
 static int32
 isprint_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return isprint(c);
 }
 
 static int32
 isdigit_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return isdigit(c);
 }
 
 static int32
 isxdigit_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return isxdigit(c);
 }
 
 static int32
 tolower_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return tolower(c);
 }
 
 static int32
 toupper_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return toupper(c);
 }
 
 static int32
 isalnum_wrapper(wasm_exec_env_t exec_env, int32 c)
 {
+    (void)exec_env;
+
     return isalnum(c);
 }
 
@@ -899,7 +934,10 @@ __cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, uint32 thrown_size)
 
 static void
 __cxa_begin_catch_wrapper(wasm_exec_env_t exec_env, void *exception_object)
-{}
+{
+    (void)exec_env;
+    (void)exception_object;
+}
 
 static void
 __cxa_throw_wrapper(wasm_exec_env_t exec_env, void *thrown_exception,
@@ -908,6 +946,10 @@ __cxa_throw_wrapper(wasm_exec_env_t exec_env, void *thrown_exception,
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     char buf[32];
 
+    (void)thrown_exception;
+    (void)tinfo;
+    (void)table_elem_idx;
+
     snprintf(buf, sizeof(buf), "%s", "exception thrown by stdc++");
     wasm_runtime_set_exception(module_inst, buf);
 }
@@ -924,10 +966,12 @@ clock_gettime_wrapper(wasm_exec_env_t exec_env, uint32 clk_id,
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     uint64 time;
 
+    (void)clk_id;
+
     if (!validate_native_addr(ts_app, sizeof(struct timespec_app)))
         return (uint32)-1;
 
-    time = os_time_get_boot_microsecond();
+    time = os_time_get_boot_us();
     ts_app->tv_sec = time / 1000000;
     ts_app->tv_nsec = (time % 1000000) * 1000;
 
@@ -937,9 +981,11 @@ clock_gettime_wrapper(wasm_exec_env_t exec_env, uint32 clk_id,
 static uint64
 clock_wrapper(wasm_exec_env_t exec_env)
 {
+    (void)exec_env;
+
     /* Convert to nano seconds as CLOCKS_PER_SEC in wasi-sdk */
 
-    return os_time_get_boot_microsecond() * 1000;
+    return os_time_get_boot_us() * 1000;
 }
 
 #if WASM_ENABLE_SPEC_TEST != 0

+ 101 - 93
core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c

@@ -72,7 +72,7 @@ min_uint32(uint32_t a, uint32_t b)
 }
 
 static inline struct fd_table *
-wasi_ctx_get_curfds(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
+wasi_ctx_get_curfds(wasi_ctx_t wasi_ctx)
 {
     if (!wasi_ctx)
         return NULL;
@@ -88,7 +88,7 @@ wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
 }
 
 static inline struct fd_prestats *
-wasi_ctx_get_prestats(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
+wasi_ctx_get_prestats(wasi_ctx_t wasi_ctx)
 {
     if (!wasi_ctx)
         return NULL;
@@ -96,7 +96,7 @@ wasi_ctx_get_prestats(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
 }
 
 static inline struct addr_pool *
-wasi_ctx_get_addr_pool(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
+wasi_ctx_get_addr_pool(wasi_ctx_t wasi_ctx)
 {
     if (!wasi_ctx)
         return NULL;
@@ -292,7 +292,7 @@ wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
+    struct fd_prestats *prestats = wasi_ctx_get_prestats(wasi_ctx);
     wasi_prestat_t prestat;
     wasi_errno_t err;
 
@@ -317,7 +317,7 @@ wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_t fd, char *path,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
+    struct fd_prestats *prestats = wasi_ctx_get_prestats(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -330,8 +330,8 @@ wasi_fd_close(wasm_exec_env_t exec_env, wasi_fd_t fd)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
-    struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
+    struct fd_prestats *prestats = wasi_ctx_get_prestats(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -344,7 +344,7 @@ wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -358,7 +358,7 @@ wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     wasi_iovec_t *iovec, *iovec_begin;
     uint64 total_size;
     size_t nread;
@@ -412,7 +412,7 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     wasi_ciovec_t *ciovec, *ciovec_begin;
     uint64 total_size;
     size_t nwritten;
@@ -465,7 +465,7 @@ wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     wasi_iovec_t *iovec, *iovec_begin;
     uint64 total_size;
     size_t nread;
@@ -517,8 +517,8 @@ wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
-    struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
+    struct fd_prestats *prestats = wasi_ctx_get_prestats(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -532,7 +532,7 @@ wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -549,7 +549,7 @@ wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -566,7 +566,7 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     wasi_fdstat_t fdstat;
     wasi_errno_t err;
 
@@ -590,7 +590,7 @@ wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -605,7 +605,7 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -619,7 +619,7 @@ wasi_fd_sync(wasm_exec_env_t exec_env, wasi_fd_t fd)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -634,7 +634,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     wasi_ciovec_t *ciovec, *ciovec_begin;
     uint64 total_size;
     size_t nwritten;
@@ -687,7 +687,7 @@ wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -701,7 +701,7 @@ wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -715,7 +715,7 @@ wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -732,8 +732,8 @@ wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
-    struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
+    struct fd_prestats *prestats = wasi_ctx_get_prestats(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -752,7 +752,7 @@ wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     wasi_fd_t fd = (wasi_fd_t)-1; /* set fd_app -1 if path open failed */
     wasi_errno_t err;
 
@@ -776,7 +776,7 @@ wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     size_t bufused;
     wasi_errno_t err;
 
@@ -802,7 +802,7 @@ wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     size_t bufused;
     wasi_errno_t err;
 
@@ -828,7 +828,7 @@ wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -844,7 +844,7 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -862,7 +862,7 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -877,7 +877,7 @@ wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -892,7 +892,7 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -912,7 +912,7 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -929,8 +929,8 @@ wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
-    struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
+    struct fd_prestats *prestats = wasi_ctx_get_prestats(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -945,7 +945,7 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -959,7 +959,7 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return (wasi_errno_t)-1;
@@ -1076,7 +1076,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     size_t nevents = 0;
     wasi_errno_t err;
 
@@ -1128,6 +1128,8 @@ wasi_proc_raise(wasm_exec_env_t exec_env, wasi_signal_t sig)
 static wasi_errno_t
 wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len)
 {
+    (void)exec_env;
+
     return wasmtime_ssp_random_get(buf, buf_len);
 }
 
@@ -1142,7 +1144,7 @@ wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fdflags_t flags,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasi_ssp_sock_accept(exec_env, curfds, fd, flags, fd_new);
 }
@@ -1161,7 +1163,7 @@ wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(addr, sizeof(__wasi_addr_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasi_ssp_sock_addr_local(exec_env, curfds, fd, addr);
 }
@@ -1180,7 +1182,7 @@ wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(addr, sizeof(__wasi_addr_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasi_ssp_sock_addr_remote(exec_env, curfds, fd, addr);
 }
@@ -1200,7 +1202,7 @@ wasi_sock_addr_resolve(wasm_exec_env_t exec_env, const char *host,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
     ns_lookup_list = wasi_ctx_get_ns_lookup_list(wasi_ctx);
 
     return wasi_ssp_sock_addr_resolve(exec_env, curfds, ns_lookup_list, host,
@@ -1219,8 +1221,8 @@ wasi_sock_bind(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
-    addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
+    addr_pool = wasi_ctx_get_addr_pool(wasi_ctx);
 
     return wasi_ssp_sock_bind(exec_env, curfds, addr_pool, fd, addr);
 }
@@ -1228,6 +1230,9 @@ wasi_sock_bind(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
 static wasi_errno_t
 wasi_sock_close(wasm_exec_env_t exec_env, wasi_fd_t fd)
 {
+    (void)exec_env;
+    (void)fd;
+
     return __WASI_ENOSYS;
 }
 
@@ -1242,8 +1247,8 @@ wasi_sock_connect(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
-    addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
+    addr_pool = wasi_ctx_get_addr_pool(wasi_ctx);
 
     return wasi_ssp_sock_connect(exec_env, curfds, addr_pool, fd, addr);
 }
@@ -1262,7 +1267,7 @@ wasi_sock_get_broadcast(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_broadcast(exec_env, curfds, fd, is_enabled);
 }
@@ -1281,7 +1286,7 @@ wasi_sock_get_keep_alive(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_keep_alive(exec_env, curfds, fd, is_enabled);
 }
@@ -1301,7 +1306,7 @@ wasi_sock_get_linger(wasm_exec_env_t exec_env, wasi_fd_t fd, bool *is_enabled,
         || !validate_native_addr(linger_s, sizeof(int)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_linger(exec_env, curfds, fd, is_enabled,
                                         linger_s);
@@ -1321,7 +1326,7 @@ wasi_sock_get_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(size, sizeof(wasi_size_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_recv_buf_size(exec_env, curfds, fd, size);
 }
@@ -1340,7 +1345,7 @@ wasi_sock_get_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(timeout_us, sizeof(uint64_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_recv_timeout(exec_env, curfds, fd, timeout_us);
 }
@@ -1359,7 +1364,7 @@ wasi_sock_get_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_reuse_addr(exec_env, curfds, fd, is_enabled);
 }
@@ -1378,7 +1383,7 @@ wasi_sock_get_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_reuse_port(exec_env, curfds, fd, is_enabled);
 }
@@ -1397,7 +1402,7 @@ wasi_sock_get_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(size, sizeof(__wasi_size_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_send_buf_size(exec_env, curfds, fd, size);
 }
@@ -1416,7 +1421,7 @@ wasi_sock_get_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(timeout_us, sizeof(uint64_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_send_timeout(exec_env, curfds, fd, timeout_us);
 }
@@ -1435,7 +1440,7 @@ wasi_sock_get_tcp_fastopen_connect(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_tcp_fastopen_connect(exec_env, curfds, fd,
                                                       is_enabled);
@@ -1455,7 +1460,7 @@ wasi_sock_get_tcp_no_delay(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_tcp_no_delay(exec_env, curfds, fd, is_enabled);
 }
@@ -1474,7 +1479,7 @@ wasi_sock_get_tcp_quick_ack(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_tcp_quick_ack(exec_env, curfds, fd,
                                                is_enabled);
@@ -1494,7 +1499,7 @@ wasi_sock_get_tcp_keep_idle(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(time_s, sizeof(uint32_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_tcp_keep_idle(exec_env, curfds, fd, time_s);
 }
@@ -1513,7 +1518,7 @@ wasi_sock_get_tcp_keep_intvl(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(time_s, sizeof(uint32_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_tcp_keep_intvl(exec_env, curfds, fd, time_s);
 }
@@ -1532,7 +1537,7 @@ wasi_sock_get_ip_multicast_loop(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_ip_multicast_loop(exec_env, curfds, fd, ipv6,
                                                    is_enabled);
@@ -1551,7 +1556,7 @@ wasi_sock_get_ip_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8_t *ttl_s)
     if (!validate_native_addr(ttl_s, sizeof(uint8_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_ip_ttl(exec_env, curfds, fd, ttl_s);
 }
@@ -1570,7 +1575,7 @@ wasi_sock_get_ip_multicast_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(ttl_s, sizeof(uint8_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_ip_multicast_ttl(exec_env, curfds, fd, ttl_s);
 }
@@ -1589,7 +1594,7 @@ wasi_sock_get_ipv6_only(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(is_enabled, sizeof(bool)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_get_ipv6_only(exec_env, curfds, fd, is_enabled);
 }
@@ -1604,7 +1609,7 @@ wasi_sock_listen(wasm_exec_env_t exec_env, wasi_fd_t fd, uint32 backlog)
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasi_ssp_sock_listen(exec_env, curfds, fd, backlog);
 }
@@ -1621,7 +1626,7 @@ wasi_sock_open(wasm_exec_env_t exec_env, wasi_fd_t poolfd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasi_ssp_sock_open(exec_env, curfds, poolfd, af, socktype, sockfd);
 }
@@ -1636,7 +1641,7 @@ wasi_sock_set_broadcast(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled)
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_broadcast(exec_env, curfds, fd, is_enabled);
 }
@@ -1652,7 +1657,7 @@ wasi_sock_set_keep_alive(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_keep_alive(exec_env, curfds, fd, is_enabled);
 }
@@ -1668,7 +1673,7 @@ wasi_sock_set_linger(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_linger(exec_env, curfds, fd, is_enabled,
                                         linger_s);
@@ -1684,7 +1689,7 @@ wasi_sock_set_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, size_t size)
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_recv_buf_size(exec_env, curfds, fd, size);
 }
@@ -1700,7 +1705,7 @@ wasi_sock_set_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_recv_timeout(exec_env, curfds, fd, timeout_us);
 }
@@ -1716,7 +1721,7 @@ wasi_sock_set_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_reuse_addr(exec_env, curfds, fd, is_enabled);
 }
@@ -1732,7 +1737,7 @@ wasi_sock_set_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_reuse_port(exec_env, curfds, fd, is_enabled);
 }
@@ -1747,7 +1752,7 @@ wasi_sock_set_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, size_t size)
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_send_buf_size(exec_env, curfds, fd, size);
 }
@@ -1763,7 +1768,7 @@ wasi_sock_set_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_send_timeout(exec_env, curfds, fd, timeout_us);
 }
@@ -1779,7 +1784,7 @@ wasi_sock_set_tcp_fastopen_connect(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_tcp_fastopen_connect(exec_env, curfds, fd,
                                                       is_enabled);
@@ -1796,7 +1801,7 @@ wasi_sock_set_tcp_no_delay(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_tcp_no_delay(exec_env, curfds, fd, is_enabled);
 }
@@ -1812,7 +1817,7 @@ wasi_sock_set_tcp_quick_ack(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_tcp_quick_ack(exec_env, curfds, fd,
                                                is_enabled);
@@ -1829,7 +1834,7 @@ wasi_sock_set_tcp_keep_idle(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_tcp_keep_idle(exec_env, curfds, fd, time_s);
 }
@@ -1845,7 +1850,7 @@ wasi_sock_set_tcp_keep_intvl(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_tcp_keep_intvl(exec_env, curfds, fd, time_s);
 }
@@ -1861,7 +1866,7 @@ wasi_sock_set_ip_multicast_loop(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_ip_multicast_loop(exec_env, curfds, fd, ipv6,
                                                    is_enabled);
@@ -1882,7 +1887,7 @@ wasi_sock_set_ip_add_membership(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(imr_multiaddr, sizeof(__wasi_addr_ip_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_ip_add_membership(
         exec_env, curfds, fd, imr_multiaddr, imr_interface);
@@ -1903,7 +1908,7 @@ wasi_sock_set_ip_drop_membership(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!validate_native_addr(imr_multiaddr, sizeof(__wasi_addr_ip_t)))
         return __WASI_EINVAL;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_ip_drop_membership(
         exec_env, curfds, fd, imr_multiaddr, imr_interface);
@@ -1919,7 +1924,7 @@ wasi_sock_set_ip_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8_t ttl_s)
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_ip_ttl(exec_env, curfds, fd, ttl_s);
 }
@@ -1935,7 +1940,7 @@ wasi_sock_set_ip_multicast_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd,
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_ip_multicast_ttl(exec_env, curfds, fd, ttl_s);
 }
@@ -1950,7 +1955,7 @@ wasi_sock_set_ipv6_only(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled)
     if (!wasi_ctx)
         return __WASI_EACCES;
 
-    curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     return wasmtime_ssp_sock_set_ipv6_only(exec_env, curfds, fd, is_enabled);
 }
@@ -2013,7 +2018,8 @@ copy_buffer_to_iovec_app(wasm_module_inst_t module_inst, uint8 *buf_begin,
         }
 
         if (buf >= buf_begin + buf_size
-            || buf + data->buf_len < buf /* integer overflow */
+            /* integer overflow */
+            || data->buf_len > UINTPTR_MAX - (uintptr_t)buf
             || buf + data->buf_len > buf_begin + buf_size
             || size_to_copy == 0) {
             break;
@@ -2048,7 +2054,7 @@ wasi_sock_recv_from(wasm_exec_env_t exec_env, wasi_fd_t sock,
      **/
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     uint64 total_size;
     uint8 *buf_begin = NULL;
     wasi_errno_t err;
@@ -2152,7 +2158,7 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
      **/
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     uint64 buf_size = 0;
     uint8 *buf = NULL;
     wasi_errno_t err;
@@ -2192,12 +2198,12 @@ wasi_sock_send_to(wasm_exec_env_t exec_env, wasi_fd_t sock,
      **/
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
     uint64 buf_size = 0;
     uint8 *buf = NULL;
     wasi_errno_t err;
     size_t send_bytes = 0;
-    struct addr_pool *addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
+    struct addr_pool *addr_pool = wasi_ctx_get_addr_pool(wasi_ctx);
 
     if (!wasi_ctx) {
         return __WASI_EINVAL;
@@ -2226,7 +2232,7 @@ wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
-    struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    struct fd_table *curfds = wasi_ctx_get_curfds(wasi_ctx);
 
     if (!wasi_ctx)
         return __WASI_EINVAL;
@@ -2237,6 +2243,8 @@ wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
 static wasi_errno_t
 wasi_sched_yield(wasm_exec_env_t exec_env)
 {
+    (void)exec_env;
+
     return wasmtime_ssp_sched_yield();
 }
 

+ 21 - 0
core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.c

@@ -7,6 +7,7 @@
 
 #include "ssp_config.h"
 #include "blocking_op.h"
+#include "libc_errno.h"
 
 __wasi_errno_t
 blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
@@ -170,3 +171,23 @@ blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
     wasm_runtime_end_blocking_op(exec_env);
     return error;
 }
+
+#ifndef BH_PLATFORM_WINDOWS
+/* REVISIT: apply the os_file_handle style abstraction for pollfd? */
+__wasi_errno_t
+blocking_op_poll(wasm_exec_env_t exec_env, struct pollfd *pfds, nfds_t nfds,
+                 int timeout_ms, int *retp)
+{
+    int ret;
+    if (!wasm_runtime_begin_blocking_op(exec_env)) {
+        return __WASI_EINTR;
+    }
+    ret = poll(pfds, nfds, timeout_ms);
+    wasm_runtime_end_blocking_op(exec_env);
+    if (ret == -1) {
+        return convert_errno(errno);
+    }
+    *retp = ret;
+    return 0;
+}
+#endif

+ 7 - 1
core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.h

@@ -50,4 +50,10 @@ __wasi_errno_t
 blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
                    const char *path, __wasi_oflags_t oflags,
                    __wasi_fdflags_t fd_flags, __wasi_lookupflags_t lookup_flags,
-                   wasi_libc_file_access_mode access_mode, os_file_handle *out);
+                   wasi_libc_file_access_mode access_mode, os_file_handle *out);
+
+#ifndef BH_PLATFORM_WINDOWS
+__wasi_errno_t
+blocking_op_poll(wasm_exec_env_t exec_env, struct pollfd *pfds, nfds_t nfds,
+                 int timeout, int *retp);
+#endif

+ 1 - 1
core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/locking.h

@@ -88,7 +88,7 @@ struct LOCKABLE rwlock {
 };
 
 static inline bool
-rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock)
+rwlock_initialize(struct rwlock *lock) REQUIRES_UNLOCKED(*lock)
 {
     return os_rwlock_init(&lock->object) == 0 ? true : false;
 }

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

@@ -204,7 +204,7 @@ struct fd_prestat {
 bool
 fd_prestats_init(struct fd_prestats *pt)
 {
-    if (!rwlock_init(&pt->lock))
+    if (!rwlock_initialize(&pt->lock))
         return false;
     pt->prestats = NULL;
     pt->size = 0;
@@ -340,7 +340,7 @@ struct fd_entry {
 bool
 fd_table_init(struct fd_table *ft)
 {
-    if (!rwlock_init(&ft->lock))
+    if (!rwlock_initialize(&ft->lock))
         return false;
     ft->entries = NULL;
     ft->size = 0;
@@ -1017,9 +1017,13 @@ wasmtime_ssp_fd_fdstat_get(wasm_exec_env_t exec_env, struct fd_table *curfds,
                            __wasi_fd_t fd, __wasi_fdstat_t *buf)
 {
     struct fd_table *ft = curfds;
-    rwlock_rdlock(&ft->lock);
     struct fd_entry *fe;
-    __wasi_errno_t error = fd_table_get_entry(ft, fd, 0, 0, &fe);
+    __wasi_errno_t error;
+
+    (void)exec_env;
+
+    rwlock_rdlock(&ft->lock);
+    error = fd_table_get_entry(ft, fd, 0, 0, &fe);
     if (error != __WASI_ESUCCESS) {
         rwlock_unlock(&ft->lock);
         return error;
@@ -1071,9 +1075,13 @@ wasmtime_ssp_fd_fdstat_set_rights(wasm_exec_env_t exec_env,
                                   __wasi_rights_t fs_rights_inheriting)
 {
     struct fd_table *ft = curfds;
-    rwlock_wrlock(&ft->lock);
     struct fd_entry *fe;
-    __wasi_errno_t error =
+    __wasi_errno_t error;
+
+    (void)exec_env;
+
+    rwlock_wrlock(&ft->lock);
+    error =
         fd_table_get_entry(ft, fd, fs_rights_base, fs_rights_inheriting, &fe);
     if (error != 0) {
         rwlock_unlock(&ft->lock);
@@ -2222,11 +2230,10 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
         timeout = -1;
     }
 
-    int ret = poll(pfds, nsubscriptions, timeout);
-
-    __wasi_errno_t error = 0;
-    if (ret == -1) {
-        error = convert_errno(errno);
+    int ret;
+    int error = blocking_op_poll(exec_env, pfds, nsubscriptions, timeout, &ret);
+    if (error != 0) {
+        /* got an error */
     }
     else if (ret == 0 && *nevents == 0 && clock_subscription != NULL) {
         // No events triggered. Trigger the clock event.
@@ -2980,7 +2987,9 @@ argv_environ_init(struct argv_environ_values *argv_environ, char *argv_buf,
 
 void
 argv_environ_destroy(struct argv_environ_values *argv_environ)
-{}
+{
+    (void)argv_environ;
+}
 
 void
 fd_table_destroy(struct fd_table *ft)

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

@@ -34,7 +34,7 @@
 #define CONFIG_HAS_GETRANDOM 0
 #endif
 
-#if defined(__CloudABI__)
+#if defined(__CloudABI__) || defined(BH_PLATFORM_FREERTOS)
 #define CONFIG_HAS_CAP_ENTER 1
 #else
 #define CONFIG_HAS_CAP_ENTER 0

+ 70 - 60
core/iwasm/libraries/thread-mgr/thread_manager.c

@@ -442,9 +442,10 @@ final:
     return ret;
 }
 
-/* The caller must lock cluster->lock */
-static bool
-allocate_aux_stack(WASMExecEnv *exec_env, uint32 *start, uint32 *size)
+/* The caller must not have any locks */
+bool
+wasm_cluster_allocate_aux_stack(WASMExecEnv *exec_env, uint32 *p_start,
+                                uint32 *p_size)
 {
     WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
 #if WASM_ENABLE_HEAP_AUX_STACK_ALLOCATION != 0
@@ -454,8 +455,8 @@ allocate_aux_stack(WASMExecEnv *exec_env, uint32 *start, uint32 *size)
 
     stack_end = wasm_runtime_module_malloc_internal(module_inst, exec_env,
                                                     cluster->stack_size, NULL);
-    *start = stack_end + cluster->stack_size;
-    *size = cluster->stack_size;
+    *p_start = stack_end + cluster->stack_size;
+    *p_size = cluster->stack_size;
 
     return stack_end != 0;
 #else
@@ -463,27 +464,35 @@ allocate_aux_stack(WASMExecEnv *exec_env, uint32 *start, uint32 *size)
 
     /* If the module doesn't have aux stack info,
         it can't create any threads */
-    if (!cluster->stack_segment_occupied)
+
+    cluster_lock_thread_list(cluster, exec_env);
+
+    if (!cluster->stack_segment_occupied) {
+        cluster_unlock_thread_list(cluster);
         return false;
+    }
 
     for (i = 0; i < cluster_max_thread_num; i++) {
         if (!cluster->stack_segment_occupied[i]) {
-            if (start)
-                *start = cluster->stack_tops[i];
-            if (size)
-                *size = cluster->stack_size;
+            if (p_start)
+                *p_start = cluster->stack_tops[i];
+            if (p_size)
+                *p_size = cluster->stack_size;
             cluster->stack_segment_occupied[i] = true;
+            cluster_unlock_thread_list(cluster);
             return true;
         }
     }
 
+    cluster_unlock_thread_list(cluster);
+
     return false;
 #endif
 }
 
-/* The caller must lock cluster->lock */
-static bool
-free_aux_stack(WASMExecEnv *exec_env, uint32 start)
+/* The caller must not have any locks */
+bool
+wasm_cluster_free_aux_stack(WASMExecEnv *exec_env, uint32 start)
 {
     WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
 
@@ -504,43 +513,19 @@ free_aux_stack(WASMExecEnv *exec_env, uint32 start)
 #else
     uint32 i;
 
+    cluster_lock_thread_list(cluster, exec_env);
     for (i = 0; i < cluster_max_thread_num; i++) {
         if (start == cluster->stack_tops[i]) {
             cluster->stack_segment_occupied[i] = false;
+            cluster_unlock_thread_list(cluster);
             return true;
         }
     }
+    cluster_unlock_thread_list(cluster);
     return false;
 #endif
 }
 
-bool
-wasm_cluster_allocate_aux_stack(WASMExecEnv *exec_env, uint32 *p_start,
-                                uint32 *p_size)
-{
-    WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
-    bool ret;
-
-    cluster_lock_thread_list(cluster, exec_env);
-    ret = allocate_aux_stack(exec_env, p_start, p_size);
-    cluster_unlock_thread_list(cluster);
-
-    return ret;
-}
-
-bool
-wasm_cluster_free_aux_stack(WASMExecEnv *exec_env, uint32 start)
-{
-    WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
-    bool ret;
-
-    cluster_lock_thread_list(cluster, exec_env);
-    ret = free_aux_stack(exec_env, start);
-    cluster_unlock_thread_list(cluster);
-
-    return ret;
-}
-
 WASMCluster *
 wasm_cluster_create(WASMExecEnv *exec_env)
 {
@@ -845,6 +830,13 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
         goto fail1;
     }
 
+    if (!wasm_cluster_allocate_aux_stack(exec_env, &aux_stack_start,
+                                         &aux_stack_size)) {
+        LOG_ERROR("thread manager error: "
+                  "failed to allocate aux stack space for new thread");
+        goto fail1;
+    }
+
     cluster_lock_thread_list(cluster, exec_env);
 
     if (cluster->has_exception || cluster->processing) {
@@ -871,37 +863,31 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
         goto fail2;
     }
 
-    if (!allocate_aux_stack(exec_env, &aux_stack_start, &aux_stack_size)) {
-        LOG_ERROR("thread manager error: "
-                  "failed to allocate aux stack space for new thread");
-        goto fail3;
-    }
-
     /* Set aux stack for current thread */
     if (!wasm_exec_env_set_aux_stack(new_exec_env, aux_stack_start,
                                      aux_stack_size)) {
-        goto fail4;
+        goto fail3;
     }
 
     /* Inherit suspend_flags of parent thread, no need to acquire
        thread_state_lock as the thread list has been locked */
-    new_exec_env->suspend_flags.flags = exec_env->suspend_flags.flags;
+    new_exec_env->suspend_flags.flags =
+        (exec_env->suspend_flags.flags & WASM_SUSPEND_FLAG_INHERIT_MASK);
 
     if (!wasm_cluster_add_exec_env(cluster, new_exec_env)) {
-        goto fail4;
+        goto fail3;
     }
 
     cluster_unlock_thread_list(cluster);
 
     return new_exec_env;
 
-fail4:
-    /* Free the allocated aux stack space */
-    free_aux_stack(exec_env, aux_stack_start);
 fail3:
     wasm_exec_env_destroy_internal(new_exec_env);
 fail2:
     cluster_unlock_thread_list(cluster);
+    /* free the allocated aux stack space */
+    wasm_cluster_free_aux_stack(exec_env, aux_stack_start);
 fail1:
     wasm_runtime_deinstantiate_internal(new_module_inst, true);
 
@@ -916,11 +902,26 @@ wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env)
     WASMExecEnv *self = get_exec_env_of_current_thread();
 
     bh_assert(cluster != NULL);
+    WASMExecEnv *exec_env_tls = NULL;
 
-    cluster_lock_thread_list(cluster, self);
+#ifdef OS_ENABLE_HW_BOUND_CHECK
+    /* Note: free_aux_stack can execute the module's "free" function
+     * using the specified exec_env. In case of OS_ENABLE_HW_BOUND_CHECK,
+     * it needs to match the TLS exec_env if available. (Consider a native
+     * function which calls wasm_cluster_destroy_spawned_exec_env.)
+     */
+    exec_env_tls = wasm_runtime_get_exec_env_tls();
+#endif
+    if (exec_env_tls == NULL) {
+        exec_env_tls = exec_env;
+    }
 
     /* Free aux stack space */
-    free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
+    wasm_cluster_free_aux_stack(exec_env_tls,
+                                exec_env->aux_stack_bottom.bottom);
+
+    cluster_lock_thread_list(cluster, self);
+
     /* Remove exec_env */
     wasm_cluster_del_exec_env_internal(cluster, exec_env, false);
     /* Destroy exec_env */
@@ -964,6 +965,9 @@ thread_manager_start_routine(void *arg)
 
     /* Routine exit */
 
+    /* Free aux stack space */
+    wasm_cluster_free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
+
     cluster_lock_thread_list(cluster, exec_env);
 
     exec_env->current_status.running_state = WASM_THREAD_EXITED;
@@ -984,8 +988,12 @@ thread_manager_start_routine(void *arg)
     }
     os_mutex_unlock(&exec_env->wait_lock);
 
-    /* Free aux stack space */
-    free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
+#if WASM_ENABLE_PERF_PROFILING != 0
+    os_printf("============= Spawned thread ===========\n");
+    wasm_runtime_dump_perf_profiling(module_inst);
+    os_printf("========================================\n");
+#endif
+
     /* Remove exec_env */
     wasm_cluster_del_exec_env_internal(cluster, exec_env, false);
     /* Destroy exec_env */
@@ -1039,7 +1047,8 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env,
 
     /* Inherit suspend_flags of parent thread, no need to acquire
        thread_state_lock as the thread list has been locked */
-    new_exec_env->suspend_flags.flags = exec_env->suspend_flags.flags;
+    new_exec_env->suspend_flags.flags =
+        (exec_env->suspend_flags.flags & WASM_SUSPEND_FLAG_INHERIT_MASK);
 
     if (!wasm_cluster_add_exec_env(cluster, new_exec_env))
         goto fail2;
@@ -1082,7 +1091,7 @@ wasm_cluster_dup_c_api_imports(WASMModuleInstanceCommon *module_inst_dst,
 {
     /* workaround about passing instantiate-linking information */
     CApiFuncImport **new_c_api_func_imports = NULL;
-    CApiFuncImport *c_api_func_imports;
+    CApiFuncImport *c_api_func_imports = NULL;
     uint32 import_func_count = 0;
     uint32 size_in_bytes = 0;
 
@@ -1336,6 +1345,9 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
 
     /* App exit the thread, free the resources before exit native thread */
 
+    /* Free aux stack space */
+    wasm_cluster_free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
+
     cluster_lock_thread_list(cluster, exec_env);
 
     exec_env->current_status.running_state = WASM_THREAD_EXITED;
@@ -1359,8 +1371,6 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
 
     module_inst = exec_env->module_inst;
 
-    /* Free aux stack space */
-    free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
     /* Remove exec_env */
     wasm_cluster_del_exec_env_internal(cluster, exec_env, false);
     /* Destroy exec_env */

+ 8 - 1
core/shared/platform/alios/alios_time.c

@@ -6,7 +6,14 @@
 #include "platform_api_vmcore.h"
 
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
     return (uint64)aos_now_ms() * 1000;
 }
+
+uint64
+os_time_thread_cputime_us(void)
+{
+    /* FIXME if u know the right api */
+    return os_time_get_boot_us();
+}

+ 2 - 2
core/shared/platform/android/platform_internal.h

@@ -80,8 +80,6 @@ typedef jmp_buf korp_jmpbuf;
 #define os_longjmp longjmp
 #define os_alloca alloca
 
-#define os_getpagesize getpagesize
-
 typedef void (*os_signal_handler)(void *sig_addr);
 
 int
@@ -101,6 +99,8 @@ os_sigreturn();
 #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
 #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
+#define os_getpagesize getpagesize
+
 typedef long int __syscall_slong_t;
 
 #if __ANDROID_API__ < 19

+ 1 - 1
core/shared/platform/common/freertos/freertos_thread.c

@@ -204,7 +204,7 @@ os_thread_wrapper(void *arg)
     thread_data_list_add(thread_data);
 
     thread_data->start_routine(thread_data->arg);
-    os_thread_cleanup();
+    os_thread_exit(NULL);
 }
 
 int

+ 8 - 1
core/shared/platform/common/freertos/freertos_time.c

@@ -6,8 +6,15 @@
 #include "platform_api_vmcore.h"
 
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
     TickType_t ticks = xTaskGetTickCount();
     return (uint64)1000 * 1000 / configTICK_RATE_HZ * ticks;
 }
+
+uint64
+os_time_thread_cputime_us(void)
+{
+    /* FIXME if u know the right api */
+    return os_time_get_boot_us();
+}

+ 12 - 0
core/shared/platform/common/memory/mremap.c

@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2024 Amazon Inc.  All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "bh_memutils.h"
+
+void *
+os_mremap(void *old_addr, size_t old_size, size_t new_size)
+{
+    return bh_memory_remap_slow(old_addr, old_size, new_size);
+}

+ 4 - 0
core/shared/platform/common/memory/platform_api_memory.cmake

@@ -0,0 +1,4 @@
+# Copyright (C) 2024 Amazon Inc.  All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+file (GLOB_RECURSE PLATFORM_COMMON_MEMORY_SOURCE ${CMAKE_CURRENT_LIST_DIR}/*.c)

+ 15 - 0
core/shared/platform/common/posix/platform_api_posix.cmake

@@ -16,4 +16,19 @@ else()
     set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
 endif()
 
+# This is to support old CMake version. Newer version of CMake could use
+# list APPEND/POP_BACK methods.
+include(CheckSymbolExists)
+set (CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE ${CMAKE_REQUIRED_DEFINITIONS})
+check_symbol_exists (mremap "sys/mman.h" MREMAP_EXISTS)
+list (REMOVE_AT CMAKE_REQUIRED_DEFINITIONS 0)
+
+if(MREMAP_EXISTS)
+    add_definitions (-DWASM_HAVE_MREMAP=1)
+else()
+    add_definitions (-DWASM_HAVE_MREMAP=0)
+    include (${CMAKE_CURRENT_LIST_DIR}/../memory/platform_api_memory.cmake)
+    set (source_all ${source_all} ${PLATFORM_COMMON_MEMORY_SOURCE})
+endif()
+
 set (PLATFORM_COMMON_POSIX_SOURCE ${source_all} )

+ 1 - 0
core/shared/platform/common/posix/posix_blocking_op.c

@@ -15,6 +15,7 @@ static void
 blocking_op_sighandler(int signo)
 {
     /* nothing */
+    (void)signo;
 }
 
 void

+ 2 - 0
core/shared/platform/common/posix/posix_clock.c

@@ -73,6 +73,8 @@ os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
     clockid_t nclock_id;
     __wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
 
+    (void)precision;
+
     if (error != __WASI_ESUCCESS)
         return error;
 

+ 2 - 0
core/shared/platform/common/posix/posix_file.c

@@ -25,12 +25,14 @@
  * For NuttX, CONFIG_HAS_ISATTY is provided by its platform header.
  * (platform_internal.h)
  */
+#if !defined(CONFIG_HAS_D_INO)
 #if !defined(__NuttX__)
 #define CONFIG_HAS_D_INO 1
 #define CONFIG_HAS_ISATTY 1
 #else
 #define CONFIG_HAS_D_INO 0
 #endif
+#endif
 
 #if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(__COSMOPOLITAN__)
 #define CONFIG_HAS_POSIX_FALLOCATE 1

+ 29 - 14
core/shared/platform/common/posix/posix_memmap.c

@@ -3,10 +3,17 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
+#if !defined(_GNU_SOURCE) && WASM_HAVE_MREMAP != 0
+/* Enable mremap */
+#define _GNU_SOURCE
+#include "bh_memutils.h"
+#endif
+
 #include "platform_api_vmcore.h"
 
 #if defined(__APPLE__) || defined(__MACH__)
 #include <libkern/OSCacheControl.h>
+#include <TargetConditionals.h>
 #endif
 
 #ifndef BH_ENABLE_TRACE_MMAP
@@ -78,19 +85,15 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
         map_prot |= PROT_EXEC;
 
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
+#ifndef __APPLE__
     if (flags & MMAP_MAP_32BIT)
         map_flags |= MAP_32BIT;
+#endif
 #endif
 
     if (flags & MMAP_MAP_FIXED)
         map_flags |= MAP_FIXED;
 
-#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
-#if defined(__APPLE__)
-retry_without_map_32bit:
-#endif
-#endif
-
 #if defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64)
     /* As AOT relocation in RISCV64 may require that the code/data mapped
      * is in range 0 to 2GB, we try to map the memory with hint address
@@ -148,14 +151,6 @@ retry_without_map_32bit:
     }
 
     if (addr == MAP_FAILED) {
-#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
-#if defined(__APPLE__)
-        if ((map_flags & MAP_32BIT) != 0) {
-            map_flags &= ~MAP_32BIT;
-            goto retry_without_map_32bit;
-        }
-#endif
-#endif
 #if BH_ENABLE_TRACE_MMAP != 0
         os_printf("mmap failed\n");
 #endif
@@ -247,6 +242,23 @@ os_munmap(void *addr, size_t size)
     }
 }
 
+#if WASM_HAVE_MREMAP != 0
+void *
+os_mremap(void *old_addr, size_t old_size, size_t new_size)
+{
+    void *ptr = mremap(old_addr, old_size, new_size, MREMAP_MAYMOVE);
+
+    if (ptr == MAP_FAILED) {
+#if BH_ENABLE_TRACE_MMAP != 0
+        os_printf("mremap failed: %d\n", errno);
+#endif
+        return bh_memory_remap_slow(old_addr, old_size, new_size);
+    }
+
+    return ptr;
+}
+#endif
+
 int
 os_mprotect(void *addr, size_t size, int prot)
 {
@@ -278,5 +290,8 @@ os_icache_flush(void *start, size_t len)
 {
 #if defined(__APPLE__) || defined(__MACH__)
     sys_icache_invalidate(start, len);
+#else
+    (void)start;
+    (void)len;
 #endif
 }

+ 2 - 2
core/shared/platform/common/posix/posix_socket.c

@@ -884,7 +884,7 @@ os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
 int
 os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
 {
-    socklen_t opt_len = sizeof(ttl_s);
+    socklen_t opt_len = sizeof(*ttl_s);
     if (getsockopt(socket, IPPROTO_IP, IP_TTL, ttl_s, &opt_len) != 0) {
         return BHT_ERROR;
     }
@@ -906,7 +906,7 @@ os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
 int
 os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
 {
-    socklen_t opt_len = sizeof(ttl_s);
+    socklen_t opt_len = sizeof(*ttl_s);
     if (getsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, ttl_s, &opt_len)
         != 0) {
         return BHT_ERROR;

+ 4 - 0
core/shared/platform/common/posix/posix_thread.c

@@ -9,6 +9,10 @@
 #include "platform_api_vmcore.h"
 #include "platform_api_extension.h"
 
+#if defined(__APPLE__) || defined(__MACH__)
+#include <TargetConditionals.h>
+#endif
+
 typedef struct {
     thread_start_routine_t start;
     void *arg;

+ 12 - 1
core/shared/platform/common/posix/posix_time.c

@@ -6,7 +6,7 @@
 #include "platform_api_vmcore.h"
 
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
     struct timespec ts;
     if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
@@ -15,3 +15,14 @@ os_time_get_boot_microsecond()
 
     return ((uint64)ts.tv_sec) * 1000 * 1000 + ((uint64)ts.tv_nsec) / 1000;
 }
+
+uint64
+os_time_thread_cputime_us()
+{
+    struct timespec ts;
+    if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) {
+        return 0;
+    }
+
+    return ((uint64)ts.tv_sec) * 1000 * 1000 + ((uint64)ts.tv_nsec) / 1000;
+}

+ 9 - 2
core/shared/platform/cosmopolitan/platform_internal.h

@@ -55,6 +55,7 @@ typedef pthread_t korp_tid;
 typedef pthread_mutex_t korp_mutex;
 typedef pthread_cond_t korp_cond;
 typedef pthread_t korp_thread;
+typedef pthread_rwlock_t korp_rwlock;
 typedef sem_t korp_sem;
 
 #define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@@ -67,6 +68,12 @@ typedef int os_file_handle;
 typedef DIR *os_dir_stream;
 typedef int os_raw_file_handle;
 
+static inline os_file_handle
+os_get_invalid_handle()
+{
+    return -1;
+}
+
 #if WASM_DISABLE_WRITE_GS_BASE == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
 #define os_writegsbase(base_addr)                                 \
@@ -98,8 +105,6 @@ typedef jmp_buf korp_jmpbuf;
 #define os_longjmp longjmp
 #define os_alloca alloca
 
-#define os_getpagesize getpagesize
-
 typedef void (*os_signal_handler)(void *sig_addr);
 
 int
@@ -119,6 +124,8 @@ os_sigreturn();
 #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
 #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
+#define os_getpagesize getpagesize
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 2
core/shared/platform/darwin/platform_internal.h

@@ -82,8 +82,6 @@ typedef jmp_buf korp_jmpbuf;
 #define os_longjmp longjmp
 #define os_alloca alloca
 
-#define os_getpagesize getpagesize
-
 typedef void (*os_signal_handler)(void *sig_addr);
 
 int
@@ -103,6 +101,8 @@ os_sigreturn();
 #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
 #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
+#define os_getpagesize getpagesize
+
 #if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
 #define OS_ENABLE_WAKEUP_BLOCKING_OP
 #endif

+ 3 - 0
core/shared/platform/darwin/shared_platform.cmake

@@ -12,6 +12,9 @@ include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
 
 file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
 
+include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
+set (source_all ${source_all} ${PLATFORM_COMMON_MEMORY_SOURCE})
+
 set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_POSIX_SOURCE})
 
 file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)

+ 8 - 1
core/shared/platform/esp-idf/espidf_platform.c

@@ -36,11 +36,18 @@ os_vprintf(const char *format, va_list ap)
 }
 
 uint64
-os_time_get_boot_microsecond(void)
+os_time_get_boot_us(void)
 {
     return (uint64)esp_timer_get_time();
 }
 
+uint64
+os_time_thread_cputime_us(void)
+{
+    /* FIXME if u know the right api */
+    return os_time_get_boot_us();
+}
+
 uint8 *
 os_thread_get_stack_boundary(void)
 {

+ 2 - 2
core/shared/platform/freebsd/platform_internal.h

@@ -85,8 +85,6 @@ typedef jmp_buf korp_jmpbuf;
 #define os_longjmp longjmp
 #define os_alloca alloca
 
-#define os_getpagesize getpagesize
-
 typedef void (*os_signal_handler)(void *sig_addr);
 
 int
@@ -106,6 +104,8 @@ os_sigreturn();
 #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
 #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
+#define os_getpagesize getpagesize
+
 #if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
 #define OS_ENABLE_WAKEUP_BLOCKING_OP
 #endif

+ 13 - 2
core/shared/platform/include/platform_api_vmcore.h

@@ -64,7 +64,13 @@ os_vprintf(const char *format, va_list ap);
  * Get microseconds after boot.
  */
 uint64
-os_time_get_boot_microsecond(void);
+os_time_get_boot_us(void);
+
+/**
+ * Get thread-specific CPU-time clock in microseconds
+ */
+uint64
+os_time_thread_cputime_us(void);
 
 /**
  * Get current thread id.
@@ -129,7 +135,7 @@ enum {
     MMAP_MAP_32BIT = 1,
     /* Don't interpret addr as a hint: place the mapping at exactly
        that address. */
-    MMAP_MAP_FIXED = 2
+    MMAP_MAP_FIXED = 2,
 };
 
 void *
@@ -139,6 +145,11 @@ os_munmap(void *addr, size_t size);
 int
 os_mprotect(void *addr, size_t size, int prot);
 
+/* Doesn't guarantee that protection flags will be preserved.
+   os_mprotect() must be called after remapping. */
+void *
+os_mremap(void *old_addr, size_t old_size, size_t new_size);
+
 #if (WASM_MEM_DUAL_BUS_MIRROR != 0)
 void *
 os_get_dbus_mirror(void *ibus);

+ 2 - 0
core/shared/platform/linux-sgx/platform_internal.h

@@ -79,6 +79,8 @@ os_get_invalid_handle()
     return -1;
 }
 
+#define os_getpagesize getpagesize
+
 #ifdef __cplusplus
 }
 #endif

+ 16 - 1
core/shared/platform/linux-sgx/sgx_time.c

@@ -26,7 +26,7 @@ ocall_clock_nanosleep(int *p_ret, unsigned clock_id, int flags,
                       const void *rem_buf, unsigned int rem_buf_size);
 
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
 #ifndef SGX_DISABLE_WASI
     struct timespec ts;
@@ -40,6 +40,21 @@ os_time_get_boot_microsecond()
 #endif
 }
 
+uint64
+os_time_thread_cputime_us(void)
+{
+#ifndef SGX_DISABLE_WASI
+    struct timespec ts;
+    if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) {
+        return 0;
+    }
+
+    return ((uint64)ts.tv_sec) * 1000 * 1000 + ((uint64)ts.tv_nsec) / 1000;
+#else
+    return 0;
+#endif
+}
+
 #ifndef SGX_DISABLE_WASI
 
 int

+ 3 - 0
core/shared/platform/linux-sgx/shared_platform.cmake

@@ -37,6 +37,9 @@ else()
   set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
 endif()
 
+include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
+set (source_all ${source_all} ${PLATFORM_COMMON_MEMORY_SOURCE})
+
 file (GLOB source_all_untrusted ${PLATFORM_SHARED_DIR}/untrusted/*.c)
 
 set (PLATFORM_SHARED_SOURCE ${source_all})

+ 2 - 2
core/shared/platform/linux/platform_internal.h

@@ -95,8 +95,6 @@ typedef jmp_buf korp_jmpbuf;
 #define os_longjmp longjmp
 #define os_alloca alloca
 
-#define os_getpagesize getpagesize
-
 typedef void (*os_signal_handler)(void *sig_addr);
 
 int
@@ -116,6 +114,8 @@ os_sigreturn();
 #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
 #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
+#define os_getpagesize getpagesize
+
 #if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
 #define OS_ENABLE_WAKEUP_BLOCKING_OP
 #endif

+ 16 - 1
core/shared/platform/nuttx/nuttx_platform.c

@@ -87,6 +87,7 @@ os_dumps_proc_mem_info(char *out, unsigned int size)
 void *
 os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
 {
+    void *p;
 #if (WASM_MEM_DUAL_BUS_MIRROR != 0)
     void *i_addr, *d_addr;
 #endif
@@ -110,7 +111,21 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
         return in_ibus_ext(i_addr) ? i_addr : d_addr;
     }
 #endif
-    return malloc((uint32)size);
+    /* Note: aot_loader.c assumes that os_mmap provides large enough
+     * alignment for any data sections. Some sections like rodata.cst32
+     * actually require alignment larger than the natural alignment
+     * provided by malloc.
+     *
+     * Probably it's cleaner to add an explicit alignment argument to
+     * os_mmap. However, it only makes sense if we change our aot format
+     * to keep the necessary alignment.
+     *
+     * For now, let's assume 32 byte alignment is enough.
+     */
+    if (posix_memalign(&p, 32, size)) {
+        return NULL;
+    }
+    return p;
 }
 
 void

+ 2 - 0
core/shared/platform/nuttx/platform_internal.h

@@ -44,6 +44,8 @@ typedef pthread_t korp_thread;
 typedef pthread_rwlock_t korp_rwlock;
 typedef sem_t korp_sem;
 
+#define os_getpagesize getpagesize
+
 #define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
 
 #define BH_APPLET_PRESERVED_STACK_SIZE (2 * BH_KB)

+ 2 - 1
core/shared/platform/nuttx/shared_platform.cmake

@@ -16,5 +16,6 @@ if (WAMR_BUILD_LIBC_WASI EQUAL 1)
   set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
 endif ()
 
-set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE})
+include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
+set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE} ${PLATFORM_COMMON_MEMORY_SOURCE})
 

+ 11 - 4
core/shared/platform/riot/riot_time.c

@@ -10,25 +10,32 @@
 
 #if IS_USED(MODULE_ZTIMER64_USEC)
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
     return ztimer64_now(ZTIMER64_USEC);
 }
 #elif IS_USED(MODULE_ZTIMER64_MSEC)
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
     return ztimer64_now(ZTIMER64_MSEC) * 1000;
 }
 #else
 #ifdef __GNUC__
 __attribute__((weak)) uint64
-os_time_get_boot_microsecond();
+os_time_get_boot_us();
 #endif
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
     static uint64_t times;
     return ++times;
 }
 #endif
+
+uint64
+os_time_thread_cputime_us(void)
+{
+    /* FIXME if u know the right api */
+    return os_time_get_boot_us();
+}

+ 8 - 1
core/shared/platform/rt-thread/rtt_platform.c

@@ -120,13 +120,20 @@ os_vprintf(const char *format, va_list ap)
 }
 
 uint64
-os_time_get_boot_microsecond(void)
+os_time_get_boot_us(void)
 {
     uint64 ret = rt_tick_get() * 1000;
     ret /= RT_TICK_PER_SECOND;
     return ret;
 }
 
+uint64
+os_time_thread_cputime_us(void)
+{
+    /* FIXME if u know the right api */
+    return os_time_get_boot_us();
+}
+
 korp_tid
 os_self_thread(void)
 {

+ 2 - 2
core/shared/platform/vxworks/platform_internal.h

@@ -79,8 +79,6 @@ typedef jmp_buf korp_jmpbuf;
 #define os_longjmp longjmp
 #define os_alloca alloca
 
-#define os_getpagesize getpagesize
-
 typedef void (*os_signal_handler)(void *sig_addr);
 
 int
@@ -100,6 +98,8 @@ os_sigreturn();
 #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64 */
 #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
+#define os_getpagesize getpagesize
+
 static inline os_file_handle
 os_get_invalid_handle()
 {

+ 3 - 0
core/shared/platform/windows/shared_platform.cmake

@@ -20,6 +20,9 @@ else()
     set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
 endif()
 
+include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
+set (source_all ${source_all} ${PLATFORM_COMMON_MEMORY_SOURCE})
+
 set (PLATFORM_SHARED_SOURCE ${source_all})
 
 file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)

+ 4 - 0
core/shared/platform/windows/win_socket.c

@@ -32,6 +32,7 @@ static bool is_winsock_inited = false;
 int
 init_winsock()
 {
+#if WASM_ENABLE_HOST_SOCKET_INIT == 0
     WSADATA wsaData;
 
     if (!is_winsock_inited) {
@@ -42,6 +43,7 @@ init_winsock()
 
         is_winsock_inited = true;
     }
+#endif
 
     return BHT_OK;
 }
@@ -49,9 +51,11 @@ init_winsock()
 void
 deinit_winsock()
 {
+#if WASM_ENABLE_HOST_SOCKET_INIT == 0
     if (is_winsock_inited) {
         WSACleanup();
     }
+#endif
 }
 
 int

+ 8 - 1
core/shared/platform/windows/win_time.c

@@ -6,7 +6,7 @@
 #include "platform_api_vmcore.h"
 
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
     struct timespec ts;
 #if defined(__MINGW32__)
@@ -18,3 +18,10 @@ os_time_get_boot_microsecond()
 
     return ((uint64)ts.tv_sec) * 1000 * 1000 + ((uint64)ts.tv_nsec) / 1000;
 }
+
+uint64
+os_time_thread_cputime_us(void)
+{
+    /* FIXME if u know the right api */
+    return os_time_get_boot_us();
+}

+ 8 - 1
core/shared/platform/zephyr/zephyr_time.c

@@ -6,7 +6,14 @@
 #include "platform_api_vmcore.h"
 
 uint64
-os_time_get_boot_microsecond()
+os_time_get_boot_us()
 {
     return k_uptime_get() * 1000;
 }
+
+uint64
+os_time_thread_cputime_us(void)
+{
+    /* FIXME if u know the right api */
+    return os_time_get_boot_us();
+}

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio