Sfoglia il codice sorgente

Merge branch main into dev/thread_suspension

Wenyong Huang 1 anno fa
parent
commit
e209942a0e
100 ha cambiato i file con 5398 aggiunte e 3989 eliminazioni
  1. 5 0
      .github/ISSUE_TEMPLATE/blank_issue.md
  2. 28 0
      .github/ISSUE_TEMPLATE/improvement.md
  3. 36 0
      .github/ISSUE_TEMPLATE/report_bug.md
  4. 35 0
      .github/dependabot.yml
  5. 282 0
      .github/scripts/codeql_buildscript.sh
  6. 124 0
      .github/scripts/codeql_fail_on_error.py
  7. 6 3
      .github/scripts/fetch_and_compare_version.py
  8. 7 1
      .github/workflows/build_llvm_libraries.yml
  9. 1 3
      .github/workflows/build_wamr_lldb.yml
  10. 6 0
      .github/workflows/build_wamr_sdk.yml
  11. 1 1
      .github/workflows/build_wamr_vscode_ext.yml
  12. 117 0
      .github/workflows/codeql.yml
  13. 72 11
      .github/workflows/compilation_on_android_ubuntu.yml
  14. 28 11
      .github/workflows/compilation_on_macos.yml
  15. 23 2
      .github/workflows/compilation_on_nuttx.yml
  16. 16 2
      .github/workflows/create_tag.yml
  17. 77 9
      .github/workflows/nightly_run.yml
  18. 5 5
      .github/workflows/release_process.yml
  19. 4 1
      .github/workflows/spec_test_on_nuttx.yml
  20. 36 0
      ADOPTERS.md
  21. 2 6
      ATTRIBUTIONS.md
  22. 6 1
      CMakeLists.txt
  23. 1 1
      CONTRIBUTING.md
  24. 17 14
      README.md
  25. 99 0
      RELEASE_NOTES.md
  26. 38 1
      build-scripts/config_common.cmake
  27. 88 42
      build-scripts/esp-idf/wamr/CMakeLists.txt
  28. 77 0
      build-scripts/esp-idf/wamr/Kconfig
  29. 0 8
      core/app-mgr/README.md
  30. 0 1747
      core/app-mgr/app-manager/module_wasm_app.c
  31. 0 70
      core/app-mgr/app-manager/platform/zephyr/app_mgr_zephyr.c
  32. 96 4
      core/config.h
  33. 82 82
      core/iwasm/aot/aot_intrinsic.c
  34. 1 1
      core/iwasm/aot/aot_intrinsic.h
  35. 144 216
      core/iwasm/aot/aot_loader.c
  36. 120 0
      core/iwasm/aot/aot_perf_map.c
  37. 15 0
      core/iwasm/aot/aot_perf_map.h
  38. 6 1
      core/iwasm/aot/aot_reloc.h
  39. 271 141
      core/iwasm/aot/aot_runtime.c
  40. 46 25
      core/iwasm/aot/aot_runtime.h
  41. 0 1
      core/iwasm/aot/debug/elf_parser.c
  42. 10 3
      core/iwasm/aot/debug/jit_debug.c
  43. 6 1
      core/iwasm/common/gc/gc_common.c
  44. 10 0
      core/iwasm/common/gc/gc_object.c
  45. 10 0
      core/iwasm/common/gc/gc_object.h
  46. 137 31
      core/iwasm/common/gc/gc_type.c
  47. 6 0
      core/iwasm/common/gc/gc_type.h
  48. 33 19
      core/iwasm/common/wasm_application.c
  49. 64 16
      core/iwasm/common/wasm_c_api.c
  50. 6 6
      core/iwasm/common/wasm_exec_env.c
  51. 6 10
      core/iwasm/common/wasm_exec_env.h
  52. 166 66
      core/iwasm/common/wasm_memory.c
  53. 23 5
      core/iwasm/common/wasm_memory.h
  54. 8 3
      core/iwasm/common/wasm_native.c
  55. 511 99
      core/iwasm/common/wasm_runtime_common.c
  56. 47 32
      core/iwasm/common/wasm_runtime_common.h
  57. 1 2
      core/iwasm/common/wasm_shared_memory.c
  58. 3 3
      core/iwasm/compilation/aot.h
  59. 7 56
      core/iwasm/compilation/aot_compiler.c
  60. 116 93
      core/iwasm/compilation/aot_emit_aot_file.c
  61. 8 2
      core/iwasm/compilation/aot_emit_control.c
  62. 6 6
      core/iwasm/compilation/aot_emit_exception.c
  63. 105 25
      core/iwasm/compilation/aot_emit_function.c
  64. 2 4
      core/iwasm/compilation/aot_emit_memory.c
  65. 9 3
      core/iwasm/compilation/aot_emit_variable.c
  66. 80 16
      core/iwasm/compilation/aot_llvm.c
  67. 39 3
      core/iwasm/compilation/debug/dwarf_extractor.cpp
  68. 0 9
      core/iwasm/compilation/simd/simd_conversions.c
  69. 0 4
      core/iwasm/compilation/simd/simd_conversions.h
  70. 0 14
      core/iwasm/compilation/simd/simd_floating_point.c
  71. 0 8
      core/iwasm/compilation/simd/simd_floating_point.h
  72. 1 10
      core/iwasm/compilation/simd/simd_int_arith.c
  73. 0 4
      core/iwasm/compilation/simd/simd_int_arith.h
  74. 0 15
      core/iwasm/compilation/simd/simd_sat_int_arith.c
  75. 0 4
      core/iwasm/compilation/simd/simd_sat_int_arith.h
  76. 6 6
      core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp
  77. 10 3
      core/iwasm/fast-jit/fe/jit_emit_function.c
  78. 11 9
      core/iwasm/fast-jit/fe/jit_emit_memory.c
  79. 14 8
      core/iwasm/fast-jit/jit_frontend.c
  80. 6 0
      core/iwasm/include/aot_export.h
  81. 16 0
      core/iwasm/include/gc_export.h
  82. 5 0
      core/iwasm/include/lib_export.h
  83. 36 0
      core/iwasm/include/wasm_c_api.h
  84. 232 77
      core/iwasm/include/wasm_export.h
  85. 54 13
      core/iwasm/interpreter/wasm.h
  86. 345 177
      core/iwasm/interpreter/wasm_interp_classic.c
  87. 81 50
      core/iwasm/interpreter/wasm_interp_fast.c
  88. 305 256
      core/iwasm/interpreter/wasm_loader.c
  89. 1 1
      core/iwasm/interpreter/wasm_loader.h
  90. 318 198
      core/iwasm/interpreter/wasm_mini_loader.c
  91. 10 10
      core/iwasm/interpreter/wasm_opcode.h
  92. 400 120
      core/iwasm/interpreter/wasm_runtime.c
  93. 57 30
      core/iwasm/interpreter/wasm_runtime.h
  94. 2 2
      core/iwasm/libraries/debug-engine/debug_engine.c
  95. 2 2
      core/iwasm/libraries/debug-engine/debug_engine.h
  96. 3 1
      core/iwasm/libraries/debug-engine/handler.c
  97. 8 6
      core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c
  98. 1 1
      core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
  99. 3 3
      core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c
  100. 34 34
      core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c

+ 5 - 0
.github/ISSUE_TEMPLATE/blank_issue.md

@@ -0,0 +1,5 @@
+---
+name: Blank Issue
+about: Create a blank issue.
+title: ''
+---

+ 28 - 0
.github/ISSUE_TEMPLATE/improvement.md

@@ -0,0 +1,28 @@
+---
+name: Improvement
+about: A feature request or code improvement.
+title: ''
+labels: ''
+assignees: ''
+---
+
+Thanks for filing a feature request! Please fill out the TODOs below.
+
+#### Feature
+
+TODO: Brief description of the feature/improvement you'd like to see in WAMR
+
+#### Benefit
+
+TODO: What is the value of adding this in WAMR? What problems does it solve?
+
+#### Implementation
+
+TODO: Do you have an implementation plan, and/or ideas for data structures or
+algorithms to use?
+
+#### Alternatives
+
+TODO: What are the alternative implementation approaches or alternative ways to
+solve the problem that this feature would solve? How do these alternatives
+compare to this proposal?

+ 36 - 0
.github/ISSUE_TEMPLATE/report_bug.md

@@ -0,0 +1,36 @@
+---
+name: WAMR bug or defect report
+about: Report a bug or defect in WAMR
+title: ''
+---
+
+Thanks for filing a bug or defect report! Please fill out the TODOs below.
+
+### Subject of the issue
+
+Describe the bug or defect here.
+
+### Test case
+
+Upload the related wasm file, wast file or the source files if you can.
+
+### Your environment
+
+* Host OS
+* WAMR version, platform, cpu architecture, running mode, etc.
+
+### Steps to reproduce
+
+Tell us how to reproduce this bug or defect.
+
+### Expected behavior
+
+Tell us what should happen
+
+### Actual behavior
+
+Tell us what happens instead
+
+### Extra Info
+
+Anything else you'd like to add?

+ 35 - 0
.github/dependabot.yml

@@ -0,0 +1,35 @@
+# Copyright (C) 2019 Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+version: 2
+updates:
+
+- package-ecosystem: "github-actions"
+  directory: "/"
+  schedule:
+    interval: "weekly"
+
+- package-ecosystem: "docker"
+  directory: "/.devcontainer"
+  schedule:
+    interval: "weekly"
+
+- package-ecosystem: "devcontainers"
+  directory: "/"
+  schedule:
+    interval: "weekly"
+
+- package-ecosystem: "pip"
+  directory: "/build-scripts"
+  schedule:
+    interval: "weekly"
+
+- package-ecosystem: "pip"
+  directory: "/language-bindings/python/wasm-c-api"
+  schedule:
+    interval: "weekly"
+
+- package-ecosystem: "pip"
+  directory: "/language-bindings/python/wamr-api"
+  schedule:
+    interval: "weekly"

+ 282 - 0
.github/scripts/codeql_buildscript.sh

@@ -0,0 +1,282 @@
+#!/usr/bin/env bash
+
+#
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+
+sudo apt update
+
+sudo apt install -y build-essential cmake g++-multilib libgcc-11-dev lib32gcc-11-dev ccache ninja-build ccache
+
+WAMR_DIR=${PWD}
+
+# TODO: use pre-built llvm binary to build wamrc to
+#       avoid static code analysing for llvm
+: '
+# build wamrc
+cd ${WAMR_DIR}/wamr-compiler
+./build_llvm.sh
+rm -fr build && mkdir build && cd build
+cmake ..
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build wamrc!"
+    exit 1;
+fi
+'
+
+# build iwasm with default features enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -fr build && mkdir build && cd build
+cmake ..
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with default features enabled!"
+    exit 1;
+fi
+
+# build iwasm with default features enabled on x86_32
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -fr build && mkdir build && cd build
+cmake .. -DWAMR_BUILD_TARGET=X86_32
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with default features enabled on x86_32!"
+    exit 1;
+fi
+
+# build iwasm with classic interpreter enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_FAST_INTERP=0
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with classic interpreter enabled!"
+    exit 1;
+fi
+
+# build iwasm with extra features enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -fr build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug \
+    -DWAMR_BUILD_LIB_PTHREAD=1 -DWAMR_BUILD_LIB_PTHREAD_SEMAPHORE=1 \
+    -DWAMR_BUILD_MULTI_MODULE=1 -DWAMR_BUILD_SIMD=1 \
+    -DWAMR_BUILD_TAIL_CALL=1 -DWAMR_BUILD_REF_TYPES=1 \
+    -DWAMR_BUILD_CUSTOM_NAME_SECTION=1 -DWAMR_BUILD_MEMORY_PROFILING=1 \
+    -DWAMR_BUILD_PERF_PROFILING=1 -DWAMR_BUILD_DUMP_CALL_STACK=1 \
+    -DWAMR_BUILD_LOAD_CUSTOM_SECTION=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build wamrc iwasm with extra features enabled!"
+    exit 1;
+fi
+
+# build iwasm with global heap pool enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -fr build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug \
+    -DWAMR_BUILD_ALLOC_WITH_USER_DATA=1 \
+    -DWAMR_DISABLE_STACK_HW_BOUND_CHECK=1 \
+    -DWAMR_BUILD_GLOBAL_HEAP_POOL=1 \
+    -DWAMR_BUILD_GLOBAL_HEAP_SIZE=131072
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with global heap pool enabled!"
+    exit 1;
+fi
+
+# build iwasm with wasi-threads enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -fr build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_LIB_WASI_THREADS=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with wasi-threads enabled!"
+    exit 1;
+fi
+
+# build iwasm with GC enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_GC=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with GC enabled!"
+    exit 1;
+fi
+
+# build iwasm with exception handling enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_EXCE_HANDLING=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with exception handling enabled!"
+    exit 1;
+fi
+
+# build iwasm with memory64 enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_MEMORY64=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with memory64 enabled!"
+    exit 1;
+fi
+
+# build iwasm with hardware boundary check disabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_DISABLE_HW_BOUND_CHECK=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with hardware boundary check disabled!"
+    exit 1;
+fi
+
+# build iwasm with quick AOT entry disabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_QUICK_AOT_ENTRY=0
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with quick AOT entry disabled!"
+    exit 1;
+fi
+
+# build iwasm with wakeup of blocking operations disabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_DISABLE_WAKEUP_BLOCKING_OP=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with wakeup of blocking operations disabled!"
+    exit 1;
+fi
+
+# build iwasm with module instance context disabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_MODULE_INST_CONTEXT=0 \
+         -DWAMR_BUILD_LIBC_BUILTIN=0 -DWAMR_BUILD_LIBC_WASI=0
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with module instance context disabled!"
+    exit 1;
+fi
+
+# build iwasm with libc-uvwasi enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -fr build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_LIBC_UVWASI=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with libc-uvwasi enabled!"
+    exit 1;
+fi
+
+# build iwasm with fast jit lazy mode enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_FAST_JIT_DUMP=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with fast jit lazy mode enabled!"
+    exit 1;
+fi
+
+# build iwasm with fast jit eager mode enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_FAST_JIT_DUMP=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with fast jit eager mode enabled!"
+    exit 1;
+fi
+
+# TODO: use pre-built llvm binary to build llvm-jit and multi-tier-jit
+: '
+# build iwasm with llvm jit lazy mode enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_JIT=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build llvm jit lazy mode enabled!"
+    exit 1;
+fi
+
+# build iwasm with llvm jit eager mode enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build llvm jit eager mode enabled!"
+    exit 1;
+fi
+
+# build iwasm with multi-tier jit enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=1 \
+                                    -DWAMR_BUILD_FAST_JIT_DUMP=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with multi-tier jit enabled!"
+    exit 1;
+fi
+'
+
+# build iwasm with wasm mini-loader enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_MINI_LOADER=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build with wasm mini-loader enabled!"
+    exit 1;
+fi
+
+# build iwasm with source debugging enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_DEBUG_INTERP=1 -DWAMR_BUILD_DEBUG_AOT=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with source debugging enabled!"
+    exit 1;
+fi
+
+# build iwasm with AOT static PGO enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_STATIC_PGO=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with AOT static PGO enabled!"
+    exit 1;
+fi
+
+# build iwasm with configurable bounds checks enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_CONFIGUABLE_BOUNDS_CHECKS=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with configurable bounds checks enabled!"
+    exit 1;
+fi
+
+# build iwasm with linux perf support enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux/
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_LINUX_PERF=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with linux perf support enabled!"
+    exit 1;
+fi

+ 124 - 0
.github/scripts/codeql_fail_on_error.py

@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+
+import json
+import sys
+import os
+import requests
+
+
+def fetch_dismissed_alerts(repo_name, github_token):
+    headers = {
+        "Authorization": f"token {github_token}",
+        "Accept": "application/vnd.github.v3+json",
+    }
+    url = (
+        f"https://api.github.com/repos/{repo_name}/code-scanning/alerts?state=dismissed"
+    )
+    response = requests.get(url, headers=headers)
+    return response.json()  # This assumes a successful API call
+
+
+def parse_location(location):
+    path = location.get("physicalLocation", {}).get("artifactLocation", {}).get("uri")
+    start_line = location.get("physicalLocation", {}).get("region", {}).get("startLine")
+    column_range = (
+        location.get("physicalLocation", {}).get("region", {}).get("startColumn"),
+        location.get("physicalLocation", {}).get("region", {}).get("endColumn"),
+    )
+    return (path, start_line, column_range)
+
+
+def is_dismissed(rule_id, path, start_line, column_range, dismissed_alerts):
+    for alert in dismissed_alerts:
+        alert_rule_id = alert.get("rule", {}).get("id")
+        alert_path = alert.get("location", {}).get("path")
+        alert_start_line = alert.get("location", {}).get("start_line")
+        alert_column_range = (
+            alert.get("location", {}).get("start_column"),
+            alert.get("location", {}).get("end_column"),
+        )
+
+        if (
+            rule_id == alert_rule_id
+            and path == alert_path
+            and start_line == alert_start_line
+            and column_range == alert_column_range
+        ):
+            return True
+    return False
+
+
+# Return whether SARIF file contains error-level results
+def codeql_sarif_contain_error(filename, dismissed_alerts):
+    has_error = False
+
+    with open(filename, "r") as f:
+        s = json.load(f)
+
+    for run in s.get("runs", []):
+        rules_metadata = run["tool"]["driver"]["rules"]
+        if not rules_metadata:
+            rules_metadata = run["tool"]["extensions"][0]["rules"]
+
+        for res in run.get("results", []):
+            if "ruleIndex" in res:
+                rule_index = res["ruleIndex"]
+            elif "rule" in res and "index" in res["rule"]:
+                rule_index = res["rule"]["index"]
+            else:
+                continue
+
+            # check whether it's dismissed before
+            rule_id = res["ruleId"]
+            path, start_line, column_range = parse_location(res["locations"][0])
+            # the source code is from dependencies
+            if "_deps" in path:
+                continue
+            if is_dismissed(rule_id, path, start_line, column_range, dismissed_alerts):
+                print(
+                    f"====== Finding a dismissed entry: {rule_id} at {path}:{start_line} is dismissed.======"
+                )
+                print(res)
+                continue
+
+            try:
+                rule_level = rules_metadata[rule_index]["defaultConfiguration"]["level"]
+            except IndexError as e:
+                print(e, rule_index, len(rules_metadata))
+            else:
+                if rule_level == "error":
+                    # very likely to be an actual error
+                    if rules_metadata[rule_index]["properties"].get("precision") in [
+                        "high",
+                        "very-high",
+                    ]:
+                        # the security severity is above medium(Common Vulnerability Scoring System (CVSS) >= 4.0)
+                        if "security-severity" in rules_metadata[rule_index][
+                            "properties"
+                        ] and (
+                            float(
+                                rules_metadata[rule_index]["properties"][
+                                    "security-severity"
+                                ]
+                            )
+                            > 4.0
+                        ):
+                            print("====== Finding a likely error. ======")
+                            print(res)
+                            has_error = True
+
+    return has_error
+
+
+if __name__ == "__main__":
+    GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
+    GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY")
+    dismissed_alerts = fetch_dismissed_alerts(GITHUB_REPOSITORY, GITHUB_TOKEN)
+
+    if codeql_sarif_contain_error(sys.argv[1], dismissed_alerts):
+        sys.exit(1)

+ 6 - 3
.github/scripts/fetch_and_compare_version.py

@@ -42,9 +42,12 @@ def fetch_version_from_code():
 
 
 def fetch_latest_git_tag():
-    list_tag_cmd = (
-        'git tag --list WAMR-*.*.* --sort=committerdate --format="%(refname:short)"'
-    )
+    """
+    Get the most recent tag from the HEAD,
+    if it's main branch, it should be the latest release tag.
+    if it's release/x.x.x branch, it should be the latest release tag of the branch.
+    """
+    list_tag_cmd = "git describe --tags --abbrev=0 HEAD"
     p = subprocess.run(shlex.split(list_tag_cmd), capture_output=True, check=True)
 
     all_tags = p.stdout.decode().strip()

+ 7 - 1
.github/workflows/build_llvm_libraries.yml

@@ -33,10 +33,16 @@ jobs:
       - name: checkout
         uses: actions/checkout@v4
 
-      - name: install dependencies
+      - name: install dependencies for non macos-14
+        if: inputs.os != 'macos-14'
         run: /usr/bin/env python3 -m pip install -r requirements.txt
         working-directory: build-scripts
 
+      - name: install dependencies for macos-14
+        if: inputs.os == 'macos-14'
+        run: /usr/bin/env python3 -m pip install -r requirements.txt --break-system-packages
+        working-directory: build-scripts
+
       - name: retrive the last commit ID
         id: get_last_commit
         run: echo "last_commit=$(GH_TOKEN=${{ secrets.GITHUB_TOKEN }} /usr/bin/env python3 ./build_llvm.py --llvm-ver)" >> $GITHUB_OUTPUT

+ 1 - 3
.github/workflows/build_wamr_lldb.yml

@@ -82,9 +82,7 @@ jobs:
       - name: install utils macos
         if: steps.lldb_build_cache.outputs.cache-hit != 'true' && contains(inputs.runner, 'macos')
         run: |
-          brew remove swig
-          brew install swig@4.1 cmake ninja libedit
-          brew link --overwrite swig@4.1
+          brew install swig cmake ninja libedit
           sudo rm -rf /Library/Developer/CommandLineTools
 
       - name: install utils ubuntu

+ 6 - 0
.github/workflows/build_wamr_sdk.yml

@@ -58,6 +58,12 @@ jobs:
           sudo rm ${basename}
           sudo mv wasi-sdk-* wasi-sdk
 
+      - name: download dependencies
+        run: |
+          cd ./wamr-app-framework/deps
+          ./download.sh
+        working-directory: wamr-sdk
+
       - name: generate wamr-sdk release
         run: |
           cd ./wamr-app-framework/wamr-sdk

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

@@ -21,7 +21,7 @@ jobs:
       - uses: actions/checkout@v4
 
       - name: Use Node.js 16.x
-        uses: actions/setup-node@v3
+        uses: actions/setup-node@v4
         with:
           node-version: 16.x
 

+ 117 - 0
.github/workflows/codeql.yml

@@ -0,0 +1,117 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+name: "CodeQL"
+
+on:
+  #pull_request:
+  #  types:
+  #    - opened
+  #  branches: '*'
+  #push:
+  #   branches: [ "main" ]
+  # midnight UTC
+  schedule:
+    - cron: '0 0 * * *'
+  # allow to be triggered manually
+  workflow_dispatch:
+
+jobs:
+  analyze:
+    if: github.repository == 'bytecodealliance/wasm-micro-runtime'
+    name: Analyze
+    # Runner size impacts CodeQL analysis time. To learn more, please see:
+    #   - https://gh.io/recommended-hardware-resources-for-running-codeql
+    #   - https://gh.io/supported-runners-and-hardware-resources
+    #   - https://gh.io/using-larger-runners
+    # Consider using larger runners for possible analysis time improvements.
+    runs-on: ${{ (matrix.language == 'swift' && 'macos-13') || 'ubuntu-20.04' }}
+    timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
+    permissions:
+      actions: read
+      contents: read
+      security-events: write
+
+    strategy:
+      fail-fast: false
+      matrix:
+        language: [ 'cpp' ]
+        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
+
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v3
+      with:
+        submodules: recursive
+
+    # Initializes the CodeQL tools for scanning.
+    - name: Initialize CodeQL
+      uses: github/codeql-action/init@v3
+      with:
+        languages: ${{ matrix.language }}
+
+        # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+        # queries: security-extended,security-and-quality
+        queries: security-and-quality
+
+    # Command-line programs to run using the OS shell.
+    # See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
+
+    #   If the Autobuild fails above, remove it and uncomment the following three lines.
+    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
+
+    - run: |
+        ./.github/scripts/codeql_buildscript.sh
+    - name: Perform CodeQL Analysis
+      uses: github/codeql-action/analyze@v3
+      with:
+        category: "/language:${{matrix.language}}"
+        upload: false
+      id: step1
+
+    # Filter out rules with low severity or high false positve rate
+    # Also filter out warnings in third-party code
+    - name: Filter out unwanted errors and warnings
+      uses: advanced-security/filter-sarif@v1
+      with:
+        patterns: |
+          -**:cpp/path-injection
+          -**:cpp/world-writable-file-creation
+          -**:cpp/poorly-documented-function
+          -**:cpp/potentially-dangerous-function
+          -**:cpp/use-of-goto
+          -**:cpp/integer-multiplication-cast-to-long
+          -**:cpp/comparison-with-wider-type
+          -**:cpp/leap-year/*
+          -**:cpp/ambiguously-signed-bit-field
+          -**:cpp/suspicious-pointer-scaling
+          -**:cpp/suspicious-pointer-scaling-void
+          -**:cpp/unsigned-comparison-zero
+          -**/cmake*/Modules/**
+        input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
+        output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
+
+    - name: Upload CodeQL results to code scanning
+      uses: github/codeql-action/upload-sarif@v3
+      with:
+        sarif_file: ${{ steps.step1.outputs.sarif-output }}
+        category: "/language:${{matrix.language}}"
+
+    - name: Upload CodeQL results as an artifact
+      if: success() || failure()
+      uses: actions/upload-artifact@v4
+      with:
+        name: codeql-results
+        path: ${{ steps.step1.outputs.sarif-output }}
+        retention-days: 10
+
+    - name: Fail if an error is found
+      run: |
+        ./.github/scripts/codeql_fail_on_error.py \
+          ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        GITHUB_REPOSITORY: ${{ github.repository }}

+ 72 - 11
.github/workflows/compilation_on_android_ubuntu.yml

@@ -65,6 +65,7 @@ env:
   WASI_TEST_OPTIONS: "-s wasi_certification -w"
   WAMR_COMPILER_TEST_OPTIONS: "-s wamr_compiler -S -b -P"
   GC_TEST_OPTIONS: "-s spec -G -b -P"
+  MEMORY64_TEST_OPTIONS: "-s spec -W -b -P"
 
 jobs:
   build_llvm_libraries_on_ubuntu_2204:
@@ -144,6 +145,7 @@ jobs:
             "-DWAMR_BUILD_SIMD=1",
             "-DWAMR_BUILD_TAIL_CALL=1",
             "-DWAMR_DISABLE_HW_BOUND_CHECK=1",
+            "-DWAMR_BUILD_MEMORY64=1",
           ]
         os: [ubuntu-22.04]
         platform: [android, linux]
@@ -202,11 +204,32 @@ jobs:
             make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
           - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
             make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
-          # Fast-JIT and Multi-Tier-JIT mode don't support android(X86-32)
+          # Memory64 only on CLASSIC INTERP mode, and only on 64-bit platform
+          - make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+            platform: android
+          - make_options_run_mode: $AOT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          # Fast-JIT and Multi-Tier-JIT mode don't support android
           - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
             platform: android
           - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
             platform: android
+          # LLVM JIT pre-built binary wasn't compiled by Android NDK
+          # and isn't available for android
+          - make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
+            platform: android
+          - make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
+            platform: android
         include:
           - os: ubuntu-22.04
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
@@ -232,13 +255,23 @@ jobs:
         if: endsWith(matrix.make_options_run_mode, '_JIT_BUILD_OPTIONS') && (steps.retrieve_llvm_libs.outputs.cache-hit != 'true')
         run: echo "::error::can not get prebuilt llvm libraries" && exit 1
 
-      - name: Build iwasm
+      - name: Build iwasm for linux
+        if: matrix.platform == 'linux'
         run: |
           mkdir build && cd build
           cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }}
           cmake --build . --config Release --parallel 4
         working-directory: product-mini/platforms/${{ matrix.platform }}
 
+      - name: Build iwasm for android
+        if: matrix.platform == 'android'
+        run: |
+          mkdir build && cd build
+          cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }} \
+                -DWAMR_BUILD_TARGET=X86_64
+          cmake --build . --config Release --parallel 4
+        working-directory: product-mini/platforms/${{ matrix.platform }}
+
       - name: Build and run unit tests
         run: |
           mkdir build-unittests && cd build-unittests
@@ -356,14 +389,14 @@ jobs:
           cd /opt
           sudo wget ${{ matrix.wasi_sdk_release }}
           sudo tar -xzf wasi-sdk-*.tar.gz
-          sudo mv wasi-sdk-20.0 wasi-sdk
+          sudo ln -sf wasi-sdk-20.0 wasi-sdk
 
       - name: download and install wabt
         run: |
           cd /opt
           sudo wget ${{ matrix.wabt_release }}
           sudo tar -xzf wabt-1.0.31-*.tar.gz
-          sudo mv wabt-1.0.31 wabt
+          sudo ln -sf wabt-1.0.31 wabt
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
         uses: actions/cache@v4
@@ -448,6 +481,23 @@ jobs:
           ./build.sh
           ./run.sh
 
+      - name: Build Sample [debug-tools]
+        run: |
+          cd samples/debug-tools
+          mkdir build && cd build
+          cmake ..
+          cmake --build . --config Debug --parallel 4
+          ./iwasm wasm-apps/trap.wasm | grep "#" > call_stack.txt
+          ./iwasm wasm-apps/trap.aot | grep "#" > call_stack_aot.txt
+          bash -x ../symbolicate.sh
+
+      - name: Build Sample [native-stack-overflow]
+        run: |
+          cd samples/native-stack-overflow
+          ./build.sh
+          ./run.sh test1
+          ./run.sh test2
+
   test:
     needs:
       [
@@ -477,6 +527,7 @@ jobs:
             $THREADS_TEST_OPTIONS,
             $WASI_TEST_OPTIONS,
             $GC_TEST_OPTIONS,
+            $MEMORY64_TEST_OPTIONS,
           ]
         wasi_sdk_release:
           [
@@ -515,19 +566,30 @@ jobs:
             test_option: $GC_TEST_OPTIONS
           - running_mode: "multi-tier-jit"
             test_option: $GC_TEST_OPTIONS
+          # aot, fast-interp, fast-jit, llvm-jit, multi-tier-jit don't support Memory64
+          - running_mode: "aot"
+            test_option: $MEMORY64_TEST_OPTIONS
+          - running_mode: "fast-interp"
+            test_option: $MEMORY64_TEST_OPTIONS
+          - running_mode: "fast-jit"
+            test_option: $MEMORY64_TEST_OPTIONS
+          - running_mode: "jit"
+            test_option: $MEMORY64_TEST_OPTIONS
+          - running_mode: "multi-tier-jit"
+            test_option: $MEMORY64_TEST_OPTIONS
     steps:
       - name: checkout
         uses: actions/checkout@v4
 
       - name: Set-up OCaml
         uses: ocaml/setup-ocaml@v2
-        if: matrix.test_option == '$GC_TEST_OPTIONS'
+        if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS'
         with:
           ocaml-compiler: 4.13
 
       - name: Set-up Ocamlbuild
-        if: matrix.test_option == '$GC_TEST_OPTIONS'
-        run: opam install ocamlbuild dune
+        if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS'
+        run: opam install ocamlbuild dune menhir
 
       - name: download and install wasi-sdk
         if: matrix.test_option == '$WASI_TEST_OPTIONS'
@@ -546,7 +608,6 @@ jobs:
           make -j AR=/opt/wasi-sdk/bin/llvm-ar NM=/opt/wasi-sdk/bin/llvm-nm CC=/opt/wasi-sdk/bin/clang THREAD_MODEL=posix
           echo "SYSROOT_PATH=$PWD/sysroot" >> $GITHUB_ENV
 
-
       - name: set env variable(if llvm are used)
         if: matrix.running_mode == 'aot' || matrix.running_mode == 'jit' || matrix.running_mode == 'multi-tier-jit'
         run: echo "USE_LLVM=true" >> $GITHUB_ENV
@@ -592,13 +653,13 @@ jobs:
 
       - name: run tests
         timeout-minutes: 30
-        if: matrix.test_option != '$GC_TEST_OPTIONS'
+        if: matrix.test_option != '$GC_TEST_OPTIONS' && matrix.test_option != '$MEMORY64_TEST_OPTIONS'
         run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
         working-directory: ./tests/wamr-test-suites
 
-      - name: run gc tests
+      - name: run gc or memory64 tests
         timeout-minutes: 20
-        if: matrix.test_option == '$GC_TEST_OPTIONS'
+        if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS'
         run: |
           eval $(opam env)
           ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}

+ 28 - 11
.github/workflows/compilation_on_macos.yml

@@ -56,7 +56,7 @@ jobs:
   build_llvm_libraries_on_intel_macos:
     uses: ./.github/workflows/build_llvm_libraries.yml
     with:
-      os: "macos-latest"
+      os: "macos-13"
       arch: "X86"
   build_llvm_libraries_on_arm_macos:
     uses: ./.github/workflows/build_llvm_libraries.yml
@@ -70,7 +70,7 @@ jobs:
     strategy:
       matrix:
         include:
-          - os: macos-latest
+          - os: macos-13
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}
     steps:
       - name: checkout
@@ -131,7 +131,7 @@ jobs:
             "-DWAMR_BUILD_TAIL_CALL=1",
             "-DWAMR_DISABLE_HW_BOUND_CHECK=1",
           ]
-        os: [macos-latest]
+        os: [macos-13]
         platform: [darwin]
         exclude:
           # uncompatiable feature and platform
@@ -173,7 +173,7 @@ jobs:
           - make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
             make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
         include:
-          - os: macos-latest
+          - os: macos-13
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}
     steps:
       - name: checkout
@@ -218,7 +218,7 @@ jobs:
             #$LLVM_EAGER_JIT_BUILD_OPTIONS,
             #$AOT_BUILD_OPTIONS,
           ]
-        os: [macos-latest]
+        os: [macos-13]
         wasi_sdk_release:
           [
             "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-macos.tar.gz",
@@ -242,7 +242,7 @@ jobs:
         run: |
           cmake -S . -B build ${{ matrix.make_options }}
           cmake --build build --config Release --parallel 4
-          ctest --test-dir build
+          ctest --test-dir build --output-on-failure
         working-directory: samples/wasm-c-api
 
   build_samples_others:
@@ -250,7 +250,7 @@ jobs:
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
-        os: [macos-latest, macos-14]
+        os: [macos-13, macos-14]
         wasi_sdk_release:
           [
             "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-macos.tar.gz",
@@ -260,7 +260,7 @@ jobs:
             "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-macos-12.tar.gz",
           ]
         include:
-          - os: macos-latest
+          - os: macos-13
             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 }}
@@ -273,14 +273,14 @@ jobs:
           cd /opt
           sudo wget ${{ matrix.wasi_sdk_release }}
           sudo tar -xzf wasi-sdk-*.tar.gz
-          sudo mv wasi-sdk-20.0 wasi-sdk
+          sudo ln -sf wasi-sdk-20.0 wasi-sdk
 
       - name: download and install wabt
         run: |
           cd /opt
           sudo wget ${{ matrix.wabt_release }}
           sudo tar -xzf wabt-1.0.31-*.tar.gz
-          sudo mv wabt-1.0.31 wabt
+          sudo ln -sf wabt-1.0.31 wabt
 
       - name: Build Sample [basic]
         run: |
@@ -346,7 +346,7 @@ jobs:
           cmake ..
           cmake --build . --config Release --parallel 4
         working-directory: wamr-compiler
-        
+
       - name: Build Sample [wasi-threads]
         run: |
           cd samples/wasi-threads
@@ -369,3 +369,20 @@ jobs:
           cd samples/terminate
           ./build.sh
           ./run.sh
+
+      - name: Build Sample [debug-tools]
+        run: |
+          cd samples/debug-tools
+          mkdir build && cd build
+          cmake ..
+          cmake --build . --config Debug --parallel 4
+          ./iwasm wasm-apps/trap.wasm | grep "#" > call_stack.txt
+          ./iwasm wasm-apps/trap.aot | grep "#" > call_stack_aot.txt
+          bash -x ../symbolicate.sh
+
+      - name: Build Sample [native-stack-overflow]
+        run: |
+          cd samples/native-stack-overflow
+          ./build.sh
+          ./run.sh test1
+          ./run.sh test2

+ 23 - 2
.github/workflows/compilation_on_nuttx.yml

@@ -61,8 +61,6 @@ jobs:
           "boards/arm/rp2040/raspberrypi-pico/configs/nsh",
           # cortex-m7
           "boards/arm/stm32h7/nucleo-h743zi/configs/nsh",
-          # riscv32imc
-          "boards/risc-v/espressif/esp32c3-generic/configs/nsh",
           # riscv32gc
           "boards/risc-v/qemu-rv/rv-virt/configs/nsh",
           # riscv64gc
@@ -114,3 +112,26 @@ jobs:
           cd nuttx
           tools/configure.sh ${{ matrix.nuttx_board_config }}
           make -j$(nproc) EXTRAFLAGS=-Werror
+
+      - name: Checkout Bloaty
+        uses: actions/checkout@v3
+        with:
+          repository: google/bloaty
+          submodules: recursive
+          path: bloaty
+
+      - name: Build Bloaty
+        run: |
+          cmake -Bbuild -GNinja bloaty
+          cmake --build build
+
+      - name: Size Report
+        run: |
+          echo "Build target: ${{ matrix.nuttx_board_config }}"
+          echo "WAMR build config: ${{ matrix.wamr_config_option }}"
+          echo "WAMR size:"
+          build/bloaty -d compileunits --source-filter wamr nuttx/nuttx
+          echo "libc-builtin size (if enabled):"
+          build/bloaty -d compileunits --source-filter libc-builtin nuttx/nuttx
+          echo "libc-wasi size (if enabled):"
+          build/bloaty -d compileunits --source-filter libc-wasi nuttx/nuttx

+ 16 - 2
.github/workflows/create_tag.yml

@@ -32,8 +32,22 @@ jobs:
       - name: prepare
         id: preparation
         run: |
-          # show latest 3 versions
-          git tag --list WAMR-*.*.* --sort=committerdate --format="%(refname:short)" | tail -n 3
+          # show latest 3 versions on the branch that create release
+          # Set the initial commit to the head of the branch
+          commit="HEAD"
+          # 
+          # Loop to get the three most recent tags
+          for i in {1..3}
+          do
+              # Get the most recent tag reachable from the current commit
+              tag=$(git describe --tags --abbrev=0 $commit)
+
+              # Print the tag
+              echo "$tag"
+
+              # Move to the commit before the found tag to find the next tag in the next iteration
+              commit=$(git rev-list -n 1 $tag^)
+          done
           # compare latest git tag and semantic version definition
           result=$(python3 ./.github/scripts/fetch_and_compare_version.py)
           echo "script result is ${result}"

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

@@ -8,7 +8,7 @@ on:
     types:
       - opened
       - synchronize
-    # running nightly pipeline if you're changing it 
+    # running nightly pipeline if you're changing it
     # stress tests are run only in nightly at the moment, so running them in they are changed
     paths:
       - ".github/workflows/nightly_run.yml"
@@ -54,7 +54,7 @@ jobs:
     with:
       os: "ubuntu-22.04"
       arch: "X86"
-  
+
   build_wamrc:
     needs:
       [
@@ -65,7 +65,7 @@ jobs:
       matrix:
         include:
           - os: ubuntu-20.04
-            llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}  
+            llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
     steps:
       - name: checkout
         uses: actions/checkout@v4
@@ -130,6 +130,7 @@ jobs:
             "-DWAMR_BUILD_SIMD=1",
             "-DWAMR_BUILD_TAIL_CALL=1",
             "-DWAMR_DISABLE_HW_BOUND_CHECK=1",
+            "-DWAMR_BUILD_MEMORY64=1",
           ]
         os: [ubuntu-20.04]
         platform: [android, linux]
@@ -188,11 +189,32 @@ jobs:
             make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
           - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
             make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
-          # Fast-JIT and Multi-Tier-JIT mode don't support android(X86-32)
+          # Memory64 only on CLASSIC INTERP mode, and only on 64-bit platform
+          - make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+            platform: android
+          - make_options_run_mode: $AOT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          # Fast-JIT and Multi-Tier-JIT mode don't support android
           - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
             platform: android
           - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
             platform: android
+          # LLVM JIT pre-built binary wasn't compiled by Android NDK
+          # and isn't available for android
+          - make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
+            platform: android
+          - make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
+            platform: android
         include:
           - os: ubuntu-20.04
             llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
@@ -219,13 +241,23 @@ jobs:
         if: endsWith(matrix.make_options_run_mode, '_JIT_BUILD_OPTIONS') && (steps.retrieve_llvm_libs.outputs.cache-hit != 'true')
         run: echo "::error::can not get prebuilt llvm libraries" && exit 1
 
-      - name: Build iwasm
+      - name: Build iwasm for linux
+        if: matrix.platform == 'linux'
         run: |
           mkdir build && cd build
           cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }}
           cmake --build . --config Release --parallel 4
         working-directory: product-mini/platforms/${{ matrix.platform }}
 
+      - name: Build iwasm for android
+        if: matrix.platform == 'android'
+        run: |
+          mkdir build && cd build
+          cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }} \
+                -DWAMR_BUILD_TARGET=X86_64
+          cmake --build . --config Release --parallel 4
+        working-directory: product-mini/platforms/${{ matrix.platform }}
+
   build_iwasm_linux_gcc4_8:
     runs-on: ubuntu-latest
     container:
@@ -255,6 +287,7 @@ jobs:
             "-DWAMR_BUILD_SIMD=1",
             "-DWAMR_BUILD_TAIL_CALL=1",
             "-DWAMR_DISABLE_HW_BOUND_CHECK=1",
+            "-DWAMR_BUILD_MEMORY64=1",
           ]
         exclude:
           # uncompatiable feature and platform
@@ -283,6 +316,11 @@ jobs:
           # MINI_LOADER only on INTERP mode
           - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
             make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
+          # Memory64 only on CLASSIC INTERP mode
+          - make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
+          - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
+            make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
     steps:
       - name: checkout
         uses: actions/checkout@v3
@@ -421,13 +459,13 @@ jobs:
           cd /opt
           sudo wget ${{ matrix.wasi_sdk_release }}
           sudo tar -xzf wasi-sdk-*.tar.gz
-          sudo mv wasi-sdk-20.0 wasi-sdk
+          sudo ln -sf wasi-sdk-20.0 wasi-sdk
       - name: download and install wabt
         run: |
           cd /opt
           sudo wget ${{ matrix.wabt_release }}
           sudo tar -xzf wabt-1.0.31-*.tar.gz
-          sudo mv wabt-1.0.31 wabt
+          sudo ln -sf wabt-1.0.31 wabt
 
       - name: Get LLVM libraries
         id: retrieve_llvm_libs
@@ -509,6 +547,34 @@ jobs:
           cd samples/terminate
           ./build.sh
           ./run.sh
+
+      - name: Build Sample [native-stack-overflow]
+        run: |
+          cd samples/native-stack-overflow
+          ./build.sh
+          ./run.sh test1
+          ./run.sh test2
+
+      - name: Build Sample [native-lib]
+        run: |
+          mkdir build && cd build
+          cmake ..
+          cmake --build . --config Release --parallel 4
+          ./iwasm --native-lib=./libtest_add.so --native-lib=./libtest_sqrt.so --native-lib=./libtest_hello.so --native-lib=./libtest_hello2.so wasm-app/test.wasm
+        working-directory: ./samples/native-lib
+
+      - name: checkout wamr-app-framework
+        run: git clone https://github.com/bytecodealliance/wamr-app-framework.git
+      - name: download wamr-app-framework dependencies
+        run: LVGL=0 LV_DRIVERS=0 ./download.sh
+        working-directory: ./wamr-app-framework/deps
+      - name: Build Sample [simple]
+        run: |
+          ./build.sh -p host-interp
+          python3 ./sample_test_run.py $(pwd)/out
+          exit $?
+        working-directory: ./wamr-app-framework/samples/simple
+
   test:
     needs:
       [
@@ -605,7 +671,7 @@ jobs:
           sudo tar -xzf wasi-sdk-*.tar.gz
           sudo mv wasi-sdk-20.0 wasi-sdk
 
-      # It is a temporary solution until new wasi-sdk that includes bug fixes is released 
+      # It is a temporary solution until new wasi-sdk that includes bug fixes is released
       - name: build wasi-libc from source
         if: matrix.test_option == '$WASI_TEST_OPTIONS'
         run: |
@@ -626,7 +692,9 @@ jobs:
         run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV
 
       - name: set additional tsan options
-        run: echo "TSAN_OPTIONS=suppressions=$PWD/tsan_suppressions.txt" >> $GITHUB_ENV
+        run: |
+          echo "TSAN_OPTIONS=suppressions=$PWD/tsan_suppressions.txt" >> $GITHUB_ENV
+          sudo sysctl vm.mmap_rnd_bits=28
         working-directory: tests/wamr-test-suites
 
       #only download llvm libraries in jit and aot mode

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

@@ -69,7 +69,7 @@ jobs:
     needs: [create_tag, create_release]
     uses: ./.github/workflows/build_llvm_libraries.yml
     with:
-      os: "macos-latest"
+      os: "macos-13"
       arch: "AArch64 ARM Mips RISCV X86"
 
   #
@@ -100,7 +100,7 @@ jobs:
     with:
       llvm_cache_key: ${{ needs.build_llvm_libraries_on_macos.outputs.cache_key }}
       release: true
-      runner: macos-latest
+      runner: macos-13
       upload_url: ${{ needs.create_release.outputs.upload_url }}
       ver_num: ${{ needs.create_tag.outputs.new_ver }}
 
@@ -132,7 +132,7 @@ jobs:
     with:
       cwd: product-mini/platforms/darwin
       llvm_cache_key: ${{ needs.build_llvm_libraries_on_macos.outputs.cache_key }}
-      runner: macos-latest
+      runner: macos-13
       upload_url: ${{ needs.create_release.outputs.upload_url }}
       ver_num: ${{ needs.create_tag.outputs.new_ver}}
 
@@ -165,7 +165,7 @@ jobs:
     uses: ./.github/workflows/build_wamr_sdk.yml
     with:
       config_file: wamr_config_macos_release.cmake
-      runner: macos-latest
+      runner: macos-13
       upload_url: ${{ needs.create_release.outputs.upload_url }}
       ver_num: ${{ needs.create_tag.outputs.new_ver}}
       wasi_sdk_url: https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-macos.tar.gz
@@ -212,7 +212,7 @@ jobs:
     needs: [create_tag, create_release]
     uses: ./.github/workflows/build_wamr_lldb.yml
     with:
-      runner: macos-latest
+      runner: macos-13
       arch: universal
       upload_url: ${{ needs.create_release.outputs.upload_url }}
       ver_num: ${{ needs.create_tag.outputs.new_ver}}

+ 4 - 1
.github/workflows/spec_test_on_nuttx.yml

@@ -22,11 +22,14 @@ on:
 
   workflow_dispatch:
 
+# Note on INTERPRETERS_WAMR_STACK_GUARD_SIZE:
+# https://github.com/apache/nuttx-apps/pull/2241 is not included in
+# releases/12.4 branch as of writing this.
 env:
   LLVM_CACHE_SUFFIX: "build-llvm_libraries_ex"
   WASI_SDK_PATH: "/opt/wasi-sdk"
   WAMR_COMMON_OPTION:
-    "CONFIG_INTERPRETERS_WAMR=y\\nCONFIG_INTERPRETERS_WAMR_STACKSIZE=327680\\nCONFIG_INTERPRETERS_WAMR_LOG=y\\nCONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN=y\\nCONFIG_INTERPRETERS_WAMR_REF_TYPES=y\\nCONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST=y\\nCONFIG_INTERPRETERS_WAMR_SHARED_MEMORY=y\\nCONFIG_INTERPRETERS_WAMR_BULK_MEMORY=y\\nCONFIG_EOL_IS_LF=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE=y\\nCONFIG_RISCV_SEMIHOSTING_HOSTFS=y\\nCONFIG_FS_HOSTFS=y\\nCONFIG_LIBC_FLOATINGPOINT=y\\n"
+    "CONFIG_INTERPRETERS_WAMR=y\\nCONFIG_INTERPRETERS_WAMR_STACKSIZE=327680\\nCONFIG_INTERPRETERS_WAMR_LOG=y\\nCONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN=y\\nCONFIG_INTERPRETERS_WAMR_REF_TYPES=y\\nCONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST=y\\nCONFIG_INTERPRETERS_WAMR_SHARED_MEMORY=y\\nCONFIG_INTERPRETERS_WAMR_BULK_MEMORY=y\\nCONFIG_EOL_IS_LF=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE=y\\nCONFIG_RISCV_SEMIHOSTING_HOSTFS=y\\nCONFIG_FS_HOSTFS=y\\nCONFIG_LIBC_FLOATINGPOINT=y\\nCONFIG_INTERPRETERS_WAMR_STACK_GUARD_SIZE=1024\\n"
 
 jobs:
   build_llvm_libraries:

+ 36 - 0
ADOPTERS.md

@@ -0,0 +1,36 @@
+# WAMR adopters
+
+_If you are using WAMR in production/pre-production at your organization, please add your company name to this list.
+The list is in alphabetical order._
+
+| Organization                           | Contact                                                      | Status                                                       | Description of Use                                           |
+| -------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [Alibaba](https://www.alibaba.com)     | [@johnlanni](https://github.com/johnlanni)                   | ![production](https://img.shields.io/badge/-production-blue?style=flat) | Higress is a next-generation cloud-native gateway built on the core of open-source Istio + Envoy based on Alibaba's internal Envoy Gateway practice. |
+| [Amazon](https://www.amazon.com)       | [@loganek](https://github.com/loganek)                       | ![production](https://img.shields.io/badge/-production-blue?style=flat) | Prime Video is a global streaming service by Amazon that provides on-demand access to a vast library of movies, TV shows, and original programming, as well as live content. |
+| [Ant Group](https://www.antgroup.com)  | [@wei-tang](https://github.com/wei-tang)                     | ![production](https://img.shields.io/badge/-production-blue?style=flat) | AntChain is a blockchain technology platform owned by Ant Group, a Chinese tech conglomerate that also runs Alipay, China's largest digital payment system. |
+| [Bosch](https://www.bosch.com)         | emily.ruppel@us.bosch.com | ![Undisclosed](https://img.shields.io/badge/-Undisclosed-orange?style=flat)   | Silverline Cloud-Edge platform                              |
+| [Disney](https://www.disney.com)     |                                                 | ![production](https://img.shields.io/badge/-production-blue?style=flat)                                                 | Disney+ Streaming                                            |
+| [Intel](https://www.intel.com)      | [@wenyongh](https://github.com/wenyongh)                                    | ![Undisclosed](https://img.shields.io/badge/-Undisclosed-orange?style=flat) | Edge and the embedded environments |
+| [Moonbit](https://www.moonbitlang.com) | [@peter-jerry-ye](https://github.com/peter-jerry-ye) | ![Undisclosed](https://img.shields.io/badge/-Undisclosed-orange?style=flat) | MoonBit is an end-to-end programming language toolchain for cloud and edge computing using WebAssembly. |
+| [Microsoft](https://www.microsoft.com) | [@Mossaka](https://github.com/Mossaka)                       | ![production](https://img.shields.io/badge/-production-blue?style=flat)                                                       | Hyperlight runs Wasm workloads in VMs without OS and kernel, it is a solution for improving the management and security of Wasm workloads on Azure. |
+| [Midokura](https://www.midokura.com)                          |   [@yamt](https://github.com/yamt)                                     | ![Undisclosed](https://img.shields.io/badge/-Undisclosed-orange?style=flat) | The next-generation Edge AI sensing platform                                                   |
+| [Siemens](https://www.siemens.com)    | [@ttrenner](https://github.com/ttrenner)                     | ![Undisclosed](https://img.shields.io/badge/-Undisclosed-orange?style=flat)                                                | Industrial, IoT                                               |
+| [Sony Semiconductor Solutions](https://www.sony-semicon.com)      | [@dongsheng28849455](https://github.com/dongsheng28849455)                                    | ![production](https://img.shields.io/badge/-production-blue?style=flat) | AI digital camera                                                   |
+| [Xiaomi](https://www.mi.com)           | [@no1wudi](https://github.com/no1wudi)                       | ![production](https://img.shields.io/badge/-production-blue?style=flat) | Xiaomi Vela is Xiaomi's IoT embedded software platform based on the open-source, real-time operating system NuttX. |
+| [Xiaomi](https://www.mi.com)           | [@no1wudi](https://github.com/no1wudi)                       | ![production](https://img.shields.io/badge/-production-blue?style=flat) | TEE (trusted execution environment) app engine. |
+
+# Adopted in open-source projects
+
+_The list is in alphabetical order._
+
+| Project                                                      | Reference                                                    |
+| ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [Apache Teaclave](https://github.com/apache/incubator-teaclave) | https://github.com/apache/incubator-teaclave/blob/master/docs/executing-wasm.md |
+| [Envoy](https://github.com/envoyproxy/envoy)                 | https://github.com/envoyproxy/envoy/blob/main/docs/root/configuration/other_features/wasm.rst |
+| [faasm](https://github.com/faasm/faasm)                      | https://github.com/faasm/faasm/blob/main/docs/source/wamr.md |
+| [fluent-bit](https://github.com/fluent/fluent-bit)           | https://github.com/fluent/fluent-bit/tree/master/lib/wasm-micro-runtime-WAMR-1.3.0 |
+| [harfbuzz](https://github.com/harfbuzz/harfbuzz)             | https://github.com/harfbuzz/harfbuzz/blob/main/docs/wasm-shaper.md#enabling-the-wasm-shaper-when-building-harfbuzz |
+| [inclave-containers](https://github.com/inclavare-containers/inclavare-containers) | https://github.com/inclavare-containers/inclavare-containers |
+| [private-data-objects](https://github.com/hyperledger-labs/private-data-objects) | https://github.com/hyperledger-labs/private-data-objects/blob/main/common/interpreter/wawaka_wasm/README.md |
+| [runwasi](https://github.com/containerd/runwasi)             | https://github.com/containerd/runwasi/pull/508 (WIP)         |
+| [Wasmnizer-ts](https://github.com/web-devkits/Wasmnizer-ts)  | https://github.com/web-devkits/Wasmnizer-ts                  |

+ 2 - 6
ATTRIBUTIONS.md

@@ -60,11 +60,11 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
 
 ### llvm
 
-[LICENSE](./core/deps/llvm/llvm/LICENCE.txt)
+[LICENSE](./LICENCE.txt)
 
 ### wasm-c-api
 
-[LICENSE](https://github.com/bytecodealliance/wamr-app-framework/blob/main/samples/wasm-c-api/src/LICENSE)
+[LICENSE](./samples/wasm-c-api/src/LICENSE)
 
 ### wasmtime
 
@@ -78,10 +78,6 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
 
 [LICENSE](https://github.com/bytecodealliance/wamr-app-framework/blob/main/samples/gui/wasm-runtime-wgl/src/platform/zephyr/LICENSE)
 
-### wac
-
-[LICENSE](./tests/wamr-test-suites/spec-test-script/LICENSE)
-
 ### libuv
 
 [LICENSE](./core/iwasm/libraries/libc-uvwasi/LICENSE_LIBUV)

+ 6 - 1
CMakeLists.txt

@@ -3,6 +3,11 @@
 
 cmake_minimum_required (VERSION 3.0)
 
+if(ESP_PLATFORM)
+  include (${COMPONENT_DIR}/build-scripts/esp-idf/wamr/CMakeLists.txt)
+  return()
+endif()
+
 project (iwasm)
 
 set (CMAKE_VERBOSE_MAKEFILE OFF)
@@ -151,7 +156,7 @@ if (WAMR_BUILD_WASM_CACHE EQUAL 1)
 endif ()
 
 if (MINGW)
-  target_link_libraries (iwasm_shared -lWs2_32)
+  target_link_libraries (iwasm_shared INTERFACE -lWs2_32 -lwsock32)
 endif ()
 
 install (TARGETS iwasm_shared LIBRARY DESTINATION lib)

+ 1 - 1
CONTRIBUTING.md

@@ -27,7 +27,7 @@ We Use Github Flow, So All Code Changes Happen Through Pull Requests. Pull reque
 Coding Style
 ===============================
 Please use [K&R](https://en.wikipedia.org/wiki/Indentation_style#K.26R) coding style, such as 4 spaces for indentation rather than tabs etc.
-We suggest use Eclipse like IDE or stable coding format tools to make your code compliant to K&R format.
+We suggest using VS Code like IDE or stable coding format tools, like clang-format, to make your code compliant to the customized format(in .clang-format).
 
 Report bugs
 ===================

+ 17 - 14
README.md

@@ -10,18 +10,23 @@
 [Build WAMR](./doc/build_wamr.md) | [Build AOT Compiler](./wamr-compiler/README.md) | [Embed WAMR](./doc/embed_wamr.md) | [Export Native API](./doc/export_native_api.md) | [Build Wasm Apps](./doc/build_wasm_app.md) | [Samples](./samples/README.md)
 
 WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm) runtime with small footprint, high performance and highly configurable features for applications cross from embedded, IoT, edge to Trusted Execution Environment (TEE), smart contract, cloud native and so on. It includes a few parts as below:
-- [**VMcore**](./core/iwasm/): A set of runtime libraries for loading and running Wasm modules. It supports several execution modes including interpreter, Ahead-of-Time compilation(AoT) and Just-in-Time compilation (JIT). The WAMR supports two JIT tiers - Fast JIT, LLVM JIT, and dynamic tier-up from Fast JIT to LLVM JIT.
-- [**iwasm**](./product-mini/): The executable binary built with WAMR VMcore supports WASI and command line interface.
+- [**VMcore**](./core/iwasm/): A set of runtime libraries for loading and running Wasm modules. It supports rich running modes including interpreter, Ahead-of-Time compilation(AoT) and Just-in-Time compilation (JIT). WAMR supports two JIT tiers - Fast JIT, LLVM JIT, and dynamic tier-up from Fast JIT to LLVM JIT.
+- [**iwasm**](./product-mini/): The executable binary built with WAMR VMcore which supports WASI and command line interface.
 - [**wamrc**](./wamr-compiler/): The AOT compiler to compile Wasm file into AOT file
 - Useful components and tools for building real solutions with WAMR vmcore:
   - [App-framework](https://github.com/bytecodealliance/wamr-app-framework/blob/main/app-framework/README.md): A framework for supporting APIs for the Wasm applications
-  - [App-manager](https://github.com/bytecodealliance/wamr-app-framework/blob/main/app-mgr/README.md): a framework for dynamical loading the Wasm module remotely
+  - [App-manager](https://github.com/bytecodealliance/wamr-app-framework/blob/main/app-mgr/README.md): A framework for dynamical loading the Wasm module remotely
   - [WAMR-IDE](./test-tools/wamr-ide): An experimental VSCode extension for developping WebAssembly applications with C/C++
 
 
 ### Key features
 - Full compliant to the W3C Wasm MVP
-- Small runtime binary size (~85K for interpreter and ~50K for AOT) and low memory usage
+- Small runtime binary size (core vmlib on cortex-m4f with tail-call/bulk memroy/shared memroy support, text size from bloaty)
+  * ~58.9K for fast interpreter
+  * ~56.3K for classic interpreter
+  * ~29.4K for aot runtime
+  * ~21.4K for libc-wasi library
+  * ~3.7K for libc-builtin library
 - Near to native speed by AOT and JIT
 - Self-implemented AOT module loader to enable AOT working on Linux, Windows, MacOS, Android, SGX and MCU systems
 - Choices of Wasm application libc support: the built-in libc subset for the embedded environment or [WASI](https://github.com/WebAssembly/WASI) for the standard libc
@@ -35,25 +40,24 @@ WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm)
 - [XIP (Execution In Place) support](./doc/xip.md), ref to [document](./doc/xip.md)
 - [Berkeley/Posix Socket support](./doc/socket_api.md), ref to [document](./doc/socket_api.md) and [sample](./samples/socket-api)
 - [Multi-tier JIT](./product-mini#linux) and [Running mode control](https://bytecodealliance.github.io/wamr.dev/blog/introduction-to-wamr-running-modes/)
-- Language bindings: [Go](./language-bindings/go/README.md), [Python](./language-bindings/python/README.md)
+- Language bindings: [Go](./language-bindings/go/README.md), [Python](./language-bindings/python/README.md), [Rust](./language-bindings/rust/README.md)
 
 ### Wasm post-MVP features
 - [wasm-c-api](https://github.com/WebAssembly/wasm-c-api), ref to [document](doc/wasm_c_api.md) and [sample](samples/wasm-c-api)
 - [128-bit SIMD](https://github.com/WebAssembly/simd), ref to [samples/workload](samples/workload)
 - [Reference Types](https://github.com/WebAssembly/reference-types), ref to [document](doc/ref_types.md) and [sample](samples/ref-types)
-- [Non-trapping float-to-int conversions](https://github.com/WebAssembly/nontrapping-float-to-int-conversions)
-- [Sign-extension operators](https://github.com/WebAssembly/sign-extension-ops), [Bulk memory operations](https://github.com/WebAssembly/bulk-memory-operations)
-- [Multi-value](https://github.com/WebAssembly/multi-value), [Tail-call](https://github.com/WebAssembly/tail-call), [Shared memory](https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md#shared-linear-memory)
+- [Bulk memory operations](https://github.com/WebAssembly/bulk-memory-operations), [Shared memory](https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md#shared-linear-memory), [Memory64](https://github.com/WebAssembly/memory64)
+- [Tail-call](https://github.com/WebAssembly/tail-call), [Garbage Collection](https://github.com/WebAssembly/gc), [Exception Handling](https://github.com/WebAssembly/exception-handling)
 
 ### Supported architectures and platforms
-The WAMR VMcore supports the following architectures:  
+The WAMR VMcore supports the following architectures:
 - X86-64, X86-32
 - ARM, THUMB (ARMV7 Cortex-M7 and Cortex-A15 are tested)
 - AArch64 (Cortex-A57 and Cortex-A53 are tested)
 - RISCV64, RISCV32 (RISC-V LP64 and RISC-V LP64D are tested)
 - XTENSA, MIPS, ARC
 
-The following platforms are supported, click each link below for how to build iwasm on that platform. Refer to [WAMR porting guide](./doc/port_wamr.md) for how to port WAMR to a new platform.  
+The following platforms are supported, click each link below for how to build iwasm on that platform. Refer to [WAMR porting guide](./doc/port_wamr.md) for how to port WAMR to a new platform.
 - [Linux](./product-mini/README.md#linux),  [Linux SGX (Intel Software Guard Extension)](./doc/linux_sgx.md),  [MacOS](./product-mini/README.md#macos),  [Android](./product-mini/README.md#android), [Windows](./product-mini/README.md#windows), [Windows (MinGW)](./product-mini/README.md#mingw)
 - [Zephyr](./product-mini/README.md#zephyr),  [AliOS-Things](./product-mini/README.md#alios-things),  [VxWorks](./product-mini/README.md#vxworks), [NuttX](./product-mini/README.md#nuttx), [RT-Thread](./product-mini/README.md#RT-Thread), [ESP-IDF](./product-mini/README.md#esp-idf)
 
@@ -61,14 +65,14 @@ The following platforms are supported, click each link below for how to build iw
 ## Getting started
 - [Build VM core](./doc/build_wamr.md) and [Build wamrc AOT compiler](./wamr-compiler/README.md)
 - [Build iwasm (mini product)](./product-mini/README.md): [Linux](./product-mini/README.md#linux), [SGX](./doc/linux_sgx.md), [MacOS](./product-mini/README.md#macos) and [Windows](./product-mini/README.md#windows)
-- [Embed into C/C++](./doc/embed_wamr.md), [Embed into Python](./language-bindings/python), [Embed into Go](./language-bindings/go)
+- [Embed into C/C++](./doc/embed_wamr.md), [Embed into Python](./language-bindings/python), [Embed into Go](./language-bindings/go), [Embed in Rust](./language-bindings/rust)
 - [Register native APIs for Wasm applications](./doc/export_native_api.md)
 - [Build wamrc AOT compiler](./wamr-compiler/README.md)
 - [Build Wasm applications](./doc/build_wasm_app.md)
 - [Port WAMR to a new platform](./doc/port_wamr.md)
 - [VS Code development container](./doc/devcontainer.md)
-- [Samples](./samples) and [Benchmarks](./tests/benchmarks) 
-
+- [Samples](./samples) and [Benchmarks](./tests/benchmarks)
+- [End-user APIs documentation](https://bytecodealliance.github.io/wamr.dev/apis/)
 
 
 ### Performance and memory
@@ -82,7 +86,6 @@ The following platforms are supported, click each link below for how to build iw
 - [Performance and footprint data](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Performance): the performance and footprint data
 
 
-
 Project Technical Steering Committee
 ====================================
 The [WAMR PTSC Charter](./TSC_Charter.md) governs the operations of the project TSC.

+ 99 - 0
RELEASE_NOTES.md

@@ -1,3 +1,102 @@
+## WAMR-2.0.0
+
+### Breaking Changes
+- The AOT ABI was changed after GC and memory64 features were introduced:
+  - Implement GC feature for interpreter, AOT and LLVM-JIT (#3125)
+  - Implement memory64 for classic interpreter (#3266)
+  - Always allocate linear memory using mmap (#3052)
+  - Refactor APIs and data structures as preliminary work for Memory64 (#3209)
+- Remove unused argument in wasm_runtime_lookup_function (#3218)
+- Separate app-manager and app-framework from WAMR (#3129)
+
+### New Features
+- Implement GC feature for interpreter, AOT and LLVM-JIT (#3125)
+- Implement memory64 for classic interpreter (#3266)
+- Add wasi_ephemeral_nn module support (#3241)
+
+### Bug Fixes
+- EH: Fix broken stack usage calculation (#3121)
+- Fix loader check_wasi_abi_compatibility (#3126)
+- Fix possible integer overflow in loader target block check (#3133)
+- Fix locel.set in polymorphic stack (#3135)
+- Fix threads opcodes' boundary check in classic-interp and fast-interp (#3136)
+- fast-interp: Fix copy_stack_top_i64 overlap issue (#3146)
+- Fix a ubsan complaint "applying zero offset to null pointer" (#3160)
+- fast-interp: Fix GC opcode ref.as_non_null (#3156)
+- Fix llvm jit push funcref/externref result type issue (#3169)
+- Fix wasm loader handling opcode br_table (#3176)
+- Fix ref.func opcode check when GC is enabled (#3181)
+- lldb_function_to_function_dbi: Fix a null dereference (#3189)
+- Fix compilation errors on MinGW (#3217)
+- Fix compilation errors on esp-idf platform (#3224)
+- Fix aot relocation symbols not found on windows 32-bit (#3231)
+- posix_file.c: Correct the dirfd argument that passes to fstatat (#3244)
+- Fix compilation errors on zephyr platform (#3255)
+- Fix dynamic offset not updated in op_br for block with ret type (#3269)
+- aot debug: Fix a NULL dereference (#3274)
+- thread mgr: Free aux stack only when it was allocated (#3282)
+- interp: Restore context from prev_frame after tail calling a native function (#3283)
+- Sync simd opcode definitions spec (#3290)
+- Fix posix_fadvise error handling (#3323)
+- Fix windows relocation string parsing issue (#3333)
+
+### Enhancements
+- Zero the memory mapped from os_mmap in NuttX (#3132)
+- Use logger for runtime error/debug prints (#3097)
+- aot_compile_op_call: Stop setting calling convention explicitly (#3140)
+- aot compiler: Place precheck wrapper before the corresponding wrapped function (#3141)
+- Fix null pointer access in fast-interp when configurable soft bound check is enabled (#3150)
+- Clarify how to verify SGX evidence without an Intel SGX-enabled platform (#3158)
+- zephyr: Use zephyr sys_cache instead of CMSIS (#3162)
+- VSCode IDE enhancement and readme update (#3172)
+- Add vprintf override for android and esp-idf (#3174)
+- zephyr: Include math only with minimal libc (#3177)
+- zephyr: Implement Alloc_With_System_Allocator (#3179)
+- Use indirect call in pre-checker function to avoid relocation in XIP mode (#3142)
+- Implement the remaining Windows filesystem functions (#3166)
+- Fix LLVM assertion failure and update CONTRIBUTING.md (#3197)
+- Allow overriding max memory on module instantiation (#3198)
+- Get location info from function indexes in addr2line script (#3206)
+- Demangle function names in stack trace when using addr2line script (#3211)
+- Refactor APIs and data structures as preliminary work for Memory64 (#3209)
+- Allow converting the zero wasm address to native (#3215)
+- Small refactor on WASMModuleInstance and fix Go/Python language bindings (#3227)
+- Add esp32c6 support (#3234)
+- Make android platform's cmake flags configurable (#3239)
+- Go binding: Change C.long to C.int64_t when call wasm_runtime_set_wasi_args_ex (#3235)
+- Implement apis to set and get the name of a wasm module (#3254)
+- Append '\0' to every name string in aot name section (#3249)
+- Add cmake flag to control aot intrinsics (#3261)
+- Add lock and ref_count for runtime init (#3263)
+- nuttx: Migrate NuttX CMake build for WAMR (#3256)
+- LLVM 19: Switch to debug records (#3272)
+- aot debug: Process lldb_function_to_function_dbi only for C (#3278)
+- Fix warnings/issues reported in Windows and by CodeQL/Coverity (#3275)
+- Enhance wasm loading with LoadArgs and support module names (#3265)
+- Add wamr to esp-idf components registry (#3287)
+- zephyr: Add missing pthread library functions (#3291)
+- Add more checks in wasm loader (#3300)
+- Log warning if growing table failed (#3310)
+- Enhance GC subtyping checks (#3317)
+- User defined memory allocator for different purposes (#3316)
+- Add a comment on WASM_STACK_GUARD_SIZE (#3332)
+- Allow executing malloc/free from native in memory64 mode (#3315)
+- Add functions to expose module import/export info (#3330)
+
+### Others
+- Add ARM MacOS to the CI (#3120)
+- Download jetstream src from github instead of browserbench.org (#3196)
+- Update document to add wamr-rust-sdk introduction (#3204)
+- Fix nightly run tsan ASLR issue (#3233)
+- Add CodeQL Workflow for Code Security Analysis (#2812)
+- Add issue templates (#3248)
+- Fix CI error when install packages for macos-14 (#3270)
+- Update document for GC, exception handling and memory64 features (#3284)
+- Update release CI (#3295)
+- Add native-stack-overflow sample (#3321)
+
+---
+
 ## WAMR-1.3.2
 
 ### Breaking Changes

+ 38 - 1
build-scripts/config_common.cmake

@@ -134,7 +134,9 @@ endif ()
 
 # Sanitizers
 
-set(WAMR_BUILD_SANITIZER $ENV{WAMR_BUILD_SANITIZER})
+if (NOT DEFINED WAMR_BUILD_SANITIZER)
+  set(WAMR_BUILD_SANITIZER $ENV{WAMR_BUILD_SANITIZER})
+endif ()
 
 if (NOT DEFINED WAMR_BUILD_SANITIZER)
   set(WAMR_BUILD_SANITIZER "")
@@ -248,6 +250,15 @@ if (WAMR_BUILD_SHARED_MEMORY EQUAL 1)
 else ()
   add_definitions (-DWASM_ENABLE_SHARED_MEMORY=0)
 endif ()
+if (WAMR_BUILD_MEMORY64 EQUAL 1)
+  # if native is 32-bit or cross-compiled to 32-bit
+  if (NOT WAMR_BUILD_TARGET MATCHES ".*64.*")
+    message (FATAL_ERROR "-- Memory64 is only available on the 64-bit platform/target")
+  endif()
+  add_definitions (-DWASM_ENABLE_MEMORY64=1)
+  set (WAMR_DISABLE_HW_BOUND_CHECK 1)
+  message ("     Memory64 memory enabled")
+endif ()
 if (WAMR_BUILD_THREAD_MGR EQUAL 1)
   message ("     Thread manager enabled")
 endif ()
@@ -430,6 +441,10 @@ if (WAMR_BUILD_WASI_NN EQUAL 1)
   if (DEFINED WAMR_BUILD_WASI_NN_EXTERNAL_DELEGATE_PATH)
       add_definitions (-DWASM_WASI_NN_EXTERNAL_DELEGATE_PATH="${WAMR_BUILD_WASI_NN_EXTERNAL_DELEGATE_PATH}")
   endif ()
+  if (WAMR_BUILD_WASI_EPHEMERAL_NN EQUAL 1)
+      message ("     WASI-NN: WASI-Ephemeral-NN enabled")
+      add_definitions (-DWASM_ENABLE_WASI_EPHEMERAL_NN=1)
+  endif()
 endif ()
 if (WAMR_BUILD_ALLOC_WITH_USER_DATA EQUAL 1)
   add_definitions(-DWASM_MEM_ALLOC_WITH_USER_DATA=1)
@@ -525,3 +540,25 @@ else ()
   # Disable quick aot/jit entries for interp and fast-jit
   add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=0)
 endif ()
+if (WAMR_BUILD_AOT EQUAL 1)
+  if (NOT DEFINED WAMR_BUILD_AOT_INTRINSICS)
+    # Enable aot intrinsics by default
+    set (WAMR_BUILD_AOT_INTRINSICS 1)
+  endif ()
+  if (WAMR_BUILD_AOT_INTRINSICS EQUAL 1)
+    add_definitions (-DWASM_ENABLE_AOT_INTRINSICS=1)
+    message ("     AOT intrinsics enabled")
+  else ()
+    add_definitions (-DWASM_ENABLE_AOT_INTRINSICS=0)
+    message ("     AOT intrinsics disabled")
+  endif ()
+else ()
+  # Disable aot intrinsics for interp, fast-jit and llvm-jit
+  add_definitions (-DWASM_ENABLE_AOT_INTRINSICS=0)
+endif ()
+if (WAMR_BUILD_ALLOC_WITH_USAGE EQUAL 1)
+  add_definitions(-DWASM_MEM_ALLOC_WITH_USAGE=1)
+endif()
+if (NOT WAMR_BUILD_SANITIZER STREQUAL "")
+  message ("     Sanitizer ${WAMR_BUILD_SANITIZER} enabled")
+endif ()

+ 88 - 42
build-scripts/esp-idf/wamr/CMakeLists.txt

@@ -2,56 +2,102 @@
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 # Set WAMR's build options
-if("${IDF_TARGET}" STREQUAL "esp32c3")
-    set(WAMR_BUILD_TARGET "RISCV32")
-else()
-    set(WAMR_BUILD_TARGET "XTENSA")
-endif()
+if (NOT CMAKE_BUILD_EARLY_EXPANSION)
 
-set(WAMR_BUILD_PLATFORM "esp-idf")
+  if (CONFIG_IDF_TARGET_ARCH_RISCV)
+      set (WAMR_BUILD_TARGET "RISCV32")
+  elseif (CONFIG_IDF_TARGET_ARCH_XTENSA)
+      set (WAMR_BUILD_TARGET "XTENSA")
+  else ()
+      message (FATAL_ERROR "Arch ${CONFIG_IDF_TARGET_ARCH} is not supported")
+  endif ()
 
-if (NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release)
-endif ()
+  set (WAMR_BUILD_PLATFORM "esp-idf")
 
-if (NOT DEFINED WAMR_BUILD_INTERP)
-  set (WAMR_BUILD_INTERP 1)
-endif ()
+  if (CONFIG_WAMR_BUILD_DEBUG)
+    set (CMAKE_BUILD_TYPE Debug)
+  else ()
+    set (CMAKE_BUILD_TYPE Release)
+  endif ()
 
-if (NOT DEFINED WAMR_BUILD_FAST_INTERP)
-  set (WAMR_BUILD_FAST_INTERP 1)
-endif ()
+  if (CONFIG_WAMR_ENABLE_INTERP)
+    set (WAMR_BUILD_INTERP 1)
+  endif ()
 
-if (NOT DEFINED WAMR_BUILD_AOT)
-  set (WAMR_BUILD_AOT 1)
-endif ()
+  if (CONFIG_WAMR_INTERP_FAST)
+    set (WAMR_BUILD_FAST_INTERP 1)
+  endif ()
 
-if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
-  set (WAMR_BUILD_LIBC_BUILTIN 1)
-endif ()
+  if (CONFIG_WAMR_ENABLE_AOT)
+    set (WAMR_BUILD_AOT 1)
+  endif ()
+
+  if (CONFIG_WAMR_ENABLE_LIBC_BUILTIN)
+    set (WAMR_BUILD_LIBC_BUILTIN 1)
+  endif ()
+
+  if (CONFIG_WAMR_INTERP_LOADER_MINI)
+    set (WAMR_BUILD_MINI_LOADER 1)
+  endif ()
+
+  if (CONFIG_WAMR_ENABLE_MULTI_MODULE)
+      set (WAMR_BUILD_MULTI_MODULE 1)
+  endif ()
+
+  if (CONFIG_WAMR_ENABLE_SHARED_MEMORY)
+      set (WAMR_BUILD_SHARED_MEMORY 1)
+  endif ()
+
+  if (CONFIG_WAMR_ENABLE_MEMORY_PROFILING)
+      set (WAMR_BUILD_MEMORY_PROFILING 1)
+  endif ()
+
+  if (CONFIG_WAMR_ENABLE_PERF_PROFILING)
+      set (WAMR_BUILD_PERF_PROFILING 1)
+  endif ()
 
-if (NOT DEFINED WAMR_BUILD_APP_FRAMEWORK)
-  set (WAMR_BUILD_APP_FRAMEWORK 0)
+  if (CONFIG_WAMR_ENABLE_REF_TYPES)
+      set (WAMR_BUILD_REF_TYPES 1)
+  endif ()
+
+  if (CONFIG_WAMR_ENABLE_LIBC_WASI)
+      set (WAMR_BUILD_LIBC_WASI 1)
+  endif ()
+
+  if (CONFIG_WAMR_ENABLE_LIB_PTHREAD)
+      set (WAMR_BUILD_LIB_PTHREAD 1)
+  endif ()
+
+  set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..)
+  include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
+
+  list (APPEND srcs "${WAMR_RUNTIME_LIB_SOURCE}"
+                    "${PLATFORM_SHARED_SOURCE}")
+
+  set (include_dirs "${IWASM_DIR}/include"
+                    "${UTILS_SHARED_DIR}"
+                    "${PLATFORM_SHARED_DIR}"
+                    "${PLATFORM_SHARED_DIR}/../include"
+                    "${IWASM_COMMON_DIR}")
 endif ()
 
-if (NOT CMAKE_BUILD_EARLY_EXPANSION)
-    if (WAMR_BUILD_TARGET STREQUAL "XTENSA")
-      idf_build_set_property(COMPILE_DEFINITIONS "-DBUILD_TARGET_XTENSA=1" APPEND)
-    endif ()
-    if (WAMR_BUILD_INTERP)
-      idf_build_set_property(COMPILE_DEFINITIONS "-DWASM_ENABLE_INTERP=1" APPEND)
-    endif ()
-    if (WAMR_BUILD_AOT)
-      idf_build_set_property(COMPILE_DEFINITIONS "-DWASM_ENABLE_AOT=1" APPEND)
-    endif ()
-
-    set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..)
-    include(${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
-endif()
-
-idf_component_register(SRCS ${WAMR_RUNTIME_LIB_SOURCE} ${PLATFORM_SHARED_SOURCE}
-  INCLUDE_DIRS ${IWASM_DIR}/include ${UTILS_SHARED_DIR} ${PLATFORM_SHARED_DIR} ${PLATFORM_SHARED_DIR}/../include
-  REQUIRES pthread lwip esp_timer
-)
+idf_component_register(SRCS ${srcs}
+                       INCLUDE_DIRS ${include_dirs}
+                       REQUIRES pthread lwip esp_timer
+                       KCONFIG ${CMAKE_CURRENT_LIST_DIR}/Kconfig)
 
+target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
 
+if (CONFIG_IDF_TARGET_ARCH_RISCV)
+  target_compile_definitions(${COMPONENT_LIB} PUBLIC -DBUILD_TARGET_RISCV32_ILP32=1)
+elseif (CONFIG_IDF_TARGET_ARCH_XTENSA)
+  target_compile_definitions(${COMPONENT_LIB} PUBLIC -DBUILD_TARGET_XTENSA=1)
+endif ()
+
+if (CONFIG_WAMR_ENABLE_AOT)
+  target_compile_definitions(${COMPONENT_LIB} PUBLIC -DWASM_ENABLE_AOT=1)
+endif ()
+
+if (CONFIG_WAMR_ENABLE_INTERP)
+  target_compile_definitions(${COMPONENT_LIB} PUBLIC -DWASM_ENABLE_INTERP=1)
+endif ()

+ 77 - 0
build-scripts/esp-idf/wamr/Kconfig

@@ -0,0 +1,77 @@
+menu "WASM Micro Runtime"
+    choice WAMR_BUILD_TYPE
+        prompt "Build type"
+        default WAMR_BUILD_RELEASE
+
+        config WAMR_BUILD_RELEASE
+            bool "Release"
+
+        config WAMR_BUILD_DEBUG
+            bool "Debug"
+    endchoice
+
+    config WAMR_ENABLE_AOT
+        bool "AOT"
+        default y
+
+    menuconfig WAMR_ENABLE_INTERP
+        bool "Interpreter"
+        default y
+
+    if WAMR_ENABLE_INTERP
+
+       choice WAMR_INTERP_MODE
+            prompt "Interpreter mode"
+            default WAMR_INTERP_FAST
+
+            config WAMR_INTERP_CLASSIC
+                bool "Classic"
+
+            config WAMR_INTERP_FAST
+                bool "Fast"
+        endchoice
+
+        choice WAMR_INTERP_LOADER_MODE
+            prompt "Loader mode"
+            default WAMR_INTERP_LOADER_NORMAL
+
+            config WAMR_INTERP_LOADER_NORMAL
+                bool "Normal"
+
+            config WAMR_INTERP_LOADER_MINI
+                bool "Mini"
+        endchoice
+    endif
+
+    config WAMR_ENABLE_LIB_PTHREAD
+        bool "Lib pthread"
+        default y
+
+    config WAMR_ENABLE_LIBC_BUILTIN
+        bool "Libc builtin"
+        default y
+
+    config WAMR_ENABLE_LIBC_WASI
+        bool "Libc WASI"
+        default y
+
+    config WAMR_ENABLE_MEMORY_PROFILING
+        bool "Memory profiling"
+        default n
+
+    config WAMR_ENABLE_MULTI_MODULE
+        bool "Multi module"
+        default n
+
+    config WAMR_ENABLE_PERF_PROFILING
+        bool "Performance profiling"
+        default n
+
+    config WAMR_ENABLE_REF_TYPES
+        bool "Reference types"
+        default n
+
+    config WAMR_ENABLE_SHARED_MEMORY
+        bool "Shared memory"
+        default n
+endmenu

+ 0 - 8
core/app-mgr/README.md

@@ -1,8 +0,0 @@
-# Remote application management
-
-The WAMR application manager supports [remote application management](../../core/app-mgr) from the host environment or the cloud through any physical communications such as TCP, UPD, UART, BLE, etc. Its modular design makes it able to support application management for different managed runtimes.
-
-The tool [host_tool](../../test-tools/host-tool) communicates to the WAMR app manager for installing/uninstalling the WASM applications on companion chip from the host system. And the [IoT App Store Demo](../../test-tools/IoT-APP-Store-Demo/) shows the conception of remotely managing the device applications from the cloud.
-
-
-<img src="../../doc/pics/wamr-arch.JPG" width="80%">

+ 0 - 1747
core/app-mgr/app-manager/module_wasm_app.c

@@ -1,1747 +0,0 @@
-/*
- * Copyright (C) 2019 Intel Corporation.  All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
-
-#include "module_wasm_app.h"
-
-#include "native_interface.h" /* for request_t type */
-#include "app_manager_host.h"
-#include "bh_platform.h"
-#include "bi-inc/attr_container.h"
-#include "coap_ext.h"
-#include "event.h"
-#include "watchdog.h"
-#include "runtime_lib.h"
-#if WASM_ENABLE_INTERP != 0
-#include "wasm.h"
-#endif
-#if WASM_ENABLE_AOT != 0
-#include "aot_export.h"
-#endif
-
-/* clang-format off */
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-/* Wasm bytecode file 4 version bytes */
-static uint8 wasm_bytecode_version[4] = {
-    (uint8)0x01,
-    (uint8)0x00,
-    (uint8)0x00,
-    (uint8)0x00
-};
-#endif
-
-#if WASM_ENABLE_AOT != 0
-/* Wasm aot file 4 version bytes */
-static uint8 wasm_aot_version[4] = {
-    (uint8)0x02,
-    (uint8)0x00,
-    (uint8)0x00,
-    (uint8)0x00
-};
-#endif
-/* clang-format on */
-
-static union {
-    int a;
-    char b;
-} __ue = { .a = 1 };
-
-#define is_little_endian() (__ue.b == 1)
-/* Wasm App Install Request Receiving Phase */
-typedef enum wasm_app_install_req_recv_phase_t {
-    Phase_Req_Ver,
-    Phase_Req_Action,
-    Phase_Req_Fmt,
-    Phase_Req_Mid,
-    Phase_Req_Sender,
-    Phase_Req_Url_Len,
-    Phase_Req_Payload_Len, /* payload is wasm app binary */
-    Phase_Req_Url,
-
-    /* Magic phase */
-    Phase_App_Magic,
-
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-    /* Phases of wasm bytecode file */
-    Phase_Wasm_Version,
-    Phase_Wasm_Section_Type,
-    Phase_Wasm_Section_Size,
-    Phase_Wasm_Section_Content,
-#endif
-
-#if WASM_ENABLE_AOT != 0
-    /* Phases of wasm AOT file */
-    Phase_AOT_Version,
-    Phase_AOT_Section_ID,
-    Phase_AOT_Section_Size,
-    Phase_AOT_Section_Content
-#endif
-} wasm_app_install_req_recv_phase_t;
-
-/* Message for insall wasm app */
-typedef struct install_wasm_app_msg_t {
-    uint8 request_version;
-    uint8 request_action;
-    uint16 request_fmt;
-    uint32 request_mid;
-    uint32 request_sender;
-    uint16 request_url_len;
-    uint32 wasm_app_size; /* payload size is just wasm app binary size */
-    char *request_url;
-    wasm_app_file_t app_file;
-    int app_file_magic;
-} install_wasm_app_msg_t;
-
-/* Wasm App Install Request Receive Context */
-typedef struct wasm_app_install_req_recv_ctx_t {
-    wasm_app_install_req_recv_phase_t phase;
-    int size_in_phase;
-    install_wasm_app_msg_t message;
-    int total_received_size;
-} wasm_app_install_req_recv_ctx_t;
-
-/* Current wasm app install request receive context */
-static wasm_app_install_req_recv_ctx_t recv_ctx;
-
-static bool
-wasm_app_module_init(void);
-
-static bool
-wasm_app_module_install(request_t *msg);
-
-static bool
-wasm_app_module_uninstall(request_t *msg);
-
-static void
-wasm_app_module_watchdog_kill(module_data *module_data);
-
-static bool
-wasm_app_module_handle_host_url(void *queue_msg);
-
-static module_data *
-wasm_app_module_get_module_data(void *inst);
-
-static bool
-wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
-                                               int *received_size);
-
-static bool
-module_wasm_app_handle_install_msg(install_wasm_app_msg_t *message);
-
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-static void
-destroy_all_wasm_sections(wasm_section_list_t sections);
-
-static void
-destroy_part_wasm_sections(wasm_section_list_t *p_sections,
-                           uint8 *section_types, int section_cnt);
-#endif
-
-#if WASM_ENABLE_AOT != 0
-static void
-destroy_all_aot_sections(aot_section_list_t sections);
-
-static void
-destroy_part_aot_sections(aot_section_list_t *p_sections, uint8 *section_types,
-                          int section_cnt);
-#endif
-
-#define Max_Msg_Callback 10
-int g_msg_type[Max_Msg_Callback] = { 0 };
-message_type_handler_t g_msg_callbacks[Max_Msg_Callback] = { 0 };
-
-#define Max_Cleanup_Callback 10
-static resource_cleanup_handler_t g_cleanup_callbacks[Max_Cleanup_Callback] = {
-    0
-};
-
-module_interface wasm_app_module_interface = {
-    wasm_app_module_init,
-    wasm_app_module_install,
-    wasm_app_module_uninstall,
-    wasm_app_module_watchdog_kill,
-    wasm_app_module_handle_host_url,
-    wasm_app_module_get_module_data,
-    wasm_app_module_on_install_request_byte_arrive
-};
-
-#if WASM_ENABLE_INTERP == 0
-static unsigned
-align_uint(unsigned v, unsigned b)
-{
-    unsigned m = b - 1;
-    return (v + m) & ~m;
-}
-#endif
-
-static void
-exchange_uint32(uint8 *p_data)
-{
-    uint8 value = *p_data;
-    *p_data = *(p_data + 3);
-    *(p_data + 3) = value;
-
-    value = *(p_data + 1);
-    *(p_data + 1) = *(p_data + 2);
-    *(p_data + 2) = value;
-}
-
-static wasm_function_inst_t
-app_manager_lookup_function(const wasm_module_inst_t module_inst,
-                            const char *name, const char *signature)
-{
-    wasm_function_inst_t func;
-
-    func = wasm_runtime_lookup_function(module_inst, name, signature);
-    if (!func && name[0] == '_')
-        func = wasm_runtime_lookup_function(module_inst, name + 1, signature);
-    return func;
-}
-
-static void
-app_instance_queue_callback(void *queue_msg, void *arg)
-{
-    uint32 argv[2];
-    wasm_function_inst_t func_onRequest, func_onTimer;
-
-    wasm_module_inst_t inst = (wasm_module_inst_t)arg;
-    module_data *m_data = app_manager_get_module_data(Module_WASM_App, inst);
-    wasm_data *wasm_app_data;
-    int message_type;
-
-    bh_assert(m_data);
-    wasm_app_data = (wasm_data *)m_data->internal_data;
-    message_type = bh_message_type(queue_msg);
-
-    if (message_type < BASE_EVENT_MAX) {
-        switch (message_type) {
-            case RESTFUL_REQUEST:
-            {
-                request_t *request = (request_t *)bh_message_payload(queue_msg);
-                int size;
-                char *buffer;
-                int32 buffer_offset;
-
-                app_manager_printf("App %s got request, url %s, action %d\n",
-                                   m_data->module_name, request->url,
-                                   request->action);
-
-                func_onRequest = app_manager_lookup_function(
-                    inst, "_on_request", "(i32i32)");
-                if (!func_onRequest) {
-                    app_manager_printf("Cannot find function onRequest\n");
-                    break;
-                }
-
-                buffer = pack_request(request, &size);
-                if (buffer == NULL)
-                    break;
-
-                buffer_offset =
-                    wasm_runtime_module_dup_data(inst, buffer, size);
-                if (buffer_offset == 0) {
-                    const char *exception = wasm_runtime_get_exception(inst);
-                    if (exception) {
-                        app_manager_printf(
-                            "Got exception running wasm code: %s\n", exception);
-                        wasm_runtime_clear_exception(inst);
-                    }
-                    free_req_resp_packet(buffer);
-                    break;
-                }
-
-                free_req_resp_packet(buffer);
-
-                argv[0] = (uint32)buffer_offset;
-                argv[1] = (uint32)size;
-
-                if (!wasm_runtime_call_wasm(wasm_app_data->exec_env,
-                                            func_onRequest, 2, argv)) {
-                    const char *exception = wasm_runtime_get_exception(inst);
-                    bh_assert(exception);
-                    app_manager_printf("Got exception running wasm code: %s\n",
-                                       exception);
-                    wasm_runtime_clear_exception(inst);
-                    wasm_runtime_module_free(inst, buffer_offset);
-                    break;
-                }
-
-                wasm_runtime_module_free(inst, buffer_offset);
-                app_manager_printf("Wasm app process request success.\n");
-                break;
-            }
-            case RESTFUL_RESPONSE:
-            {
-                wasm_function_inst_t func_onResponse;
-                response_t *response =
-                    (response_t *)bh_message_payload(queue_msg);
-                int size;
-                char *buffer;
-                int32 buffer_offset;
-
-                app_manager_printf("App %s got response_t,status %d\n",
-                                   m_data->module_name, response->status);
-
-                func_onResponse = app_manager_lookup_function(
-                    inst, "_on_response", "(i32i32)");
-                if (!func_onResponse) {
-                    app_manager_printf("Cannot find function on_response\n");
-                    break;
-                }
-
-                buffer = pack_response(response, &size);
-                if (buffer == NULL)
-                    break;
-
-                buffer_offset =
-                    wasm_runtime_module_dup_data(inst, buffer, size);
-                if (buffer_offset == 0) {
-                    const char *exception = wasm_runtime_get_exception(inst);
-                    if (exception) {
-                        app_manager_printf(
-                            "Got exception running wasm code: %s\n", exception);
-                        wasm_runtime_clear_exception(inst);
-                    }
-                    free_req_resp_packet(buffer);
-                    break;
-                }
-
-                free_req_resp_packet(buffer);
-
-                argv[0] = (uint32)buffer_offset;
-                argv[1] = (uint32)size;
-
-                if (!wasm_runtime_call_wasm(wasm_app_data->exec_env,
-                                            func_onResponse, 2, argv)) {
-                    const char *exception = wasm_runtime_get_exception(inst);
-                    bh_assert(exception);
-                    app_manager_printf("Got exception running wasm code: %s\n",
-                                       exception);
-                    wasm_runtime_clear_exception(inst);
-                    wasm_runtime_module_free(inst, buffer_offset);
-                    break;
-                }
-
-                wasm_runtime_module_free(inst, buffer_offset);
-                app_manager_printf("Wasm app process response success.\n");
-                break;
-            }
-            default:
-            {
-                for (int i = 0; i < Max_Msg_Callback; i++) {
-                    if (g_msg_type[i] == message_type) {
-                        g_msg_callbacks[i](m_data, queue_msg);
-                        return;
-                    }
-                }
-                app_manager_printf(
-                    "Invalid message type of WASM app queue message.\n");
-                break;
-            }
-        }
-    }
-    else {
-        switch (message_type) {
-            case TIMER_EVENT_WASM:
-            {
-                unsigned int timer_id;
-                if (bh_message_payload(queue_msg)) {
-                    /* Call Timer.callOnTimer() method */
-                    func_onTimer = app_manager_lookup_function(
-                        inst, "_on_timer_callback", "(i32)");
-
-                    if (!func_onTimer) {
-                        app_manager_printf(
-                            "Cannot find function _on_timer_callback\n");
-                        break;
-                    }
-                    timer_id =
-                        (unsigned int)(uintptr_t)bh_message_payload(queue_msg);
-                    argv[0] = timer_id;
-                    if (!wasm_runtime_call_wasm(wasm_app_data->exec_env,
-                                                func_onTimer, 1, argv)) {
-                        const char *exception =
-                            wasm_runtime_get_exception(inst);
-                        bh_assert(exception);
-                        app_manager_printf(
-                            "Got exception running wasm code: %s\n", exception);
-                        wasm_runtime_clear_exception(inst);
-                    }
-                }
-                break;
-            }
-            default:
-            {
-                for (int i = 0; i < Max_Msg_Callback; i++) {
-                    if (g_msg_type[i] == message_type) {
-                        g_msg_callbacks[i](m_data, queue_msg);
-                        return;
-                    }
-                }
-                app_manager_printf(
-                    "Invalid message type of WASM app queue message.\n");
-                break;
-            }
-        }
-    }
-}
-
-#if WASM_ENABLE_LIBC_WASI != 0
-static bool
-wasm_app_prepare_wasi_dir(wasm_module_t module, const char *module_name,
-                          char *wasi_dir_buf, uint32 buf_size)
-{
-    const char *wasi_root = wasm_get_wasi_root_dir();
-    char *p = wasi_dir_buf;
-    uint32 module_name_len = strlen(module_name);
-    uint32 wasi_root_len = strlen(wasi_root);
-    uint32 total_size;
-    struct stat st = { 0 };
-
-    bh_assert(wasi_root);
-
-    /* wasi_dir: wasi_root/module_name */
-    total_size = wasi_root_len + 1 + module_name_len + 1;
-    if (total_size > buf_size)
-        return false;
-    memcpy(p, wasi_root, wasi_root_len);
-    p += wasi_root_len;
-    *p++ = '/';
-    memcpy(p, module_name, module_name_len);
-    p += module_name_len;
-    *p++ = '\0';
-
-    if (mkdir(wasi_dir_buf, 0777) != 0) {
-        if (errno == EEXIST) {
-            /* Failed due to dir already exist */
-            if ((stat(wasi_dir_buf, &st) == 0) && (st.st_mode & S_IFDIR)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    return true;
-}
-#endif
-
-/* WASM app thread main routine */
-static void *
-wasm_app_routine(void *arg)
-{
-    wasm_function_inst_t func_onInit;
-    wasm_function_inst_t func_onDestroy;
-
-    module_data *m_data = (module_data *)arg;
-    wasm_data *wasm_app_data = (wasm_data *)m_data->internal_data;
-    wasm_module_inst_t inst = wasm_app_data->wasm_module_inst;
-
-    /* Set m_data to the VM managed instance's custom data */
-    wasm_runtime_set_custom_data(inst, m_data);
-
-    app_manager_printf("WASM app '%s' started\n", m_data->module_name);
-
-#if WASM_ENABLE_LIBC_WASI != 0
-    if (wasm_runtime_is_wasi_mode(inst)) {
-        wasm_function_inst_t func_start;
-        /* In wasi mode, we should call function named "_start"
-           which initializes the wasi envrionment. The "_start" function
-           will call "main" function */
-        if ((func_start = wasm_runtime_lookup_wasi_start_function(inst))) {
-            if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_start, 0,
-                                        NULL)) {
-                const char *exception = wasm_runtime_get_exception(inst);
-                bh_assert(exception);
-                app_manager_printf(
-                    "Got exception running wasi start function: %s\n",
-                    exception);
-                wasm_runtime_clear_exception(inst);
-                goto fail1;
-            }
-        }
-        /* if no start function is found, we execute
-           the _on_init function as normal */
-    }
-#endif
-
-    /* Call app's onInit() method */
-    func_onInit = app_manager_lookup_function(inst, "_on_init", "()");
-    if (!func_onInit) {
-        app_manager_printf("Cannot find function on_init().\n");
-        goto fail1;
-    }
-
-    if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onInit, 0,
-                                NULL)) {
-        const char *exception = wasm_runtime_get_exception(inst);
-        bh_assert(exception);
-        app_manager_printf("Got exception running WASM code: %s\n", exception);
-        wasm_runtime_clear_exception(inst);
-        /* call on_destroy() in case some resources are opened in on_init()
-         * and then exception thrown */
-        goto fail2;
-    }
-
-    /* Enter queue loop run to receive and process applet queue message */
-    bh_queue_enter_loop_run(m_data->queue, app_instance_queue_callback, inst);
-
-    app_manager_printf("App instance main thread exit.\n");
-
-fail2:
-    /* Call WASM app onDestroy() method if there is */
-    func_onDestroy = app_manager_lookup_function(inst, "_on_destroy", "()");
-    if (func_onDestroy) {
-        if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onDestroy, 0,
-                                    NULL)) {
-            const char *exception = wasm_runtime_get_exception(inst);
-            bh_assert(exception);
-            app_manager_printf("Got exception running WASM code: %s\n",
-                               exception);
-            wasm_runtime_clear_exception(inst);
-        }
-    }
-
-fail1:
-
-    return NULL;
-}
-
-static void
-cleanup_app_resource(module_data *m_data)
-{
-    int i;
-    wasm_data *wasm_app_data = (wasm_data *)m_data->internal_data;
-    bool is_bytecode = wasm_app_data->is_bytecode;
-
-    am_cleanup_registeration(m_data->id);
-
-    am_unregister_event(NULL, m_data->id);
-
-    for (i = 0; i < Max_Cleanup_Callback; i++) {
-        if (g_cleanup_callbacks[i] != NULL)
-            g_cleanup_callbacks[i](m_data->id);
-        else
-            break;
-    }
-
-    wasm_runtime_deinstantiate(wasm_app_data->wasm_module_inst);
-
-    /* Destroy remain sections (i.e. data segment section for bytecode file
-     * or text section of aot file) from app file's section list. */
-    if (is_bytecode) {
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-        destroy_all_wasm_sections(
-            (wasm_section_list_t)(wasm_app_data->sections));
-#else
-        bh_assert(0);
-#endif
-    }
-    else {
-#if WASM_ENABLE_AOT != 0
-        destroy_all_aot_sections((aot_section_list_t)(wasm_app_data->sections));
-#else
-        bh_assert(0);
-#endif
-    }
-
-    if (wasm_app_data->wasm_module)
-        wasm_runtime_unload(wasm_app_data->wasm_module);
-
-    if (wasm_app_data->exec_env)
-        wasm_runtime_destroy_exec_env(wasm_app_data->exec_env);
-
-    /* Destroy watchdog timer */
-    watchdog_timer_destroy(&m_data->wd_timer);
-
-    /* Remove module data from module data list and free it */
-    app_manager_del_module_data(m_data);
-}
-
-/************************************************************/
-/*        Module specific functions implementation          */
-/************************************************************/
-
-static bool
-wasm_app_module_init(void)
-{
-    uint32 version;
-
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-    version = WASM_CURRENT_VERSION;
-    if (!is_little_endian())
-        exchange_uint32((uint8 *)&version);
-    bh_memcpy_s(wasm_bytecode_version, 4, &version, 4);
-#endif
-
-#if WASM_ENABLE_AOT != 0
-    version = AOT_CURRENT_VERSION;
-    if (!is_little_endian())
-        exchange_uint32((uint8 *)&version);
-    bh_memcpy_s(wasm_aot_version, 4, &version, 4);
-#endif
-    return true;
-}
-
-#define APP_NAME_MAX_LEN 128
-#define MAX_INT_STR_LEN 11
-
-static bool
-wasm_app_module_install(request_t *msg)
-{
-    unsigned int m_data_size, heap_size, stack_size;
-    unsigned int timeout, timers, err_size;
-    char *properties;
-    int properties_offset;
-    wasm_app_file_t *wasm_app_file;
-    wasm_data *wasm_app_data;
-    package_type_t package_type;
-    module_data *m_data = NULL;
-    wasm_module_t module = NULL;
-    wasm_module_inst_t inst = NULL;
-    wasm_exec_env_t exec_env = NULL;
-    char m_name[APP_NAME_MAX_LEN] = { 0 };
-    char timeout_str[MAX_INT_STR_LEN] = { 0 };
-    char heap_size_str[MAX_INT_STR_LEN] = { 0 };
-    char timers_str[MAX_INT_STR_LEN] = { 0 }, err[128], err_resp[256];
-#if WASM_ENABLE_LIBC_WASI != 0
-    char wasi_dir_buf[PATH_MAX] = { 0 };
-    const char *wasi_dir_list[] = { wasi_dir_buf };
-#endif
-
-    err_size = sizeof(err);
-
-    /* Check payload */
-    if (!msg->payload || msg->payload_len == 0) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: invalid wasm file.");
-        return false;
-    }
-
-    /* Judge the app type is AOTed or not */
-    package_type = get_package_type((uint8 *)msg->payload, msg->payload_len);
-    wasm_app_file = (wasm_app_file_t *)msg->payload;
-
-    /* Check app name */
-    properties_offset = check_url_start(msg->url, strlen(msg->url), "/applet");
-    bh_assert(properties_offset > 0);
-    if (properties_offset <= 0) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: invalid app name.");
-        goto fail;
-    }
-
-    properties = msg->url + properties_offset;
-    find_key_value(properties, strlen(properties), "name", m_name,
-                   sizeof(m_name) - 1, '&');
-
-    if (strlen(m_name) == 0) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: invalid app name.");
-        goto fail;
-    }
-
-    if (app_manager_lookup_module_data(m_name)) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: app already installed.");
-        goto fail;
-    }
-
-    /* Parse heap size */
-    heap_size = APP_HEAP_SIZE_DEFAULT;
-    find_key_value(properties, strlen(properties), "heap", heap_size_str,
-                   sizeof(heap_size_str) - 1, '&');
-    if (strlen(heap_size_str) > 0) {
-        heap_size = atoi(heap_size_str);
-        if (heap_size < APP_HEAP_SIZE_MIN)
-            heap_size = APP_HEAP_SIZE_MIN;
-        else if (heap_size > APP_HEAP_SIZE_MAX)
-            heap_size = APP_HEAP_SIZE_MAX;
-    }
-
-    /* Load WASM file and instantiate*/
-    switch (package_type) {
-#if WASM_ENABLE_AOT != 0
-        case Wasm_Module_AoT:
-        {
-            wasm_aot_file_t *aot_file;
-            /* clang-format off */
-            /* Sections to be released after loading */
-            uint8 sections1[] = {
-                AOT_SECTION_TYPE_TARGET_INFO,
-                AOT_SECTION_TYPE_INIT_DATA,
-                AOT_SECTION_TYPE_FUNCTION,
-                AOT_SECTION_TYPE_EXPORT,
-                AOT_SECTION_TYPE_RELOCATION,
-                AOT_SECTION_TYPE_SIGANATURE,
-                AOT_SECTION_TYPE_CUSTOM,
-            };
-            /* clang-format on */
-
-            aot_file = &wasm_app_file->u.aot;
-
-            /* Load AOT module from sections */
-            module = wasm_runtime_load_from_sections(aot_file->sections, true,
-                                                     err, err_size);
-            if (!module) {
-                snprintf(err_resp, sizeof(err_resp),
-                         "Install WASM app failed: %s", err);
-                SEND_ERR_RESPONSE(msg->mid, err_resp);
-                goto fail;
-            }
-            /* Destroy useless sections from list after load */
-            destroy_part_aot_sections(&aot_file->sections, sections1,
-                                      sizeof(sections1) / sizeof(uint8));
-
-#if WASM_ENABLE_LIBC_WASI != 0
-            if (!wasm_app_prepare_wasi_dir(module, m_name, wasi_dir_buf,
-                                           sizeof(wasi_dir_buf))) {
-                SEND_ERR_RESPONSE(
-                    msg->mid,
-                    "Install WASM app failed: prepare wasi env failed.");
-                goto fail;
-            }
-            wasm_runtime_set_wasi_args(module, wasi_dir_list, 1, NULL, 0, NULL,
-                                       0, NULL, 0);
-#endif
-
-            /* Instantiate the AOT module */
-            inst =
-                wasm_runtime_instantiate(module, 0, heap_size, err, err_size);
-            if (!inst) {
-                snprintf(err_resp, sizeof(err_resp),
-                         "Install WASM app failed: %s", err);
-                SEND_ERR_RESPONSE(msg->mid, err);
-                goto fail;
-            }
-            break;
-        }
-#endif /* endof WASM_ENABLE_AOT != 0 */
-
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-        case Wasm_Module_Bytecode:
-        {
-            wasm_bytecode_file_t *bytecode_file;
-            /* Sections to be released after loading */
-            uint8 sections1[] = {
-                SECTION_TYPE_USER,
-                SECTION_TYPE_TYPE,
-                SECTION_TYPE_IMPORT,
-                SECTION_TYPE_FUNC,
-                SECTION_TYPE_TABLE,
-                SECTION_TYPE_MEMORY,
-                SECTION_TYPE_GLOBAL,
-                SECTION_TYPE_EXPORT,
-                SECTION_TYPE_START,
-                SECTION_TYPE_ELEM,
-#if WASM_ENABLE_BULK_MEMORY != 0
-                SECTION_TYPE_DATACOUNT
-#endif
-
-            };
-            /* Sections to be released after instantiating */
-            uint8 sections2[] = { SECTION_TYPE_DATA };
-
-            bytecode_file = &wasm_app_file->u.bytecode;
-
-            /* Load wasm module from sections */
-            module = wasm_runtime_load_from_sections(bytecode_file->sections,
-                                                     false, err, err_size);
-            if (!module) {
-                snprintf(err_resp, sizeof(err_resp),
-                         "Install WASM app failed: %s", err);
-                SEND_ERR_RESPONSE(msg->mid, err_resp);
-                goto fail;
-            }
-
-            /* Destroy useless sections from list after load */
-            destroy_part_wasm_sections(&bytecode_file->sections, sections1,
-                                       sizeof(sections1) / sizeof(uint8));
-
-#if WASM_ENABLE_LIBC_WASI != 0
-            if (!wasm_app_prepare_wasi_dir(module, m_name, wasi_dir_buf,
-                                           sizeof(wasi_dir_buf))) {
-                SEND_ERR_RESPONSE(
-                    msg->mid,
-                    "Install WASM app failed: prepare wasi env failed.");
-                goto fail;
-            }
-            wasm_runtime_set_wasi_args(module, wasi_dir_list, 1, NULL, 0, NULL,
-                                       0, NULL, 0);
-#endif
-
-            /* Instantiate the wasm module */
-            inst =
-                wasm_runtime_instantiate(module, 0, heap_size, err, err_size);
-            if (!inst) {
-                snprintf(err_resp, sizeof(err_resp),
-                         "Install WASM app failed: %s", err);
-                SEND_ERR_RESPONSE(msg->mid, err_resp);
-                goto fail;
-            }
-
-            /* Destroy useless sections from list after instantiate */
-            destroy_part_wasm_sections(&bytecode_file->sections, sections2,
-                                       sizeof(sections2) / sizeof(uint8));
-            break;
-        }
-#endif /* endof WASM_ENALBE_INTERP != 0 || WASM_ENABLE_JIT != 0 */
-        default:
-            SEND_ERR_RESPONSE(
-                msg->mid,
-                "Install WASM app failed: invalid wasm package type.");
-            goto fail;
-    }
-
-    /* Create module data including the wasm_app_data as its internal_data*/
-    m_data_size = offsetof(module_data, module_name) + strlen(m_name) + 1;
-    m_data_size = align_uint(m_data_size, 4);
-    m_data = APP_MGR_MALLOC(m_data_size + sizeof(wasm_data));
-    if (!m_data) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: allocate memory failed.");
-        goto fail;
-    }
-    memset(m_data, 0, m_data_size + sizeof(wasm_data));
-
-    m_data->module_type = Module_WASM_App;
-    m_data->internal_data = (uint8 *)m_data + m_data_size;
-    wasm_app_data = (wasm_data *)m_data->internal_data;
-    wasm_app_data->wasm_module_inst = inst;
-    wasm_app_data->wasm_module = module;
-    wasm_app_data->m_data = m_data;
-    if (package_type == Wasm_Module_Bytecode) {
-        wasm_app_data->is_bytecode = true;
-        wasm_app_data->sections = wasm_app_file->u.bytecode.sections;
-    }
-    else {
-        wasm_app_data->is_bytecode = false;
-        wasm_app_data->sections = wasm_app_file->u.aot.sections;
-    }
-
-    if (!(wasm_app_data->exec_env = exec_env =
-              wasm_runtime_create_exec_env(inst, DEFAULT_WASM_STACK_SIZE))) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: create exec env failed.");
-        goto fail;
-    }
-
-    /* Set module data - name and module type */
-    bh_strcpy_s(m_data->module_name, strlen(m_name) + 1, m_name);
-
-    /* Set module data - execution timeout */
-    timeout = DEFAULT_WATCHDOG_INTERVAL;
-    find_key_value(properties, strlen(properties), "wd", timeout_str,
-                   sizeof(timeout_str) - 1, '&');
-    if (strlen(timeout_str) > 0)
-        timeout = atoi(timeout_str);
-    m_data->timeout = timeout;
-
-    /* Set module data - create queue */
-    m_data->queue = bh_queue_create();
-    if (!m_data->queue) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: create app queue failed.");
-        goto fail;
-    }
-
-    /* Set heap size */
-    m_data->heap_size = heap_size;
-
-    /* Set module data - timers number */
-    timers = DEFAULT_TIMERS_PER_APP;
-    find_key_value(properties, strlen(properties), "timers", timers_str,
-                   sizeof(timers_str) - 1, '&');
-    if (strlen(timers_str) > 0) {
-        timers = atoi(timers_str);
-        if (timers > MAX_TIMERS_PER_APP)
-            timers = MAX_TIMERS_PER_APP;
-    }
-
-    /* Attention: must add the module before start the thread! */
-    app_manager_add_module_data(m_data);
-
-    m_data->timer_ctx = create_wasm_timer_ctx(m_data->id, timers);
-    if (!m_data->timer_ctx) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: create app timers failed.");
-        goto fail;
-    }
-
-    /* Initialize watchdog timer */
-    if (!watchdog_timer_init(m_data)) {
-        SEND_ERR_RESPONSE(
-            msg->mid,
-            "Install WASM app failed: create app watchdog timer failed.");
-        goto fail;
-    }
-
-    stack_size = APP_THREAD_STACK_SIZE_DEFAULT;
-#ifdef OS_ENABLE_HW_BOUND_CHECK
-    stack_size += 4 * BH_KB;
-#endif
-    /* Create WASM app thread. */
-    if (os_thread_create(&wasm_app_data->thread_id, wasm_app_routine,
-                         (void *)m_data, stack_size)
-        != 0) {
-        module_data_list_remove(m_data);
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Install WASM app failed: create app thread failed.");
-        goto fail;
-    }
-
-    /* only when thread is created it is the flag of installation success */
-    app_manager_post_applets_update_event();
-
-    app_manager_printf("Install WASM app success!\n");
-    send_error_response_to_host(msg->mid, CREATED_2_01, NULL); /* CREATED */
-
-    return true;
-
-fail:
-    if (m_data)
-        release_module(m_data);
-
-    if (inst)
-        wasm_runtime_deinstantiate(inst);
-
-    if (module)
-        wasm_runtime_unload(module);
-
-    if (exec_env)
-        wasm_runtime_destroy_exec_env(exec_env);
-
-    switch (package_type) {
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-        case Wasm_Module_Bytecode:
-            destroy_all_wasm_sections(wasm_app_file->u.bytecode.sections);
-            break;
-#endif
-#if WASM_ENABLE_AOT != 0
-        case Wasm_Module_AoT:
-            destroy_all_aot_sections(wasm_app_file->u.aot.sections);
-            break;
-#endif
-        default:
-            break;
-    }
-
-    return false;
-}
-
-/* For internal use: if defined to 1, the process will
- * exit when wasm app is uninstalled. Hence valgrind can
- * print memory leak report. */
-#ifndef VALGRIND_CHECK
-#define VALGRIND_CHECK 0
-#endif
-
-/* Uninstall WASM app */
-static bool
-wasm_app_module_uninstall(request_t *msg)
-{
-    module_data *m_data;
-    wasm_data *wasm_app_data;
-    char m_name[APP_NAME_MAX_LEN] = { 0 };
-    char *properties;
-    int properties_offset;
-
-    properties_offset = check_url_start(msg->url, strlen(msg->url), "/applet");
-    /* TODO: assert(properties_offset > 0) */
-    if (properties_offset <= 0)
-        return false;
-    properties = msg->url + properties_offset;
-    find_key_value(properties, strlen(properties), "name", m_name,
-                   sizeof(m_name) - 1, '&');
-
-    if (strlen(m_name) == 0) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Uninstall WASM app failed: invalid app name.");
-        return false;
-    }
-
-    m_data = app_manager_lookup_module_data(m_name);
-    if (!m_data) {
-        SEND_ERR_RESPONSE(msg->mid, "Uninstall WASM app failed: no app found.");
-        return false;
-    }
-
-    if (m_data->module_type != Module_WASM_App) {
-        SEND_ERR_RESPONSE(msg->mid,
-                          "Uninstall WASM app failed: invalid module type.");
-        return false;
-    }
-
-    if (m_data->wd_timer.is_interrupting) {
-        SEND_ERR_RESPONSE(
-            msg->mid,
-            "Uninstall WASM app failed: app is being interrupted by watchdog.");
-        return false;
-    }
-
-    /* Exit app queue loop run */
-    bh_queue_exit_loop_run(m_data->queue);
-
-    /* Wait for wasm app thread to exit */
-    wasm_app_data = (wasm_data *)m_data->internal_data;
-    os_thread_join(wasm_app_data->thread_id, NULL);
-
-    cleanup_app_resource(m_data);
-
-    app_manager_post_applets_update_event();
-
-    app_manager_printf("Uninstall WASM app successful!\n");
-
-#ifdef COLLECT_CODE_COVERAGE
-    /* Exit app manager so as to collect code coverage data */
-    if (!strcmp(m_name, "__exit_app_manager__")) {
-        app_manager_printf("Exit app manager\n");
-        bh_queue_exit_loop_run(get_app_manager_queue());
-    }
-#endif
-
-#if VALGRIND_CHECK != 0
-    bh_queue_exit_loop_run(get_app_manager_queue());
-#endif
-
-    send_error_response_to_host(msg->mid, DELETED_2_02, NULL); /* DELETED */
-    return true;
-}
-
-static bool
-wasm_app_module_handle_host_url(void *queue_msg)
-{
-    /* TODO: implement in future */
-    app_manager_printf("App handles host url address %d\n",
-                       (int)(uintptr_t)queue_msg);
-    return false;
-}
-
-static module_data *
-wasm_app_module_get_module_data(void *inst)
-{
-    wasm_module_inst_t module_inst = (wasm_module_inst_t)inst;
-    return (module_data *)wasm_runtime_get_custom_data(module_inst);
-}
-
-static void
-wasm_app_module_watchdog_kill(module_data *m_data)
-{
-    /* TODO: implement in future */
-    app_manager_printf("Watchdog kills app: %s\n", m_data->module_name);
-    return;
-}
-
-bool
-wasm_register_msg_callback(int message_type,
-                           message_type_handler_t message_handler)
-{
-    int i;
-    int freeslot = -1;
-    for (i = 0; i < Max_Msg_Callback; i++) {
-        /* replace handler for the same event registered */
-        if (g_msg_type[i] == message_type)
-            break;
-
-        if (g_msg_callbacks[i] == NULL && freeslot == -1)
-            freeslot = i;
-    }
-
-    if (i != Max_Msg_Callback)
-        g_msg_callbacks[i] = message_handler;
-    else if (freeslot != -1) {
-        g_msg_callbacks[freeslot] = message_handler;
-        g_msg_type[freeslot] = message_type;
-    }
-    else
-        return false;
-
-    return true;
-}
-
-bool
-wasm_register_cleanup_callback(resource_cleanup_handler_t handler)
-{
-    int i;
-
-    for (i = 0; i < Max_Cleanup_Callback; i++) {
-        if (g_cleanup_callbacks[i] == NULL) {
-            g_cleanup_callbacks[i] = handler;
-            return true;
-        }
-    }
-
-    return false;
-}
-
-#define RECV_INTEGER(value, next_phase)                \
-    do {                                               \
-        uint8 *p = (uint8 *)&value;                    \
-        p[recv_ctx.size_in_phase++] = ch;              \
-        if (recv_ctx.size_in_phase == sizeof(value)) { \
-            if (sizeof(value) == 4)                    \
-                value = ntohl(value);                  \
-            else if (sizeof(value) == 2)               \
-                value = ntohs(value);                  \
-            recv_ctx.phase = next_phase;               \
-            recv_ctx.size_in_phase = 0;                \
-        }                                              \
-    } while (0)
-
-/* return:
- * 1: whole wasm app arrived
- * 0: one valid byte arrived
- * -1: fail to process the byte arrived, e.g. allocate memory fail
- */
-static bool
-wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
-                                               int *received_size)
-{
-    uint8 *p;
-    int magic;
-    package_type_t package_type = Package_Type_Unknown;
-
-    if (recv_ctx.phase == Phase_Req_Ver) {
-        recv_ctx.phase = Phase_Req_Ver;
-        recv_ctx.size_in_phase = 0;
-        recv_ctx.total_received_size = 0;
-    }
-
-    recv_ctx.total_received_size++;
-    *received_size = recv_ctx.total_received_size;
-
-    if (recv_ctx.phase == Phase_Req_Ver) {
-        if (ch != 1 /* REQUES_PACKET_VER from restful_utils.c */)
-            return false;
-        recv_ctx.phase = Phase_Req_Action;
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Req_Action) {
-        recv_ctx.message.request_action = ch;
-        recv_ctx.phase = Phase_Req_Fmt;
-        recv_ctx.size_in_phase = 0;
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Req_Fmt) {
-        RECV_INTEGER(recv_ctx.message.request_fmt, Phase_Req_Mid);
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Req_Mid) {
-        RECV_INTEGER(recv_ctx.message.request_mid, Phase_Req_Sender);
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Req_Sender) {
-        RECV_INTEGER(recv_ctx.message.request_sender, Phase_Req_Url_Len);
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Req_Url_Len) {
-        p = (uint8 *)&recv_ctx.message.request_url_len;
-
-        p[recv_ctx.size_in_phase++] = ch;
-        if (recv_ctx.size_in_phase
-            == sizeof(recv_ctx.message.request_url_len)) {
-            recv_ctx.message.request_url_len =
-                ntohs(recv_ctx.message.request_url_len);
-            recv_ctx.message.request_url =
-                APP_MGR_MALLOC(recv_ctx.message.request_url_len + 1);
-            if (NULL == recv_ctx.message.request_url) {
-                app_manager_printf("Allocate memory failed!\n");
-                SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                                  "Install WASM app failed: "
-                                  "allocate memory failed.");
-                goto fail;
-            }
-            memset(recv_ctx.message.request_url, 0,
-                   recv_ctx.message.request_url_len + 1);
-            recv_ctx.phase = Phase_Req_Payload_Len;
-            recv_ctx.size_in_phase = 0;
-        }
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Req_Payload_Len) {
-        RECV_INTEGER(recv_ctx.message.wasm_app_size, Phase_Req_Url);
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Req_Url) {
-        recv_ctx.message.request_url[recv_ctx.size_in_phase++] = ch;
-        if (recv_ctx.size_in_phase == recv_ctx.message.request_url_len) {
-            recv_ctx.phase = Phase_App_Magic;
-            recv_ctx.size_in_phase = 0;
-        }
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_App_Magic) {
-        /* start to receive wasm app magic: bytecode or aot */
-        p = (uint8 *)&recv_ctx.message.app_file_magic;
-
-        p[recv_ctx.size_in_phase++] = ch;
-
-        if (recv_ctx.size_in_phase == sizeof(recv_ctx.message.app_file_magic)) {
-            magic = recv_ctx.message.app_file_magic;
-            package_type = get_package_type((uint8 *)&magic, sizeof(magic) + 1);
-            switch (package_type) {
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-                case Wasm_Module_Bytecode:
-                    recv_ctx.message.app_file.u.bytecode.magic =
-                        recv_ctx.message.app_file_magic;
-                    recv_ctx.phase = Phase_Wasm_Version;
-                    recv_ctx.size_in_phase = 0;
-                    break;
-#endif
-#if WASM_ENABLE_AOT != 0
-                case Wasm_Module_AoT:
-                    recv_ctx.message.app_file.u.aot.magic =
-                        recv_ctx.message.app_file_magic;
-                    recv_ctx.phase = Phase_AOT_Version;
-                    recv_ctx.size_in_phase = 0;
-                    break;
-#endif
-                default:
-                    SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                                      "Install WASM app failed: "
-                                      "invalid file format.");
-                    goto fail;
-            }
-        }
-        return true;
-    }
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-    else if (recv_ctx.phase == Phase_Wasm_Version) {
-        p = (uint8 *)&recv_ctx.message.app_file.u.bytecode.version;
-
-        if (ch == wasm_bytecode_version[recv_ctx.size_in_phase])
-            p[recv_ctx.size_in_phase++] = ch;
-        else {
-            app_manager_printf("Invalid WASM version!\n");
-            SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                              "Install WASM app failed: invalid WASM version.");
-            goto fail;
-        }
-
-        if (recv_ctx.size_in_phase
-            == sizeof(recv_ctx.message.app_file.u.bytecode.version)) {
-            recv_ctx.phase = Phase_Wasm_Section_Type;
-            recv_ctx.size_in_phase = 0;
-        }
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Wasm_Section_Type) {
-        uint8 section_type = ch;
-#if WASM_ENABLE_BULK_MEMORY == 0
-        uint8 section_type_max = SECTION_TYPE_DATA;
-#else
-#if WASM_ENABLE_STRINGREF != 0
-        uint8 section_type_max = SECTION_TYPE_STRINGREF;
-#else
-        uint8 section_type_max = SECTION_TYPE_DATACOUNT;
-#endif /* end of WASM_ENABLE_STRINGREF != 0 */
-#endif
-        if (section_type <= section_type_max) {
-            wasm_section_t *new_section;
-            if (!(new_section = (wasm_section_t *)APP_MGR_MALLOC(
-                      sizeof(wasm_section_t)))) {
-                app_manager_printf("Allocate memory failed!\n");
-                SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                                  "Install WASM app failed: "
-                                  "allocate memory failed.");
-                goto fail;
-            }
-            memset(new_section, 0, sizeof(wasm_section_t));
-            new_section->section_type = section_type;
-            new_section->next = NULL;
-
-            /* add the section to tail of link list */
-            if (NULL == recv_ctx.message.app_file.u.bytecode.sections) {
-                recv_ctx.message.app_file.u.bytecode.sections = new_section;
-                recv_ctx.message.app_file.u.bytecode.section_end = new_section;
-            }
-            else {
-                recv_ctx.message.app_file.u.bytecode.section_end->next =
-                    new_section;
-                recv_ctx.message.app_file.u.bytecode.section_end = new_section;
-            }
-
-            recv_ctx.phase = Phase_Wasm_Section_Size;
-            recv_ctx.size_in_phase = 0;
-
-            return true;
-        }
-        else {
-            char error_buf[128];
-
-            app_manager_printf("Invalid wasm section type: %d\n", section_type);
-            snprintf(error_buf, sizeof(error_buf),
-                     "Install WASM app failed: invalid wasm section type %d",
-                     section_type);
-            SEND_ERR_RESPONSE(recv_ctx.message.request_mid, error_buf);
-            goto fail;
-        }
-    }
-    else if (recv_ctx.phase == Phase_Wasm_Section_Size) {
-        /* the last section is the current receiving one */
-        wasm_section_t *section =
-            recv_ctx.message.app_file.u.bytecode.section_end;
-        uint32 byte;
-
-        bh_assert(section);
-
-        byte = ch;
-
-        section->section_body_size |=
-            ((byte & 0x7f) << recv_ctx.size_in_phase * 7);
-        recv_ctx.size_in_phase++;
-        /* check leab128 overflow for uint32 value */
-        if (recv_ctx.size_in_phase
-            > (sizeof(section->section_body_size) * 8 + 7 - 1) / 7) {
-            app_manager_printf("LEB overflow when parsing section size\n");
-            SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                              "Install WASM app failed: "
-                              "LEB overflow when parsing section size");
-            goto fail;
-        }
-
-        if ((byte & 0x80) == 0) {
-            /* leb128 encoded section size parsed done */
-            if (!(section->section_body =
-                      APP_MGR_MALLOC(section->section_body_size))) {
-                app_manager_printf("Allocate memory failed!\n");
-                SEND_ERR_RESPONSE(
-                    recv_ctx.message.request_mid,
-                    "Install WASM app failed: allocate memory failed");
-                goto fail;
-            }
-            recv_ctx.phase = Phase_Wasm_Section_Content;
-            recv_ctx.size_in_phase = 0;
-        }
-
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_Wasm_Section_Content) {
-        /* the last section is the current receiving one */
-        wasm_section_t *section =
-            recv_ctx.message.app_file.u.bytecode.section_end;
-
-        bh_assert(section);
-
-        section->section_body[recv_ctx.size_in_phase++] = ch;
-
-        if (recv_ctx.size_in_phase == section->section_body_size) {
-            if (recv_ctx.total_received_size == request_total_size) {
-                /* whole wasm app received */
-                if (module_wasm_app_handle_install_msg(&recv_ctx.message)) {
-                    APP_MGR_FREE(recv_ctx.message.request_url);
-                    recv_ctx.message.request_url = NULL;
-                    memset(&recv_ctx, 0, sizeof(recv_ctx));
-                    return true;
-                }
-                else {
-                    app_manager_printf("Handle install message failed!\n");
-                    SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                                      "Install WASM app failed: "
-                                      "handle install message failed");
-                    /**
-                     * The sections were destroyed inside
-                     * module_wasm_app_handle_install_msg(),
-                     * no need to destroy again.
-                     */
-                    return false;
-                }
-            }
-            else {
-                recv_ctx.phase = Phase_Wasm_Section_Type;
-                recv_ctx.size_in_phase = 0;
-                return true;
-            }
-        }
-
-        return true;
-    }
-#endif /* end of WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0 */
-#if WASM_ENABLE_AOT != 0
-    else if (recv_ctx.phase == Phase_AOT_Version) {
-        p = (uint8 *)&recv_ctx.message.app_file.u.aot.version;
-
-        if (ch == wasm_aot_version[recv_ctx.size_in_phase])
-            p[recv_ctx.size_in_phase++] = ch;
-        else {
-            app_manager_printf("Invalid AOT version!\n");
-            SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                              "Install WASM app failed: invalid AOT version");
-            goto fail;
-        }
-
-        if (recv_ctx.size_in_phase
-            == sizeof(recv_ctx.message.app_file.u.aot.version)) {
-            recv_ctx.phase = Phase_AOT_Section_ID;
-            recv_ctx.size_in_phase = 0;
-        }
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_AOT_Section_ID) {
-        aot_section_t *cur_section;
-        uint32 aot_file_cur_offset =
-            recv_ctx.total_received_size - 1
-            - 18 /* Request fixed part */ - recv_ctx.message.request_url_len;
-
-        if (recv_ctx.size_in_phase == 0) {
-            /* Skip paddings */
-            if (aot_file_cur_offset % 4)
-                return true;
-
-            if (!(cur_section =
-                      (aot_section_t *)APP_MGR_MALLOC(sizeof(aot_section_t)))) {
-                app_manager_printf("Allocate memory failed!\n");
-                SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                                  "Install WASM app failed: "
-                                  "allocate memory failed");
-                goto fail;
-            }
-            memset(cur_section, 0, sizeof(aot_section_t));
-
-            /* add the section to tail of link list */
-            if (NULL == recv_ctx.message.app_file.u.aot.sections) {
-                recv_ctx.message.app_file.u.aot.sections = cur_section;
-                recv_ctx.message.app_file.u.aot.section_end = cur_section;
-            }
-            else {
-                recv_ctx.message.app_file.u.aot.section_end->next = cur_section;
-                recv_ctx.message.app_file.u.aot.section_end = cur_section;
-            }
-        }
-        else {
-            cur_section = recv_ctx.message.app_file.u.aot.section_end;
-            bh_assert(cur_section);
-        }
-
-        p = (uint8 *)&cur_section->section_type;
-        p[recv_ctx.size_in_phase++] = ch;
-        if (recv_ctx.size_in_phase == sizeof(cur_section->section_type)) {
-            /* Notes: integers are always little endian encoded in AOT file */
-            if (!is_little_endian())
-                exchange_uint32(p);
-            if (cur_section->section_type < AOT_SECTION_TYPE_SIGANATURE
-                || cur_section->section_type == AOT_SECTION_TYPE_CUSTOM) {
-                recv_ctx.phase = Phase_AOT_Section_Size;
-                recv_ctx.size_in_phase = 0;
-            }
-            else {
-                char error_buf[128];
-
-                app_manager_printf("Invalid AOT section id: %d\n",
-                                   cur_section->section_type);
-                snprintf(error_buf, sizeof(error_buf),
-                         "Install WASM app failed: invalid AOT section id %d",
-                         cur_section->section_type);
-                SEND_ERR_RESPONSE(recv_ctx.message.request_mid, error_buf);
-                goto fail;
-            }
-        }
-
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_AOT_Section_Size) {
-        /* the last section is the current receiving one */
-        aot_section_t *section = recv_ctx.message.app_file.u.aot.section_end;
-        bh_assert(section);
-
-        p = (uint8 *)&section->section_body_size;
-        p[recv_ctx.size_in_phase++] = ch;
-        if (recv_ctx.size_in_phase == sizeof(section->section_body_size)) {
-            /* Notes: integers are always little endian encoded in AOT file */
-            if (!is_little_endian())
-                exchange_uint32(p);
-            /* Allocate memory for section body */
-            if (section->section_body_size > 0) {
-                if (section->section_type == AOT_SECTION_TYPE_TEXT) {
-                    int map_prot =
-                        MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
-#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
-    || defined(BUILD_TARGET_RISCV64_LP64D)                       \
-    || defined(BUILD_TARGET_RISCV64_LP64)
-                    /* aot code and data in x86_64 must be in range 0 to 2G due
-                       to relocation for R_X86_64_32/32S/PC32 */
-                    int map_flags = MMAP_MAP_32BIT;
-#else
-                    int map_flags = MMAP_MAP_NONE;
-#endif
-                    uint64 total_size = (uint64)section->section_body_size
-                                        + aot_get_plt_table_size();
-                    total_size = (total_size + 3) & ~((uint64)3);
-                    if (total_size >= UINT32_MAX
-                        || !(section->section_body =
-                                 os_mmap(NULL, (uint32)total_size, map_prot,
-                                         map_flags, os_get_invalid_handle()))) {
-                        app_manager_printf(
-                            "Allocate executable memory failed!\n");
-                        SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                                          "Install WASM app failed: "
-                                          "allocate memory failed");
-                        goto fail;
-                    }
-#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
-                    /* address must be in the first 2 Gigabytes of
-                       the process address space */
-                    bh_assert((uintptr_t)section->section_body < INT32_MAX);
-#endif
-                }
-                else {
-                    if (!(section->section_body =
-                              APP_MGR_MALLOC(section->section_body_size))) {
-                        app_manager_printf("Allocate memory failed!\n");
-                        SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                                          "Install WASM app failed: "
-                                          "allocate memory failed");
-                        goto fail;
-                    }
-                }
-            }
-
-            recv_ctx.phase = Phase_AOT_Section_Content;
-            recv_ctx.size_in_phase = 0;
-        }
-
-        return true;
-    }
-    else if (recv_ctx.phase == Phase_AOT_Section_Content) {
-        /* the last section is the current receiving one */
-        aot_section_t *section = recv_ctx.message.app_file.u.aot.section_end;
-        bh_assert(section && section->section_body);
-
-        section->section_body[recv_ctx.size_in_phase++] = ch;
-
-        if (recv_ctx.size_in_phase == section->section_body_size) {
-            if (section->section_type == AOT_SECTION_TYPE_TEXT) {
-                uint32 total_size =
-                    section->section_body_size + aot_get_plt_table_size();
-                total_size = (total_size + 3) & ~3;
-                if (total_size > section->section_body_size) {
-                    memset(section->section_body + section->section_body_size,
-                           0, total_size - section->section_body_size);
-                    section->section_body_size = total_size;
-                }
-            }
-            if (recv_ctx.total_received_size == request_total_size) {
-                /* whole aot file received */
-                if (module_wasm_app_handle_install_msg(&recv_ctx.message)) {
-                    APP_MGR_FREE(recv_ctx.message.request_url);
-                    recv_ctx.message.request_url = NULL;
-                    memset(&recv_ctx, 0, sizeof(recv_ctx));
-                    return true;
-                }
-                else {
-                    app_manager_printf("Handle install message failed!\n");
-                    SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
-                                      "Install WASM app failed: "
-                                      "handle install message failed");
-                    /**
-                     * The sections were destroyed inside
-                     * module_wasm_app_handle_install_msg(),
-                     * no need to destroy again.
-                     */
-                    return false;
-                }
-            }
-            else {
-                recv_ctx.phase = Phase_AOT_Section_ID;
-                recv_ctx.size_in_phase = 0;
-                return true;
-            }
-        }
-
-        return true;
-    }
-#endif /* end of WASM_ENABLE_AOT != 0 */
-
-fail:
-    /* Restore the package type */
-    magic = recv_ctx.message.app_file_magic;
-    package_type = get_package_type((uint8 *)&magic, sizeof(magic) + 1);
-    switch (package_type) {
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-        case Wasm_Module_Bytecode:
-            destroy_all_wasm_sections(
-                recv_ctx.message.app_file.u.bytecode.sections);
-            break;
-#endif
-#if WASM_ENABLE_AOT != 0
-        case Wasm_Module_AoT:
-            destroy_all_aot_sections(recv_ctx.message.app_file.u.aot.sections);
-            break;
-#endif
-        default:
-            break;
-    }
-
-    if (recv_ctx.message.request_url != NULL) {
-        APP_MGR_FREE(recv_ctx.message.request_url);
-        recv_ctx.message.request_url = NULL;
-    }
-
-    memset(&recv_ctx, 0, sizeof(recv_ctx));
-    return false;
-}
-
-static bool
-module_wasm_app_handle_install_msg(install_wasm_app_msg_t *message)
-{
-    request_t *request = NULL;
-    bh_message_t msg;
-
-    request = (request_t *)APP_MGR_MALLOC(sizeof(request_t));
-    if (request == NULL)
-        return false;
-
-    memset(request, 0, sizeof(*request));
-    request->action = message->request_action;
-    request->fmt = message->request_fmt;
-    request->url = bh_strdup(message->request_url);
-    request->sender = ID_HOST;
-    request->mid = message->request_mid;
-    request->payload_len = sizeof(message->app_file);
-    request->payload = APP_MGR_MALLOC(request->payload_len);
-
-    if (request->url == NULL || request->payload == NULL) {
-        request_cleaner(request);
-        return false;
-    }
-
-    /* Request payload is set to wasm_app_file_t struct,
-     * but not whole app buffer */
-    bh_memcpy_s(request->payload, request->payload_len, &message->app_file,
-                request->payload_len);
-
-    /* Since it's a wasm app install request, so directly post to app-mgr's
-     * queue. The benefit is that section list can be freed when the msg
-     * failed to post to app-mgr's queue. The defect is missing url check. */
-    if (!(msg = bh_new_msg(RESTFUL_REQUEST, request, sizeof(*request),
-                           request_cleaner))) {
-        request_cleaner(request);
-        return false;
-    }
-
-    if (!bh_post_msg2(get_app_manager_queue(), msg))
-        return false;
-
-    return true;
-}
-
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-static void
-destroy_all_wasm_sections(wasm_section_list_t sections)
-{
-    wasm_section_t *cur = sections;
-    while (cur) {
-        wasm_section_t *next = cur->next;
-        if (cur->section_body != NULL)
-            APP_MGR_FREE(cur->section_body);
-        APP_MGR_FREE(cur);
-        cur = next;
-    }
-}
-
-static void
-destroy_part_wasm_sections(wasm_section_list_t *p_sections,
-                           uint8 *section_types, int section_cnt)
-{
-    int i;
-    for (i = 0; i < section_cnt; i++) {
-        uint8 section_type = section_types[i];
-        wasm_section_t *cur = *p_sections, *prev = NULL;
-
-        while (cur) {
-            wasm_section_t *next = cur->next;
-            if (cur->section_type == section_type) {
-                if (prev)
-                    prev->next = next;
-                else
-                    *p_sections = next;
-
-                if (cur->section_body != NULL)
-                    APP_MGR_FREE(cur->section_body);
-                APP_MGR_FREE(cur);
-                break;
-            }
-            else {
-                prev = cur;
-                cur = next;
-            }
-        }
-    }
-}
-#endif
-
-#if WASM_ENABLE_AOT != 0
-static void
-destroy_all_aot_sections(aot_section_list_t sections)
-{
-    aot_section_t *cur = sections;
-    while (cur) {
-        aot_section_t *next = cur->next;
-        if (cur->section_body != NULL) {
-            if (cur->section_type == AOT_SECTION_TYPE_TEXT)
-                os_munmap(cur->section_body, cur->section_body_size);
-            else
-                APP_MGR_FREE(cur->section_body);
-        }
-        APP_MGR_FREE(cur);
-        cur = next;
-    }
-}
-
-static void
-destroy_part_aot_sections(aot_section_list_t *p_sections, uint8 *section_types,
-                          int section_cnt)
-{
-    int i;
-    for (i = 0; i < section_cnt; i++) {
-        uint8 section_type = section_types[i];
-        aot_section_t *cur = *p_sections, *prev = NULL;
-
-        while (cur) {
-            aot_section_t *next = cur->next;
-            if (cur->section_type == section_type) {
-                if (prev)
-                    prev->next = next;
-                else
-                    *p_sections = next;
-
-                if (cur->section_body != NULL) {
-                    if (cur->section_type == AOT_SECTION_TYPE_TEXT)
-                        os_munmap(cur->section_body, cur->section_body_size);
-                    else
-                        APP_MGR_FREE(cur->section_body);
-                }
-                APP_MGR_FREE(cur);
-                break;
-            }
-            else {
-                prev = cur;
-                cur = next;
-            }
-        }
-    }
-}
-#endif
-
-#if WASM_ENABLE_LIBC_WASI != 0
-static char wasi_root_dir[PATH_MAX] = { '.' };
-
-bool
-wasm_set_wasi_root_dir(const char *root_dir)
-{
-    char *path, resolved_path[PATH_MAX];
-
-    if (!(path = realpath(root_dir, resolved_path)))
-        return false;
-
-    snprintf(wasi_root_dir, sizeof(wasi_root_dir), "%s", path);
-    return true;
-}
-
-const char *
-wasm_get_wasi_root_dir()
-{
-    return wasi_root_dir;
-}
-#endif

+ 0 - 70
core/app-mgr/app-manager/platform/zephyr/app_mgr_zephyr.c

@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019 Intel Corporation.  All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
-
-#include "app_manager.h"
-#include "bh_platform.h"
-#include <autoconf.h>
-
-#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */
-#include <zephyr.h>
-#include <kernel.h>
-#else
-#include <zephyr/kernel.h>
-#endif
-
-#if 0
-#include <sigverify.h>
-#endif
-typedef struct k_timer_watchdog {
-    struct k_timer timer;
-    watchdog_timer *wd_timer;
-} k_timer_watchdog;
-
-void *
-app_manager_timer_create(void (*timer_callback)(void *),
-                         watchdog_timer *wd_timer)
-{
-    struct k_timer_watchdog *timer =
-        APP_MGR_MALLOC(sizeof(struct k_timer_watchdog));
-
-    if (timer) {
-        k_timer_init(&timer->timer, (void (*)(struct k_timer *))timer_callback,
-                     NULL);
-        timer->wd_timer = wd_timer;
-    }
-
-    return timer;
-}
-
-void
-app_manager_timer_destroy(void *timer)
-{
-    APP_MGR_FREE(timer);
-}
-
-void
-app_manager_timer_start(void *timer, int timeout)
-{
-    k_timer_start(timer, Z_TIMEOUT_MS(timeout), Z_TIMEOUT_MS(0));
-}
-
-void
-app_manager_timer_stop(void *timer)
-{
-    k_timer_stop(timer);
-}
-
-watchdog_timer *
-app_manager_get_wd_timer_from_timer_handle(void *timer)
-{
-    return ((k_timer_watchdog *)timer)->wd_timer;
-}
-#if 0
-int app_manager_signature_verify(const uint8_t *file, unsigned int file_len,
-        const uint8_t *signature, unsigned int sig_size)
-{
-    return signature_verify(file, file_len, signature, sig_size);
-}
-#endif

+ 96 - 4
core/config.h

@@ -152,6 +152,10 @@
 #define WASM_ENABLE_WASI_NN_EXTERNAL_DELEGATE 0
 #endif
 
+#ifndef WASM_ENABLE_WASI_EPHEMERAL_NN
+#define WASM_ENABLE_WASI_EPHEMERAL_NN 0
+#endif
+
 /* Default disable libc emcc */
 #ifndef WASM_ENABLE_LIBC_EMCC
 #define WASM_ENABLE_LIBC_EMCC 0
@@ -411,7 +415,7 @@
 #else
 #define DEFAULT_WASM_STACK_SIZE (12 * 1024)
 #endif
-/* Min auxilliary stack size of each wasm thread */
+/* Min auxiliary stack size of each wasm thread */
 #define WASM_THREAD_AUX_STACK_SIZE_MIN (256)
 
 /* Default/min native stack size of each app thread */
@@ -441,20 +445,91 @@
 #endif
 
 /* Reserved bytes to the native thread stack boundary, throw native
-   stack overflow exception if the guard boudary is reached */
+ * stack overflow exception if the guard boudary is reached
+ *
+ * WASM_STACK_GUARD_SIZE needs to be large enough for:
+ *
+ * - native functions
+ *
+ *   w/o hw bound check, the overhead (aot_call_function etc) + the native
+ *   function itself. as of writing this, the former is about 1000 bytes
+ *   on macOS amd64.
+ *
+ *   with hw bound check, theoretically, only needs to cover the logic to
+ *   set up the jmp_buf stack.
+ *
+ * - aot runtime functions
+ *   eg. aot_enlarge_memory.
+ *
+ * - w/o hw bound check, the intepreter loop
+ *
+ *   the stack consumption heavily depends on compiler settings,
+ *   especially for huge functions like the classic interpreter's
+ *   wasm_interp_call_func_bytecode:
+ *
+ *     200 bytes (release build, macOS/amd64)
+ *     2600 bytes (debug build, macOS/amd64)
+ *
+ *   libc snprintf (used by eg. wasm_runtime_set_exception) consumes about
+ *   1600 bytes stack on macOS/amd64, about 2000 bytes on Ubuntu amd64 20.04.
+ *
+ * - stack check wrapper functions generated by the aot compiler
+ *   (--stack-bounds-checks=1)
+ *
+ *   wamrc issues a warning
+ *   "precheck functions themselves consume relatively large amount of stack"
+ *   when it detects wrapper functions requiring more than 1KB.
+ *
+ * Note: on platforms with lazy function binding, don't forget to consider
+ * the symbol resolution overhead on the first call. For example,
+ * on Ubuntu amd64 20.04, it seems to consume about 1500 bytes.
+ * For some reasons, macOS amd64 12.7.4 seems to resolve symbols eagerly.
+ * (Observed with a binary with traditional non-chained fixups.)
+ * The latest macOS seems to apply chained fixups in kernel on page-in time.
+ * (thus it wouldn't consume userland stack.)
+ */
 #ifndef WASM_STACK_GUARD_SIZE
 #if WASM_ENABLE_UVWASI != 0
 /* UVWASI requires larger native stack */
 #define WASM_STACK_GUARD_SIZE (4096 * 6)
 #else
-#define WASM_STACK_GUARD_SIZE (1024)
+/*
+ * Use a larger default for platforms like macOS/Linux.
+ *
+ * For example, the classic intepreter loop which ended up with a trap
+ * (wasm_runtime_set_exception) would consume about 2KB stack on x86-64
+ * macOS. On Ubuntu amd64 20.04, it seems to consume a bit more.
+ *
+ * Although product-mini/platforms/nuttx always overrides
+ * WASM_STACK_GUARD_SIZE, exclude NuttX here just in case.
+ */
+#if defined(__APPLE__) || (defined(__unix__) && !defined(__NuttX__))
+#if BH_DEBUG != 0 /* assumption: BH_DEBUG matches CMAKE_BUILD_TYPE=Debug */
+#define WASM_STACK_GUARD_SIZE (1024 * 5)
+#else
+#define WASM_STACK_GUARD_SIZE (1024 * 3)
+#endif
+#else
+/*
+ * Otherwise, assume very small requirement for now.
+ *
+ * Embedders for very small devices likely fine-tune WASM_STACK_GUARD_SIZE
+ * for their specific applications anyway.
+ */
+#define WASM_STACK_GUARD_SIZE 1024
+#endif
 #endif
 #endif
 
 /* Guard page count for stack overflow check with hardware trap */
 #ifndef STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT
+#if defined(__APPLE__) && defined(__aarch64__)
+/* Note: on macOS/iOS arm64, the user page size is 16KB */
+#define STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT 1
+#else
 #define STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT 3
 #endif
+#endif
 
 /* Default wasm block address cache size and conflict list size */
 #ifndef BLOCK_ADDR_CACHE_SIZE
@@ -560,14 +635,31 @@
 #endif
 
 /* Support registering quick AOT/JIT function entries of some func types
-   to speedup the calling process of invoking the AOT/JIT functions of
+   to speed up the calling process of invoking the AOT/JIT functions of
    these types from the host embedder */
 #ifndef WASM_ENABLE_QUICK_AOT_ENTRY
 #define WASM_ENABLE_QUICK_AOT_ENTRY 1
 #endif
 
+/* Support AOT intrinsic functions which can be called from the AOT code
+   when `--disable-llvm-intrinsics` flag or
+   `--enable-builtin-intrinsics=<intr1,intr2,...>` is used by wamrc to
+   generate the AOT file */
+#ifndef WASM_ENABLE_AOT_INTRINSICS
+#define WASM_ENABLE_AOT_INTRINSICS 1
+#endif
+
+/* Disable memory64 by default */
+#ifndef WASM_ENABLE_MEMORY64
+#define WASM_ENABLE_MEMORY64 0
+#endif
+
 #ifndef WASM_TABLE_MAX_SIZE
 #define WASM_TABLE_MAX_SIZE 1024
 #endif
 
+#ifndef WASM_MEM_ALLOC_WITH_USAGE
+#define WASM_MEM_ALLOC_WITH_USAGE 0
+#endif
+
 #endif /* end of _CONFIG_H_ */

+ 82 - 82
core/iwasm/aot/aot_intrinsic.c

@@ -5,86 +5,6 @@
 
 #include "aot_intrinsic.h"
 
-typedef struct {
-    const char *llvm_intrinsic;
-    const char *native_intrinsic;
-    uint64 flag;
-} aot_intrinsic;
-
-/* clang-format off */
-static const aot_intrinsic g_intrinsic_mapping[] = {
-    { "llvm.experimental.constrained.fadd.f32", "aot_intrinsic_fadd_f32", AOT_INTRINSIC_FLAG_F32_FADD },
-    { "llvm.experimental.constrained.fadd.f64", "aot_intrinsic_fadd_f64", AOT_INTRINSIC_FLAG_F64_FADD },
-    { "llvm.experimental.constrained.fsub.f32", "aot_intrinsic_fsub_f32", AOT_INTRINSIC_FLAG_F32_FSUB },
-    { "llvm.experimental.constrained.fsub.f64", "aot_intrinsic_fsub_f64", AOT_INTRINSIC_FLAG_F64_FSUB },
-    { "llvm.experimental.constrained.fmul.f32", "aot_intrinsic_fmul_f32", AOT_INTRINSIC_FLAG_F32_FMUL },
-    { "llvm.experimental.constrained.fmul.f64", "aot_intrinsic_fmul_f64", AOT_INTRINSIC_FLAG_F64_FMUL },
-    { "llvm.experimental.constrained.fdiv.f32", "aot_intrinsic_fdiv_f32", AOT_INTRINSIC_FLAG_F32_FDIV },
-    { "llvm.experimental.constrained.fdiv.f64", "aot_intrinsic_fdiv_f64", AOT_INTRINSIC_FLAG_F64_FDIV },
-    { "llvm.fabs.f32", "aot_intrinsic_fabs_f32", AOT_INTRINSIC_FLAG_F32_FABS },
-    { "llvm.fabs.f64", "aot_intrinsic_fabs_f64", AOT_INTRINSIC_FLAG_F64_FABS },
-    { "llvm.ceil.f32", "aot_intrinsic_ceil_f32", AOT_INTRINSIC_FLAG_F32_CEIL },
-    { "llvm.ceil.f64", "aot_intrinsic_ceil_f64", AOT_INTRINSIC_FLAG_F64_CEIL },
-    { "llvm.floor.f32", "aot_intrinsic_floor_f32", AOT_INTRINSIC_FLAG_F32_FLOOR },
-    { "llvm.floor.f64", "aot_intrinsic_floor_f64", AOT_INTRINSIC_FLAG_F64_FLOOR },
-    { "llvm.trunc.f32", "aot_intrinsic_trunc_f32", AOT_INTRINSIC_FLAG_F32_TRUNC },
-    { "llvm.trunc.f64", "aot_intrinsic_trunc_f64", AOT_INTRINSIC_FLAG_F64_TRUNC },
-    { "llvm.rint.f32", "aot_intrinsic_rint_f32", AOT_INTRINSIC_FLAG_F32_RINT },
-    { "llvm.rint.f64", "aot_intrinsic_rint_f64", AOT_INTRINSIC_FLAG_F64_RINT },
-    { "llvm.sqrt.f32", "aot_intrinsic_sqrt_f32", AOT_INTRINSIC_FLAG_F32_SQRT },
-    { "llvm.sqrt.f64", "aot_intrinsic_sqrt_f64", AOT_INTRINSIC_FLAG_F64_SQRT },
-    { "llvm.copysign.f32", "aot_intrinsic_copysign_f32", AOT_INTRINSIC_FLAG_F32_COPYSIGN },
-    { "llvm.copysign.f64", "aot_intrinsic_copysign_f64", AOT_INTRINSIC_FLAG_F64_COPYSIGN },
-    { "llvm.minnum.f32", "aot_intrinsic_fmin_f32", AOT_INTRINSIC_FLAG_F32_MIN },
-    { "llvm.minnum.f64", "aot_intrinsic_fmin_f64", AOT_INTRINSIC_FLAG_F64_MIN },
-    { "llvm.maxnum.f32", "aot_intrinsic_fmax_f32", AOT_INTRINSIC_FLAG_F32_MAX },
-    { "llvm.maxnum.f64", "aot_intrinsic_fmax_f64", AOT_INTRINSIC_FLAG_F64_MAX },
-    { "llvm.ctlz.i32", "aot_intrinsic_clz_i32", AOT_INTRINSIC_FLAG_I32_CLZ },
-    { "llvm.ctlz.i64", "aot_intrinsic_clz_i64", AOT_INTRINSIC_FLAG_I64_CLZ },
-    { "llvm.cttz.i32", "aot_intrinsic_ctz_i32", AOT_INTRINSIC_FLAG_I32_CTZ },
-    { "llvm.cttz.i64", "aot_intrinsic_ctz_i64", AOT_INTRINSIC_FLAG_I64_CTZ },
-    { "llvm.ctpop.i32", "aot_intrinsic_popcnt_i32", AOT_INTRINSIC_FLAG_I32_POPCNT },
-    { "llvm.ctpop.i64", "aot_intrinsic_popcnt_i64", AOT_INTRINSIC_FLAG_I64_POPCNT },
-    { "f64_convert_i32_s", "aot_intrinsic_i32_to_f64", AOT_INTRINSIC_FLAG_I32_TO_F64 },
-    { "f64_convert_i32_u", "aot_intrinsic_u32_to_f64", AOT_INTRINSIC_FLAG_U32_TO_F64 },
-    { "f32_convert_i32_s", "aot_intrinsic_i32_to_f32", AOT_INTRINSIC_FLAG_I32_TO_F32 },
-    { "f32_convert_i32_u", "aot_intrinsic_u32_to_f32", AOT_INTRINSIC_FLAG_U32_TO_F32 },
-    { "f64_convert_i64_s", "aot_intrinsic_i64_to_f64", AOT_INTRINSIC_FLAG_I32_TO_F64 },
-    { "f64_convert_i64_u", "aot_intrinsic_u64_to_f64", AOT_INTRINSIC_FLAG_U64_TO_F64 },
-    { "f32_convert_i64_s", "aot_intrinsic_i64_to_f32", AOT_INTRINSIC_FLAG_I64_TO_F32 },
-    { "f32_convert_i64_u", "aot_intrinsic_u64_to_f32", AOT_INTRINSIC_FLAG_U64_TO_F32 },
-    { "i32_trunc_f32_u", "aot_intrinsic_f32_to_u32", AOT_INTRINSIC_FLAG_F32_TO_U32 },
-    { "i32_trunc_f32_s", "aot_intrinsic_f32_to_i32", AOT_INTRINSIC_FLAG_F32_TO_I32 },
-    { "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_F64_TO_U32 },
-    { "i32_trunc_f64_s", "aot_intrinsic_f64_to_i32", AOT_INTRINSIC_FLAG_F64_TO_I32 },
-    { "i64_trunc_f64_u", "aot_intrinsic_f64_to_u64", AOT_INTRINSIC_FLAG_F64_TO_U64 },
-    { "i64_trunc_f32_s", "aot_intrinsic_f32_to_i64", AOT_INTRINSIC_FLAG_F32_TO_I64 },
-    { "i64_trunc_f32_u", "aot_intrinsic_f32_to_u64", AOT_INTRINSIC_FLAG_F32_TO_U64 },
-    { "i64_trunc_f64_s", "aot_intrinsic_f64_to_i64", AOT_INTRINSIC_FLAG_F64_TO_I64 },
-    { "f32_demote_f64", "aot_intrinsic_f64_to_f32", AOT_INTRINSIC_FLAG_F64_TO_F32 },
-    { "f64_promote_f32", "aot_intrinsic_f32_to_f64", AOT_INTRINSIC_FLAG_F32_TO_F64 },
-    { "f32_cmp", "aot_intrinsic_f32_cmp", AOT_INTRINSIC_FLAG_F32_CMP },
-    { "f64_cmp", "aot_intrinsic_f64_cmp", AOT_INTRINSIC_FLAG_F64_CMP },
-    { "i32.const", NULL, AOT_INTRINSIC_FLAG_I32_CONST },
-    { "i64.const", NULL, AOT_INTRINSIC_FLAG_I64_CONST },
-    { "f32.const", NULL, AOT_INTRINSIC_FLAG_F32_CONST },
-    { "f64.const", NULL, AOT_INTRINSIC_FLAG_F64_CONST },
-    { "i64.div_s", "aot_intrinsic_i64_div_s", AOT_INTRINSIC_FLAG_I64_DIV_S},
-    { "i32.div_s", "aot_intrinsic_i32_div_s", AOT_INTRINSIC_FLAG_I32_DIV_S},
-    { "i32.div_u", "aot_intrinsic_i32_div_u", AOT_INTRINSIC_FLAG_I32_DIV_U},
-    { "i32.rem_s", "aot_intrinsic_i32_rem_s", AOT_INTRINSIC_FLAG_I32_REM_S},
-    { "i32.rem_u", "aot_intrinsic_i32_rem_u", AOT_INTRINSIC_FLAG_I32_REM_U},
-    { "i64.div_u", "aot_intrinsic_i64_div_u", AOT_INTRINSIC_FLAG_I64_DIV_U},
-    { "i64.rem_s", "aot_intrinsic_i64_rem_s", AOT_INTRINSIC_FLAG_I64_REM_S},
-    { "i64.rem_u", "aot_intrinsic_i64_rem_u", AOT_INTRINSIC_FLAG_I64_REM_U},
-    { "i64.or", "aot_intrinsic_i64_bit_or", AOT_INTRINSIC_FLAG_I64_BIT_OR},
-    { "i64.and", "aot_intrinsic_i64_bit_and", AOT_INTRINSIC_FLAG_I64_BIT_AND},
-};
-/* clang-format on */
-
-static const uint32 g_intrinsic_count =
-    sizeof(g_intrinsic_mapping) / sizeof(aot_intrinsic);
-
 float32
 aot_intrinsic_fadd_f32(float32 a, float32 b)
 {
@@ -565,6 +485,88 @@ aot_intrinsic_i64_bit_and(uint64 l, uint64 r)
     return l & r;
 }
 
+#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
+
+typedef struct {
+    const char *llvm_intrinsic;
+    const char *native_intrinsic;
+    uint64 flag;
+} aot_intrinsic;
+
+/* clang-format off */
+static const aot_intrinsic g_intrinsic_mapping[] = {
+    { "llvm.experimental.constrained.fadd.f32", "aot_intrinsic_fadd_f32", AOT_INTRINSIC_FLAG_F32_FADD },
+    { "llvm.experimental.constrained.fadd.f64", "aot_intrinsic_fadd_f64", AOT_INTRINSIC_FLAG_F64_FADD },
+    { "llvm.experimental.constrained.fsub.f32", "aot_intrinsic_fsub_f32", AOT_INTRINSIC_FLAG_F32_FSUB },
+    { "llvm.experimental.constrained.fsub.f64", "aot_intrinsic_fsub_f64", AOT_INTRINSIC_FLAG_F64_FSUB },
+    { "llvm.experimental.constrained.fmul.f32", "aot_intrinsic_fmul_f32", AOT_INTRINSIC_FLAG_F32_FMUL },
+    { "llvm.experimental.constrained.fmul.f64", "aot_intrinsic_fmul_f64", AOT_INTRINSIC_FLAG_F64_FMUL },
+    { "llvm.experimental.constrained.fdiv.f32", "aot_intrinsic_fdiv_f32", AOT_INTRINSIC_FLAG_F32_FDIV },
+    { "llvm.experimental.constrained.fdiv.f64", "aot_intrinsic_fdiv_f64", AOT_INTRINSIC_FLAG_F64_FDIV },
+    { "llvm.fabs.f32", "aot_intrinsic_fabs_f32", AOT_INTRINSIC_FLAG_F32_FABS },
+    { "llvm.fabs.f64", "aot_intrinsic_fabs_f64", AOT_INTRINSIC_FLAG_F64_FABS },
+    { "llvm.ceil.f32", "aot_intrinsic_ceil_f32", AOT_INTRINSIC_FLAG_F32_CEIL },
+    { "llvm.ceil.f64", "aot_intrinsic_ceil_f64", AOT_INTRINSIC_FLAG_F64_CEIL },
+    { "llvm.floor.f32", "aot_intrinsic_floor_f32", AOT_INTRINSIC_FLAG_F32_FLOOR },
+    { "llvm.floor.f64", "aot_intrinsic_floor_f64", AOT_INTRINSIC_FLAG_F64_FLOOR },
+    { "llvm.trunc.f32", "aot_intrinsic_trunc_f32", AOT_INTRINSIC_FLAG_F32_TRUNC },
+    { "llvm.trunc.f64", "aot_intrinsic_trunc_f64", AOT_INTRINSIC_FLAG_F64_TRUNC },
+    { "llvm.rint.f32", "aot_intrinsic_rint_f32", AOT_INTRINSIC_FLAG_F32_RINT },
+    { "llvm.rint.f64", "aot_intrinsic_rint_f64", AOT_INTRINSIC_FLAG_F64_RINT },
+    { "llvm.sqrt.f32", "aot_intrinsic_sqrt_f32", AOT_INTRINSIC_FLAG_F32_SQRT },
+    { "llvm.sqrt.f64", "aot_intrinsic_sqrt_f64", AOT_INTRINSIC_FLAG_F64_SQRT },
+    { "llvm.copysign.f32", "aot_intrinsic_copysign_f32", AOT_INTRINSIC_FLAG_F32_COPYSIGN },
+    { "llvm.copysign.f64", "aot_intrinsic_copysign_f64", AOT_INTRINSIC_FLAG_F64_COPYSIGN },
+    { "llvm.minnum.f32", "aot_intrinsic_fmin_f32", AOT_INTRINSIC_FLAG_F32_MIN },
+    { "llvm.minnum.f64", "aot_intrinsic_fmin_f64", AOT_INTRINSIC_FLAG_F64_MIN },
+    { "llvm.maxnum.f32", "aot_intrinsic_fmax_f32", AOT_INTRINSIC_FLAG_F32_MAX },
+    { "llvm.maxnum.f64", "aot_intrinsic_fmax_f64", AOT_INTRINSIC_FLAG_F64_MAX },
+    { "llvm.ctlz.i32", "aot_intrinsic_clz_i32", AOT_INTRINSIC_FLAG_I32_CLZ },
+    { "llvm.ctlz.i64", "aot_intrinsic_clz_i64", AOT_INTRINSIC_FLAG_I64_CLZ },
+    { "llvm.cttz.i32", "aot_intrinsic_ctz_i32", AOT_INTRINSIC_FLAG_I32_CTZ },
+    { "llvm.cttz.i64", "aot_intrinsic_ctz_i64", AOT_INTRINSIC_FLAG_I64_CTZ },
+    { "llvm.ctpop.i32", "aot_intrinsic_popcnt_i32", AOT_INTRINSIC_FLAG_I32_POPCNT },
+    { "llvm.ctpop.i64", "aot_intrinsic_popcnt_i64", AOT_INTRINSIC_FLAG_I64_POPCNT },
+    { "f64_convert_i32_s", "aot_intrinsic_i32_to_f64", AOT_INTRINSIC_FLAG_I32_TO_F64 },
+    { "f64_convert_i32_u", "aot_intrinsic_u32_to_f64", AOT_INTRINSIC_FLAG_U32_TO_F64 },
+    { "f32_convert_i32_s", "aot_intrinsic_i32_to_f32", AOT_INTRINSIC_FLAG_I32_TO_F32 },
+    { "f32_convert_i32_u", "aot_intrinsic_u32_to_f32", AOT_INTRINSIC_FLAG_U32_TO_F32 },
+    { "f64_convert_i64_s", "aot_intrinsic_i64_to_f64", AOT_INTRINSIC_FLAG_I32_TO_F64 },
+    { "f64_convert_i64_u", "aot_intrinsic_u64_to_f64", AOT_INTRINSIC_FLAG_U64_TO_F64 },
+    { "f32_convert_i64_s", "aot_intrinsic_i64_to_f32", AOT_INTRINSIC_FLAG_I64_TO_F32 },
+    { "f32_convert_i64_u", "aot_intrinsic_u64_to_f32", AOT_INTRINSIC_FLAG_U64_TO_F32 },
+    { "i32_trunc_f32_u", "aot_intrinsic_f32_to_u32", AOT_INTRINSIC_FLAG_F32_TO_U32 },
+    { "i32_trunc_f32_s", "aot_intrinsic_f32_to_i32", AOT_INTRINSIC_FLAG_F32_TO_I32 },
+    { "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_F64_TO_U32 },
+    { "i32_trunc_f64_s", "aot_intrinsic_f64_to_i32", AOT_INTRINSIC_FLAG_F64_TO_I32 },
+    { "i64_trunc_f64_u", "aot_intrinsic_f64_to_u64", AOT_INTRINSIC_FLAG_F64_TO_U64 },
+    { "i64_trunc_f32_s", "aot_intrinsic_f32_to_i64", AOT_INTRINSIC_FLAG_F32_TO_I64 },
+    { "i64_trunc_f32_u", "aot_intrinsic_f32_to_u64", AOT_INTRINSIC_FLAG_F32_TO_U64 },
+    { "i64_trunc_f64_s", "aot_intrinsic_f64_to_i64", AOT_INTRINSIC_FLAG_F64_TO_I64 },
+    { "f32_demote_f64", "aot_intrinsic_f64_to_f32", AOT_INTRINSIC_FLAG_F64_TO_F32 },
+    { "f64_promote_f32", "aot_intrinsic_f32_to_f64", AOT_INTRINSIC_FLAG_F32_TO_F64 },
+    { "f32_cmp", "aot_intrinsic_f32_cmp", AOT_INTRINSIC_FLAG_F32_CMP },
+    { "f64_cmp", "aot_intrinsic_f64_cmp", AOT_INTRINSIC_FLAG_F64_CMP },
+    { "i32.const", NULL, AOT_INTRINSIC_FLAG_I32_CONST },
+    { "i64.const", NULL, AOT_INTRINSIC_FLAG_I64_CONST },
+    { "f32.const", NULL, AOT_INTRINSIC_FLAG_F32_CONST },
+    { "f64.const", NULL, AOT_INTRINSIC_FLAG_F64_CONST },
+    { "i64.div_s", "aot_intrinsic_i64_div_s", AOT_INTRINSIC_FLAG_I64_DIV_S},
+    { "i32.div_s", "aot_intrinsic_i32_div_s", AOT_INTRINSIC_FLAG_I32_DIV_S},
+    { "i32.div_u", "aot_intrinsic_i32_div_u", AOT_INTRINSIC_FLAG_I32_DIV_U},
+    { "i32.rem_s", "aot_intrinsic_i32_rem_s", AOT_INTRINSIC_FLAG_I32_REM_S},
+    { "i32.rem_u", "aot_intrinsic_i32_rem_u", AOT_INTRINSIC_FLAG_I32_REM_U},
+    { "i64.div_u", "aot_intrinsic_i64_div_u", AOT_INTRINSIC_FLAG_I64_DIV_U},
+    { "i64.rem_s", "aot_intrinsic_i64_rem_s", AOT_INTRINSIC_FLAG_I64_REM_S},
+    { "i64.rem_u", "aot_intrinsic_i64_rem_u", AOT_INTRINSIC_FLAG_I64_REM_U},
+    { "i64.or", "aot_intrinsic_i64_bit_or", AOT_INTRINSIC_FLAG_I64_BIT_OR},
+    { "i64.and", "aot_intrinsic_i64_bit_and", AOT_INTRINSIC_FLAG_I64_BIT_AND},
+};
+/* clang-format on */
+
+static const uint32 g_intrinsic_count =
+    sizeof(g_intrinsic_mapping) / sizeof(aot_intrinsic);
+
 const char *
 aot_intrinsic_get_symbol(const char *llvm_intrinsic)
 {
@@ -577,8 +579,6 @@ aot_intrinsic_get_symbol(const char *llvm_intrinsic)
     return NULL;
 }
 
-#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
-
 static void
 add_intrinsic_capability(AOTCompContext *comp_ctx, uint64 flag)
 {

+ 1 - 1
core/iwasm/aot/aot_intrinsic.h

@@ -287,10 +287,10 @@ aot_intrinsic_i64_bit_or(uint64 l, uint64 r);
 uint64
 aot_intrinsic_i64_bit_and(uint64 l, uint64 r);
 
+#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
 const char *
 aot_intrinsic_get_symbol(const char *llvm_intrinsic);
 
-#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
 bool
 aot_intrinsic_check_capability(const AOTCompContext *comp_ctx,
                                const char *llvm_intrinsic);

+ 144 - 216
core/iwasm/aot/aot_loader.c

@@ -16,6 +16,10 @@
 #include "debug/jit_debug.h"
 #endif
 
+#if WASM_ENABLE_LINUX_PERF != 0
+#include "aot_perf_map.h"
+#endif
+
 #define YMM_PLT_PREFIX "__ymm@"
 #define XMM_PLT_PREFIX "__xmm@"
 #define REAL_PLT_PREFIX "__real@"
@@ -289,55 +293,6 @@ loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
     return mem;
 }
 
-static char *
-const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
-#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
-                     bool is_vram_word_align,
-#endif
-                     char *error_buf, uint32 error_buf_size)
-{
-    HashMap *set = module->const_str_set;
-    char *c_str, *value;
-
-    /* Create const string set if it isn't created */
-    if (!set
-        && !(set = module->const_str_set = bh_hash_map_create(
-                 32, false, (HashFunc)wasm_string_hash,
-                 (KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) {
-        set_error_buf(error_buf, error_buf_size,
-                      "create const string set failed");
-        return NULL;
-    }
-
-    /* Lookup const string set, use the string if found */
-    if (!(c_str = loader_malloc((uint32)len, error_buf, error_buf_size))) {
-        return NULL;
-    }
-#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
-    if (is_vram_word_align) {
-        bh_memcpy_wa(c_str, (uint32)len, str, (uint32)len);
-    }
-    else
-#endif
-    {
-        bh_memcpy_s(c_str, len, str, (uint32)len);
-    }
-
-    if ((value = bh_hash_map_find(set, c_str))) {
-        wasm_runtime_free(c_str);
-        return value;
-    }
-
-    if (!bh_hash_map_insert(set, c_str, c_str)) {
-        set_error_buf(error_buf, error_buf_size,
-                      "insert string to hash map failed");
-        wasm_runtime_free(c_str);
-        return NULL;
-    }
-
-    return c_str;
-}
-
 static char *
 load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
             bool is_load_from_file_buf,
@@ -359,9 +314,9 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
     }
 #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
     else if (is_vram_word_align) {
-        if (!(str = const_str_set_insert((uint8 *)p, str_len, module,
-                                         is_vram_word_align, error_buf,
-                                         error_buf_size))) {
+        if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module,
+                                             is_vram_word_align, error_buf,
+                                             error_buf_size))) {
             goto fail;
         }
     }
@@ -378,11 +333,11 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
            after loading, we must create another string and insert it
            into const string set */
         bh_assert(p[str_len - 1] == '\0');
-        if (!(str = const_str_set_insert((uint8 *)p, str_len, module,
+        if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module,
 #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
-                                         is_vram_word_align,
+                                             is_vram_word_align,
 #endif
-                                         error_buf, error_buf_size))) {
+                                             error_buf, error_buf_size))) {
             goto fail;
         }
     }
@@ -1479,9 +1434,20 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
         read_uint64(buf, buf_end, init_expr_value);
 #if WASM_ENABLE_GC != 0
         if (wasm_is_type_multi_byte_type(elem_type)) {
-            /* TODO: check ref_type */
-            read_uint16(buf, buf_end, reftype.ref_ht_common.ref_type);
-            read_uint16(buf, buf_end, reftype.ref_ht_common.nullable);
+            uint16 ref_type, nullable;
+            read_uint16(buf, buf_end, ref_type);
+            if (elem_type != ref_type) {
+                set_error_buf(error_buf, error_buf_size, "invalid elem type");
+                return false;
+            }
+            reftype.ref_ht_common.ref_type = (uint8)ref_type;
+            read_uint16(buf, buf_end, nullable);
+            if (nullable != 0 && nullable != 1) {
+                set_error_buf(error_buf, error_buf_size,
+                              "invalid nullable value");
+                return false;
+            }
+            reftype.ref_ht_common.nullable = (uint8)nullable;
             read_uint32(buf, buf_end, reftype.ref_ht_common.heap_type);
         }
         else
@@ -1559,30 +1525,42 @@ fail:
     return false;
 }
 
+static void
+destroy_type(AOTType *type)
+{
+#if WASM_ENABLE_GC != 0
+    if (type->ref_count > 1) {
+        /* The type is referenced by other types
+           of current aot module */
+        type->ref_count--;
+        return;
+    }
+
+    if (type->type_flag == WASM_TYPE_FUNC) {
+        AOTFuncType *func_type = (AOTFuncType *)type;
+        if (func_type->ref_type_maps != NULL) {
+            bh_assert(func_type->ref_type_map_count > 0);
+            wasm_runtime_free(func_type->ref_type_maps);
+        }
+    }
+    else if (type->type_flag == WASM_TYPE_STRUCT) {
+        AOTStructType *struct_type = (AOTStructType *)type;
+        if (struct_type->ref_type_maps != NULL) {
+            bh_assert(struct_type->ref_type_map_count > 0);
+            wasm_runtime_free(struct_type->ref_type_maps);
+        }
+    }
+#endif
+    wasm_runtime_free(type);
+}
+
 static void
 destroy_types(AOTType **types, uint32 count)
 {
     uint32 i;
     for (i = 0; i < count; i++) {
-
         if (types[i]) {
-#if WASM_ENABLE_GC != 0
-            if (types[i]->type_flag == WASM_TYPE_FUNC) {
-                AOTFuncType *func_type = (AOTFuncType *)types[i];
-                if (func_type->ref_type_maps != NULL) {
-                    bh_assert(func_type->ref_type_map_count > 0);
-                    wasm_runtime_free(func_type->ref_type_maps);
-                }
-            }
-            else if (types[i]->type_flag == WASM_TYPE_STRUCT) {
-                AOTStructType *struct_type = (AOTStructType *)types[i];
-                if (struct_type->ref_type_maps != NULL) {
-                    bh_assert(struct_type->ref_type_map_count > 0);
-                    wasm_runtime_free(struct_type->ref_type_maps);
-                }
-            }
-#endif
-            wasm_runtime_free(types[i]);
+            destroy_type(types[i]);
         }
     }
     wasm_runtime_free(types);
@@ -1590,14 +1568,17 @@ destroy_types(AOTType **types, uint32 count)
 
 #if WASM_ENABLE_GC != 0
 static void
-init_base_type(AOTType *base_type, uint16 type_flag, bool is_sub_final,
-               uint32 parent_type_idx, uint16 rec_count, uint16 rec_idx)
+init_base_type(AOTType *base_type, uint32 type_idx, uint16 type_flag,
+               bool is_sub_final, uint32 parent_type_idx, uint16 rec_count,
+               uint16 rec_idx)
 {
     base_type->type_flag = type_flag;
+    base_type->ref_count = 1;
     base_type->is_sub_final = is_sub_final;
     base_type->parent_type_idx = parent_type_idx;
     base_type->rec_count = rec_count;
     base_type->rec_idx = rec_idx;
+    base_type->rec_begin_type_idx = type_idx - rec_idx;
 }
 
 static bool
@@ -1610,7 +1591,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
     uint32 i, j;
     uint32 type_flag, param_cell_num, ret_cell_num;
     uint16 param_count, result_count, ref_type_map_count, rec_count, rec_idx;
-    bool is_sub_final;
+    bool is_equivalence_type, is_sub_final;
     uint32 parent_type_idx;
     WASMRefType ref_type;
 
@@ -1624,12 +1605,31 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
 
     /* Create each type */
     for (i = 0; i < module->type_count; i++) {
-
         buf = align_ptr(buf, 4);
 
         /* Read base type info */
         read_uint16(buf, buf_end, type_flag);
-        read_uint16(buf, buf_end, is_sub_final);
+
+        read_uint8(buf, buf_end, is_equivalence_type);
+        /* If there is an equivalence type, re-use it */
+        if (is_equivalence_type) {
+            uint8 u8;
+            /* padding */
+            read_uint8(buf, buf_end, u8);
+            (void)u8;
+
+            read_uint32(buf, buf_end, j);
+            if (module->types[j]->ref_count == UINT16_MAX) {
+                set_error_buf(error_buf, error_buf_size,
+                              "wasm type's ref count too large");
+                goto fail;
+            }
+            module->types[j]->ref_count++;
+            module->types[i] = module->types[j];
+            continue;
+        }
+
+        read_uint8(buf, buf_end, is_sub_final);
         read_uint32(buf, buf_end, parent_type_idx);
         read_uint16(buf, buf_end, rec_count);
         read_uint16(buf, buf_end, rec_idx);
@@ -1654,7 +1654,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
 
             types[i] = (AOTType *)func_type;
 
-            init_base_type((AOTType *)func_type, type_flag, is_sub_final,
+            init_base_type((AOTType *)func_type, i, type_flag, is_sub_final,
                            parent_type_idx, rec_count, rec_idx);
             func_type->param_count = param_count;
             func_type->result_count = result_count;
@@ -1760,7 +1760,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
             offset = (uint32)offsetof(WASMStructObject, field_data);
             types[i] = (AOTType *)struct_type;
 
-            init_base_type((AOTType *)struct_type, type_flag, is_sub_final,
+            init_base_type((AOTType *)struct_type, i, type_flag, is_sub_final,
                            parent_type_idx, rec_count, rec_idx);
             struct_type->field_count = field_count;
             struct_type->ref_type_map_count = ref_type_map_count;
@@ -1846,7 +1846,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
 
             types[i] = (AOTType *)array_type;
 
-            init_base_type((AOTType *)array_type, type_flag, is_sub_final,
+            init_base_type((AOTType *)array_type, i, type_flag, is_sub_final,
                            parent_type_idx, rec_count, rec_idx);
             read_uint16(buf, buf_end, array_type->elem_flags);
             read_uint8(buf, buf_end, array_type->elem_type);
@@ -1875,7 +1875,6 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
             if (rec_count == 0) {
                 bh_assert(rec_idx == 0);
             }
-
             for (j = i - rec_idx; j <= i; j++) {
                 AOTType *cur_type = module->types[j];
                 parent_type_idx = cur_type->parent_type_idx;
@@ -1884,6 +1883,11 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
 
                     module->types[j]->parent_type = parent_type;
                     module->types[j]->root_type = parent_type->root_type;
+                    if (parent_type->inherit_depth == UINT16_MAX) {
+                        set_error_buf(error_buf, error_buf_size,
+                                      "parent type's inherit depth too large");
+                        goto fail;
+                    }
                     module->types[j]->inherit_depth =
                         parent_type->inherit_depth + 1;
                 }
@@ -1901,7 +1905,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
                     AOTType *parent_type = module->types[parent_type_idx];
                     /* subtyping has been checked during compilation */
                     bh_assert(wasm_type_is_subtype_of(
-                        module->types[j], parent_type, module->types, i));
+                        module->types[j], parent_type, module->types, i + 1));
                     (void)parent_type;
                 }
             }
@@ -2423,13 +2427,22 @@ load_init_data_section(const uint8 *buf, const uint8 *buf_end,
     }
 
     read_uint32(p, p_end, module->aux_data_end_global_index);
-    read_uint32(p, p_end, module->aux_data_end);
+    read_uint64(p, p_end, module->aux_data_end);
     read_uint32(p, p_end, module->aux_heap_base_global_index);
-    read_uint32(p, p_end, module->aux_heap_base);
+    read_uint64(p, p_end, module->aux_heap_base);
     read_uint32(p, p_end, module->aux_stack_top_global_index);
-    read_uint32(p, p_end, module->aux_stack_bottom);
+    read_uint64(p, p_end, module->aux_stack_bottom);
     read_uint32(p, p_end, module->aux_stack_size);
 
+    if (module->aux_data_end >= MAX_LINEAR_MEMORY_SIZE
+        || module->aux_heap_base >= MAX_LINEAR_MEMORY_SIZE
+        || module->aux_stack_bottom >= MAX_LINEAR_MEMORY_SIZE) {
+        set_error_buf(
+            error_buf, error_buf_size,
+            "invalid range of aux_date_end/aux_heap_base/aux_stack_bottom");
+        return false;
+    }
+
     if (!load_object_data_sections_info(&p, p_end, module,
                                         is_load_from_file_buf, error_buf,
                                         error_buf_size))
@@ -2500,15 +2513,26 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
     const uint8 *p = buf, *p_end = buf_end;
     uint32 i;
     uint64 size, text_offset;
+    uint32 func_count = module->func_count;
+
+#if defined(BUILD_TARGET_XTENSA)
+    /*
+     * For Xtensa XIP, real func_count is doubled, including aot_func and
+     * aot_func_internal, so need to multipy func_count by 2 here.
+     */
+    if (module->is_indirect_mode) {
+        func_count *= 2;
+    }
+#endif
 
-    size = sizeof(void *) * (uint64)module->func_count;
+    size = sizeof(void *) * (uint64)func_count;
     if (size > 0
         && !(module->func_ptrs =
                  loader_malloc(size, error_buf, error_buf_size))) {
         return false;
     }
 
-    for (i = 0; i < module->func_count; i++) {
+    for (i = 0; i < func_count; i++) {
         if (sizeof(void *) == 8) {
             read_uint64(p, p_end, text_offset);
         }
@@ -2543,14 +2567,14 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
         module->start_function = NULL;
     }
 
-    size = sizeof(uint32) * (uint64)module->func_count;
+    size = sizeof(uint32) * (uint64)func_count;
     if (size > 0
         && !(module->func_type_indexes =
                  loader_malloc(size, error_buf, error_buf_size))) {
         return false;
     }
 
-    for (i = 0; i < module->func_count; i++) {
+    for (i = 0; i < func_count; i++) {
         read_uint32(p, p_end, module->func_type_indexes[i]);
         if (module->func_type_indexes[i] >= module->type_count) {
             set_error_buf(error_buf, error_buf_size, "unknown type");
@@ -2897,6 +2921,17 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
             }
             symbol_addr = module->func_ptrs[func_index];
         }
+        else if (!strncmp(symbol, "_" AOT_FUNC_INTERNAL_PREFIX,
+                          strlen("_" AOT_FUNC_INTERNAL_PREFIX))) {
+            p = symbol + strlen("_" AOT_FUNC_INTERNAL_PREFIX);
+            if (*p == '\0'
+                || (func_index = (uint32)atoi(p)) > module->func_count) {
+                set_error_buf_v(error_buf, error_buf_size, "invalid symbol %s",
+                                symbol);
+                goto check_symbol_fail;
+            }
+            symbol_addr = module->func_ptrs[func_index];
+        }
 #endif
         else if (is_text_section(symbol)) {
             symbol_addr = module->code;
@@ -3260,37 +3295,26 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
             bh_memcpy_s(symbol_name_buf, (uint32)sizeof(symbol_name_buf),
                         symbol_name, symbol_name_len);
 
-            if ((group_name_len == strlen(".text")
-                 || (module->is_indirect_mode
-                     && group_name_len == strlen(".text") + 1))
+            /* aot compiler emits string with '\0' since 2.0.0 */
+            if (group_name_len == strlen(".text") + 1
                 && !strncmp(group_name, ".text", strlen(".text"))) {
-                if ((symbol_name_len == strlen(YMM_PLT_PREFIX) + 64
-                     || (module->is_indirect_mode
-                         && symbol_name_len == strlen(YMM_PLT_PREFIX) + 64 + 1))
+                /* aot compiler emits string with '\0' since 2.0.0 */
+                if (symbol_name_len == strlen(YMM_PLT_PREFIX) + 64 + 1
                     && !strncmp(symbol_name, YMM_PLT_PREFIX,
                                 strlen(YMM_PLT_PREFIX))) {
                     module->ymm_plt_count++;
                 }
-                else if ((symbol_name_len == strlen(XMM_PLT_PREFIX) + 32
-                          || (module->is_indirect_mode
-                              && symbol_name_len
-                                     == strlen(XMM_PLT_PREFIX) + 32 + 1))
+                else if (symbol_name_len == strlen(XMM_PLT_PREFIX) + 32 + 1
                          && !strncmp(symbol_name, XMM_PLT_PREFIX,
                                      strlen(XMM_PLT_PREFIX))) {
                     module->xmm_plt_count++;
                 }
-                else if ((symbol_name_len == strlen(REAL_PLT_PREFIX) + 16
-                          || (module->is_indirect_mode
-                              && symbol_name_len
-                                     == strlen(REAL_PLT_PREFIX) + 16 + 1))
+                else if (symbol_name_len == strlen(REAL_PLT_PREFIX) + 16 + 1
                          && !strncmp(symbol_name, REAL_PLT_PREFIX,
                                      strlen(REAL_PLT_PREFIX))) {
                     module->real_plt_count++;
                 }
-                else if ((symbol_name_len >= strlen(REAL_PLT_PREFIX) + 8
-                          || (module->is_indirect_mode
-                              && symbol_name_len
-                                     == strlen(REAL_PLT_PREFIX) + 8 + 1))
+                else if (symbol_name_len >= strlen(REAL_PLT_PREFIX) + 8 + 1
                          && !strncmp(symbol_name, REAL_PLT_PREFIX,
                                      strlen(REAL_PLT_PREFIX))) {
                     module->float_plt_count++;
@@ -3608,104 +3632,6 @@ fail:
     return ret;
 }
 
-#if WASM_ENABLE_LINUX_PERF != 0
-struct func_info {
-    uint32 idx;
-    void *ptr;
-};
-
-static uint32
-get_func_size(const AOTModule *module, struct func_info *sorted_func_ptrs,
-              uint32 idx)
-{
-    uint32 func_sz;
-
-    if (idx == module->func_count - 1)
-        func_sz = (uintptr_t)module->code + module->code_size
-                  - (uintptr_t)(sorted_func_ptrs[idx].ptr);
-    else
-        func_sz = (uintptr_t)(sorted_func_ptrs[idx + 1].ptr)
-                  - (uintptr_t)(sorted_func_ptrs[idx].ptr);
-
-    return func_sz;
-}
-
-static int
-compare_func_ptrs(const void *f1, const void *f2)
-{
-    return (intptr_t)((struct func_info *)f1)->ptr
-           - (intptr_t)((struct func_info *)f2)->ptr;
-}
-
-static struct func_info *
-sort_func_ptrs(const AOTModule *module, char *error_buf, uint32 error_buf_size)
-{
-    uint64 content_len;
-    struct func_info *sorted_func_ptrs;
-    unsigned i;
-
-    content_len = (uint64)sizeof(struct func_info) * module->func_count;
-    sorted_func_ptrs = loader_malloc(content_len, error_buf, error_buf_size);
-    if (!sorted_func_ptrs)
-        return NULL;
-
-    for (i = 0; i < module->func_count; i++) {
-        sorted_func_ptrs[i].idx = i;
-        sorted_func_ptrs[i].ptr = module->func_ptrs[i];
-    }
-
-    qsort(sorted_func_ptrs, module->func_count, sizeof(struct func_info),
-          compare_func_ptrs);
-
-    return sorted_func_ptrs;
-}
-
-static bool
-create_perf_map(const AOTModule *module, char *error_buf, uint32 error_buf_size)
-{
-    struct func_info *sorted_func_ptrs = NULL;
-    char perf_map_info[128] = { 0 };
-    FILE *perf_map = NULL;
-    uint32 i;
-    pid_t pid = getpid();
-    bool ret = false;
-
-    sorted_func_ptrs = sort_func_ptrs(module, error_buf, error_buf_size);
-    if (!sorted_func_ptrs)
-        goto quit;
-
-    snprintf(perf_map_info, 128, "/tmp/perf-%d.map", pid);
-    perf_map = fopen(perf_map_info, "w");
-    if (!perf_map) {
-        LOG_WARNING("warning: can't create /tmp/perf-%d.map, because %s", pid,
-                    strerror(errno));
-        goto quit;
-    }
-
-    for (i = 0; i < module->func_count; i++) {
-        memset(perf_map_info, 0, 128);
-        snprintf(perf_map_info, 128, "%lx  %x  aot_func#%u\n",
-                 (uintptr_t)sorted_func_ptrs[i].ptr,
-                 get_func_size(module, sorted_func_ptrs, i),
-                 sorted_func_ptrs[i].idx);
-
-        fwrite(perf_map_info, 1, strlen(perf_map_info), perf_map);
-    }
-
-    LOG_VERBOSE("generate /tmp/perf-%d.map", pid);
-    ret = true;
-
-quit:
-    if (sorted_func_ptrs)
-        free(sorted_func_ptrs);
-
-    if (perf_map)
-        fclose(perf_map);
-
-    return ret;
-}
-#endif /* WASM_ENABLE_LINUX_PERF != 0*/
-
 static bool
 load_from_sections(AOTModule *module, AOTSection *sections,
                    bool is_load_from_file_buf, char *error_buf,
@@ -3896,7 +3822,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
 }
 
 static AOTModule *
-create_module(char *error_buf, uint32 error_buf_size)
+create_module(char *name, char *error_buf, uint32 error_buf_size)
 {
     AOTModule *module =
         loader_malloc(sizeof(AOTModule), error_buf, error_buf_size);
@@ -3908,6 +3834,8 @@ create_module(char *error_buf, uint32 error_buf_size)
 
     module->module_type = Wasm_Module_AoT;
 
+    module->name = name;
+
 #if WASM_ENABLE_MULTI_MODULE != 0
     module->import_module_list = &module->import_module_list_head;
     ret = bh_list_init(module->import_module_list);
@@ -3942,7 +3870,7 @@ AOTModule *
 aot_load_from_sections(AOTSection *section_list, char *error_buf,
                        uint32 error_buf_size)
 {
-    AOTModule *module = create_module(error_buf, error_buf_size);
+    AOTModule *module = create_module("", error_buf, error_buf_size);
 
     if (!module)
         return NULL;
@@ -4188,7 +4116,7 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
 
 #if WASM_ENABLE_LINUX_PERF != 0
     if (wasm_runtime_get_linux_perf())
-        if (!create_perf_map(module, error_buf, error_buf_size))
+        if (!aot_create_perf_map(module, error_buf, error_buf_size))
             goto fail;
 #endif
 
@@ -4198,10 +4126,10 @@ fail:
 }
 
 AOTModule *
-aot_load_from_aot_file(const uint8 *buf, uint32 size, char *error_buf,
-                       uint32 error_buf_size)
+aot_load_from_aot_file(const uint8 *buf, uint32 size, const LoadArgs *args,
+                       char *error_buf, uint32 error_buf_size)
 {
-    AOTModule *module = create_module(error_buf, error_buf_size);
+    AOTModule *module = create_module(args->name, error_buf, error_buf_size);
 
     if (!module)
         return NULL;
@@ -4395,7 +4323,7 @@ aot_unload(AOTModule *module)
         }
 
         if (module->string_literal_ptrs) {
-            wasm_runtime_free(module->string_literal_ptrs);
+            wasm_runtime_free((void *)module->string_literal_ptrs);
         }
     }
 #endif

+ 120 - 0
core/iwasm/aot/aot_perf_map.c

@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "aot_perf_map.h"
+#include "bh_log.h"
+#include "bh_platform.h"
+
+#if WASM_ENABLE_LINUX_PERF != 0
+struct func_info {
+    uint32 idx;
+    void *ptr;
+};
+
+static uint32
+get_func_size(const AOTModule *module, struct func_info *sorted_func_ptrs,
+              uint32 idx)
+{
+    uint32 func_sz;
+
+    if (idx == module->func_count - 1)
+        func_sz = (uintptr_t)module->code + module->code_size
+                  - (uintptr_t)(sorted_func_ptrs[idx].ptr);
+    else
+        func_sz = (uintptr_t)(sorted_func_ptrs[idx + 1].ptr)
+                  - (uintptr_t)(sorted_func_ptrs[idx].ptr);
+
+    return func_sz;
+}
+
+static int
+compare_func_ptrs(const void *f1, const void *f2)
+{
+    return (intptr_t)((struct func_info *)f1)->ptr
+           - (intptr_t)((struct func_info *)f2)->ptr;
+}
+
+static struct func_info *
+sort_func_ptrs(const AOTModule *module, char *error_buf, uint32 error_buf_size)
+{
+    uint64 content_len;
+    struct func_info *sorted_func_ptrs;
+    unsigned i;
+
+    content_len = (uint64)sizeof(struct func_info) * module->func_count;
+    sorted_func_ptrs = wasm_runtime_malloc(content_len);
+    if (!sorted_func_ptrs) {
+        snprintf(error_buf, error_buf_size,
+                 "allocate memory failed when creating perf map");
+        return NULL;
+    }
+
+    for (i = 0; i < module->func_count; i++) {
+        sorted_func_ptrs[i].idx = i;
+        sorted_func_ptrs[i].ptr = module->func_ptrs[i];
+    }
+
+    qsort(sorted_func_ptrs, module->func_count, sizeof(struct func_info),
+          compare_func_ptrs);
+
+    return sorted_func_ptrs;
+}
+
+bool
+aot_create_perf_map(const AOTModule *module, char *error_buf,
+                    uint32 error_buf_size)
+{
+    struct func_info *sorted_func_ptrs = NULL;
+    char perf_map_path[64] = { 0 };
+    char perf_map_info[128] = { 0 };
+    FILE *perf_map = NULL;
+    uint32 i;
+    pid_t pid = getpid();
+    bool ret = false;
+
+    sorted_func_ptrs = sort_func_ptrs(module, error_buf, error_buf_size);
+    if (!sorted_func_ptrs)
+        goto quit;
+
+    snprintf(perf_map_path, sizeof(perf_map_path) - 1, "/tmp/perf-%d.map", pid);
+    perf_map = fopen(perf_map_path, "a");
+    if (!perf_map) {
+        LOG_WARNING("warning: can't create /tmp/perf-%d.map, because %s", pid,
+                    strerror(errno));
+        goto quit;
+    }
+
+    const char *module_name = aot_get_module_name((AOTModule *)module);
+    for (i = 0; i < module->func_count; i++) {
+        memset(perf_map_info, 0, 128);
+        if (strlen(module_name) > 0)
+            snprintf(perf_map_info, 128, "%lx  %x  [%s]#aot_func#%u\n",
+                     (uintptr_t)sorted_func_ptrs[i].ptr,
+                     get_func_size(module, sorted_func_ptrs, i), module_name,
+                     sorted_func_ptrs[i].idx);
+        else
+            snprintf(perf_map_info, 128, "%lx  %x  aot_func#%u\n",
+                     (uintptr_t)sorted_func_ptrs[i].ptr,
+                     get_func_size(module, sorted_func_ptrs, i),
+                     sorted_func_ptrs[i].idx);
+
+        /* fwrite() is thread safe */
+        fwrite(perf_map_info, 1, strlen(perf_map_info), perf_map);
+    }
+
+    LOG_VERBOSE("write map information from %s into /tmp/perf-%d.map",
+                module_name, pid);
+    ret = true;
+
+quit:
+    if (sorted_func_ptrs)
+        wasm_runtime_free(sorted_func_ptrs);
+
+    if (perf_map)
+        fclose(perf_map);
+
+    return ret;
+}
+#endif /* WASM_ENABLE_LINUX_PERF != 0 */

+ 15 - 0
core/iwasm/aot/aot_perf_map.h

@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _AOT_PERF_MAP_H_
+#define _AOT_PERF_MAP_H_
+
+#include "aot_runtime.h"
+
+bool
+aot_create_perf_map(const AOTModule *module, char *error_buf,
+                    uint32 error_buf_size);
+
+#endif /* _AOT_PERF_MAP_H_ */

+ 6 - 1
core/iwasm/aot/aot_reloc.h

@@ -62,6 +62,7 @@ typedef struct {
 #define REG_AOT_TRACE_SYM()
 #endif
 
+#if WASM_ENABLE_AOT_INTRINSICS != 0
 #define REG_INTRINSIC_SYM()               \
     REG_SYM(aot_intrinsic_fabs_f32),      \
     REG_SYM(aot_intrinsic_fabs_f64),      \
@@ -124,7 +125,10 @@ typedef struct {
     REG_SYM(aot_intrinsic_i32_div_s),     \
     REG_SYM(aot_intrinsic_i32_div_u),     \
     REG_SYM(aot_intrinsic_i32_rem_s),     \
-    REG_SYM(aot_intrinsic_i32_rem_u),     \
+    REG_SYM(aot_intrinsic_i32_rem_u),
+#else
+#define REG_INTRINSIC_SYM()
+#endif
 
 #if WASM_ENABLE_STATIC_PGO != 0
 #define REG_LLVM_PGO_SYM()               \
@@ -139,6 +143,7 @@ typedef struct {
     REG_SYM(aot_array_init_with_data),     \
     REG_SYM(aot_create_func_obj),          \
     REG_SYM(aot_obj_is_instance_of),       \
+    REG_SYM(aot_func_type_is_super_of),    \
     REG_SYM(aot_rtt_type_new),             \
     REG_SYM(wasm_array_obj_copy),          \
     REG_SYM(wasm_array_obj_new),           \

+ 271 - 141
core/iwasm/aot/aot_runtime.c

@@ -47,15 +47,15 @@ bh_static_assert(offsetof(AOTModuleInstance, func_type_indexes)
                  == 6 * sizeof(uint64));
 bh_static_assert(offsetof(AOTModuleInstance, cur_exception)
                  == 13 * sizeof(uint64));
+bh_static_assert(offsetof(AOTModuleInstance, c_api_func_imports)
+                 == 13 * sizeof(uint64) + 128 + 7 * sizeof(uint64));
 bh_static_assert(offsetof(AOTModuleInstance, global_table_data)
-                 == 13 * sizeof(uint64) + 128 + 11 * sizeof(uint64));
+                 == 13 * sizeof(uint64) + 128 + 14 * sizeof(uint64));
 
-bh_static_assert(sizeof(AOTMemoryInstance) == 104);
+bh_static_assert(sizeof(AOTMemoryInstance) == 120);
 bh_static_assert(offsetof(AOTTableInstance, elems) == 24);
 
 bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0);
-bh_static_assert(offsetof(AOTModuleInstanceExtra, common.c_api_func_imports)
-                 == sizeof(uint64));
 
 bh_static_assert(sizeof(CApiFuncImport) == sizeof(uintptr_t) * 3);
 
@@ -783,15 +783,19 @@ static AOTMemoryInstance *
 memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
                    AOTModule *module, AOTMemoryInstance *memory_inst,
                    AOTMemory *memory, uint32 memory_idx, uint32 heap_size,
-                   char *error_buf, uint32 error_buf_size)
+                   uint32 max_memory_pages, char *error_buf,
+                   uint32 error_buf_size)
 {
     void *heap_handle;
     uint32 num_bytes_per_page = memory->num_bytes_per_page;
     uint32 init_page_count = memory->mem_init_page_count;
-    uint32 max_page_count = memory->mem_max_page_count;
-    uint32 inc_page_count, aux_heap_base, global_idx;
+    uint32 max_page_count =
+        wasm_runtime_get_max_mem(max_memory_pages, memory->mem_init_page_count,
+                                 memory->mem_max_page_count);
+    uint32 inc_page_count, global_idx;
     uint32 bytes_of_last_page, bytes_to_page_end;
-    uint32 heap_offset = num_bytes_per_page * init_page_count;
+    uint64 aux_heap_base,
+        heap_offset = (uint64)num_bytes_per_page * init_page_count;
     uint64 memory_data_size, max_memory_data_size;
     uint8 *p = NULL, *global_addr;
 
@@ -816,6 +820,15 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
         heap_size = 0;
     }
 
+    /* If initial memory is the largest size allowed, disallowing insert host
+     * managed heap */
+    if (heap_size > 0 && heap_offset == MAX_LINEAR_MEMORY_SIZE) {
+        set_error_buf(error_buf, error_buf_size,
+                      "failed to insert app heap into linear memory, "
+                      "try using `--heap-size=0` option");
+        return NULL;
+    }
+
     if (init_page_count == max_page_count && init_page_count == 1) {
         /* If only one page and at most one page, we just append
            the app heap to the end of linear memory, enlarge the
@@ -839,7 +852,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
         }
         else if (module->aux_heap_base_global_index != (uint32)-1
                  && module->aux_heap_base
-                        < num_bytes_per_page * init_page_count) {
+                        < (uint64)num_bytes_per_page * init_page_count) {
             /* Insert app heap before __heap_base */
             aux_heap_base = module->aux_heap_base;
             bytes_of_last_page = aux_heap_base % num_bytes_per_page;
@@ -866,15 +879,15 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
                          - module->import_global_count;
             global_addr = module_inst->global_data
                           + module->globals[global_idx].data_offset;
-            *(uint32 *)global_addr = aux_heap_base;
-            LOG_VERBOSE("Reset __heap_base global to %u", aux_heap_base);
+            *(uint32 *)global_addr = (uint32)aux_heap_base;
+            LOG_VERBOSE("Reset __heap_base global to %" PRIu64, aux_heap_base);
         }
         else {
             /* Insert app heap before new page */
             inc_page_count =
                 (heap_size + num_bytes_per_page - 1) / num_bytes_per_page;
-            heap_offset = num_bytes_per_page * init_page_count;
-            heap_size = num_bytes_per_page * inc_page_count;
+            heap_offset = (uint64)num_bytes_per_page * init_page_count;
+            heap_size = (uint64)num_bytes_per_page * inc_page_count;
             if (heap_size > 0)
                 heap_size -= 1 * BH_KB;
         }
@@ -886,34 +899,26 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
                           "try using `--heap-size=0` option");
             return NULL;
         }
-        else if (init_page_count == DEFAULT_MAX_PAGES) {
-            num_bytes_per_page = UINT32_MAX;
-            init_page_count = max_page_count = 1;
-        }
         if (max_page_count > DEFAULT_MAX_PAGES)
             max_page_count = DEFAULT_MAX_PAGES;
     }
-    else { /* heap_size == 0 */
-        if (init_page_count == DEFAULT_MAX_PAGES) {
-            num_bytes_per_page = UINT32_MAX;
-            init_page_count = max_page_count = 1;
-        }
-    }
 
     LOG_VERBOSE("Memory instantiate:");
     LOG_VERBOSE("  page bytes: %u, init pages: %u, max pages: %u",
                 num_bytes_per_page, init_page_count, max_page_count);
-    LOG_VERBOSE("  data offset: %u, stack size: %d", module->aux_data_end,
-                module->aux_stack_size);
-    LOG_VERBOSE("  heap offset: %u, heap size: %d\n", heap_offset, heap_size);
+    LOG_VERBOSE("  data offset: %" PRIu64 ", stack size: %d",
+                module->aux_data_end, module->aux_stack_size);
+    LOG_VERBOSE("  heap offset: %" PRIu64 ", heap size: %d\n", heap_offset,
+                heap_size);
 
     max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
-    bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB);
+    bh_assert(max_memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
     (void)max_memory_data_size;
 
-    if (wasm_allocate_linear_memory(&p, is_shared_memory, num_bytes_per_page,
-                                    init_page_count, max_page_count,
-                                    &memory_data_size)
+    /* TODO: memory64 uses is_memory64 flag */
+    if (wasm_allocate_linear_memory(&p, is_shared_memory, false,
+                                    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");
@@ -924,11 +929,11 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
     memory_inst->num_bytes_per_page = num_bytes_per_page;
     memory_inst->cur_page_count = init_page_count;
     memory_inst->max_page_count = max_page_count;
-    memory_inst->memory_data_size = (uint32)memory_data_size;
+    memory_inst->memory_data_size = memory_data_size;
 
     /* Init memory info */
     memory_inst->memory_data = p;
-    memory_inst->memory_data_end = p + (uint32)memory_data_size;
+    memory_inst->memory_data_end = p + memory_data_size;
 
     /* Initialize heap info */
     memory_inst->heap_data = p + heap_offset;
@@ -984,7 +989,8 @@ aot_get_default_memory(AOTModuleInstance *module_inst)
 
 static bool
 memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
-                     AOTModule *module, uint32 heap_size, char *error_buf,
+                     AOTModule *module, uint32 heap_size,
+                     uint32 max_memory_pages, char *error_buf,
                      uint32 error_buf_size)
 {
     uint32 global_index, global_data_offset, base_offset, length;
@@ -1002,9 +1008,9 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
 
     memories = module_inst->global_table_data.memory_instances;
     for (i = 0; i < memory_count; i++, memories++) {
-        memory_inst = memory_instantiate(module_inst, parent, module, memories,
-                                         &module->memories[i], i, heap_size,
-                                         error_buf, error_buf_size);
+        memory_inst = memory_instantiate(
+            module_inst, parent, module, memories, &module->memories[i], i,
+            heap_size, max_memory_pages, error_buf, error_buf_size);
         if (!memory_inst) {
             return false;
         }
@@ -1065,8 +1071,8 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
         /* Check memory data */
         /* check offset since length might negative */
         if (base_offset > memory_inst->memory_data_size) {
-            LOG_DEBUG("base_offset(%d) > memory_data_size(%d)", base_offset,
-                      memory_inst->memory_data_size);
+            LOG_DEBUG("base_offset(%d) > memory_data_size(%" PRIu64 ")",
+                      base_offset, memory_inst->memory_data_size);
 #if WASM_ENABLE_REF_TYPES != 0
             set_error_buf(error_buf, error_buf_size,
                           "out of bounds memory access");
@@ -1080,7 +1086,8 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
         /* check offset + length(could be zero) */
         length = data_seg->byte_count;
         if (base_offset + length > memory_inst->memory_data_size) {
-            LOG_DEBUG("base_offset(%d) + length(%d) > memory_data_size(%d)",
+            LOG_DEBUG("base_offset(%d) + length(%d) > memory_data_size(%" PRIu64
+                      ")",
                       base_offset, length, memory_inst->memory_data_size);
 #if WASM_ENABLE_REF_TYPES != 0
             set_error_buf(error_buf, error_buf_size,
@@ -1094,7 +1101,7 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
 
         if (memory_inst->memory_data) {
             bh_memcpy_s((uint8 *)memory_inst->memory_data + base_offset,
-                        memory_inst->memory_data_size - base_offset,
+                        (uint32)memory_inst->memory_data_size - base_offset,
                         data_seg->bytes, length);
         }
     }
@@ -1108,10 +1115,21 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
 {
     uint32 i;
     void **func_ptrs;
-    uint64 total_size = ((uint64)module->import_func_count + module->func_count)
-                        * sizeof(void *);
+    uint32 func_count = module->func_count;
+#if defined(BUILD_TARGET_XTENSA)
+    /*
+     * For Xtensa XIP, real func_count is doubled, including aot_func and
+     * aot_func_internal, so need to multipy func_count by 2 here.
+     */
+    if (module->is_indirect_mode) {
+        func_count *= 2;
+    }
+#endif
 
-    if (module->import_func_count + module->func_count == 0)
+    uint64 total_size =
+        ((uint64)module->import_func_count + func_count) * sizeof(void *);
+
+    if (module->import_func_count + func_count == 0)
         return true;
 
     /* Allocate memory */
@@ -1133,8 +1151,8 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
     }
 
     /* Set defined function pointers */
-    bh_memcpy_s(func_ptrs, sizeof(void *) * module->func_count,
-                module->func_ptrs, sizeof(void *) * module->func_count);
+    bh_memcpy_s(func_ptrs, sizeof(void *) * func_count, module->func_ptrs,
+                sizeof(void *) * func_count);
     return true;
 }
 
@@ -1144,10 +1162,21 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
 {
     uint32 i;
     uint32 *func_type_index;
-    uint64 total_size = ((uint64)module->import_func_count + module->func_count)
-                        * sizeof(uint32);
+    uint32 func_count = module->func_count;
+#if defined(BUILD_TARGET_XTENSA)
+    /*
+     * For Xtensa XIP, real func_count is doubled, including aot_func and
+     * aot_func_internal, so need to multipy func_count by 2 here.
+     */
+    if (module->is_indirect_mode) {
+        func_count *= 2;
+    }
+#endif
+
+    uint64 total_size =
+        ((uint64)module->import_func_count + func_count) * sizeof(uint32);
 
-    if (module->import_func_count + module->func_count == 0)
+    if (module->import_func_count + func_count == 0)
         return true;
 
     /* Allocate memory */
@@ -1161,8 +1190,8 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
     for (i = 0; i < module->import_func_count; i++, func_type_index++)
         *func_type_index = module->import_funcs[i].func_type_index;
 
-    bh_memcpy_s(func_type_index, sizeof(uint32) * module->func_count,
-                module->func_type_indexes, sizeof(uint32) * module->func_count);
+    bh_memcpy_s(func_type_index, sizeof(uint32) * func_count,
+                module->func_type_indexes, sizeof(uint32) * func_count);
     return true;
 }
 
@@ -1247,7 +1276,7 @@ lookup_post_instantiate_func(AOTModuleInstance *module_inst,
     AOTFunctionInstance *func;
     AOTFuncType *func_type;
 
-    if (!(func = aot_lookup_function(module_inst, func_name, NULL)))
+    if (!(func = aot_lookup_function(module_inst, func_name)))
         /* Not found */
         return NULL;
 
@@ -1439,7 +1468,7 @@ check_linked_symbol(AOTModule *module, char *error_buf, uint32 error_buf_size)
 AOTModuleInstance *
 aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
                 WASMExecEnv *exec_env_main, uint32 stack_size, uint32 heap_size,
-                char *error_buf, uint32 error_buf_size)
+                uint32 max_memory_pages, char *error_buf, uint32 error_buf_size)
 {
     AOTModuleInstance *module_inst;
 #if WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_REF_TYPES != 0
@@ -1529,7 +1558,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
         &((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list_head;
     ret = wasm_runtime_sub_module_instantiate(
         (WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst,
-        stack_size, heap_size, error_buf, error_buf_size);
+        stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
     if (!ret) {
         LOG_DEBUG("build a sub module list failed");
         goto fail;
@@ -1591,8 +1620,8 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
         goto fail;
 
     /* Initialize memory space */
-    if (!memories_instantiate(module_inst, parent, module, heap_size, error_buf,
-                              error_buf_size))
+    if (!memories_instantiate(module_inst, parent, module, heap_size,
+                              max_memory_pages, error_buf, error_buf_size))
         goto fail;
 
     /* Initialize function pointers */
@@ -1692,6 +1721,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
 
         bh_assert(table_init_data);
 
+        bh_assert(table_init_data->table_index < module_inst->table_count);
         table = module_inst->tables[table_init_data->table_index];
         bh_assert(table);
 
@@ -1699,8 +1729,9 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
         bh_assert(table_data);
 
         wasm_runtime_get_table_inst_elem_type(
-            (WASMModuleInstanceCommon *)module_inst, i, &tbl_elem_type,
-            &tbl_elem_ref_type, &tbl_init_size, &tbl_max_size);
+            (WASMModuleInstanceCommon *)module_inst,
+            table_init_data->table_index, &tbl_elem_type, &tbl_elem_ref_type,
+            &tbl_init_size, &tbl_max_size);
 
         if (!wasm_elem_is_declarative(table_init_data->mode)
             && !wasm_reftype_is_subtype_of(
@@ -1882,9 +1913,8 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
     if (module_inst->func_type_indexes)
         wasm_runtime_free(module_inst->func_type_indexes);
 
-    if (common->c_api_func_imports)
-        wasm_runtime_free(((AOTModuleInstanceExtra *)module_inst->e)
-                              ->common.c_api_func_imports);
+    if (module_inst->c_api_func_imports)
+        wasm_runtime_free(module_inst->c_api_func_imports);
 
 #if WASM_ENABLE_GC != 0
     if (!is_sub_inst) {
@@ -1915,8 +1945,7 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
 }
 
 AOTFunctionInstance *
-aot_lookup_function(const AOTModuleInstance *module_inst, const char *name,
-                    const char *signature)
+aot_lookup_function(const AOTModuleInstance *module_inst, const char *name)
 {
     uint32 i;
     AOTFunctionInstance *export_funcs =
@@ -1925,7 +1954,6 @@ aot_lookup_function(const AOTModuleInstance *module_inst, const char *name,
     for (i = 0; i < module_inst->export_func_count; i++)
         if (!strcmp(export_funcs[i].func_name, name))
             return &export_funcs[i];
-    (void)signature;
     return NULL;
 }
 
@@ -1939,8 +1967,6 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
     AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
     WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
-    uint32 page_size = os_getpagesize();
-    uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
 #ifdef BH_PLATFORM_WINDOWS
     int result;
     bool has_exception;
@@ -1951,10 +1977,7 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
     /* Check native stack overflow firstly to ensure we have enough
        native stack to run the following codes before actually calling
        the aot function in invokeNative function. */
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&module_inst);
-    if ((uint8 *)&module_inst < exec_env->native_stack_boundary
-                                    + page_size * (guard_page_count + 1)) {
-        aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         return false;
     }
 
@@ -2131,8 +2154,8 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
        hw bound check is enabled */
 #endif
 
-    /* Set exec env so it can be later retrieved from instance */
-    ((AOTModuleInstanceExtra *)module_inst->e)->common.cur_exec_env = exec_env;
+    /* Set exec env, so it can be later retrieved from instance */
+    module_inst->cur_exec_env = exec_env;
 
     if (ext_ret_count > 0) {
         uint32 cell_num = 0, i;
@@ -2446,9 +2469,9 @@ execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
     return ret;
 }
 
-uint32
+uint64
 aot_module_malloc_internal(AOTModuleInstance *module_inst,
-                           WASMExecEnv *exec_env, uint32 size,
+                           WASMExecEnv *exec_env, uint64 size,
                            void **p_native_addr)
 {
     AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
@@ -2456,38 +2479,37 @@ aot_module_malloc_internal(AOTModuleInstance *module_inst,
     uint8 *addr = NULL;
     uint32 offset = 0;
 
+    /* TODO: Memory64 size check based on memory idx type */
+    bh_assert(size <= UINT32_MAX);
+
     if (!memory_inst) {
         aot_set_exception(module_inst, "uninitialized memory");
         return 0;
     }
 
     if (memory_inst->heap_handle) {
-        addr = mem_allocator_malloc(memory_inst->heap_handle, size);
+        addr = mem_allocator_malloc(memory_inst->heap_handle, (uint32)size);
     }
     else if (module->malloc_func_index != (uint32)-1
              && module->free_func_index != (uint32)-1) {
         AOTFunctionInstance *malloc_func, *retain_func = NULL;
         char *malloc_func_name;
-        char *malloc_func_sig;
 
         if (module->retain_func_index != (uint32)-1) {
             malloc_func_name = "__new";
-            malloc_func_sig = "(ii)i";
-            retain_func = aot_lookup_function(module_inst, "__retain", "(i)i");
+            retain_func = aot_lookup_function(module_inst, "__retain");
             if (!retain_func)
-                retain_func = aot_lookup_function(module_inst, "__pin", "(i)i");
+                retain_func = aot_lookup_function(module_inst, "__pin");
             bh_assert(retain_func);
         }
         else {
             malloc_func_name = "malloc";
-            malloc_func_sig = "(i)i";
         }
-        malloc_func =
-            aot_lookup_function(module_inst, malloc_func_name, malloc_func_sig);
+        malloc_func = aot_lookup_function(module_inst, malloc_func_name);
 
         if (!malloc_func
             || !execute_malloc_function(module_inst, exec_env, malloc_func,
-                                        retain_func, size, &offset)) {
+                                        retain_func, (uint32)size, &offset)) {
             return 0;
         }
         addr = offset ? (uint8 *)memory_inst->memory_data + offset : NULL;
@@ -2500,23 +2522,28 @@ aot_module_malloc_internal(AOTModuleInstance *module_inst,
             aot_set_exception(module_inst, "app heap corrupted");
         }
         else {
-            LOG_WARNING("warning: allocate %u bytes memory failed", size);
+            LOG_WARNING("warning: allocate %" PRIu64 " bytes memory failed",
+                        size);
         }
         return 0;
     }
     if (p_native_addr)
         *p_native_addr = addr;
-    return (uint32)(addr - memory_inst->memory_data);
+    return (uint64)(addr - memory_inst->memory_data);
 }
 
-uint32
+uint64
 aot_module_realloc_internal(AOTModuleInstance *module_inst,
-                            WASMExecEnv *exec_env, uint32 ptr, uint32 size,
+                            WASMExecEnv *exec_env, uint64 ptr, uint64 size,
                             void **p_native_addr)
 {
     AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
     uint8 *addr = NULL;
 
+    /* TODO: Memory64 ptr and size check based on memory idx type */
+    bh_assert(ptr <= UINT32_MAX);
+    bh_assert(size <= UINT32_MAX);
+
     if (!memory_inst) {
         aot_set_exception(module_inst, "uninitialized memory");
         return 0;
@@ -2525,7 +2552,8 @@ aot_module_realloc_internal(AOTModuleInstance *module_inst,
     if (memory_inst->heap_handle) {
         addr = mem_allocator_realloc(
             memory_inst->heap_handle,
-            ptr ? memory_inst->memory_data + ptr : NULL, size);
+            (uint32)ptr ? memory_inst->memory_data + (uint32)ptr : NULL,
+            (uint32)size);
     }
 
     /* Only support realloc in WAMR's app heap */
@@ -2544,12 +2572,12 @@ aot_module_realloc_internal(AOTModuleInstance *module_inst,
 
     if (p_native_addr)
         *p_native_addr = addr;
-    return (uint32)(addr - memory_inst->memory_data);
+    return (uint64)(addr - memory_inst->memory_data);
 }
 
 void
 aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
-                         uint32 ptr)
+                         uint64 ptr)
 {
     AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
     AOTModule *module = (AOTModule *)module_inst->module;
@@ -2558,8 +2586,11 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
         return;
     }
 
+    /* TODO: Memory64 ptr and size check based on memory idx type */
+    bh_assert(ptr <= UINT32_MAX);
+
     if (ptr) {
-        uint8 *addr = memory_inst->memory_data + ptr;
+        uint8 *addr = memory_inst->memory_data + (uint32)ptr;
         uint8 *memory_data_end;
 
         /* memory->memory_data_end may be changed in memory grow */
@@ -2584,26 +2615,26 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
             else {
                 free_func_name = "free";
             }
-            free_func =
-                aot_lookup_function(module_inst, free_func_name, "(i)i");
+            free_func = aot_lookup_function(module_inst, free_func_name);
             if (!free_func && module->retain_func_index != (uint32)-1)
-                free_func = aot_lookup_function(module_inst, "__unpin", "(i)i");
+                free_func = aot_lookup_function(module_inst, "__unpin");
 
             if (free_func)
-                execute_free_function(module_inst, exec_env, free_func, ptr);
+                execute_free_function(module_inst, exec_env, free_func,
+                                      (uint32)ptr);
         }
     }
 }
 
-uint32
-aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
+uint64
+aot_module_malloc(AOTModuleInstance *module_inst, uint64 size,
                   void **p_native_addr)
 {
     return aot_module_malloc_internal(module_inst, NULL, size, p_native_addr);
 }
 
-uint32
-aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
+uint64
+aot_module_realloc(AOTModuleInstance *module_inst, uint64 ptr, uint64 size,
                    void **p_native_addr)
 {
     return aot_module_realloc_internal(module_inst, NULL, ptr, size,
@@ -2611,23 +2642,27 @@ aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
 }
 
 void
-aot_module_free(AOTModuleInstance *module_inst, uint32 ptr)
+aot_module_free(AOTModuleInstance *module_inst, uint64 ptr)
 {
     aot_module_free_internal(module_inst, NULL, ptr);
 }
 
-uint32
+uint64
 aot_module_dup_data(AOTModuleInstance *module_inst, const char *src,
-                    uint32 size)
+                    uint64 size)
 {
     char *buffer;
-    uint32 buffer_offset =
-        aot_module_malloc(module_inst, size, (void **)&buffer);
+    uint64 buffer_offset;
+
+    /* TODO: Memory64 size check based on memory idx type */
+    bh_assert(size <= UINT32_MAX);
+
+    buffer_offset = aot_module_malloc(module_inst, size, (void **)&buffer);
 
     if (buffer_offset != 0) {
         buffer = wasm_runtime_addr_app_to_native(
             (WASMModuleInstanceCommon *)module_inst, buffer_offset);
-        bh_memcpy_s(buffer, size, src, size);
+        bh_memcpy_s(buffer, (uint32)size, src, (uint32)size);
     }
     return buffer_offset;
 }
@@ -2645,11 +2680,9 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
     AOTModuleInstance *module_inst =
         (AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env);
     AOTModule *aot_module = (AOTModule *)module_inst->module;
-    AOTModuleInstanceExtra *module_inst_extra =
-        (AOTModuleInstanceExtra *)module_inst->e;
     CApiFuncImport *c_api_func_import =
-        module_inst_extra->common.c_api_func_imports
-            ? module_inst_extra->common.c_api_func_imports + func_idx
+        module_inst->c_api_func_imports
+            ? module_inst->c_api_func_imports + func_idx
             : NULL;
     uint32 *func_type_indexes = module_inst->func_type_indexes;
     uint32 func_type_idx = func_type_indexes[func_idx];
@@ -2752,9 +2785,7 @@ aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
        exec_env->native_stack_boundary must have been set, we don't set
        it again */
 
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&module_inst);
-    if ((uint8 *)&module_inst < exec_env->native_stack_boundary) {
-        aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         goto fail;
     }
 
@@ -2773,7 +2804,7 @@ aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
     }
 
 #if WASM_ENABLE_GC == 0
-    func_idx = tbl_elem_val;
+    func_idx = (uint32)tbl_elem_val;
 #else
     func_idx =
         wasm_func_obj_get_func_idx_bound((WASMFuncObjectRef)tbl_elem_val);
@@ -2909,7 +2940,7 @@ fail:
 
 bool
 aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
-                               uint32 app_buf_addr, uint32 app_buf_size,
+                               uint64 app_buf_addr, uint64 app_buf_size,
                                void **p_native_addr)
 {
     bool ret;
@@ -2973,7 +3004,7 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
     }
 
     if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
-                                        dst, len))
+                                        (uint64)dst, (uint64)len))
         return false;
 
     if ((uint64)offset + (uint64)len > seg_len) {
@@ -2982,10 +3013,11 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
     }
 
     maddr = wasm_runtime_addr_app_to_native(
-        (WASMModuleInstanceCommon *)module_inst, dst);
+        (WASMModuleInstanceCommon *)module_inst, (uint64)dst);
 
     SHARED_MEMORY_LOCK(memory_inst);
-    bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
+    bh_memcpy_s(maddr, (uint32)(memory_inst->memory_data_size - dst),
+                data + offset, len);
     SHARED_MEMORY_UNLOCK(memory_inst);
     return true;
 }
@@ -3004,14 +3036,14 @@ aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
 
 #if WASM_ENABLE_THREAD_MGR != 0
 bool
-aot_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
+aot_set_aux_stack(WASMExecEnv *exec_env, uint64 start_offset, uint32 size)
 {
     AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
     AOTModule *module = (AOTModule *)module_inst->module;
 
     uint32 stack_top_idx = module->aux_stack_top_global_index;
-    uint32 data_end = module->aux_data_end;
-    uint32 stack_bottom = module->aux_stack_bottom;
+    uint64 data_end = module->aux_data_end;
+    uint64 stack_bottom = module->aux_stack_bottom;
     bool is_stack_before_data = stack_bottom < data_end ? true : false;
 
     /* Check the aux stack space, currently we don't allocate space in heap */
@@ -3024,12 +3056,13 @@ aot_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
             set the initial value for the global */
         uint32 global_offset = module->globals[stack_top_idx].data_offset;
         uint8 *global_addr = module_inst->global_data + global_offset;
-        *(int32 *)global_addr = start_offset;
+        /* TODO: Memory64 the type i32/i64 depends on memory idx type*/
+        *(int32 *)global_addr = (uint32)start_offset;
 
         /* The aux stack boundary is a constant value,
             set the value to exec_env */
-        exec_env->aux_stack_boundary.boundary = start_offset - size;
-        exec_env->aux_stack_bottom.bottom = start_offset;
+        exec_env->aux_stack_boundary = (uintptr_t)start_offset - size;
+        exec_env->aux_stack_bottom = (uintptr_t)start_offset;
         return true;
     }
 
@@ -3037,14 +3070,14 @@ aot_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
 }
 
 bool
-aot_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, uint32 *size)
+aot_get_aux_stack(WASMExecEnv *exec_env, uint64 *start_offset, uint32 *size)
 {
     AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
     AOTModule *module = (AOTModule *)module_inst->module;
 
     /* The aux stack information is resolved in loader
         and store in module */
-    uint32 stack_bottom = module->aux_stack_bottom;
+    uint64 stack_bottom = module->aux_stack_bottom;
     uint32 total_aux_stack_size = module->aux_stack_size;
 
     if (stack_bottom != 0 && total_aux_stack_size != 0) {
@@ -3328,39 +3361,49 @@ aot_table_fill(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 length,
 }
 
 uint32
-aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx,
-               uint32 inc_entries, table_elem_type_t init_val)
+aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 inc_size,
+               table_elem_type_t init_val)
 {
-    uint32 entry_count, i, orig_tbl_sz;
     AOTTableInstance *tbl_inst;
+    uint32 i, orig_size, total_size;
 
     tbl_inst = module_inst->tables[tbl_idx];
     if (!tbl_inst) {
         return (uint32)-1;
     }
 
-    orig_tbl_sz = tbl_inst->cur_size;
+    orig_size = tbl_inst->cur_size;
 
-    if (!inc_entries) {
-        return orig_tbl_sz;
+    if (!inc_size) {
+        return orig_size;
     }
 
-    if (tbl_inst->cur_size > UINT32_MAX - inc_entries) {
+    if (tbl_inst->cur_size > UINT32_MAX - inc_size) {
+#if WASM_ENABLE_SPEC_TEST == 0
+        LOG_WARNING("table grow (%" PRIu32 "-> %" PRIu32
+                    ") failed because of integer overflow",
+                    tbl_inst->cur_size, inc_size);
+#endif
         return (uint32)-1;
     }
 
-    entry_count = tbl_inst->cur_size + inc_entries;
-    if (entry_count > tbl_inst->max_size) {
+    total_size = tbl_inst->cur_size + inc_size;
+    if (total_size > tbl_inst->max_size) {
+#if WASM_ENABLE_SPEC_TEST == 0
+        LOG_WARNING("table grow (%" PRIu32 "-> %" PRIu32
+                    ") failed because of over max size",
+                    tbl_inst->cur_size, inc_size);
+#endif
         return (uint32)-1;
     }
 
     /* fill in */
-    for (i = 0; i < inc_entries; ++i) {
+    for (i = 0; i < inc_size; ++i) {
         tbl_inst->elems[tbl_inst->cur_size + i] = init_val;
     }
 
-    tbl_inst->cur_size = entry_count;
-    return orig_tbl_sz;
+    tbl_inst->cur_size = total_size;
+    return orig_size;
 }
 #endif /* WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
 
@@ -3662,14 +3705,14 @@ aot_create_call_stack(struct WASMExecEnv *exec_env)
 
         frame.instance = module_inst;
         frame.module_offset = 0;
-        frame.func_index = cur_frame->func_index;
-        frame.func_offset = cur_frame->ip_offset;
-        frame.func_name_wp =
-            get_func_name_from_index(module_inst, cur_frame->func_index);
+        frame.func_index = (uint32)cur_frame->func_index;
+        frame.func_offset = (uint32)cur_frame->ip_offset;
+        frame.func_name_wp = get_func_name_from_index(
+            module_inst, (uint32)cur_frame->func_index);
 
         if (cur_frame->func_index >= module->import_func_count) {
             uint32 aot_func_idx =
-                cur_frame->func_index - module->import_func_count;
+                (uint32)(cur_frame->func_index - module->import_func_count);
             max_local_cell_num = module->max_local_cell_nums[aot_func_idx];
             max_stack_cell_num = module->max_stack_cell_nums[aot_func_idx];
         }
@@ -4439,6 +4482,22 @@ aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
     return wasm_obj_is_instance_of(gc_obj, type_index, types, type_count);
 }
 
+bool
+aot_func_type_is_super_of(AOTModuleInstance *module_inst, uint32 type_idx1,
+                          uint32 type_idx2)
+{
+    AOTModule *aot_module = (AOTModule *)module_inst->module;
+    AOTType **types = aot_module->types;
+
+    if (type_idx1 == type_idx2)
+        return true;
+
+    bh_assert(types[type_idx1]->type_flag == WASM_TYPE_FUNC);
+    bh_assert(types[type_idx2]->type_flag == WASM_TYPE_FUNC);
+    return wasm_func_type_is_super_of((WASMFuncType *)types[type_idx1],
+                                      (WASMFuncType *)types[type_idx2]);
+}
+
 WASMRttTypeRef
 aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index)
 {
@@ -4629,3 +4688,74 @@ aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap)
     return true;
 }
 #endif /* end of WASM_ENABLE_GC != 0 */
+
+char *
+aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
+#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
+                         bool is_vram_word_align,
+#endif
+                         char *error_buf, uint32 error_buf_size)
+{
+    HashMap *set = module->const_str_set;
+    char *c_str, *value;
+
+    /* Create const string set if it isn't created */
+    if (!set
+        && !(set = module->const_str_set = bh_hash_map_create(
+                 32, false, (HashFunc)wasm_string_hash,
+                 (KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) {
+        set_error_buf(error_buf, error_buf_size,
+                      "create const string set failed");
+        return NULL;
+    }
+
+    /* Lookup const string set, use the string if found */
+    if (!(c_str = runtime_malloc((uint32)len, error_buf, error_buf_size))) {
+        return NULL;
+    }
+#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
+    if (is_vram_word_align) {
+        bh_memcpy_wa(c_str, (uint32)len, str, (uint32)len);
+    }
+    else
+#endif
+    {
+        bh_memcpy_s(c_str, len, str, (uint32)len);
+    }
+
+    if ((value = bh_hash_map_find(set, c_str))) {
+        wasm_runtime_free(c_str);
+        return value;
+    }
+
+    if (!bh_hash_map_insert(set, c_str, c_str)) {
+        set_error_buf(error_buf, error_buf_size,
+                      "insert string to hash map failed");
+        wasm_runtime_free(c_str);
+        return NULL;
+    }
+
+    return c_str;
+}
+
+bool
+aot_set_module_name(AOTModule *module, const char *name, char *error_buf,
+                    uint32_t error_buf_size)
+{
+    if (!name)
+        return false;
+
+    module->name = aot_const_str_set_insert((const uint8 *)name,
+                                            (uint32)(strlen(name) + 1), module,
+#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
+                                            false,
+#endif
+                                            error_buf, error_buf_size);
+    return module->name != NULL;
+}
+
+const char *
+aot_get_module_name(AOTModule *module)
+{
+    return module->name;
+}

+ 46 - 25
core/iwasm/aot/aot_runtime.h

@@ -246,19 +246,19 @@ typedef struct AOTModule {
        -1 means unexported */
     uint32 aux_data_end_global_index;
     /* auxiliary __data_end exported by wasm app */
-    uint32 aux_data_end;
+    uint64 aux_data_end;
 
     /* the index of auxiliary __heap_base global,
        -1 means unexported */
     uint32 aux_heap_base_global_index;
     /* auxiliary __heap_base exported by wasm app */
-    uint32 aux_heap_base;
+    uint64 aux_heap_base;
 
     /* the index of auxiliary stack top global,
        -1 means unexported */
     uint32 aux_stack_top_global_index;
     /* auxiliary stack bottom resolved */
-    uint32 aux_stack_bottom;
+    uint64 aux_stack_bottom;
     /* auxiliary stack size resolved */
     uint32 aux_stack_size;
 
@@ -307,6 +307,9 @@ typedef struct AOTModule {
 #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
     WASMCustomSection *custom_section_list;
 #endif
+
+    /* user defined name */
+    char *name;
 } AOTModule;
 
 #define AOTMemoryInstance WASMMemoryInstance
@@ -441,8 +444,8 @@ typedef struct LLVMProfileData_64 {
  * @return return AOT module loaded, NULL if failed
  */
 AOTModule *
-aot_load_from_aot_file(const uint8 *buf, uint32 size, char *error_buf,
-                       uint32 error_buf_size);
+aot_load_from_aot_file(const uint8 *buf, uint32 size, const LoadArgs *args,
+                       char *error_buf, uint32 error_buf_size);
 
 /**
  * Load a AOT module from a specified AOT section list.
@@ -482,7 +485,8 @@ aot_unload(AOTModule *module);
 AOTModuleInstance *
 aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
                 WASMExecEnv *exec_env_main, uint32 stack_size, uint32 heap_size,
-                char *error_buf, uint32 error_buf_size);
+                uint32 max_memory_pages, char *error_buf,
+                uint32 error_buf_size);
 
 /**
  * Deinstantiate a AOT module instance, destroy the resources.
@@ -498,14 +502,12 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst);
  *
  * @param module_inst the module instance
  * @param name the name of the function
- * @param signature the signature of the function, use "i32"/"i64"/"f32"/"f64"
- *        to represent the type of i32/i64/f32/f64, e.g. "(i32i64)" "(i32)f32"
  *
  * @return the function instance found
  */
 AOTFunctionInstance *
-aot_lookup_function(const AOTModuleInstance *module_inst, const char *name,
-                    const char *signature);
+aot_lookup_function(const AOTModuleInstance *module_inst, const char *name);
+
 /**
  * Call the given AOT function of a AOT module instance with
  * arguments.
@@ -557,32 +559,32 @@ aot_get_exception(AOTModuleInstance *module_inst);
 bool
 aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf);
 
-uint32
+uint64
 aot_module_malloc_internal(AOTModuleInstance *module_inst, WASMExecEnv *env,
-                           uint32 size, void **p_native_addr);
+                           uint64 size, void **p_native_addr);
 
-uint32
+uint64
 aot_module_realloc_internal(AOTModuleInstance *module_inst, WASMExecEnv *env,
-                            uint32 ptr, uint32 size, void **p_native_addr);
+                            uint64 ptr, uint64 size, void **p_native_addr);
 
 void
 aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *env,
-                         uint32 ptr);
+                         uint64 ptr);
 
-uint32
-aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
+uint64
+aot_module_malloc(AOTModuleInstance *module_inst, uint64 size,
                   void **p_native_addr);
 
-uint32
-aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
+uint64
+aot_module_realloc(AOTModuleInstance *module_inst, uint64 ptr, uint64 size,
                    void **p_native_addr);
 
 void
-aot_module_free(AOTModuleInstance *module_inst, uint32 ptr);
+aot_module_free(AOTModuleInstance *module_inst, uint64 ptr);
 
-uint32
+uint64
 aot_module_dup_data(AOTModuleInstance *module_inst, const char *src,
-                    uint32 size);
+                    uint64 size);
 
 bool
 aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count);
@@ -604,7 +606,7 @@ aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
  */
 bool
 aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
-                               uint32 app_buf_addr, uint32 app_buf_size,
+                               uint64 app_buf_addr, uint64 app_buf_size,
                                void **p_native_addr);
 
 uint32
@@ -633,10 +635,10 @@ aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index);
 
 #if WASM_ENABLE_THREAD_MGR != 0
 bool
-aot_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size);
+aot_set_aux_stack(WASMExecEnv *exec_env, uint64 start_offset, uint32 size);
 
 bool
-aot_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, uint32 *size);
+aot_get_aux_stack(WASMExecEnv *exec_env, uint64 *start_offset, uint32 *size);
 #endif
 
 void
@@ -750,6 +752,11 @@ bool
 aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
                        uint32 type_index);
 
+/* Whether func type1 is one of super types of func type2 */
+bool
+aot_func_type_is_super_of(AOTModuleInstance *module_inst, uint32 type_idx1,
+                          uint32 type_idx2);
+
 WASMRttTypeRef
 aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index);
 
@@ -762,6 +769,20 @@ bool
 aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap);
 #endif /* end of WASM_ENABLE_GC != 0 */
 
+char *
+aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
+#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
+                         bool is_vram_word_align,
+#endif
+                         char *error_buf, uint32 error_buf_size);
+
+bool
+aot_set_module_name(AOTModule *module, const char *name, char *error_buf,
+                    uint32_t error_buf_size);
+
+const char *
+aot_get_module_name(AOTModule *module);
+
 #ifdef __cplusplus
 } /* end of extern "C" */
 #endif

+ 0 - 1
core/iwasm/aot/debug/elf_parser.c

@@ -7,7 +7,6 @@
 #include <assert.h>
 #include <fcntl.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
 #include <errno.h>
 #include <stdbool.h>

+ 10 - 3
core/iwasm/aot/debug/jit_debug.c

@@ -24,7 +24,6 @@
 #include <stdio.h>
 #include <assert.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
 #include <errno.h>
 #include <stdbool.h>
@@ -56,6 +55,12 @@ typedef struct JITDescriptor {
     JITCodeEntry *first_entry_;
 } JITDescriptor;
 
+#if defined(_WIN32) || defined(_WIN32_)
+#define attribute_noinline __declspec(noinline)
+#else
+#define attribute_noinline __attribute__((noinline))
+#endif
+
 /* LLVM has already define this */
 #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
 /**
@@ -63,9 +68,11 @@ typedef struct JITDescriptor {
  * To prevent GCC from inlining or removing it we place noinline attribute
  * and inline assembler statement inside.
  */
-void __attribute__((noinline)) __jit_debug_register_code();
+void attribute_noinline
+__jit_debug_register_code();
 
-void __attribute__((noinline)) __jit_debug_register_code()
+void attribute_noinline
+__jit_debug_register_code()
 {
     int x;
     *(char *)&x = '\0';

+ 6 - 1
core/iwasm/common/gc/gc_common.c

@@ -304,7 +304,12 @@ wasm_defined_type_equal(WASMType *const def_type1, WASMType *const def_type2,
     }
 #endif
 #if WASM_ENABLE_AOT != 0
-    /* TODO */
+    if (module->module_type == Wasm_Module_AoT) {
+        AOTModule *aot_module = (AOTModule *)module;
+
+        types = aot_module->types;
+        type_count = aot_module->type_count;
+    }
 #endif
 
     bh_assert(types);

+ 10 - 0
core/iwasm/common/gc/gc_object.c

@@ -189,6 +189,16 @@ wasm_struct_obj_get_field(const WASMStructObjectRef struct_obj,
     }
 }
 
+uint32
+wasm_struct_obj_get_field_count(const WASMStructObjectRef struct_obj)
+{
+    WASMRttTypeRef rtt_type =
+        (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
+    WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
+
+    return struct_type->field_count;
+}
+
 WASMArrayObjectRef
 wasm_array_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
                             uint32 length, WASMValue *init_value)

+ 10 - 0
core/iwasm/common/gc/gc_object.h

@@ -157,6 +157,16 @@ void
 wasm_struct_obj_get_field(const WASMStructObjectRef struct_obj,
                           uint32 field_idx, bool sign_extend, WASMValue *value);
 
+/**
+ * Return the field count of the WASM struct object.
+ *
+ * @param struct_obj the WASM struct object
+ *
+ * @return the field count of the WASM struct object
+ */
+uint32
+wasm_struct_obj_get_field_count(const WASMStructObjectRef struct_obj);
+
 WASMArrayObjectRef
 wasm_array_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
                             uint32 length, WASMValue *init_value);

+ 137 - 31
core/iwasm/common/gc/gc_type.c

@@ -148,7 +148,7 @@ wasm_dump_func_type(const WASMFuncType *type)
 
     os_printf("] -> [");
 
-    for (; i < type->param_count + type->result_count; i++) {
+    for (; i < (uint32)(type->param_count + type->result_count); i++) {
         if (wasm_is_type_multi_byte_type(type->types[i])) {
             bh_assert(j < type->ref_type_map_count);
             bh_assert(i == type->ref_type_maps[j].index);
@@ -250,6 +250,51 @@ wasm_value_types_is_subtype_of(const uint8 *types1,
     return true;
 }
 
+static bool
+rec_ref_type_equal(const WASMRefType *ref_type1, const WASMRefType *ref_type2,
+                   uint32 rec_begin_type_idx1, uint32 rec_begin_type_idx2,
+                   uint32 rec_count, const WASMTypePtr *types,
+                   uint32 type_count)
+{
+    uint32 type_idx1, type_idx2;
+
+    if (!wasm_is_refheaptype_typeidx(&ref_type1->ref_ht_common)
+        || !wasm_is_refheaptype_typeidx(&ref_type2->ref_ht_common))
+        return ref_type1->ref_ht_common.heap_type
+                       == ref_type2->ref_ht_common.heap_type
+                   ? true
+                   : false;
+
+    /* Now both ref types are type of (ref type_idx) */
+    type_idx1 = ref_type1->ref_ht_typeidx.type_idx;
+    type_idx2 = ref_type2->ref_ht_typeidx.type_idx;
+
+    if (type_idx1 >= rec_begin_type_idx1
+        && type_idx1 < rec_begin_type_idx1 + rec_count) {
+        /* The converted iso-recursive types should be the same */
+        bool ret = (type_idx2 >= rec_begin_type_idx2
+                    && type_idx2 < rec_begin_type_idx2 + rec_count
+                    && type_idx1 - rec_begin_type_idx1
+                           == type_idx2 - rec_begin_type_idx2)
+                       ? true
+                       : false;
+        return ret;
+    }
+    else if (type_idx2 >= rec_begin_type_idx2
+             && type_idx2 < rec_begin_type_idx2 + rec_count) {
+        /* The converted iso-recursive types should be the same */
+        bool ret = (type_idx1 >= rec_begin_type_idx1
+                    && type_idx1 < rec_begin_type_idx1 + rec_count
+                    && type_idx1 - rec_begin_type_idx1
+                           == type_idx2 - rec_begin_type_idx2)
+                       ? true
+                       : false;
+        return ret;
+    }
+
+    return types[type_idx1] == types[type_idx2] ? true : false;
+}
+
 bool
 wasm_func_type_equal(const WASMFuncType *type1, const WASMFuncType *type2,
                      const WASMTypePtr *types, uint32 type_count)
@@ -264,7 +309,7 @@ wasm_func_type_equal(const WASMFuncType *type1, const WASMFuncType *type2,
         || type1->ref_type_map_count != type2->ref_type_map_count)
         return false;
 
-    for (i = 0; i < type1->param_count + type1->result_count; i++) {
+    for (i = 0; i < (uint32)(type1->param_count + type1->result_count); i++) {
         if (type1->types[i] != type2->types[i])
             return false;
 
@@ -277,9 +322,11 @@ wasm_func_type_equal(const WASMFuncType *type1, const WASMFuncType *type2,
 
             ref_type1 = type1->ref_type_maps[j].ref_type;
             ref_type2 = type2->ref_type_maps[j].ref_type;
-            if (!wasm_reftype_equal(ref_type1->ref_type, ref_type1,
-                                    ref_type2->ref_type, ref_type2, types,
-                                    type_count))
+
+            if (!rec_ref_type_equal(
+                    ref_type1, ref_type2, type1->base_type.rec_begin_type_idx,
+                    type2->base_type.rec_begin_type_idx,
+                    type1->base_type.rec_count, types, type_count))
                 return false;
 
             j++;
@@ -316,9 +363,11 @@ wasm_struct_type_equal(const WASMStructType *type1, const WASMStructType *type2,
 
             ref_type1 = type1->ref_type_maps[j].ref_type;
             ref_type2 = type2->ref_type_maps[j].ref_type;
-            if (!wasm_reftype_equal(ref_type1->ref_type, ref_type1,
-                                    ref_type2->ref_type, ref_type2, types,
-                                    type_count))
+
+            if (!rec_ref_type_equal(
+                    ref_type1, ref_type2, type1->base_type.rec_begin_type_idx,
+                    type2->base_type.rec_begin_type_idx,
+                    type1->base_type.rec_count, types, type_count))
                 return false;
 
             j++;
@@ -338,21 +387,67 @@ wasm_array_type_equal(const WASMArrayType *type1, const WASMArrayType *type2,
     if (type1->elem_flags != type2->elem_flags)
         return false;
 
-    return wasm_reftype_equal(type1->elem_type, type1->elem_ref_type,
-                              type2->elem_type, type2->elem_ref_type, types,
-                              type_count);
+    if (type1->elem_type != type2->elem_type)
+        return false;
+
+    if (!wasm_is_type_multi_byte_type(type1->elem_type))
+        return true;
+
+    return rec_ref_type_equal(type1->elem_ref_type, type2->elem_ref_type,
+                              type1->base_type.rec_begin_type_idx,
+                              type2->base_type.rec_begin_type_idx,
+                              type1->base_type.rec_count, types, type_count);
 }
 
 bool
 wasm_type_equal(const WASMType *type1, const WASMType *type2,
                 const WASMTypePtr *types, uint32 type_count)
 {
+    uint32 rec_begin_type_idx1 = type1->rec_begin_type_idx;
+    uint32 rec_begin_type_idx2 = type2->rec_begin_type_idx;
+    uint32 parent_type_idx1, parent_type_idx2, rec_count;
+
     if (type1 == type2)
         return true;
 
-    if (type1->type_flag != type2->type_flag)
+    if (!(type1->type_flag == type2->type_flag
+          && type1->is_sub_final == type2->is_sub_final
+          && type1->rec_count == type2->rec_count
+          && type1->rec_idx == type2->rec_idx))
         return false;
 
+    rec_count = type1->rec_count;
+
+    parent_type_idx1 = type1->parent_type_idx;
+    parent_type_idx2 = type2->parent_type_idx;
+
+    if (parent_type_idx1 >= rec_begin_type_idx1
+        && parent_type_idx1 < rec_begin_type_idx1 + rec_count) {
+        /* The converted iso-recursive types should be the same */
+        if (!(parent_type_idx2 >= rec_begin_type_idx2
+              && parent_type_idx2 < rec_begin_type_idx2 + rec_count
+              && parent_type_idx1 - rec_begin_type_idx1
+                     == parent_type_idx2 - rec_begin_type_idx2)) {
+            return false;
+        }
+    }
+    else if (parent_type_idx2 >= rec_begin_type_idx2
+             && parent_type_idx2 < rec_begin_type_idx2 + rec_count) {
+        /* The converted iso-recursive types should be the same */
+        if (!(parent_type_idx1 >= rec_begin_type_idx1
+              && parent_type_idx1 < rec_begin_type_idx1 + rec_count
+              && parent_type_idx1 - rec_begin_type_idx1
+                     == parent_type_idx2 - rec_begin_type_idx2)) {
+            return false;
+        }
+    }
+    else if (type1->parent_type != type2->parent_type) {
+        /* The parent types should be same since they have been
+           normalized and equivalence types with different type
+           indexes are referring to a same WASMType */
+        return false;
+    }
+
     if (wasm_type_is_func_type(type1))
         return wasm_func_type_equal((WASMFuncType *)type1,
                                     (WASMFuncType *)type2, types, type_count);
@@ -399,7 +494,7 @@ wasm_func_type_is_subtype_of(const WASMFuncType *type1,
         }
     }
 
-    for (; i < type1->param_count + type1->result_count; i++) {
+    for (; i < (uint32)(type1->param_count + type1->result_count); i++) {
         if (wasm_is_type_multi_byte_type(type1->types[i])) {
             bh_assert(j1 < type1->ref_type_map_count);
             ref_type1 = type1->ref_type_maps[j1++].ref_type;
@@ -653,12 +748,6 @@ wasm_reftype_struct_size(const WASMRefType *ref_type)
     return (uint32)sizeof(RefHeapType_Common);
 }
 
-static bool
-type_idx_equal(uint32 type_idx1, uint32 type_idx2)
-{
-    return (type_idx1 == type_idx2) ? true : false;
-}
-
 bool
 wasm_refheaptype_equal(const RefHeapType_Common *ref_heap_type1,
                        const RefHeapType_Common *ref_heap_type2,
@@ -673,8 +762,16 @@ wasm_refheaptype_equal(const RefHeapType_Common *ref_heap_type1,
     if (ref_heap_type1->heap_type != ref_heap_type2->heap_type) {
         if (wasm_is_refheaptype_typeidx(ref_heap_type1)
             && wasm_is_refheaptype_typeidx(ref_heap_type2)) {
-            return type_idx_equal(ref_heap_type1->heap_type,
-                                  ref_heap_type2->heap_type);
+            if (ref_heap_type1->heap_type == ref_heap_type2->heap_type)
+                return true;
+            else
+                /* the type_count may be 0 when called from reftype_equal */
+                return ((uint32)ref_heap_type1->heap_type < type_count
+                        && (uint32)ref_heap_type2->heap_type < type_count
+                        && types[ref_heap_type1->heap_type]
+                               == types[ref_heap_type2->heap_type])
+                           ? true
+                           : false;
         }
         return false;
     }
@@ -835,6 +932,13 @@ wasm_type_is_supers_of(const WASMType *type1, const WASMType *type2)
     return false;
 }
 
+bool
+wasm_func_type_is_super_of(const WASMFuncType *type1, const WASMFuncType *type2)
+{
+    return wasm_type_is_supers_of((const WASMType *)type1,
+                                  (const WASMType *)type2);
+}
+
 bool
 wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
                            uint8 type2, const WASMRefType *ref_type2,
@@ -914,14 +1018,15 @@ wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
 #endif
     else if (type1 == REF_TYPE_HT_NULLABLE) {
         if (wasm_is_refheaptype_typeidx(&ref_type1->ref_ht_common)) {
+            bh_assert((uint32)ref_type1->ref_ht_typeidx.type_idx < type_count);
             /* reftype1 is (ref null $t) */
             if (type2 == REF_TYPE_HT_NULLABLE && ref_type2 != NULL
                 && wasm_is_refheaptype_typeidx(&ref_type2->ref_ht_common)) {
-                return type_idx_equal(ref_type1->ref_ht_typeidx.type_idx,
-                                      ref_type2->ref_ht_typeidx.type_idx)
-                       || wasm_type_is_supers_of(
-                           types[ref_type2->ref_ht_typeidx.type_idx],
-                           types[ref_type1->ref_ht_typeidx.type_idx]);
+                bh_assert((uint32)ref_type2->ref_ht_typeidx.type_idx
+                          < type_count);
+                return wasm_type_is_supers_of(
+                    types[ref_type2->ref_ht_typeidx.type_idx],
+                    types[ref_type1->ref_ht_typeidx.type_idx]);
             }
             else if (types[ref_type1->ref_ht_typeidx.type_idx]->type_flag
                      == WASM_TYPE_STRUCT)
@@ -963,16 +1068,17 @@ wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
     else if (type1 == REF_TYPE_HT_NON_NULLABLE) {
         bh_assert(ref_type1);
         if (wasm_is_refheaptype_typeidx(&ref_type1->ref_ht_common)) {
+            bh_assert((uint32)ref_type1->ref_ht_typeidx.type_idx < type_count);
             /* reftype1 is (ref $t) */
             if ((type2 == REF_TYPE_HT_NULLABLE
                  || type2 == REF_TYPE_HT_NON_NULLABLE)
                 && ref_type2 != NULL
                 && wasm_is_refheaptype_typeidx(&ref_type2->ref_ht_common)) {
-                return type_idx_equal(ref_type1->ref_ht_typeidx.type_idx,
-                                      ref_type2->ref_ht_typeidx.type_idx)
-                       || wasm_type_is_supers_of(
-                           types[ref_type2->ref_ht_typeidx.type_idx],
-                           types[ref_type1->ref_ht_typeidx.type_idx]);
+                bh_assert((uint32)ref_type2->ref_ht_typeidx.type_idx
+                          < type_count);
+                return wasm_type_is_supers_of(
+                    types[ref_type2->ref_ht_typeidx.type_idx],
+                    types[ref_type1->ref_ht_typeidx.type_idx]);
             }
             else if (types[ref_type1->ref_ht_typeidx.type_idx]->type_flag
                      == WASM_TYPE_STRUCT) {

+ 6 - 0
core/iwasm/common/gc/gc_type.h

@@ -47,6 +47,12 @@ wasm_func_type_is_subtype_of(const WASMFuncType *type1,
                              const WASMFuncType *type2,
                              const WASMTypePtr *types, uint32 type_count);
 
+/* Whether func type1 is one of super types of func type2,
+   used for the func type check in call_indirect/call_ref opcodes */
+bool
+wasm_func_type_is_super_of(const WASMFuncType *type1,
+                           const WASMFuncType *type2);
+
 /* Whether func type1's result types are subtype of
    func type2's result types */
 bool

+ 33 - 19
core/iwasm/common/wasm_application.c

@@ -61,7 +61,7 @@ static union {
  * Implementation of wasm_application_execute_main()
  */
 static bool
-check_main_func_type(const WASMFuncType *type)
+check_main_func_type(const WASMFuncType *type, bool is_memory64)
 {
     if (!(type->param_count == 0 || type->param_count == 2)
         || type->result_count > 1) {
@@ -72,7 +72,8 @@ check_main_func_type(const WASMFuncType *type)
 
     if (type->param_count == 2
         && !(type->types[0] == VALUE_TYPE_I32
-             && type->types[1] == VALUE_TYPE_I32)) {
+             && type->types[1]
+                    == (is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32))) {
         LOG_ERROR(
             "WASM execute application failed: invalid main function type.\n");
         return false;
@@ -94,14 +95,18 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
     WASMFunctionInstanceCommon *func;
     WASMFuncType *func_type = NULL;
     WASMExecEnv *exec_env = NULL;
-    uint32 argc1 = 0, argv1[2] = { 0 };
+    uint32 argc1 = 0, argv1[3] = { 0 };
     uint32 total_argv_size = 0;
     uint64 total_size;
-    uint32 argv_buf_offset = 0;
+    uint64 argv_buf_offset = 0;
     int32 i;
     char *argv_buf, *p, *p_end;
     uint32 *argv_offsets, module_type;
-    bool ret, is_import_func = true;
+    bool ret, is_import_func = true, is_memory64 = false;
+#if WASM_ENABLE_MEMORY64 != 0
+    WASMModuleInstance *wasm_module_inst = (WASMModuleInstance *)module_inst;
+    is_memory64 = wasm_module_inst->memories[0]->is_memory64;
+#endif
 
     exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
     if (!exec_env) {
@@ -147,10 +152,10 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
     }
 #endif /* end of WASM_ENABLE_LIBC_WASI */
 
-    if (!(func = wasm_runtime_lookup_function(module_inst, "main", NULL))
-        && !(func = wasm_runtime_lookup_function(module_inst,
-                                                 "__main_argc_argv", NULL))
-        && !(func = wasm_runtime_lookup_function(module_inst, "_main", NULL))) {
+    if (!(func = wasm_runtime_lookup_function(module_inst, "main"))
+        && !(func =
+                 wasm_runtime_lookup_function(module_inst, "__main_argc_argv"))
+        && !(func = wasm_runtime_lookup_function(module_inst, "_main"))) {
 #if WASM_ENABLE_LIBC_WASI != 0
         wasm_runtime_set_exception(
             module_inst, "lookup the entry point symbol (like _start, main, "
@@ -187,7 +192,7 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
         return false;
     }
 
-    if (!check_main_func_type(func_type)) {
+    if (!check_main_func_type(func_type, is_memory64)) {
         wasm_runtime_set_exception(module_inst,
                                    "invalid function type of main function");
         return false;
@@ -202,7 +207,7 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
 
         if (total_size >= UINT32_MAX
             || !(argv_buf_offset = wasm_runtime_module_malloc(
-                     module_inst, (uint32)total_size, (void **)&argv_buf))) {
+                     module_inst, total_size, (void **)&argv_buf))) {
             wasm_runtime_set_exception(module_inst, "allocate memory failed");
             return false;
         }
@@ -214,14 +219,25 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
         for (i = 0; i < argc; i++) {
             bh_memcpy_s(p, (uint32)(p_end - p), argv[i],
                         (uint32)(strlen(argv[i]) + 1));
-            argv_offsets[i] = argv_buf_offset + (uint32)(p - argv_buf);
+            argv_offsets[i] = (uint32)argv_buf_offset + (uint32)(p - argv_buf);
             p += strlen(argv[i]) + 1;
         }
 
-        argc1 = 2;
         argv1[0] = (uint32)argc;
-        argv1[1] =
-            (uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
+#if WASM_ENABLE_MEMORY64 != 0
+        if (is_memory64) {
+            argc1 = 3;
+            uint64 app_addr =
+                wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
+            PUT_I64_TO_ADDR(&argv[1], app_addr);
+        }
+        else
+#endif
+        {
+            argc1 = 2;
+            argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst,
+                                                               argv_offsets);
+        }
     }
 
     ret = wasm_runtime_call_wasm(exec_env, func, argc1, argv1);
@@ -336,8 +352,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
     bh_assert(argc >= 0);
     LOG_DEBUG("call a function \"%s\" with %d arguments", name, argc);
 
-    if (!(target_func =
-              wasm_runtime_lookup_function(module_inst, name, NULL))) {
+    if (!(target_func = wasm_runtime_lookup_function(module_inst, name))) {
         snprintf(buf, sizeof(buf), "lookup function %s failed", name);
         wasm_runtime_set_exception(module_inst, buf);
         goto fail;
@@ -563,8 +578,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
                         is_anyref = true;
                     }
 
-                    if (wasm_is_type_multi_byte_type(
-                            type->types[type->param_count + i])) {
+                    if (wasm_is_type_multi_byte_type(type->types[i])) {
                         WASMRefType *ref_type = ref_type_map->ref_type;
                         if (wasm_is_refheaptype_common(
                                 &ref_type->ref_ht_common)) {

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

@@ -2234,7 +2234,8 @@ quit:
 #endif /* WASM_ENABLE_WASM_CACHE != 0 */
 
 wasm_module_t *
-wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
+wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
+                   const LoadArgs *args)
 {
     char error_buf[128] = { 0 };
     wasm_module_ex_t *module_ex = NULL;
@@ -2290,8 +2291,8 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
     if (!module_ex->binary->data)
         goto free_binary;
 
-    module_ex->module_comm_rt = wasm_runtime_load(
-        (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size,
+    module_ex->module_comm_rt = wasm_runtime_load_ex(
+        (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size, args,
         error_buf, (uint32)sizeof(error_buf));
     if (!(module_ex->module_comm_rt)) {
         LOG_ERROR("%s", error_buf);
@@ -2337,6 +2338,14 @@ quit:
     return NULL;
 }
 
+wasm_module_t *
+wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
+{
+    LoadArgs args = { 0 };
+    args.name = "";
+    return wasm_module_new_ex(store, binary, &args);
+}
+
 bool
 wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary)
 {
@@ -2949,6 +2958,34 @@ wasm_shared_module_delete(own wasm_shared_module_t *shared_module)
     wasm_module_delete_internal((wasm_module_t *)shared_module);
 }
 
+bool
+wasm_module_set_name(wasm_module_t *module, const char *name)
+{
+    char error_buf[256] = { 0 };
+    wasm_module_ex_t *module_ex = NULL;
+
+    if (!module)
+        return false;
+
+    module_ex = module_to_module_ext(module);
+    bool ret = wasm_runtime_set_module_name(module_ex->module_comm_rt, name,
+                                            error_buf, sizeof(error_buf) - 1);
+    if (!ret)
+        LOG_WARNING("set module name failed: %s", error_buf);
+    return ret;
+}
+
+const char *
+wasm_module_get_name(wasm_module_t *module)
+{
+    wasm_module_ex_t *module_ex = NULL;
+    if (!module)
+        return "";
+
+    module_ex = module_to_module_ext(module);
+    return wasm_runtime_get_module_name(module_ex->module_comm_rt);
+}
+
 static wasm_func_t *
 wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type,
                     wasm_func_callback_t func_callback)
@@ -3959,7 +3996,7 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
         if (index >= table_interp->cur_size) {
             return NULL;
         }
-        ref_idx = table_interp->elems[index];
+        ref_idx = (uint32)table_interp->elems[index];
     }
 #endif
 
@@ -3970,7 +4007,7 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
         if (index >= table_aot->cur_size) {
             return NULL;
         }
-        ref_idx = table_aot->elems[index];
+        ref_idx = (uint32)table_aot->elems[index];
     }
 #endif
 
@@ -4872,6 +4909,19 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
                             const wasm_extern_vec_t *imports,
                             own wasm_trap_t **trap, const uint32 stack_size,
                             const uint32 heap_size)
+{
+    InstantiationArgs inst_args = { 0 };
+    inst_args.default_stack_size = stack_size;
+    inst_args.host_managed_heap_size = heap_size;
+    return wasm_instance_new_with_args_ex(store, module, imports, trap,
+                                          &inst_args);
+}
+
+wasm_instance_t *
+wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module,
+                               const wasm_extern_vec_t *imports,
+                               own wasm_trap_t **trap,
+                               const InstantiationArgs *inst_args)
 {
     char sub_error_buf[128] = { 0 };
     char error_buf[256] = { 0 };
@@ -4911,8 +4961,8 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
      * will do the linking result check at the end of wasm_runtime_instantiate
      */
 
-    instance->inst_comm_rt = wasm_runtime_instantiate(
-        *module, stack_size, heap_size, sub_error_buf, sizeof(sub_error_buf));
+    instance->inst_comm_rt = wasm_runtime_instantiate_ex(
+        *module, inst_args, sub_error_buf, sizeof(sub_error_buf));
     if (!instance->inst_comm_rt) {
         goto failed;
     }
@@ -4926,19 +4976,17 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
     /* create the c-api func import list */
 #if WASM_ENABLE_INTERP != 0
     if (instance->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
-        WASMModuleInstanceExtra *e =
-            ((WASMModuleInstance *)instance->inst_comm_rt)->e;
-        p_func_imports = &(e->common.c_api_func_imports);
+        WASMModuleInstance *wasm_module_inst =
+            (WASMModuleInstance *)instance->inst_comm_rt;
+        p_func_imports = &(wasm_module_inst->c_api_func_imports);
         import_func_count = MODULE_INTERP(module)->import_function_count;
     }
 #endif
 #if WASM_ENABLE_AOT != 0
     if (instance->inst_comm_rt->module_type == Wasm_Module_AoT) {
-        AOTModuleInstanceExtra *e =
-            (AOTModuleInstanceExtra *)((AOTModuleInstance *)
-                                           instance->inst_comm_rt)
-                ->e;
-        p_func_imports = &(e->common.c_api_func_imports);
+        AOTModuleInstance *aot_module_inst =
+            (AOTModuleInstance *)instance->inst_comm_rt;
+        p_func_imports = &(aot_module_inst->c_api_func_imports);
         import_func_count = MODULE_AOT(module)->import_func_count;
     }
 #endif
@@ -4952,7 +5000,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
         goto failed;
     }
 
-    /* fill in module_inst->e->c_api_func_imports */
+    /* fill in module_inst->c_api_func_imports */
     for (i = 0; imports && i < imports->num_elems; i++) {
         wasm_func_t *func_host = NULL;
         wasm_extern_t *in = imports->data[i];

+ 6 - 6
core/iwasm/common/wasm_exec_env.c

@@ -135,9 +135,9 @@ wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
     /* Set the aux_stack_boundary and aux_stack_bottom */
     if (module_inst->module_type == Wasm_Module_Bytecode) {
         WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
-        exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
-        exec_env->aux_stack_boundary.boundary =
-            module->aux_stack_bottom - module->aux_stack_size;
+        exec_env->aux_stack_bottom = (uintptr_t)module->aux_stack_bottom;
+        exec_env->aux_stack_boundary =
+            (uintptr_t)module->aux_stack_bottom - module->aux_stack_size;
 #if WASM_ENABLE_GC != 0
         gc_heap_handle =
             ((WASMModuleInstance *)module_inst)->e->common.gc_heap_pool;
@@ -149,9 +149,9 @@ wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
     if (module_inst->module_type == Wasm_Module_AoT) {
         AOTModule *module =
             (AOTModule *)((AOTModuleInstance *)module_inst)->module;
-        exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
-        exec_env->aux_stack_boundary.boundary =
-            module->aux_stack_bottom - module->aux_stack_size;
+        exec_env->aux_stack_bottom = (uintptr_t)module->aux_stack_bottom;
+        exec_env->aux_stack_boundary =
+            (uintptr_t)module->aux_stack_bottom - module->aux_stack_size;
 #if WASM_ENABLE_GC != 0
         gc_heap_handle =
             ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)

+ 6 - 10
core/iwasm/common/wasm_exec_env.h

@@ -75,16 +75,10 @@ typedef struct WASMExecEnv {
     WASMSuspendFlags suspend_flags;
 
     /* Auxiliary stack boundary */
-    union {
-        uint32 boundary;
-        uintptr_t __padding__;
-    } aux_stack_boundary;
+    uintptr_t aux_stack_boundary;
 
     /* Auxiliary stack bottom */
-    union {
-        uint32 bottom;
-        uintptr_t __padding__;
-    } aux_stack_bottom;
+    uintptr_t aux_stack_bottom;
 
 #if WASM_ENABLE_AOT != 0
     /* Native symbol list, reserved */
@@ -145,6 +139,9 @@ typedef struct WASMExecEnv {
 
     /* whether current thread is detached */
     bool thread_is_detached;
+
+    /* whether the aux stack is allocated */
+    bool is_aux_stack_allocated;
 #endif
 
 #if WASM_ENABLE_GC != 0
@@ -213,8 +210,7 @@ wasm_exec_env_destroy(WASMExecEnv *exec_env);
 static inline bool
 wasm_exec_env_is_aux_stack_managed_by_runtime(WASMExecEnv *exec_env)
 {
-    return exec_env->aux_stack_boundary.boundary != 0
-           || exec_env->aux_stack_bottom.bottom != 0;
+    return exec_env->aux_stack_boundary != 0 || exec_env->aux_stack_bottom != 0;
 }
 
 /**

+ 166 - 66
core/iwasm/common/wasm_memory.c

@@ -29,24 +29,43 @@ static void *enlarge_memory_error_user_data;
 
 #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
 static void *allocator_user_data = NULL;
-static void *(*malloc_func)(void *user_data, unsigned int size) = NULL;
-static void *(*realloc_func)(void *user_data, void *ptr,
-                             unsigned int size) = NULL;
-static void (*free_func)(void *user_data, void *ptr) = NULL;
-#else
-static void *(*malloc_func)(unsigned int size) = NULL;
-static void *(*realloc_func)(void *ptr, unsigned int size) = NULL;
-static void (*free_func)(void *ptr) = NULL;
 #endif
 
+static void *(*malloc_func)(
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+    mem_alloc_usage_t usage,
+#endif
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
+#endif
+    unsigned int size) = NULL;
+
+static void *(*realloc_func)(
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+    mem_alloc_usage_t usage, bool full_size_mmaped,
+#endif
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
+#endif
+    void *ptr, unsigned int size) = NULL;
+
+static void (*free_func)(
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+    mem_alloc_usage_t usage,
+#endif
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+    void *user_data,
+#endif
+    void *ptr) = NULL;
+
 static unsigned int global_pool_size;
 
-static uint32
+static uint64
 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;
+    return aligned_size;
 }
 
 static bool
@@ -177,11 +196,14 @@ wasm_runtime_malloc_internal(unsigned int size)
         return mem_allocator_malloc(pool_allocator, size);
     }
     else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
+        return malloc_func(
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+            Alloc_For_Runtime,
+#endif
 #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
-        return malloc_func(allocator_user_data, size);
-#else
-        return malloc_func(size);
+            allocator_user_data,
 #endif
+            size);
     }
     else {
         return os_malloc(size);
@@ -201,11 +223,14 @@ wasm_runtime_realloc_internal(void *ptr, unsigned int size)
     }
     else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
         if (realloc_func)
+            return realloc_func(
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+                Alloc_For_Runtime, false,
+#endif
 #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
-            return realloc_func(allocator_user_data, ptr, size);
-#else
-            return realloc_func(ptr, size);
+                allocator_user_data,
 #endif
+                ptr, size);
         else
             return NULL;
     }
@@ -233,11 +258,14 @@ wasm_runtime_free_internal(void *ptr)
         mem_allocator_free(pool_allocator, ptr);
     }
     else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
+        free_func(
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+            Alloc_For_Runtime,
+#endif
 #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
-        free_func(allocator_user_data, ptr);
-#else
-        free_func(ptr);
+            allocator_user_data,
 #endif
+            ptr);
     }
     else {
         os_free(ptr);
@@ -282,10 +310,11 @@ wasm_runtime_get_mem_alloc_info(mem_alloc_info_t *mem_alloc_info)
 
 bool
 wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
-                               uint32 app_offset, uint32 size)
+                               uint64 app_offset, uint64 size)
 {
     WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
     WASMMemoryInstance *memory_inst;
+    uint64 max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
 
     bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
               || module_inst_comm->module_type == Wasm_Module_AoT);
@@ -299,8 +328,13 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
         goto fail;
     }
 
-    /* integer overflow check */
-    if (app_offset > UINT32_MAX - size) {
+#if WASM_ENABLE_MEMORY64 != 0
+    if (memory_inst->is_memory64)
+        max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
+#endif
+    /* boundary overflow check */
+    if (size > max_linear_memory_size
+        || app_offset > max_linear_memory_size - size) {
         goto fail;
     }
 
@@ -320,10 +354,10 @@ fail:
 
 bool
 wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
-                                   uint32 app_str_offset)
+                                   uint64 app_str_offset)
 {
     WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
-    uint32 app_end_offset;
+    uint64 app_end_offset, max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
     char *str, *str_end;
 
     bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
@@ -337,6 +371,16 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
                                          &app_end_offset))
         goto fail;
 
+#if WASM_ENABLE_MEMORY64 != 0
+    if (module_inst->memories[0]->is_memory64)
+        max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
+#endif
+    /* boundary overflow check, max start offset can only be size - 1, while end
+     * offset can be size */
+    if (app_str_offset >= max_linear_memory_size
+        || app_end_offset > max_linear_memory_size)
+        goto fail;
+
     str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset);
     str_end = str + (app_end_offset - app_str_offset);
     while (str < str_end && *str != '\0')
@@ -352,11 +396,12 @@ fail:
 
 bool
 wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
-                                  void *native_ptr, uint32 size)
+                                  void *native_ptr, uint64 size)
 {
     WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
     WASMMemoryInstance *memory_inst;
     uint8 *addr = (uint8 *)native_ptr;
+    uint64 max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
 
     bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
               || module_inst_comm->module_type == Wasm_Module_AoT);
@@ -370,8 +415,12 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
         goto fail;
     }
 
-    /* integer overflow check */
-    if ((uintptr_t)addr > UINTPTR_MAX - size) {
+#if WASM_ENABLE_MEMORY64 != 0
+    if (memory_inst->is_memory64)
+        max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
+#endif
+    /* boundary overflow check */
+    if (size > max_linear_memory_size || (uintptr_t)addr > UINTPTR_MAX - size) {
         goto fail;
     }
 
@@ -392,7 +441,7 @@ fail:
 
 void *
 wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
-                                uint32 app_offset)
+                                uint64 app_offset)
 {
     WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
     WASMMemoryInstance *memory_inst;
@@ -411,7 +460,7 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
 
     SHARED_MEMORY_LOCK(memory_inst);
 
-    addr = memory_inst->memory_data + app_offset;
+    addr = memory_inst->memory_data + (uintptr_t)app_offset;
 
     if (bounds_checks) {
         if (memory_inst->memory_data <= addr
@@ -419,18 +468,16 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
             SHARED_MEMORY_UNLOCK(memory_inst);
             return addr;
         }
-    }
-    /* If bounds checks is disabled, return the address directly */
-    else if (app_offset != 0) {
         SHARED_MEMORY_UNLOCK(memory_inst);
-        return addr;
+        return NULL;
     }
 
+    /* If bounds checks is disabled, return the address directly */
     SHARED_MEMORY_UNLOCK(memory_inst);
-    return NULL;
+    return addr;
 }
 
-uint32
+uint64
 wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
                                 void *native_ptr)
 {
@@ -438,7 +485,7 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
     WASMMemoryInstance *memory_inst;
     uint8 *addr = (uint8 *)native_ptr;
     bool bounds_checks;
-    uint32 ret;
+    uint64 ret;
 
     bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
               || module_inst_comm->module_type == Wasm_Module_AoT);
@@ -455,14 +502,14 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
     if (bounds_checks) {
         if (memory_inst->memory_data <= addr
             && addr < memory_inst->memory_data_end) {
-            ret = (uint32)(addr - memory_inst->memory_data);
+            ret = (uint64)(addr - memory_inst->memory_data);
             SHARED_MEMORY_UNLOCK(memory_inst);
             return ret;
         }
     }
     /* If bounds checks is disabled, return the offset directly */
     else if (addr != NULL) {
-        ret = (uint32)(addr - memory_inst->memory_data);
+        ret = (uint64)(addr - memory_inst->memory_data);
         SHARED_MEMORY_UNLOCK(memory_inst);
         return ret;
     }
@@ -473,12 +520,12 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
 
 bool
 wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
-                                uint32 app_offset, uint32 *p_app_start_offset,
-                                uint32 *p_app_end_offset)
+                                uint64 app_offset, uint64 *p_app_start_offset,
+                                uint64 *p_app_end_offset)
 {
     WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
     WASMMemoryInstance *memory_inst;
-    uint32 memory_data_size;
+    uint64 memory_data_size;
 
     bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
               || module_inst_comm->module_type == Wasm_Module_AoT);
@@ -541,19 +588,21 @@ wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst_comm,
 
 bool
 wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
-                                uint32 app_buf_addr, uint32 app_buf_size,
+                                uint64 app_buf_addr, uint64 app_buf_size,
                                 void **p_native_addr)
 {
     WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
     uint8 *native_addr;
     bool bounds_checks;
 
+    bh_assert(app_buf_addr <= UINTPTR_MAX && app_buf_size <= UINTPTR_MAX);
+
     if (!memory_inst) {
         wasm_set_exception(module_inst, "out of bounds memory access");
         return false;
     }
 
-    native_addr = memory_inst->memory_data + app_buf_addr;
+    native_addr = memory_inst->memory_data + (uintptr_t)app_buf_addr;
 
     bounds_checks = is_bounds_checks_enabled((wasm_module_inst_t)module_inst);
 
@@ -695,9 +744,9 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
 {
     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 num_bytes_per_page, heap_size;
     uint32 cur_page_count, max_page_count, total_page_count;
-    uint64 total_size_new;
+    uint64 total_size_old = 0, total_size_new;
     bool ret = true, full_size_mmaped;
     enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR;
 
@@ -741,18 +790,36 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
         goto return_func;
     }
 
-    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;
-    }
+    bh_assert(total_size_new
+              <= GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64));
 
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+    if (!(memory_data_new =
+              realloc_func(Alloc_For_LinearMemory, full_size_mmaped,
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+                           NULL,
+#endif
+                           memory_data_old, total_size_new))) {
+        ret = false;
+        goto return_func;
+    }
+    if (heap_size > 0) {
+        if (mem_allocator_migrate(memory->heap_handle,
+                                  (char *)heap_data_old
+                                      + (memory_data_new - memory_data_old),
+                                  heap_size)
+            != 0) {
+            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;
+#else
     if (full_size_mmaped) {
 #ifdef BH_PLATFORM_WINDOWS
         if (!os_mem_commit(memory->memory_data_end,
-                           (uint32)total_size_new - total_size_old,
+                           (mem_offset_t)(total_size_new - total_size_old),
                            MMAP_PROT_READ | MMAP_PROT_WRITE)) {
             ret = false;
             goto return_func;
@@ -760,12 +827,12 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
 #endif
 
         if (os_mprotect(memory->memory_data_end,
-                        (uint32)total_size_new - total_size_old,
+                        (mem_offset_t)(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);
+                            (mem_offset_t)(total_size_new - total_size_old));
 #endif
             ret = false;
             goto return_func;
@@ -780,9 +847,9 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
             }
         }
 
-        if (!(memory_data_new = wasm_mremap_linear_memory(
-                  memory_data_old, total_size_old, (uint32)total_size_new,
-                  (uint32)total_size_new))) {
+        if (!(memory_data_new =
+                  wasm_mremap_linear_memory(memory_data_old, total_size_old,
+                                            total_size_new, total_size_new))) {
             ret = false;
             goto return_func;
         }
@@ -807,20 +874,21 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
         os_writegsbase(memory_data_new);
 #endif
     }
+#endif /* end of WASM_MEM_ALLOC_WITH_USAGE */
 
     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;
+    SET_LINEAR_MEMORY_SIZE(memory, total_size_new);
+    memory->memory_data_end = memory->memory_data + total_size_new;
 
     wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
 
 return_func:
     if (!ret && enlarge_memory_error_cb) {
-        WASMExecEnv *exec_env =
-            wasm_runtime_get_cur_exec_env((WASMModuleInstanceCommon *)module);
+        WASMExecEnv *exec_env = module->cur_exec_env;
         bh_assert(exec_env);
+
         enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
                                 failure_reason,
                                 (WASMModuleInstanceCommon *)module, exec_env,
@@ -879,15 +947,27 @@ wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst)
 #else
     map_size = 8 * (uint64)BH_GB;
 #endif
+
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+    (void)map_size;
+    free_func(Alloc_For_LinearMemory,
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+              NULL,
+#endif
+              memory_inst->memory_data);
+#else
     wasm_munmap_linear_memory(memory_inst->memory_data,
                               memory_inst->memory_data_size, map_size);
+#endif
+
     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)
+                            bool is_memory64, uint64 num_bytes_per_page,
+                            uint64 init_page_count, uint64 max_page_count,
+                            uint64 *memory_data_size)
 {
     uint64 map_size, page_size;
 
@@ -916,13 +996,33 @@ wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
 
     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 WASM_ENABLE_MEMORY64 != 0
+    if (is_memory64) {
+        bh_assert(*memory_data_size <= MAX_LINEAR_MEM64_MEMORY_SIZE);
+    }
+    else
+#endif
+    {
+        bh_assert(*memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
+    }
+    *memory_data_size = align_as_and_cast(*memory_data_size, page_size);
 
     if (map_size > 0) {
+#if WASM_MEM_ALLOC_WITH_USAGE != 0
+        (void)wasm_mmap_linear_memory;
+        if (!(*data = malloc_func(Alloc_For_LinearMemory,
+#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
+                                  NULL,
+#endif
+                                  *memory_data_size))) {
+            return BHT_ERROR;
+        }
+#else
         if (!(*data = wasm_mmap_linear_memory(map_size, *memory_data_size))) {
             return BHT_ERROR;
         }
+#endif
     }
 
     return BHT_OK;

+ 23 - 5
core/iwasm/common/wasm_memory.h

@@ -9,16 +9,33 @@
 #include "bh_common.h"
 #include "../include/wasm_export.h"
 #include "../interpreter/wasm_runtime.h"
+#include "../common/wasm_shared_memory.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if WASM_ENABLE_SHARED_MEMORY != 0
+#if WASM_ENABLE_SHARED_MEMORY != 0 && BH_ATOMIC_64_IS_ATOMIC != 0
 #define GET_LINEAR_MEMORY_SIZE(memory) \
-    BH_ATOMIC_32_LOAD(memory->memory_data_size)
+    BH_ATOMIC_64_LOAD(memory->memory_data_size)
 #define SET_LINEAR_MEMORY_SIZE(memory, size) \
-    BH_ATOMIC_32_STORE(memory->memory_data_size, size)
+    BH_ATOMIC_64_STORE(memory->memory_data_size, size)
+#elif WASM_ENABLE_SHARED_MEMORY != 0
+static inline uint64
+GET_LINEAR_MEMORY_SIZE(const WASMMemoryInstance *memory)
+{
+    SHARED_MEMORY_LOCK(memory);
+    uint64 memory_data_size = BH_ATOMIC_64_LOAD(memory->memory_data_size);
+    SHARED_MEMORY_UNLOCK(memory);
+    return memory_data_size;
+}
+static inline void
+SET_LINEAR_MEMORY_SIZE(WASMMemoryInstance *memory, uint64 size)
+{
+    SHARED_MEMORY_LOCK(memory);
+    BH_ATOMIC_64_STORE(memory->memory_data_size, size);
+    SHARED_MEMORY_UNLOCK(memory);
+}
 #else
 #define GET_LINEAR_MEMORY_SIZE(memory) memory->memory_data_size
 #define SET_LINEAR_MEMORY_SIZE(memory, size) memory->memory_data_size = size
@@ -47,8 +64,9 @@ 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);
+                            bool is_memory64, uint64 num_bytes_per_page,
+                            uint64 init_page_count, uint64 max_page_count,
+                            uint64 *memory_data_size);
 
 #ifdef __cplusplus
 }

+ 8 - 3
core/iwasm/common/wasm_native.c

@@ -84,9 +84,9 @@ compare_type_with_signautre(uint8 type, const char signature)
     if ('r' == signature
 #if WASM_ENABLE_GC != 0
 #if WASM_ENABLE_STRINGREF != 0
-        && (type >= REF_TYPE_STRINGVIEWITER && type <= REF_TYPE_FUNCREF)
+        && (type >= REF_TYPE_STRINGVIEWITER && type <= REF_TYPE_NULLFUNCREF)
 #else
-        && (type >= REF_TYPE_NULLREF && type <= REF_TYPE_FUNCREF)
+        && (type >= REF_TYPE_HT_NULLABLE && type <= REF_TYPE_NULLFUNCREF)
 #endif
 #else
         && type == VALUE_TYPE_EXTERNREF
@@ -567,7 +567,12 @@ wasm_native_init()
 
 #if WASM_ENABLE_WASI_NN != 0
     n_native_symbols = get_wasi_nn_export_apis(&native_symbols);
-    if (!wasm_native_register_natives("wasi_nn", native_symbols,
+#if WASM_ENABLE_WASI_EPHEMERAL_NN != 0
+#define wasi_nn_module_name "wasi_ephemeral_nn"
+#else /* WASM_ENABLE_WASI_EPHEMERAL_NN == 0 */
+#define wasi_nn_module_name "wasi_nn"
+#endif /* WASM_ENABLE_WASI_EPHEMERAL_NN != 0 */
+    if (!wasm_native_register_natives(wasi_nn_module_name, native_symbols,
                                       n_native_symbols))
         goto fail;
 #endif

File diff suppressed because it is too large
+ 511 - 99
core/iwasm/common/wasm_runtime_common.c


+ 47 - 32
core/iwasm/common/wasm_runtime_common.h

@@ -373,7 +373,7 @@ typedef struct WASMModuleCommon {
 
     /* 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
+       Typically, it should be accessed by casting to the corresponding
        actual module_type dependent structure, not via this member. */
     uint8 module_data[1];
 } WASMModuleCommon;
@@ -389,7 +389,7 @@ typedef struct WASMModuleInstanceCommon {
 
     /* 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
+       Typically, it should be accessed by casting to the corresponding
        actual module_type dependent structure, not via this member. */
     uint8 module_inst_data[1];
 } WASMModuleInstanceCommon;
@@ -413,10 +413,10 @@ typedef struct WASMModuleMemConsumption {
 } WASMModuleMemConsumption;
 
 typedef struct WASMModuleInstMemConsumption {
-    uint32 total_size;
+    uint64 total_size;
     uint32 module_inst_struct_size;
-    uint32 memories_size;
     uint32 app_heap_size;
+    uint64 memories_size;
     uint32 tables_size;
     uint32 globals_size;
     uint32 functions_size;
@@ -561,13 +561,18 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
 WASM_RUNTIME_API_EXTERN void
 wasm_runtime_unload(WASMModuleCommon *module);
 
+/* Internal API */
+uint32
+wasm_runtime_get_max_mem(uint32 max_memory_pages, uint32 module_init_page_count,
+                         uint32 module_max_page_count);
+
 /* Internal API */
 WASMModuleInstanceCommon *
 wasm_runtime_instantiate_internal(WASMModuleCommon *module,
                                   WASMModuleInstanceCommon *parent,
                                   WASMExecEnv *exec_env_main, uint32 stack_size,
-                                  uint32 heap_size, char *error_buf,
-                                  uint32 error_buf_size);
+                                  uint32 heap_size, uint32 max_memory_pages,
+                                  char *error_buf, uint32 error_buf_size);
 
 /* Internal API */
 void
@@ -580,6 +585,12 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 default_stack_size,
                          uint32 host_managed_heap_size, char *error_buf,
                          uint32 error_buf_size);
 
+/* See wasm_export.h for description */
+WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon *
+wasm_runtime_instantiate_ex(WASMModuleCommon *module,
+                            const InstantiationArgs *args, char *error_buf,
+                            uint32 error_buf_size);
+
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_set_running_mode(wasm_module_inst_t module_inst,
@@ -600,7 +611,7 @@ wasm_runtime_get_module(WASMModuleInstanceCommon *module_inst);
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN WASMFunctionInstanceCommon *
 wasm_runtime_lookup_function(WASMModuleInstanceCommon *const module_inst,
-                             const char *name, const char *signature);
+                             const char *name);
 
 /* Internal API */
 WASMFuncType *
@@ -659,10 +670,6 @@ wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data);
 WASM_RUNTIME_API_EXTERN void *
 wasm_runtime_get_user_data(WASMExecEnv *exec_env);
 
-/* Get the exec_env currently used by the module instance */
-WASMExecEnv *
-wasm_runtime_get_cur_exec_env(const WASMModuleInstanceCommon *module_inst);
-
 #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN void
@@ -763,66 +770,66 @@ WASM_RUNTIME_API_EXTERN void *
 wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst);
 
 /* Internal API */
-uint32
+uint64
 wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst,
-                                    WASMExecEnv *exec_env, uint32 size,
+                                    WASMExecEnv *exec_env, uint64 size,
                                     void **p_native_addr);
 
 /* Internal API */
-uint32
+uint64
 wasm_runtime_module_realloc_internal(WASMModuleInstanceCommon *module_inst,
-                                     WASMExecEnv *exec_env, uint32 ptr,
-                                     uint32 size, void **p_native_addr);
+                                     WASMExecEnv *exec_env, uint64 ptr,
+                                     uint64 size, void **p_native_addr);
 
 /* Internal API */
 void
 wasm_runtime_module_free_internal(WASMModuleInstanceCommon *module_inst,
-                                  WASMExecEnv *exec_env, uint32 ptr);
+                                  WASMExecEnv *exec_env, uint64 ptr);
 
 /* See wasm_export.h for description */
-WASM_RUNTIME_API_EXTERN uint32
-wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint32 size,
+WASM_RUNTIME_API_EXTERN uint64
+wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint64 size,
                            void **p_native_addr);
 
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN void
-wasm_runtime_module_free(WASMModuleInstanceCommon *module_inst, uint32 ptr);
+wasm_runtime_module_free(WASMModuleInstanceCommon *module_inst, uint64 ptr);
 
 /* See wasm_export.h for description */
-WASM_RUNTIME_API_EXTERN uint32
+WASM_RUNTIME_API_EXTERN uint64
 wasm_runtime_module_dup_data(WASMModuleInstanceCommon *module_inst,
-                             const char *src, uint32 size);
+                             const char *src, uint64 size);
 
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst,
-                               uint32 app_offset, uint32 size);
+                               uint64 app_offset, uint64 size);
 
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst,
-                                   uint32 app_str_offset);
+                                   uint64 app_str_offset);
 
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst,
-                                  void *native_ptr, uint32 size);
+                                  void *native_ptr, uint64 size);
 
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN void *
 wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst,
-                                uint32 app_offset);
+                                uint64 app_offset);
 
 /* See wasm_export.h for description */
-WASM_RUNTIME_API_EXTERN uint32
+WASM_RUNTIME_API_EXTERN uint64
 wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst,
                                 void *native_ptr);
 
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst,
-                                uint32 app_offset, uint32 *p_app_start_offset,
-                                uint32 *p_app_end_offset);
+                                uint64 app_offset, uint64 *p_app_start_offset,
+                                uint64 *p_app_end_offset);
 
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN bool
@@ -891,7 +898,8 @@ bool
 wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
                                     WASMModuleInstanceCommon *module_inst,
                                     uint32 stack_size, uint32 heap_size,
-                                    char *error_buf, uint32 error_buf_size);
+                                    uint32 max_memory_pages, char *error_buf,
+                                    uint32 error_buf_size);
 void
 wasm_runtime_sub_module_deinstantiate(WASMModuleInstanceCommon *module_inst);
 #endif
@@ -908,11 +916,11 @@ wasm_runtime_is_built_in_module(const char *module_name);
 
 #if WASM_ENABLE_THREAD_MGR != 0
 bool
-wasm_exec_env_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset,
+wasm_exec_env_get_aux_stack(WASMExecEnv *exec_env, uint64 *start_offset,
                             uint32 *size);
 
 bool
-wasm_exec_env_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset,
+wasm_exec_env_set_aux_stack(WASMExecEnv *exec_env, uint64 start_offset,
                             uint32 size);
 
 WASM_RUNTIME_API_EXTERN void
@@ -1187,6 +1195,13 @@ wasm_runtime_end_blocking_op(WASMExecEnv *exec_env);
 void
 wasm_runtime_interrupt_blocking_op(WASMExecEnv *exec_env);
 
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_detect_native_stack_overflow(WASMExecEnv *exec_env);
+
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
+                                               uint32 requested_size);
+
 #if WASM_ENABLE_LINUX_PERF != 0
 bool
 wasm_runtime_get_linux_perf(void);

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

@@ -281,8 +281,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
     shared_memory_unlock(module_inst->memories[0]);
 
 #if WASM_ENABLE_THREAD_MGR != 0
-    exec_env =
-        wasm_runtime_get_cur_exec_env((WASMModuleInstanceCommon *)module_inst);
+    exec_env = module_inst->cur_exec_env;
     bh_assert(exec_env);
 #endif
 

+ 3 - 3
core/iwasm/compilation/aot.h

@@ -316,11 +316,11 @@ typedef struct AOTCompData {
     uint32 retain_func_index;
 
     uint32 aux_data_end_global_index;
-    uint32 aux_data_end;
+    uint64 aux_data_end;
     uint32 aux_heap_base_global_index;
-    uint32 aux_heap_base;
+    uint64 aux_heap_base;
     uint32 aux_stack_top_global_index;
-    uint32 aux_stack_bottom;
+    uint64 aux_stack_bottom;
     uint32 aux_stack_size;
 
 #if WASM_ENABLE_STRINGREF != 0

+ 7 - 56
core/iwasm/compilation/aot_compiler.c

@@ -330,7 +330,7 @@ aot_gen_commit_values(AOTCompFrame *frame)
         if (!p->dirty)
             continue;
 
-        n = p - frame->lp;
+        n = (uint32)(p - frame->lp);
 
         /* Commit reference flag */
         if (comp_ctx->enable_gc) {
@@ -432,7 +432,7 @@ aot_gen_commit_values(AOTCompFrame *frame)
             continue;
 
         p->dirty = 0;
-        n = p - frame->lp;
+        n = (uint32)(p - frame->lp);
 
         /* Commit values */
         switch (p->type) {
@@ -538,7 +538,7 @@ aot_gen_commit_values(AOTCompFrame *frame)
         /* Clear reference flags for unused stack slots.  */
         for (p = frame->sp; p < end; p++) {
             bh_assert(!p->ref);
-            n = p - frame->lp;
+            n = (uint32)(p - frame->lp);
 
             /* Commit reference flag.  */
             if (p->ref != p->committed_ref - 1) {
@@ -621,7 +621,7 @@ aot_gen_commit_sp_ip(AOTCompFrame *frame, bool commit_sp, bool commit_ip)
     }
 
     if (commit_sp) {
-        n = sp - frame->lp;
+        n = (uint32)(sp - frame->lp);
         value = I32_CONST(offset_of_local(comp_ctx, n));
         if (!value) {
             aot_set_last_error("llvm build const failed");
@@ -966,7 +966,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
         location = dwarf_gen_location(
             comp_ctx, func_ctx,
             (frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
-        LLVMSetCurrentDebugLocation2(comp_ctx->builder, location);
+        if (location != NULL) {
+            LLVMSetCurrentDebugLocation2(comp_ctx->builder, location);
+        }
 #endif
 
         switch (opcode) {
@@ -3450,16 +3452,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
                         break;
                     }
 
-                    case SIMD_i32x4_narrow_i64x2_s:
-                    case SIMD_i32x4_narrow_i64x2_u:
-                    {
-                        if (!aot_compile_simd_i32x4_narrow_i64x2(
-                                comp_ctx, func_ctx,
-                                SIMD_i32x4_narrow_i64x2_s == opcode))
-                            return false;
-                        break;
-                    }
-
                     case SIMD_i32x4_extend_low_i16x8_s:
                     case SIMD_i32x4_extend_high_i16x8_s:
                     {
@@ -3499,16 +3491,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
                         break;
                     }
 
-                    case SIMD_i32x4_add_sat_s:
-                    case SIMD_i32x4_add_sat_u:
-                    {
-                        if (!aot_compile_simd_i32x4_saturate(
-                                comp_ctx, func_ctx, V128_ADD,
-                                opcode == SIMD_i32x4_add_sat_s))
-                            return false;
-                        break;
-                    }
-
                     case SIMD_i32x4_sub:
                     {
                         if (!aot_compile_simd_i32x4_arith(comp_ctx, func_ctx,
@@ -3517,16 +3499,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
                         break;
                     }
 
-                    case SIMD_i32x4_sub_sat_s:
-                    case SIMD_i32x4_sub_sat_u:
-                    {
-                        if (!aot_compile_simd_i32x4_saturate(
-                                comp_ctx, func_ctx, V128_SUB,
-                                opcode == SIMD_i32x4_add_sat_s))
-                            return false;
-                        break;
-                    }
-
                     case SIMD_i32x4_mul:
                     {
                         if (!aot_compile_simd_i32x4_arith(comp_ctx, func_ctx,
@@ -3563,13 +3535,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
                         break;
                     }
 
-                    case SIMD_i32x4_avgr_u:
-                    {
-                        if (!aot_compile_simd_i32x4_avgr_u(comp_ctx, func_ctx))
-                            return false;
-                        break;
-                    }
-
                     case SIMD_i32x4_extmul_low_i16x8_s:
                     case SIMD_i32x4_extmul_high_i16x8_s:
                     {
@@ -3726,13 +3691,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
                         break;
                     }
 
-                    case SIMD_f32x4_round:
-                    {
-                        if (!aot_compile_simd_f32x4_round(comp_ctx, func_ctx))
-                            return false;
-                        break;
-                    }
-
                     case SIMD_f32x4_sqrt:
                     {
                         if (!aot_compile_simd_f32x4_sqrt(comp_ctx, func_ctx))
@@ -3786,13 +3744,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
                         break;
                     }
 
-                    case SIMD_f64x2_round:
-                    {
-                        if (!aot_compile_simd_f64x2_round(comp_ctx, func_ctx))
-                            return false;
-                        break;
-                    }
-
                     case SIMD_f64x2_sqrt:
                     {
                         if (!aot_compile_simd_f64x2_sqrt(comp_ctx, func_ctx))

+ 116 - 93
core/iwasm/compilation/aot_emit_aot_file.c

@@ -25,73 +25,6 @@
         }                                                  \
     } while (0)
 
-#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
-static bool
-check_utf8_str(const uint8 *str, uint32 len)
-{
-    /* The valid ranges are taken from page 125, below link
-       https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */
-    const uint8 *p = str, *p_end = str + len;
-    uint8 chr;
-
-    while (p < p_end) {
-        chr = *p;
-        if (chr < 0x80) {
-            p++;
-        }
-        else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
-            if (p[1] < 0x80 || p[1] > 0xBF) {
-                return false;
-            }
-            p += 2;
-        }
-        else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) {
-            if (chr == 0xE0) {
-                if (p[1] < 0xA0 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
-                    return false;
-                }
-            }
-            else if (chr == 0xED) {
-                if (p[1] < 0x80 || p[1] > 0x9F || p[2] < 0x80 || p[2] > 0xBF) {
-                    return false;
-                }
-            }
-            else if (chr >= 0xE1 && chr <= 0xEF) {
-                if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
-                    return false;
-                }
-            }
-            p += 3;
-        }
-        else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) {
-            if (chr == 0xF0) {
-                if (p[1] < 0x90 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
-                    || p[3] < 0x80 || p[3] > 0xBF) {
-                    return false;
-                }
-            }
-            else if (chr >= 0xF1 && chr <= 0xF3) {
-                if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
-                    || p[3] < 0x80 || p[3] > 0xBF) {
-                    return false;
-                }
-            }
-            else if (chr == 0xF4) {
-                if (p[1] < 0x80 || p[1] > 0x8F || p[2] < 0x80 || p[2] > 0xBF
-                    || p[3] < 0x80 || p[3] > 0xBF) {
-                    return false;
-                }
-            }
-            p += 4;
-        }
-        else {
-            return false;
-        }
-    }
-    return (p == p_end);
-}
-#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
-
 /* Internal function in object file */
 typedef struct AOTObjectFunc {
     char *func_name;
@@ -179,6 +112,16 @@ is_little_endian_binary(const AOTObjectData *obj_data)
     return obj_data->target_info.bin_type & 1 ? false : true;
 }
 
+static bool
+need_call_wrapped_indirect(const AOTObjectData *obj_data)
+{
+    const bool need_precheck = obj_data->comp_ctx->enable_stack_bound_check
+                               || obj_data->comp_ctx->enable_stack_estimation;
+
+    return obj_data->comp_ctx->is_indirect_mode && need_precheck
+           && !strncmp(obj_data->comp_ctx->target_arch, "xtensa", 6);
+}
+
 static bool
 str_starts_with(const char *str, const char *prefix)
 {
@@ -541,15 +484,15 @@ static uint32
 get_func_type_size(AOTCompContext *comp_ctx, AOTFuncType *func_type)
 {
 #if WASM_ENABLE_GC != 0
-    /* type flag + is_sub_final + parent_type_idx + rec_count + rec_idx + param
-     * count + result count
-     * + ref_type_map_count + types + context of ref_type_map */
+    /* type flag + equivalence type flag + is_sub_final + parent_type_idx
+       + rec_count + rec_idx + param count + result count
+       + ref_type_map_count + types + context of ref_type_map */
     if (comp_ctx->enable_gc) {
         uint32 size = 0;
 
         /* type flag */
         size += sizeof(func_type->base_type.type_flag);
-        /* is_sub_final */
+        /* equivalence type flag + is_sub_final */
         size += sizeof(uint16);
         /* parent_type_idx */
         size += sizeof(func_type->base_type.parent_type_idx);
@@ -586,12 +529,12 @@ static uint32
 get_struct_type_size(AOTCompContext *comp_ctx, AOTStructType *struct_type)
 {
     uint32 size = 0;
-    /* type flag + is_sub_final + parent_type_idx + rec_count + rec_idx + field
-     * count + fields */
+    /* type flag + equivalence type flag + is_sub_final + parent_type_idx
+       + rec_count + rec_idx + field count + fields */
 
     /* type flag */
     size += sizeof(struct_type->base_type.type_flag);
-    /* is_sub_final */
+    /* equivalence type flag + is_sub_final */
     size += sizeof(uint16);
     /* parent_type_idx */
     size += sizeof(struct_type->base_type.parent_type_idx);
@@ -615,12 +558,12 @@ static uint32
 get_array_type_size(AOTCompContext *comp_ctx, AOTArrayType *array_type)
 {
     uint32 size = 0;
-    /* type flag + is_sub_final + parent_type_idx + rec_count + rec_idx +
-       elem_flags + elem_type + elem_ref_type */
+    /* type flag + equivalence type flag + is_sub_final + parent_type_idx
+       + rec_count + rec_idx + elem_flags + elem_type + elem_ref_type */
 
     /* type flag */
     size += sizeof(array_type->base_type.type_flag);
-    /* is_sub_final */
+    /* equivalence type flag + is_sub_final */
     size += sizeof(uint16);
     /* parent_type_idx (u32) */
     size += sizeof(array_type->base_type.parent_type_idx);
@@ -654,7 +597,22 @@ get_type_info_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
 #if WASM_ENABLE_GC != 0
     if (comp_ctx->enable_gc) {
         for (i = 0; i < comp_data->type_count; i++) {
+            uint32 j;
+
             size = align_uint(size, 4);
+
+            /* Emit simple info if there is an equivalence type */
+            for (j = 0; j < i; j++) {
+                if (comp_data->types[j] == comp_data->types[i]) {
+                    /* type_flag (2 bytes) + equivalence type flag (1 byte)
+                       + padding (1 byte) + equivalence type index */
+                    size += 8;
+                    break;
+                }
+            }
+            if (j < i)
+                continue;
+
             if (comp_data->types[i]->type_flag == WASM_TYPE_FUNC)
                 size += get_func_type_size(comp_ctx,
                                            (AOTFuncType *)comp_data->types[i]);
@@ -840,7 +798,7 @@ get_init_data_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
     size += (uint32)sizeof(uint32) * 2;
 
     /* aux data/heap/stack data */
-    size += sizeof(uint32) * 7;
+    size += sizeof(uint32) * 10;
 
     size += get_object_data_section_info_size(comp_ctx, obj_data);
     return size;
@@ -870,6 +828,10 @@ get_func_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
     /* function type indexes */
     size += (uint32)sizeof(uint32) * comp_data->func_count;
 
+    /* aot_func#xxx + aot_func_internal#xxx in XIP mode for xtensa */
+    if (need_call_wrapped_indirect(obj_data))
+        size *= 2;
+
     /* max_local_cell_nums */
     size += (uint32)sizeof(uint32) * comp_data->func_count;
 
@@ -1538,9 +1500,16 @@ fail_integer_too_large:
         res = (uint32)res64;                                   \
     } while (0)
 
+/*
+ * - transfer .name section in .wasm (comp_data->name_section_buf) to
+ *   aot buf (comp_data->aot_name_section_buf)
+ * - leb128 to u32
+ * - add `\0` at the end of every name, and adjust length(+1)
+ */
 static uint32
 get_name_section_size(AOTCompData *comp_data)
 {
+    /* original name section content in .wasm */
     const uint8 *p = comp_data->name_section_buf,
                 *p_end = comp_data->name_section_buf_end;
     uint8 *buf, *buf_end;
@@ -1567,22 +1536,20 @@ get_name_section_size(AOTCompData *comp_data)
         aot_set_last_error("allocate memory for custom name section failed.");
         return 0;
     }
+    memset(buf, 0, (uint32)max_aot_buf_size);
     buf_end = buf + max_aot_buf_size;
 
+    /* the size of "name". it should be 4 */
     read_leb_uint32(p, p_end, name_len);
     offset = align_uint(offset, 4);
     EMIT_U32(name_len);
 
-    if (name_len == 0 || p + name_len > p_end) {
+    if (name_len != 4 || p + name_len > p_end) {
         aot_set_last_error("unexpected end");
         return 0;
     }
 
-    if (!check_utf8_str(p, name_len)) {
-        aot_set_last_error("invalid UTF-8 encoding");
-        return 0;
-    }
-
+    /* "name" */
     if (memcmp(p, "name", 4) != 0) {
         aot_set_last_error("invalid custom name section");
         return 0;
@@ -1631,9 +1598,18 @@ get_name_section_size(AOTCompData *comp_data)
                         previous_func_index = func_index;
                         read_leb_uint32(p, p_end, func_name_len);
                         offset = align_uint(offset, 2);
-                        EMIT_U16(func_name_len);
+
+                        /* emit a string ends with `\0` */
+                        if (func_name_len + 1 > UINT16_MAX) {
+                            aot_set_last_error(
+                                "emit string failed: string too long");
+                            goto fail;
+                        }
+                        /* extra 1 byte for \0 */
+                        EMIT_U16(func_name_len + 1);
                         EMIT_BUF(p, func_name_len);
                         p += func_name_len;
+                        EMIT_U8(0);
                     }
                 }
                 break;
@@ -2132,13 +2108,32 @@ aot_emit_type_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
 
 #if WASM_ENABLE_GC != 0
     if (comp_ctx->enable_gc) {
-        int32 idx;
         AOTType **types = comp_data->types;
+        int32 idx;
+        uint32 j;
 
         for (i = 0; i < comp_data->type_count; i++) {
             offset = align_uint(offset, 4);
+
+            /* Emit simple info if there is an equivalence type */
+            for (j = 0; j < i; j++) {
+                if (types[j] == types[i]) {
+                    EMIT_U16(types[i]->type_flag);
+                    /* equivalence type flag is true */
+                    EMIT_U8(1);
+                    EMIT_U8(0);
+                    /* equivalence type index */
+                    EMIT_U32(j);
+                    break;
+                }
+            }
+            if (j < i)
+                continue;
+
             EMIT_U16(types[i]->type_flag);
-            EMIT_U16(types[i]->is_sub_final);
+            /* equivalence type flag is false */
+            EMIT_U8(0);
+            EMIT_U8(types[i]->is_sub_final);
             EMIT_U32(types[i]->parent_type_idx);
 
             EMIT_U16(types[i]->rec_count);
@@ -2414,11 +2409,11 @@ aot_emit_init_data_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
     EMIT_U32(comp_data->start_func_index);
 
     EMIT_U32(comp_data->aux_data_end_global_index);
-    EMIT_U32(comp_data->aux_data_end);
+    EMIT_U64(comp_data->aux_data_end);
     EMIT_U32(comp_data->aux_heap_base_global_index);
-    EMIT_U32(comp_data->aux_heap_base);
+    EMIT_U64(comp_data->aux_heap_base);
     EMIT_U32(comp_data->aux_stack_top_global_index);
-    EMIT_U32(comp_data->aux_stack_bottom);
+    EMIT_U64(comp_data->aux_stack_bottom);
     EMIT_U32(comp_data->aux_stack_size);
 
     if (!aot_emit_object_data_section_info(buf, buf_end, &offset, comp_ctx,
@@ -2595,9 +2590,30 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
             EMIT_U64(func->text_offset);
     }
 
+    if (need_call_wrapped_indirect(obj_data)) {
+        /*
+         * Explicitly emit aot_func_internal#xxx for Xtensa XIP, therefore,
+         * for aot_func#xxx, func_indexes ranged from 0 ~ func_count,
+         * for aot_func_internal#xxxx, from func_count + 1 ~ 2 * func_count.
+         */
+        for (i = 0, func = obj_data->funcs; i < obj_data->func_count;
+             i++, func++) {
+            if (is_32bit_binary(obj_data))
+                EMIT_U32(func->text_offset_of_aot_func_internal);
+            else
+                EMIT_U64(func->text_offset_of_aot_func_internal);
+        }
+    }
+
     for (i = 0; i < comp_data->func_count; i++)
         EMIT_U32(funcs[i]->func_type_index);
 
+    if (need_call_wrapped_indirect(obj_data)) {
+        /* func_type_index for aot_func_internal#xxxx */
+        for (i = 0; i < comp_data->func_count; i++)
+            EMIT_U32(funcs[i]->func_type_index);
+    }
+
     for (i = 0; i < comp_data->func_count; i++) {
         uint32 max_local_cell_num =
             funcs[i]->param_cell_num + funcs[i]->local_cell_num;
@@ -2611,7 +2627,7 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
     if (comp_ctx->enable_gc) {
         /* emit func_local_ref_flag arrays for both import and AOTed funcs */
         AOTFuncType *func_type;
-        uint32 j, local_ref_flags_cell_num;
+        uint32 j, local_ref_flags_cell_num, paddings;
 
         for (i = 0; i < comp_data->import_func_count; i++) {
             func_type = comp_data->import_funcs[i].func_type;
@@ -2621,6 +2637,8 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
                 local_ref_flags_cell_num += wasm_value_type_cell_num_internal(
                     func_type->types[j], comp_ctx->pointer_size);
             }
+            paddings =
+                local_ref_flags_cell_num < 2 ? 2 - local_ref_flags_cell_num : 0;
             local_ref_flags_cell_num =
                 local_ref_flags_cell_num > 2 ? local_ref_flags_cell_num : 2;
 
@@ -2632,7 +2650,7 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
                                        func_type->types[j]))
                     return false;
             }
-            for (; j < 2; j++)
+            for (j = 0; j < paddings; j++)
                 EMIT_U8(0);
         }
 
@@ -3912,7 +3930,12 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
          * Note: aot_stack_sizes_section_name section only contains
          * stack_sizes table.
          */
-        if (!strcmp(relocation->symbol_name, aot_stack_sizes_name)) {
+        if (!strcmp(relocation->symbol_name, aot_stack_sizes_name)
+            /* in windows 32, the symbol name may start with '_' */
+            || (strlen(relocation->symbol_name) > 0
+                && relocation->symbol_name[0] == '_'
+                && !strcmp(relocation->symbol_name + 1,
+                           aot_stack_sizes_name))) {
             /* discard const */
             relocation->symbol_name = (char *)aot_stack_sizes_section_name;
         }

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

@@ -374,7 +374,9 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                 goto fail;
             }
 #if WASM_ENABLE_DEBUG_AOT != 0
-            LLVMInstructionSetDebugLoc(ret, return_location);
+            if (return_location != NULL) {
+                LLVMInstructionSetDebugLoc(ret, return_location);
+            }
 #endif
         }
         else {
@@ -383,7 +385,9 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                 goto fail;
             }
 #if WASM_ENABLE_DEBUG_AOT != 0
-            LLVMInstructionSetDebugLoc(ret, return_location);
+            if (return_location != NULL) {
+                LLVMInstructionSetDebugLoc(ret, return_location);
+            }
 #endif
         }
     }
@@ -1266,6 +1270,7 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                         PUSH(values[j], target_block->result_types[j]);
                     }
                     wasm_runtime_free(values);
+                    values = NULL;
                 }
                 target_block->is_reachable = true;
                 if (i == br_count)
@@ -1291,6 +1296,7 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                         PUSH(values[j], target_block->param_types[j]);
                     }
                     wasm_runtime_free(values);
+                    values = NULL;
                 }
                 if (i == br_count)
                     default_llvm_block = target_block->llvm_entry_block;

+ 6 - 6
core/iwasm/compilation/aot_emit_exception.c

@@ -88,6 +88,12 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                 aot_set_last_error("llvm build phi failed.");
                 return false;
             }
+
+            /* Commit ip to current frame */
+            if (!commit_ip(comp_ctx, func_ctx, func_ctx->exception_ip_phi,
+                           is_64bit)) {
+                return false;
+            }
         }
 
         /* Call aot_set_exception_with_id() to throw exception */
@@ -154,12 +160,6 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
             return false;
         }
 
-        if (comp_ctx->aot_frame) {
-            if (!commit_ip(comp_ctx, func_ctx, func_ctx->exception_ip_phi,
-                           is_64bit))
-                return false;
-        }
-
         /* Create return IR */
         AOTFuncType *aot_func_type = func_ctx->aot_func->func_type;
         if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) {

+ 105 - 25
core/iwasm/compilation/aot_emit_function.c

@@ -329,13 +329,9 @@ call_aot_invoke_c_api_native(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 
     param_values[0] = func_ctx->aot_inst;
 
-    /* Get module_inst->e->common.c_api_func_imports */
-    offset_c_api_func_imports =
-        get_module_inst_extra_offset(comp_ctx)
-        + (comp_ctx->is_jit_mode
-               ? offsetof(WASMModuleInstanceExtra, common.c_api_func_imports)
-               /* offsetof(AOTModuleInstanceExtra, common.c_api_func_imports) */
-               : sizeof(uint64));
+    /* Get module_inst->c_api_func_imports, jit mode WASMModuleInstance is the
+     * same layout with AOTModuleInstance */
+    offset_c_api_func_imports = offsetof(AOTModuleInstance, c_api_func_imports);
     offset = I32_CONST(offset_c_api_func_imports);
     CHECK_LLVM_CONST(offset);
     c_api_func_imports =
@@ -1167,8 +1163,8 @@ check_app_addr_and_convert(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     /* prepare function type of aot_check_app_addr_and_convert */
     func_param_types[0] = comp_ctx->aot_inst_type; /* module_inst */
     func_param_types[1] = INT8_TYPE;               /* is_str_arg */
-    func_param_types[2] = I32_TYPE;                /* app_offset */
-    func_param_types[3] = I32_TYPE;                /* buf_size */
+    func_param_types[2] = I64_TYPE;                /* app_offset */
+    func_param_types[3] = I64_TYPE;                /* buf_size */
     func_param_types[4] =
         comp_ctx->basic_types.int8_pptr_type; /* p_native_addr */
     if (!(func_type =
@@ -1555,7 +1551,19 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                     if (signature[i + 2] == '~')
                         native_addr_size = param_values[i + 2];
                     else
-                        native_addr_size = I32_ONE;
+                        native_addr_size = I64_CONST(1);
+                    if (!(native_addr_size = LLVMBuildZExtOrBitCast(
+                              comp_ctx->builder, native_addr_size, I64_TYPE,
+                              "native_addr_size_i64"))) {
+                        aot_set_last_error("llvm build zextOrBitCast failed.");
+                        goto fail;
+                    }
+                    if (!(param_values[j] = LLVMBuildZExtOrBitCast(
+                              comp_ctx->builder, param_values[j], I64_TYPE,
+                              "native_addr_i64"))) {
+                        aot_set_last_error("llvm build zextOrBitCast failed.");
+                        goto fail;
+                    }
                     if (!check_app_addr_and_convert(
                             comp_ctx, func_ctx, false, param_values[j],
                             native_addr_size, &native_addr)) {
@@ -1564,7 +1572,13 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                     param_values[j] = native_addr;
                 }
                 else if (signature[i + 1] == '$') {
-                    native_addr_size = I32_ZERO;
+                    native_addr_size = I64_ZERO;
+                    if (!(param_values[j] = LLVMBuildZExtOrBitCast(
+                              comp_ctx->builder, param_values[j], I64_TYPE,
+                              "native_addr_i64"))) {
+                        aot_set_last_error("llvm build zextOrBitCast failed.");
+                        goto fail;
+                    }
                     if (!check_app_addr_and_convert(
                             comp_ctx, func_ctx, true, param_values[j],
                             native_addr_size, &native_addr)) {
@@ -1812,6 +1826,52 @@ fail:
     return ret;
 }
 
+#if WASM_ENABLE_GC != 0
+static LLVMValueRef
+call_aot_func_type_is_super_of_func(AOTCompContext *comp_ctx,
+                                    AOTFuncContext *func_ctx,
+                                    LLVMValueRef type_idx1,
+                                    LLVMValueRef type_idx2)
+{
+    LLVMValueRef param_values[3], ret_value, value, func;
+    LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
+
+    param_types[0] = comp_ctx->aot_inst_type;
+    param_types[1] = I32_TYPE;
+    param_types[2] = I32_TYPE;
+    ret_type = INT8_TYPE;
+
+#if WASM_ENABLE_JIT != 0
+    if (comp_ctx->is_jit_mode)
+        GET_AOT_FUNCTION(llvm_jit_func_type_is_super_of, 3);
+    else
+#endif
+        GET_AOT_FUNCTION(aot_func_type_is_super_of, 3);
+
+    param_values[0] = func_ctx->aot_inst;
+    param_values[1] = type_idx1;
+    param_values[2] = type_idx2;
+
+    if (!(ret_value =
+              LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values,
+                             3, "call_aot_func_type_is_super_of"))) {
+        aot_set_last_error("llvm build call failed.");
+        return NULL;
+    }
+
+    if (!(ret_value = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ, ret_value,
+                                    I8_ZERO, "check_fail"))) {
+        aot_set_last_error("llvm build icmp failed.");
+        return NULL;
+    }
+
+    return ret_value;
+
+fail:
+    return NULL;
+}
+#endif
+
 static bool
 call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                             AOTFuncType *aot_func_type,
@@ -2004,15 +2064,23 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
         return false;
     }
 
-    /* Find the equivalent function type whose type index is the smallest:
-       the callee function's type index is also converted to the smallest
-       one in wasm loader, so we can just check whether the two type indexes
-       are equal (the type index of call_indirect opcode and callee func),
-       we don't need to check whether the whole function types are equal,
-       including param types and result types. */
-    type_idx =
-        wasm_get_smallest_type_idx((WASMTypePtr *)comp_ctx->comp_data->types,
-                                   comp_ctx->comp_data->type_count, type_idx);
+    if (!comp_ctx->enable_gc) {
+        /* Find the equivalent function type whose type index is the smallest:
+           the callee function's type index is also converted to the smallest
+           one in wasm loader, so we can just check whether the two type indexes
+           are equal (the type index of call_indirect opcode and callee func),
+           we don't need to check whether the whole function types are equal,
+           including param types and result types. */
+        type_idx = wasm_get_smallest_type_idx(
+            (WASMTypePtr *)comp_ctx->comp_data->types,
+            comp_ctx->comp_data->type_count, type_idx);
+    }
+    else {
+        /* Call aot_func_type_is_super_of to check whether the func type
+           provided in the bytecode is a super type of the func type of
+           the function to call */
+    }
+
     ftype_idx_const = I32_CONST(type_idx);
     CHECK_LLVM_CONST(ftype_idx_const);
 
@@ -2240,11 +2308,23 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
         goto fail;
     }
 
-    /* Check if function type index not equal */
-    if (!(cmp_ftype_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, ftype_idx,
-                                        ftype_idx_const, "cmp_ftype_idx"))) {
-        aot_set_last_error("llvm build icmp failed.");
-        goto fail;
+#if WASM_ENABLE_GC != 0
+    if (comp_ctx->enable_gc) {
+        if (!(cmp_ftype_idx = call_aot_func_type_is_super_of_func(
+                  comp_ctx, func_ctx, ftype_idx_const, ftype_idx))) {
+            goto fail;
+        }
+    }
+    else
+#endif
+    {
+        /* Check if function type index not equal */
+        if (!(cmp_ftype_idx =
+                  LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, ftype_idx,
+                                ftype_idx_const, "cmp_ftype_idx"))) {
+            aot_set_last_error("llvm build icmp failed.");
+            goto fail;
+        }
     }
 
     /* Throw exception if ftype_idx != ftype_idx_const */

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

@@ -919,7 +919,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
             comp_ctx->comp_data->memories[0].num_bytes_per_page;
         uint32 init_page_count =
             comp_ctx->comp_data->memories[0].mem_init_page_count;
-        uint32 mem_data_size = num_bytes_per_page * init_page_count;
+        uint64 mem_data_size = (uint64)num_bytes_per_page * init_page_count;
         if (mem_data_size > 0 && mem_offset + mem_len <= mem_data_size) {
             /* inside memory space */
             /* maddr = mem_base_addr + moffset */
@@ -938,7 +938,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     }
     else {
         if (!(mem_size = LLVMBuildLoad2(
-                  comp_ctx->builder, I32_TYPE,
+                  comp_ctx->builder, I64_TYPE,
                   func_ctx->mem_info[0].mem_data_size_addr, "mem_size"))) {
             aot_set_last_error("llvm build load failed.");
             goto fail;
@@ -951,8 +951,6 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     offset =
         LLVMBuildZExt(comp_ctx->builder, offset, I64_TYPE, "extend_offset");
     bytes = LLVMBuildZExt(comp_ctx->builder, bytes, I64_TYPE, "extend_len");
-    mem_size =
-        LLVMBuildZExt(comp_ctx->builder, mem_size, I64_TYPE, "extend_size");
 
     BUILD_OP(Add, offset, bytes, max_addr, "max_addr");
     BUILD_ICMP(LLVMIntUGT, max_addr, mem_size, cmp, "cmp_max_mem_addr");

+ 9 - 3
core/iwasm/compilation/aot_emit_variable.c

@@ -251,7 +251,7 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
             LLVMBasicBlockRef block_curr =
                 LLVMGetInsertBlock(comp_ctx->builder);
             LLVMBasicBlockRef check_overflow_succ, check_underflow_succ;
-            LLVMValueRef cmp;
+            LLVMValueRef cmp, global_i64;
 
             /* Add basic blocks */
             if (!(check_overflow_succ = LLVMAppendBasicBlockInContext(
@@ -270,8 +270,14 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
             }
             LLVMMoveBasicBlockAfter(check_underflow_succ, check_overflow_succ);
 
+            if (!(global_i64 = LLVMBuildZExt(comp_ctx->builder, global,
+                                             I64_TYPE, "global_i64"))) {
+                aot_set_last_error("llvm build zext failed.");
+                return false;
+            }
+
             /* Check aux stack overflow */
-            if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULE, global,
+            if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULE, global_i64,
                                       func_ctx->aux_stack_bound, "cmp"))) {
                 aot_set_last_error("llvm build icmp failed.");
                 return false;
@@ -283,7 +289,7 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 
             /* Check aux stack underflow */
             LLVMPositionBuilderAtEnd(comp_ctx->builder, check_overflow_succ);
-            if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, global,
+            if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, global_i64,
                                       func_ctx->aux_stack_bottom, "cmp"))) {
                 aot_set_last_error("llvm build icmp failed.");
                 return false;

+ 80 - 16
core/iwasm/compilation/aot_llvm.c

@@ -24,6 +24,8 @@ create_native_stack_bound(const AOTCompContext *comp_ctx,
 static bool
 create_native_stack_top_min(const AOTCompContext *comp_ctx,
                             AOTFuncContext *func_ctx);
+static bool
+create_func_ptrs(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
 
 LLVMTypeRef
 wasm_type_to_llvm_type(const AOTCompContext *comp_ctx,
@@ -83,7 +85,7 @@ aot_add_llvm_func1(const AOTCompContext *comp_ctx, LLVMModuleRef module,
                    uint32 func_index, uint32 param_count, LLVMTypeRef func_type,
                    const char *prefix)
 {
-    char func_name[48];
+    char func_name[48] = { 0 };
     LLVMValueRef func;
     LLVMValueRef local_value;
     uint32 i, j;
@@ -122,7 +124,7 @@ create_basic_func_context(const AOTCompContext *comp_ctx,
 {
     LLVMValueRef aot_inst_offset = I32_TWO, aot_inst_addr;
 
-    /* Save the pameters for fast access */
+    /* Save the parameters for fast access */
     func_ctx->exec_env = LLVMGetParam(func_ctx->func, 0);
 
     /* Get aot inst address, the layout of exec_env is:
@@ -537,8 +539,51 @@ aot_build_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
     if (ret_type == VOID_TYPE) {
         name = "";
     }
-    LLVMValueRef retval =
-        LLVMBuildCall2(b, func_type, wrapped_func, params, param_count, name);
+
+    LLVMValueRef retval;
+    if (comp_ctx->is_indirect_mode
+        && !strncmp(comp_ctx->target_arch, "xtensa", 6)) {
+        /* call wrapped_func indirectly */
+        if (!create_func_ptrs(comp_ctx, func_ctx)) {
+            goto fail;
+        }
+
+        LLVMTypeRef func_ptr_type;
+        LLVMValueRef wrapped_func_indirect;
+        uint32 import_func_count = comp_ctx->comp_data->import_func_count;
+        uint32 func_count = comp_ctx->func_ctx_count;
+
+        /* Check function index */
+        if (func_index >= import_func_count + func_count) {
+            aot_set_last_error("Function index out of range.");
+            goto fail;
+        }
+
+        /* Get function type */
+        if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
+            aot_set_last_error("create LLVM function type failed.");
+            goto fail;
+        }
+
+        /*
+         * func_index layout :
+         * aot_func#xxx, range from 0 ~ func_conut - 1;
+         * aot_func#internal#xxx,  range from func_conut ~ 2 * func_conut - 1;
+         */
+        if (!(wrapped_func_indirect = aot_get_func_from_table(
+                  comp_ctx, func_ctx->func_ptrs, func_ptr_type,
+                  func_index + func_count + import_func_count))) {
+            goto fail;
+        }
+
+        /* Call the function indirectly */
+        retval = LLVMBuildCall2(b, func_type, wrapped_func_indirect, params,
+                                param_count, name);
+    }
+    else
+        retval = LLVMBuildCall2(b, func_type, wrapped_func, params, param_count,
+                                name);
+
     if (!retval) {
         goto fail;
     }
@@ -629,7 +674,8 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
     uint32 backend_thread_num, compile_thread_num;
 
     /* Check function parameter types and result types */
-    for (i = 0; i < aot_func_type->param_count + aot_func_type->result_count;
+    for (i = 0;
+         i < (uint32)(aot_func_type->param_count + aot_func_type->result_count);
          i++) {
         if (!check_wasm_type(comp_ctx, aot_func_type->types[i]))
             return NULL;
@@ -734,7 +780,9 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
     }
 
     if (need_precheck) {
-        if (!comp_ctx->is_jit_mode)
+        if (!comp_ctx->is_jit_mode
+            && !(comp_ctx->is_indirect_mode
+                 && !strncmp(comp_ctx->target_arch, "xtensa", 6)))
             LLVMSetLinkage(func, LLVMInternalLinkage);
         unsigned int kind =
             LLVMGetEnumAttributeKindForName("noinline", strlen("noinline"));
@@ -957,17 +1005,23 @@ create_aux_stack_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
 
     if (!(aux_stack_bound_addr =
               LLVMBuildBitCast(comp_ctx->builder, aux_stack_bound_addr,
-                               INT32_PTR_TYPE, "aux_stack_bound_ptr"))) {
+                               INTPTR_T_PTR_TYPE, "aux_stack_bound_ptr"))) {
         aot_set_last_error("llvm build bit cast failed");
         return false;
     }
 
     if (!(func_ctx->aux_stack_bound =
-              LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, aux_stack_bound_addr,
-                             "aux_stack_bound"))) {
+              LLVMBuildLoad2(comp_ctx->builder, INTPTR_T_TYPE,
+                             aux_stack_bound_addr, "aux_stack_bound_intptr"))) {
         aot_set_last_error("llvm build load failed");
         return false;
     }
+    if (!(func_ctx->aux_stack_bound =
+              LLVMBuildZExt(comp_ctx->builder, func_ctx->aux_stack_bound,
+                            I64_TYPE, "aux_stack_bound_i64"))) {
+        aot_set_last_error("llvm build truncOrBitCast failed.");
+        return false;
+    }
 
     /* Get aux stack bottom address */
     if (!(aux_stack_bottom_addr = LLVMBuildInBoundsGEP2(
@@ -979,16 +1033,23 @@ create_aux_stack_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
 
     if (!(aux_stack_bottom_addr =
               LLVMBuildBitCast(comp_ctx->builder, aux_stack_bottom_addr,
-                               INT32_PTR_TYPE, "aux_stack_bottom_ptr"))) {
+                               INTPTR_T_PTR_TYPE, "aux_stack_bottom_ptr"))) {
         aot_set_last_error("llvm build bit cast failed");
         return false;
     }
+
     if (!(func_ctx->aux_stack_bottom =
-              LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, aux_stack_bottom_addr,
-                             "aux_stack_bottom"))) {
+              LLVMBuildLoad2(comp_ctx->builder, INTPTR_T_TYPE,
+                             aux_stack_bottom_addr, "aux_stack_bottom"))) {
         aot_set_last_error("llvm build load failed");
         return false;
     }
+    if (!(func_ctx->aux_stack_bottom =
+              LLVMBuildZExt(comp_ctx->builder, func_ctx->aux_stack_bottom,
+                            I64_TYPE, "aux_stack_bottom_i64"))) {
+        aot_set_last_error("llvm build truncOrBitCast failed.");
+        return false;
+    }
 
     return true;
 }
@@ -1318,7 +1379,7 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     }
     if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildBitCast(
               comp_ctx->builder, func_ctx->mem_info[0].mem_data_size_addr,
-              INT32_PTR_TYPE, "mem_data_size_ptr"))) {
+              INT64_PTR_TYPE, "mem_data_size_ptr"))) {
         aot_set_last_error("llvm build bit cast failed");
         return false;
     }
@@ -1337,7 +1398,7 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
             return false;
         }
         if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildLoad2(
-                  comp_ctx->builder, I32_TYPE,
+                  comp_ctx->builder, I64_TYPE,
                   func_ctx->mem_info[0].mem_data_size_addr, "mem_data_size"))) {
             aot_set_last_error("llvm build load failed");
             return false;
@@ -1918,8 +1979,8 @@ aot_set_llvm_basic_types(AOTLLVMTypes *basic_types, LLVMContextRef context,
         basic_types->intptr_t_ptr_type = basic_types->int64_ptr_type;
     }
 
-    basic_types->gc_ref_type = LLVMPointerType(basic_types->void_type, 0);
-    basic_types->gc_ref_ptr_type = LLVMPointerType(basic_types->gc_ref_type, 0);
+    basic_types->gc_ref_type = basic_types->int8_ptr_type;
+    basic_types->gc_ref_ptr_type = basic_types->int8_pptr_type;
 
     return (basic_types->int8_ptr_type && basic_types->int8_pptr_type
             && basic_types->int16_ptr_type && basic_types->int32_ptr_type
@@ -2487,6 +2548,9 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
         aot_set_last_error("create LLVM module failed.");
         goto fail;
     }
+#if LLVM_VERSION_MAJOR >= 19
+    LLVMSetIsNewDbgInfoFormat(comp_ctx->module, true);
+#endif
 
 #if WASM_ENABLE_LINUX_PERF != 0
     if (wasm_runtime_get_linux_perf()) {

+ 39 - 3
core/iwasm/compilation/debug/dwarf_extractor.cpp

@@ -295,6 +295,28 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
     const size_t num_function_args = function_args.GetSize();
     dwarf_extractor *extractor;
 
+    /*
+     * Process only known languages.
+     * We have a few assumptions which might not be true for non-C functions.
+     *
+     * At least it's known broken for C++ and Rust:
+     * https://github.com/bytecodealliance/wasm-micro-runtime/issues/3187
+     * https://github.com/bytecodealliance/wasm-micro-runtime/issues/3163
+     */
+    LanguageType language_type = function.GetLanguage();
+    switch (language_type) {
+        case eLanguageTypeC89:
+        case eLanguageTypeC:
+        case eLanguageTypeC99:
+        case eLanguageTypeC11:
+        case eLanguageTypeC17:
+            break;
+        default:
+            LOG_WARNING("func %s has unsuppoted language_type 0x%x",
+                        function_name, (int)language_type);
+            return NULL;
+    }
+
     if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
         return NULL;
 
@@ -313,6 +335,17 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
         if (function_arg_type.IsValid()) {
             ParamTypes[function_arg_idx + 1] =
                 lldb_type_to_type_dbi(comp_ctx, function_arg_type);
+            if (ParamTypes[function_arg_idx + 1] == NULL) {
+                LOG_WARNING(
+                    "func %s arg %" PRIu32
+                    " has a type not implemented by lldb_type_to_type_dbi",
+                    function_name, function_arg_idx);
+            }
+        }
+        else {
+            LOG_WARNING("func %s arg %" PRIu32 ": GetTypeAtIndex failed",
+                        function_name, function_arg_idx);
+            ParamTypes[function_arg_idx + 1] = NULL;
         }
     }
 
@@ -381,15 +414,16 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
     for (uint32_t function_arg_idx = 0;
          function_arg_idx < variable_list.GetSize(); ++function_arg_idx) {
         SBValue variable(variable_list.GetValueAtIndex(function_arg_idx));
-        if (variable.IsValid()) {
+        if (variable.IsValid() && ParamTypes[function_arg_idx + 1] != NULL) {
             SBDeclaration dec(variable.GetDeclaration());
             auto valtype = variable.GetType();
             LLVMMetadataRef ParamLocation = LLVMDIBuilderCreateDebugLocation(
                 comp_ctx->context, dec.GetLine(), dec.GetColumn(),
                 FunctionMetadata, NULL);
+            const char *varname = variable.GetName();
             LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable(
-                DIB, FunctionMetadata, variable.GetName(),
-                strlen(variable.GetName()), function_arg_idx + 1 + 1,
+                DIB, FunctionMetadata, varname, varname ? strlen(varname) : 0,
+                function_arg_idx + 1 + 1,
                 File, // starts form 1, and 1 is exenv,
                 dec.GetLine(), ParamTypes[function_arg_idx + 1], true,
                 LLVMDIFlagZero);
@@ -473,6 +507,8 @@ dwarf_gen_location(const AOTCompContext *comp_ctx,
     dwarf_extractor *extractor;
     AOTFunc *func = func_ctx->aot_func;
 
+    if (func_ctx->debug_func == NULL)
+        return NULL;
     if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
         return NULL;
 

+ 0 - 9
core/iwasm/compilation/simd/simd_conversions.c

@@ -226,15 +226,6 @@ aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
     }
 }
 
-bool
-aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx,
-                                    AOTFuncContext *func_ctx, bool is_signed)
-{
-    /* TODO: x86 intrinsics */
-    return simd_integer_narrow_common(comp_ctx, func_ctx, e_sat_i64x2,
-                                      is_signed);
-}
-
 enum integer_extend_type {
     e_ext_i8x16,
     e_ext_i16x8,

+ 0 - 4
core/iwasm/compilation/simd/simd_conversions.h

@@ -20,10 +20,6 @@ bool
 aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
                                     AOTFuncContext *func_ctx, bool is_signed);
 
-bool
-aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx,
-                                    AOTFuncContext *func_ctx, bool is_signed);
-
 bool
 aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx,
                                     AOTFuncContext *func_ctx, bool is_low,

+ 0 - 14
core/iwasm/compilation/simd/simd_floating_point.c

@@ -129,20 +129,6 @@ aot_compile_simd_f64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
                                 "llvm.fabs.v2f64");
 }
 
-bool
-aot_compile_simd_f32x4_round(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
-{
-    return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE,
-                                "llvm.round.v4f32");
-}
-
-bool
-aot_compile_simd_f64x2_round(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
-{
-    return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE,
-                                "llvm.round.v2f64");
-}
-
 bool
 aot_compile_simd_f32x4_sqrt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
 {

+ 0 - 8
core/iwasm/compilation/simd/simd_floating_point.h

@@ -32,14 +32,6 @@ aot_compile_simd_f32x4_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
 bool
 aot_compile_simd_f64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
 
-bool
-aot_compile_simd_f32x4_round(AOTCompContext *comp_ctx,
-                             AOTFuncContext *func_ctx);
-
-bool
-aot_compile_simd_f64x2_round(AOTCompContext *comp_ctx,
-                             AOTFuncContext *func_ctx);
-
 bool
 aot_compile_simd_f32x4_sqrt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
 

+ 1 - 10
core/iwasm/compilation/simd/simd_int_arith.c

@@ -243,7 +243,6 @@ aot_compile_simd_i64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
 enum integer_avgr_u {
     e_avgr_u_i8x16,
     e_avgr_u_i16x8,
-    e_avgr_u_i32x4,
 };
 
 /* TODO: try int_x86_mmx_pavg_b and int_x86_mmx_pavg_w */
@@ -257,9 +256,8 @@ simd_v128_avg(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     LLVMTypeRef vector_type[] = {
         V128_i8x16_TYPE,
         V128_i16x8_TYPE,
-        V128_i32x4_TYPE,
     };
-    unsigned lanes[] = { 16, 8, 4 };
+    unsigned lanes[] = { 16, 8 };
 
     if (!(rhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
                                           vector_type[itype], "rhs"))
@@ -325,13 +323,6 @@ aot_compile_simd_i16x8_avgr_u(AOTCompContext *comp_ctx,
     return simd_v128_avg(comp_ctx, func_ctx, e_avgr_u_i16x8);
 }
 
-bool
-aot_compile_simd_i32x4_avgr_u(AOTCompContext *comp_ctx,
-                              AOTFuncContext *func_ctx)
-{
-    return simd_v128_avg(comp_ctx, func_ctx, e_avgr_u_i32x4);
-}
-
 bool
 aot_compile_simd_i32x4_dot_i16x8(AOTCompContext *comp_ctx,
                                  AOTFuncContext *func_ctx)

+ 0 - 4
core/iwasm/compilation/simd/simd_int_arith.h

@@ -76,10 +76,6 @@ bool
 aot_compile_simd_i16x8_avgr_u(AOTCompContext *comp_ctx,
                               AOTFuncContext *func_ctx);
 
-bool
-aot_compile_simd_i32x4_avgr_u(AOTCompContext *comp_ctx,
-                              AOTFuncContext *func_ctx);
-
 bool
 aot_compile_simd_i32x4_dot_i16x8(AOTCompContext *comp_ctx,
                                  AOTFuncContext *func_ctx);

+ 0 - 15
core/iwasm/compilation/simd/simd_sat_int_arith.c

@@ -64,18 +64,3 @@ aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
                               is_signed ? intrinsics[arith_op][0]
                                         : intrinsics[arith_op][1]);
 }
-
-bool
-aot_compile_simd_i32x4_saturate(AOTCompContext *comp_ctx,
-                                AOTFuncContext *func_ctx,
-                                V128Arithmetic arith_op, bool is_signed)
-{
-    char *intrinsics[][2] = {
-        { "llvm.sadd.sat.v4i32", "llvm.uadd.sat.v4i32" },
-        { "llvm.ssub.sat.v4i32", "llvm.usub.sat.v4i32" },
-    };
-
-    return simd_sat_int_arith(comp_ctx, func_ctx, V128_i16x8_TYPE,
-                              is_signed ? intrinsics[arith_op][0]
-                                        : intrinsics[arith_op][1]);
-}

+ 0 - 4
core/iwasm/compilation/simd/simd_sat_int_arith.h

@@ -22,10 +22,6 @@ aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
                                 AOTFuncContext *func_ctx,
                                 V128Arithmetic arith_op, bool is_signed);
 
-bool
-aot_compile_simd_i32x4_saturate(AOTCompContext *comp_ctx,
-                                AOTFuncContext *func_ctx,
-                                V128Arithmetic arith_op, bool is_signed);
 #ifdef __cplusplus
 } /* end of extern "C" */
 #endif

+ 6 - 6
core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp

@@ -7511,7 +7511,7 @@ at_rmw_xor_r_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst,
             CHECK_KIND(r3, JIT_REG_KIND_I64);                                  \
         }                                                                      \
         /* r0: read/return value r2: memory base addr can't be const */        \
-        /* already check it's not const in LOAD_4ARGS(); */                    \
+        /* already check it's not const in LOAD_4ARGS() */                     \
         reg_no_dst = jit_reg_no(r0);                                           \
         CHECK_REG_NO(reg_no_dst, jit_reg_kind(r0));                            \
         /* mem_data base address has to be non-const */                        \
@@ -9293,8 +9293,8 @@ jit_codegen_init()
         imm.setValue(INT32_MAX);
         a.jne(imm);
 
-        char *stream = (char *)a.code()->sectionById(0)->buffer().data()
-                       + a.code()->sectionById(0)->buffer().size();
+        char *stream_old = (char *)a.code()->sectionById(0)->buffer().data()
+                           + a.code()->sectionById(0)->buffer().size();
 
         /* If yes, call jit_set_exception_with_id to throw exception,
            and then set eax to JIT_INTERP_ACTION_THROWN, and jump to
@@ -9319,7 +9319,7 @@ jit_codegen_init()
         /* Patch the offset of jne instruction */
         char *stream_new = (char *)a.code()->sectionById(0)->buffer().data()
                            + a.code()->sectionById(0)->buffer().size();
-        *(int32 *)(stream - 4) = (int32)(stream_new - stream);
+        *(int32 *)(stream_old - 4) = (int32)(stream_new - stream_old);
     }
 
     /* Load compiled func ptr and call it */
@@ -9419,7 +9419,7 @@ static uint8 hreg_info_F64[3][16] = {
       1, 1, 1, 1, 1, 1, 1, 0 }, /* caller_saved_jitted */
 };
 
-static const JitHardRegInfo hreg_info = {
+static const JitHardRegInfo g_hreg_info = {
     {
         { 0, NULL, NULL, NULL }, /* VOID */
 
@@ -9459,7 +9459,7 @@ static const JitHardRegInfo hreg_info = {
 const JitHardRegInfo *
 jit_codegen_get_hreg_info()
 {
-    return &hreg_info;
+    return &g_hreg_info;
 }
 
 static const char *reg_names_i32[] = {

+ 10 - 3
core/iwasm/fast-jit/fe/jit_emit_function.c

@@ -331,12 +331,14 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call)
                 func_params[1] = NEW_CONST(I32, false); /* is_str = false */
                 func_params[2] = argvs[i];
                 if (signature[i + 2] == '~') {
+                    /* TODO: Memory64 no need to convert if mem idx type i64 */
+                    func_params[3] = jit_cc_new_reg_I64(cc);
                     /* pointer with length followed */
-                    func_params[3] = argvs[i + 1];
+                    GEN_INSN(I32TOI64, func_params[3], argvs[i + 1]);
                 }
                 else {
                     /* pointer with length followed */
-                    func_params[3] = NEW_CONST(I32, 1);
+                    func_params[3] = NEW_CONST(I64, 1);
                 }
             }
             else if (signature[i + 1] == '$') {
@@ -344,10 +346,15 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call)
                 is_pointer_arg = true;
                 func_params[1] = NEW_CONST(I32, true); /* is_str = true */
                 func_params[2] = argvs[i];
-                func_params[3] = NEW_CONST(I32, 1);
+                func_params[3] = NEW_CONST(I64, 1);
             }
 
             if (is_pointer_arg) {
+                JitReg native_addr_64 = jit_cc_new_reg_I64(cc);
+                /* TODO: Memory64 no need to convert if mem idx type i64 */
+                GEN_INSN(I32TOI64, native_addr_64, func_params[2]);
+                func_params[2] = native_addr_64;
+
                 if (!jit_emit_callnative(cc, jit_check_app_addr_and_convert,
                                          ret, func_params, 5)) {
                     goto fail;

+ 11 - 9
core/iwasm/fast-jit/fe/jit_emit_memory.c

@@ -630,13 +630,13 @@ wasm_init_memory(WASMModuleInstance *inst, uint32 mem_idx, uint32 seg_idx,
 {
     WASMMemoryInstance *mem_inst;
     WASMDataSeg *data_segment;
-    uint32 mem_size;
+    uint64 mem_size;
     uint8 *mem_addr, *data_addr;
     uint32 seg_len;
 
     /* if d + n > the length of mem.data */
     mem_inst = inst->memories[mem_idx];
-    mem_size = mem_inst->cur_page_count * mem_inst->num_bytes_per_page;
+    mem_size = mem_inst->cur_page_count * (uint64)mem_inst->num_bytes_per_page;
     if (mem_size < mem_offset || mem_size - mem_offset < len)
         goto out_of_bounds;
 
@@ -655,7 +655,7 @@ wasm_init_memory(WASMModuleInstance *inst, uint32 mem_idx, uint32 seg_idx,
         goto out_of_bounds;
 
     mem_addr = mem_inst->memory_data + mem_offset;
-    bh_memcpy_s(mem_addr, mem_size - mem_offset, data_addr, len);
+    bh_memcpy_s(mem_addr, (uint32)(mem_size - mem_offset), data_addr, len);
 
     return 0;
 out_of_bounds:
@@ -719,13 +719,15 @@ wasm_copy_memory(WASMModuleInstance *inst, uint32 src_mem_idx,
                  uint32 dst_offset)
 {
     WASMMemoryInstance *src_mem, *dst_mem;
-    uint32 src_mem_size, dst_mem_size;
+    uint64 src_mem_size, dst_mem_size;
     uint8 *src_addr, *dst_addr;
 
     src_mem = inst->memories[src_mem_idx];
     dst_mem = inst->memories[dst_mem_idx];
-    src_mem_size = src_mem->cur_page_count * src_mem->num_bytes_per_page;
-    dst_mem_size = dst_mem->cur_page_count * dst_mem->num_bytes_per_page;
+    src_mem_size =
+        src_mem->cur_page_count * (uint64)src_mem->num_bytes_per_page;
+    dst_mem_size =
+        dst_mem->cur_page_count * (uint64)dst_mem->num_bytes_per_page;
 
     /* if s + n > the length of mem.data */
     if (src_mem_size < src_offset || src_mem_size - src_offset < len)
@@ -738,7 +740,7 @@ wasm_copy_memory(WASMModuleInstance *inst, uint32 src_mem_idx,
     src_addr = src_mem->memory_data + src_offset;
     dst_addr = dst_mem->memory_data + dst_offset;
     /* allowing the destination and source to overlap */
-    bh_memmove_s(dst_addr, dst_mem_size - dst_offset, src_addr, len);
+    bh_memmove_s(dst_addr, (uint32)(dst_mem_size - dst_offset), src_addr, len);
 
     return 0;
 out_of_bounds:
@@ -784,11 +786,11 @@ wasm_fill_memory(WASMModuleInstance *inst, uint32 mem_idx, uint32 len,
                  uint32 val, uint32 dst)
 {
     WASMMemoryInstance *mem_inst;
-    uint32 mem_size;
+    uint64 mem_size;
     uint8 *dst_addr;
 
     mem_inst = inst->memories[mem_idx];
-    mem_size = mem_inst->cur_page_count * mem_inst->num_bytes_per_page;
+    mem_size = mem_inst->cur_page_count * (uint64)mem_inst->num_bytes_per_page;
 
     if (mem_size < dst || mem_size - dst < len)
         goto out_of_bounds;

+ 14 - 8
core/iwasm/fast-jit/jit_frontend.c

@@ -194,12 +194,15 @@ JitReg
 get_aux_stack_bound_reg(JitFrame *frame)
 {
     JitCompContext *cc = frame->cc;
+    JitReg tmp = jit_cc_new_reg_I32(cc);
 
     if (!frame->aux_stack_bound_reg) {
         frame->aux_stack_bound_reg = cc->aux_stack_bound_reg;
-        GEN_INSN(
-            LDI32, frame->aux_stack_bound_reg, cc->exec_env_reg,
-            NEW_CONST(I32, offsetof(WASMExecEnv, aux_stack_boundary.boundary)));
+        GEN_INSN(LDPTR, frame->aux_stack_bound_reg, cc->exec_env_reg,
+                 NEW_CONST(I32, offsetof(WASMExecEnv, aux_stack_boundary)));
+        /* TODO: Memory64 whether to convert depends on memory idx type */
+        GEN_INSN(I64TOI32, tmp, frame->aux_stack_bound_reg);
+        frame->aux_stack_bound_reg = tmp;
     }
     return frame->aux_stack_bound_reg;
 }
@@ -208,12 +211,15 @@ JitReg
 get_aux_stack_bottom_reg(JitFrame *frame)
 {
     JitCompContext *cc = frame->cc;
+    JitReg tmp = jit_cc_new_reg_I32(cc);
 
     if (!frame->aux_stack_bottom_reg) {
         frame->aux_stack_bottom_reg = cc->aux_stack_bottom_reg;
-        GEN_INSN(
-            LDI32, frame->aux_stack_bottom_reg, cc->exec_env_reg,
-            NEW_CONST(I32, offsetof(WASMExecEnv, aux_stack_bottom.bottom)));
+        GEN_INSN(LDPTR, frame->aux_stack_bottom_reg, cc->exec_env_reg,
+                 NEW_CONST(I32, offsetof(WASMExecEnv, aux_stack_bottom)));
+        /* TODO: Memory64 whether to convert depends on memory idx type */
+        GEN_INSN(I64TOI32, tmp, frame->aux_stack_bottom_reg);
+        frame->aux_stack_bottom_reg = tmp;
     }
     return frame->aux_stack_bottom_reg;
 }
@@ -915,8 +921,8 @@ create_fixed_virtual_regs(JitCompContext *cc)
     cc->import_func_ptrs_reg = jit_cc_new_reg_ptr(cc);
     cc->fast_jit_func_ptrs_reg = jit_cc_new_reg_ptr(cc);
     cc->func_type_indexes_reg = jit_cc_new_reg_ptr(cc);
-    cc->aux_stack_bound_reg = jit_cc_new_reg_I32(cc);
-    cc->aux_stack_bottom_reg = jit_cc_new_reg_I32(cc);
+    cc->aux_stack_bound_reg = jit_cc_new_reg_ptr(cc);
+    cc->aux_stack_bottom_reg = jit_cc_new_reg_ptr(cc);
 
     count = module->import_memory_count + module->memory_count;
     if (count > 0) {

+ 6 - 0
core/iwasm/include/aot_export.h

@@ -3,6 +3,12 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
+/**
+ * @file   aot_export.h
+ *
+ * @brief  This file defines the exported AOT compilation APIs
+ */
+
 #ifndef _AOT_EXPORT_H
 #define _AOT_EXPORT_H
 

+ 16 - 0
core/iwasm/include/gc_export.h

@@ -3,6 +3,12 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
+/**
+ * @file   gc_export.h
+ *
+ * @brief  This file defines the exported GC APIs
+ */
+
 #ifndef _GC_EXPORT_H
 #define _GC_EXPORT_H
 
@@ -437,6 +443,16 @@ WASM_RUNTIME_API_EXTERN void
 wasm_struct_obj_get_field(const wasm_struct_obj_t obj, uint32_t field_idx,
                           bool sign_extend, wasm_value_t *value);
 
+/**
+ * Get the field count of the a struct object.
+ *
+ * @param obj the WASM struct object
+ *
+ * @return the field count of the a struct object
+ */
+WASM_RUNTIME_API_EXTERN uint32_t
+wasm_struct_obj_get_field_count(const wasm_struct_obj_t obj);
+
 /**
  * Create an array object with the index of defined type, the obj's length is
  * length, init value is init_value

+ 5 - 0
core/iwasm/include/lib_export.h

@@ -3,6 +3,11 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
+/**
+ * @file   lib_export.h
+ *
+ */
+
 #ifndef _LIB_EXPORT_H_
 #define _LIB_EXPORT_H_
 

+ 36 - 0
core/iwasm/include/wasm_c_api.h

@@ -1,5 +1,11 @@
 // WebAssembly C API
 
+/**
+ * @file   wasm_c_api.h
+ *
+ * @brief  This file defines the WebAssembly C APIs
+ */
+
 #ifndef _WASM_C_API_H_
 #define _WASM_C_API_H_
 
@@ -186,6 +192,16 @@ struct wasm_config_t {
     /*TODO: wasi args*/
 };
 
+#ifndef INSTANTIATION_ARGS_OPTION_DEFINED
+#define INSTANTIATION_ARGS_OPTION_DEFINED
+/* WASM module instantiation arguments */
+typedef struct InstantiationArgs {
+    uint32_t default_stack_size;
+    uint32_t host_managed_heap_size;
+    uint32_t max_memory_pages;
+} InstantiationArgs;
+#endif /* INSTANTIATION_ARGS_OPTION_DEFINED */
+
 /*
  * by default:
  * - mem_alloc_type is Alloc_With_System_Allocator
@@ -507,10 +523,21 @@ struct WASMModuleCommon;
 typedef struct WASMModuleCommon *wasm_module_t;
 #endif
 
+#ifndef LOAD_ARGS_OPTION_DEFINED
+#define LOAD_ARGS_OPTION_DEFINED
+typedef struct LoadArgs {
+    char *name;
+    /* TODO: more fields? */
+} LoadArgs;
+#endif /* LOAD_ARGS_OPTION_DEFINED */
 
 WASM_API_EXTERN own wasm_module_t* wasm_module_new(
   wasm_store_t*, const wasm_byte_vec_t* binary);
 
+// please refer to wasm_runtime_load_ex(...) in core/iwasm/include/wasm_export.h
+WASM_API_EXTERN own wasm_module_t* wasm_module_new_ex(
+  wasm_store_t*, const wasm_byte_vec_t* binary, const LoadArgs *args);
+
 WASM_API_EXTERN void wasm_module_delete(own wasm_module_t*);
 
 WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
@@ -526,6 +553,9 @@ WASM_API_EXTERN own wasm_shared_module_t* wasm_module_share(wasm_module_t*);
 WASM_API_EXTERN own wasm_module_t* wasm_module_obtain(wasm_store_t*, wasm_shared_module_t*);
 WASM_API_EXTERN void wasm_shared_module_delete(own wasm_shared_module_t*);
 
+WASM_API_EXTERN bool wasm_module_set_name(wasm_module_t*, const char* name);
+WASM_API_EXTERN const char *wasm_module_get_name(wasm_module_t*);
+
 
 // Function Instances
 
@@ -644,6 +674,12 @@ WASM_API_EXTERN own wasm_instance_t* wasm_instance_new_with_args(
   own wasm_trap_t** trap, const uint32_t stack_size, const uint32_t heap_size
 );
 
+// please refer to wasm_runtime_instantiate_ex(...) in core/iwasm/include/wasm_export.h
+WASM_API_EXTERN own wasm_instance_t* wasm_instance_new_with_args_ex(
+  wasm_store_t*, const wasm_module_t*, const wasm_extern_vec_t *imports,
+  own wasm_trap_t** trap, const InstantiationArgs *inst_args
+);
+
 WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out);
 
 

+ 232 - 77
core/iwasm/include/wasm_export.h

@@ -3,6 +3,12 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
+/**
+ * @file   wasm_export.h
+ *
+ * @brief  This file defines the exported common runtime APIs
+ */
+
 #ifndef _WASM_EXPORT_H
 #define _WASM_EXPORT_H
 
@@ -26,10 +32,7 @@
 extern "C" {
 #endif
 
-/* clang-format off */
-
-#define get_module_inst(exec_env) \
-    wasm_runtime_get_module_inst(exec_env)
+#define get_module_inst(exec_env) wasm_runtime_get_module_inst(exec_env)
 
 #define validate_app_addr(offset, size) \
     wasm_runtime_validate_app_addr(module_inst, offset, size)
@@ -46,8 +49,7 @@ extern "C" {
 #define module_malloc(size, p_native_addr) \
     wasm_runtime_module_malloc(module_inst, size, p_native_addr)
 
-#define module_free(offset) \
-    wasm_runtime_module_free(module_inst, offset)
+#define module_free(offset) wasm_runtime_module_free(module_inst, offset)
 
 #define native_raw_return_type(type, args) type *raw_ret = (type *)(args)
 
@@ -63,6 +65,25 @@ struct WASMModuleCommon;
 typedef struct WASMModuleCommon *wasm_module_t;
 #endif
 
+typedef enum {
+    WASM_IMPORT_EXPORT_KIND_FUNC,
+    WASM_IMPORT_EXPORT_KIND_TABLE,
+    WASM_IMPORT_EXPORT_KIND_MEMORY,
+    WASM_IMPORT_EXPORT_KIND_GLOBAL
+} wasm_import_export_kind_t;
+
+typedef struct wasm_import_type {
+    const char *module_name;
+    const char *name;
+    wasm_import_export_kind_t kind;
+    bool linked;
+} wasm_import_type;
+
+typedef struct wasm_export_type {
+    const char *name;
+    wasm_import_export_kind_t kind;
+} wasm_export_type;
+
 /* Instantiated WASM module */
 struct WASMModuleInstanceCommon;
 typedef struct WASMModuleInstanceCommon *wasm_module_inst_t;
@@ -107,6 +128,8 @@ typedef enum {
     Alloc_With_System_Allocator,
 } mem_alloc_type_t;
 
+typedef enum { Alloc_For_Runtime, Alloc_For_LinearMemory } mem_alloc_usage_t;
+
 /* Memory allocator option */
 typedef union MemAllocOption {
     struct {
@@ -114,6 +137,9 @@ typedef union MemAllocOption {
         uint32_t heap_size;
     } pool;
     struct {
+        /* the function signature is varied when
+        WASM_MEM_ALLOC_WITH_USER_DATA and
+        WASM_MEM_ALLOC_WITH_USAGE are defined */
         void *malloc_func;
         void *realloc_func;
         void *free_func;
@@ -183,6 +209,24 @@ typedef struct RuntimeInitArgs {
     bool enable_linux_perf;
 } RuntimeInitArgs;
 
+#ifndef LOAD_ARGS_OPTION_DEFINED
+#define LOAD_ARGS_OPTION_DEFINED
+typedef struct LoadArgs {
+    char *name;
+    /* TODO: more fields? */
+} LoadArgs;
+#endif /* LOAD_ARGS_OPTION_DEFINED */
+
+#ifndef INSTANTIATION_ARGS_OPTION_DEFINED
+#define INSTANTIATION_ARGS_OPTION_DEFINED
+/* WASM module instantiation arguments */
+typedef struct InstantiationArgs {
+    uint32_t default_stack_size;
+    uint32_t host_managed_heap_size;
+    uint32_t max_memory_pages;
+} InstantiationArgs;
+#endif /* INSTANTIATION_ARGS_OPTION_DEFINED */
+
 #ifndef WASM_VALKIND_T_DEFINED
 #define WASM_VALKIND_T_DEFINED
 typedef uint8_t wasm_valkind_t;
@@ -341,8 +385,8 @@ wasm_runtime_is_xip_file(const uint8_t *buf, uint32_t size);
  * Callback to load a module file into a buffer in multi-module feature
  */
 typedef bool (*module_reader)(package_type_t module_type,
-                              const char *module_name,
-                              uint8_t **p_buffer, uint32_t *p_size);
+                              const char *module_name, uint8_t **p_buffer,
+                              uint32_t *p_size);
 
 /**
  * Callback to release the buffer loaded by module_reader callback
@@ -406,8 +450,15 @@ wasm_runtime_find_module_registered(const char *module_name);
  * @return return WASM module loaded, NULL if failed
  */
 WASM_RUNTIME_API_EXTERN wasm_module_t
-wasm_runtime_load(uint8_t *buf, uint32_t size,
-                  char *error_buf, uint32_t error_buf_size);
+wasm_runtime_load(uint8_t *buf, uint32_t size, char *error_buf,
+                  uint32_t error_buf_size);
+
+/**
+ * Load a WASM module with specified load argument.
+ */
+WASM_RUNTIME_API_EXTERN wasm_module_t
+wasm_runtime_load_ex(uint8_t *buf, uint32_t size, const LoadArgs *args,
+                     char *error_buf, uint32_t error_buf_size);
 
 /**
  * Load a WASM module from a specified WASM or AOT section list.
@@ -476,12 +527,12 @@ wasm_runtime_get_module_hash(wasm_module_t module);
  *                      for STDERR is used.
  */
 WASM_RUNTIME_API_EXTERN void
-wasm_runtime_set_wasi_args_ex(wasm_module_t module,
-                           const char *dir_list[], uint32_t dir_count,
-                           const char *map_dir_list[], uint32_t map_dir_count,
-                           const char *env[], uint32_t env_count,
-                           char *argv[], int argc, int64_t stdinfd,
-                           int64_t stdoutfd, int64_t stderrfd);
+wasm_runtime_set_wasi_args_ex(wasm_module_t module, const char *dir_list[],
+                              uint32_t dir_count, const char *map_dir_list[],
+                              uint32_t map_dir_count, const char *env[],
+                              uint32_t env_count, char *argv[], int argc,
+                              int64_t stdinfd, int64_t stdoutfd,
+                              int64_t stderrfd);
 
 /**
  * Set WASI parameters.
@@ -489,34 +540,34 @@ wasm_runtime_set_wasi_args_ex(wasm_module_t module,
  * Same as wasm_runtime_set_wasi_args_ex but with default stdio handles
  */
 WASM_RUNTIME_API_EXTERN void
-wasm_runtime_set_wasi_args(wasm_module_t module,
-                           const char *dir_list[], uint32_t dir_count,
-                           const char *map_dir_list[], uint32_t map_dir_count,
-                           const char *env[], uint32_t env_count,
-                           char *argv[], int argc);
+wasm_runtime_set_wasi_args(wasm_module_t module, const char *dir_list[],
+                           uint32_t dir_count, const char *map_dir_list[],
+                           uint32_t map_dir_count, const char *env[],
+                           uint32_t env_count, char *argv[], int argc);
 
 WASM_RUNTIME_API_EXTERN void
 wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
                                 uint32_t addr_pool_size);
 
 WASM_RUNTIME_API_EXTERN void
-wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module, const char *ns_lookup_pool[],
+wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module,
+                                     const char *ns_lookup_pool[],
                                      uint32_t ns_lookup_pool_size);
 
 /**
  * Instantiate a WASM module.
  *
  * @param module the WASM module to instantiate
- * @param default_stack_size the default stack size of the module instance when the
- *        exec env's operation stack isn't created by user, e.g. API
+ * @param default_stack_size the default stack size of the module instance when
+ *        the exec env's operation stack isn't created by user, e.g. API
  *        wasm_application_execute_main() and wasm_application_execute_func()
  *        create the operation stack internally with the stack size specified
  *        here. And API wasm_runtime_create_exec_env() creates the operation
  *        stack with stack size specified by its parameter, the stack size
  *        specified here is ignored.
- * @param host_managed_heap_size the default heap size of the module instance, a heap will
- *        be created besides the app memory space. Both wasm app and native
- *        function can allocate memory from the heap.
+ * @param host_managed_heap_size the default heap size of the module instance,
+ *        a heap will be created besides the app memory space. Both wasm app
+ *        and native function can allocate memory from the heap.
  * @param error_buf buffer to output the error info if failed
  * @param error_buf_size the size of the error buffer
  *
@@ -524,8 +575,20 @@ wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module, const char *ns_lookup
  */
 WASM_RUNTIME_API_EXTERN wasm_module_inst_t
 wasm_runtime_instantiate(const wasm_module_t module,
-                         uint32_t default_stack_size, uint32_t host_managed_heap_size,
-                         char *error_buf, uint32_t error_buf_size);
+                         uint32_t default_stack_size,
+                         uint32_t host_managed_heap_size, char *error_buf,
+                         uint32_t error_buf_size);
+
+/**
+ * Instantiate a WASM module, with specified instantiation arguments
+ *
+ * Same as wasm_runtime_instantiate, but it also allows overwriting maximum
+ * memory
+ */
+WASM_RUNTIME_API_EXTERN wasm_module_inst_t
+wasm_runtime_instantiate_ex(const wasm_module_t module,
+                            const InstantiationArgs *args, char *error_buf,
+                            uint32_t error_buf_size);
 
 /**
  * Set the running mode of a WASM module instance, override the
@@ -596,13 +659,12 @@ wasm_runtime_get_wasi_exit_code(wasm_module_inst_t module_inst);
  *
  * @param module_inst the module instance
  * @param name the name of the function
- * @param signature the signature of the function, ignored currently
  *
  * @return the function instance found, NULL if not found
  */
 WASM_RUNTIME_API_EXTERN wasm_function_inst_t
 wasm_runtime_lookup_function(wasm_module_inst_t const module_inst,
-                             const char *name, const char *signature);
+                             const char *name);
 
 /**
  * Get parameter count of the function instance
@@ -711,7 +773,8 @@ wasm_runtime_get_exec_env_singleton(wasm_module_inst_t module_inst);
  * @return debug port if success, 0 otherwise.
  */
 WASM_RUNTIME_API_EXTERN uint32_t
-wasm_runtime_start_debug_instance_with_port(wasm_exec_env_t exec_env, int32_t port);
+wasm_runtime_start_debug_instance_with_port(wasm_exec_env_t exec_env,
+                                            int32_t port);
 
 /**
  * Same as wasm_runtime_start_debug_instance_with_port(env, -1).
@@ -792,8 +855,7 @@ wasm_runtime_set_module_inst(wasm_exec_env_t exec_env,
  *   info.
  */
 WASM_RUNTIME_API_EXTERN bool
-wasm_runtime_call_wasm(wasm_exec_env_t exec_env,
-                       wasm_function_inst_t function,
+wasm_runtime_call_wasm(wasm_exec_env_t exec_env, wasm_function_inst_t function,
                        uint32_t argc, uint32_t argv[]);
 
 /**
@@ -814,9 +876,9 @@ wasm_runtime_call_wasm(wasm_exec_env_t exec_env,
  */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_call_wasm_a(wasm_exec_env_t exec_env,
-                         wasm_function_inst_t function,
-                         uint32_t num_results, wasm_val_t results[],
-                         uint32_t num_args, wasm_val_t *args);
+                         wasm_function_inst_t function, uint32_t num_results,
+                         wasm_val_t results[], uint32_t num_args,
+                         wasm_val_t *args);
 
 /**
  * Call the given WASM function of a WASM module instance with
@@ -836,9 +898,8 @@ wasm_runtime_call_wasm_a(wasm_exec_env_t exec_env,
  */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_call_wasm_v(wasm_exec_env_t exec_env,
-                         wasm_function_inst_t function,
-                         uint32_t num_results, wasm_val_t results[],
-                         uint32_t num_args, ...);
+                         wasm_function_inst_t function, uint32_t num_results,
+                         wasm_val_t results[], uint32_t num_args, ...);
 
 /**
  * Call a function reference of a given WASM runtime instance with
@@ -880,8 +941,8 @@ wasm_runtime_call_indirect(wasm_exec_env_t exec_env, uint32_t element_index,
  *   the exception info.
  */
 WASM_RUNTIME_API_EXTERN bool
-wasm_application_execute_main(wasm_module_inst_t module_inst,
-                              int32_t argc, char *argv[]);
+wasm_application_execute_main(wasm_module_inst_t module_inst, int32_t argc,
+                              char *argv[]);
 
 /**
  * Find the specified function in argv[0] from a WASM module instance
@@ -899,8 +960,8 @@ wasm_application_execute_main(wasm_module_inst_t module_inst,
  *   to get the exception info.
  */
 WASM_RUNTIME_API_EXTERN bool
-wasm_application_execute_func(wasm_module_inst_t module_inst,
-                              const char *name, int32_t argc, char *argv[]);
+wasm_application_execute_func(wasm_module_inst_t module_inst, const char *name,
+                              int32_t argc, char *argv[]);
 
 /**
  * Get exception info of the WASM module instance.
@@ -959,8 +1020,7 @@ wasm_runtime_terminate(wasm_module_inst_t module_inst);
  * @param custom_data the custom data to be set
  */
 WASM_RUNTIME_API_EXTERN void
-wasm_runtime_set_custom_data(wasm_module_inst_t module_inst,
-                             void *custom_data);
+wasm_runtime_set_custom_data(wasm_module_inst_t module_inst, void *custom_data);
 
 /**
  * Get the custom data within a WASM module instance.
@@ -979,8 +1039,7 @@ wasm_runtime_get_custom_data(wasm_module_inst_t module_inst);
  * @param enable the flag to enable/disable the memory bounds checks
  */
 WASM_RUNTIME_API_EXTERN void
-wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
-                               bool enable);
+wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst, bool enable);
 
 /**
  * Check if the memory bounds checks flag is enabled for a WASM module instance.
@@ -989,8 +1048,7 @@ wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
  * @return true if the memory bounds checks flag is enabled, false otherwise
  */
 WASM_RUNTIME_API_EXTERN bool
-wasm_runtime_is_bounds_checks_enabled(
-    wasm_module_inst_t module_inst);
+wasm_runtime_is_bounds_checks_enabled(wasm_module_inst_t module_inst);
 
 /**
  * Allocate memory from the heap of WASM module instance
@@ -1011,8 +1069,8 @@ wasm_runtime_is_bounds_checks_enabled(
  *         it is not an absolute address.
  *         Return non-zero if success, zero if failed.
  */
-WASM_RUNTIME_API_EXTERN uint32_t
-wasm_runtime_module_malloc(wasm_module_inst_t module_inst, uint32_t size,
+WASM_RUNTIME_API_EXTERN uint64_t
+wasm_runtime_module_malloc(wasm_module_inst_t module_inst, uint64_t size,
                            void **p_native_addr);
 
 /**
@@ -1022,7 +1080,7 @@ wasm_runtime_module_malloc(wasm_module_inst_t module_inst, uint32_t size,
  * @param ptr the pointer to free
  */
 WASM_RUNTIME_API_EXTERN void
-wasm_runtime_module_free(wasm_module_inst_t module_inst, uint32_t ptr);
+wasm_runtime_module_free(wasm_module_inst_t module_inst, uint64_t ptr);
 
 /**
  * Allocate memory from the heap of WASM module instance and initialize
@@ -1037,9 +1095,9 @@ wasm_runtime_module_free(wasm_module_inst_t module_inst, uint32_t ptr);
  *         it is not an absolute address.
  *         Return non-zero if success, zero if failed.
  */
-WASM_RUNTIME_API_EXTERN uint32_t
-wasm_runtime_module_dup_data(wasm_module_inst_t module_inst,
-                             const char *src, uint32_t size);
+WASM_RUNTIME_API_EXTERN uint64_t
+wasm_runtime_module_dup_data(wasm_module_inst_t module_inst, const char *src,
+                             uint64_t size);
 
 /**
  * Validate the app address, check whether it belongs to WASM module
@@ -1054,7 +1112,7 @@ wasm_runtime_module_dup_data(wasm_module_inst_t module_inst,
  */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_validate_app_addr(wasm_module_inst_t module_inst,
-                               uint32_t app_offset, uint32_t size);
+                               uint64_t app_offset, uint64_t size);
 
 /**
  * Similar to wasm_runtime_validate_app_addr(), except that the size parameter
@@ -1076,7 +1134,7 @@ wasm_runtime_validate_app_addr(wasm_module_inst_t module_inst,
  */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_validate_app_str_addr(wasm_module_inst_t module_inst,
-                                   uint32_t app_str_offset);
+                                   uint64_t app_str_offset);
 
 /**
  * Validate the native address, check whether it belongs to WASM module
@@ -1092,7 +1150,7 @@ wasm_runtime_validate_app_str_addr(wasm_module_inst_t module_inst,
  */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_validate_native_addr(wasm_module_inst_t module_inst,
-                                  void *native_ptr, uint32_t size);
+                                  void *native_ptr, uint64_t size);
 
 /**
  * Convert app address(relative address) to native address(absolute address)
@@ -1108,7 +1166,7 @@ wasm_runtime_validate_native_addr(wasm_module_inst_t module_inst,
  */
 WASM_RUNTIME_API_EXTERN void *
 wasm_runtime_addr_app_to_native(wasm_module_inst_t module_inst,
-                                uint32_t app_offset);
+                                uint64_t app_offset);
 
 /**
  * Convert native address(absolute address) to app address(relative address)
@@ -1118,7 +1176,7 @@ wasm_runtime_addr_app_to_native(wasm_module_inst_t module_inst,
  *
  * @return the app address converted
  */
-WASM_RUNTIME_API_EXTERN uint32_t
+WASM_RUNTIME_API_EXTERN uint64_t
 wasm_runtime_addr_native_to_app(wasm_module_inst_t module_inst,
                                 void *native_ptr);
 
@@ -1134,9 +1192,9 @@ wasm_runtime_addr_native_to_app(wasm_module_inst_t module_inst,
  */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_get_app_addr_range(wasm_module_inst_t module_inst,
-                                uint32_t app_offset,
-                                uint32_t *p_app_start_offset,
-                                uint32_t *p_app_end_offset);
+                                uint64_t app_offset,
+                                uint64_t *p_app_start_offset,
+                                uint64_t *p_app_end_offset);
 
 /**
  * Get the native address range (absolute address) that a native address
@@ -1157,6 +1215,48 @@ wasm_runtime_get_native_addr_range(wasm_module_inst_t module_inst,
                                    uint8_t **p_native_start_addr,
                                    uint8_t **p_native_end_addr);
 
+/**
+ * Get the number of import items for a WASM module
+ *
+ * @param module the WASM module
+ *
+ * @return the number of imports (zero for none), or -1 for failure
+ */
+WASM_RUNTIME_API_EXTERN int32_t
+wasm_runtime_get_import_count(const wasm_module_t module);
+
+/**
+ * Get information about a specific WASM module import
+ *
+ * @param module the WASM module
+ * @param import_index the desired import index
+ * @param import_type the location to store information about the import
+ */
+WASM_RUNTIME_API_EXTERN void
+wasm_runtime_get_import_type(const wasm_module_t module, int32_t import_index,
+                             wasm_import_type *import_type);
+
+/**
+ * Get the number of export items for a WASM module
+ *
+ * @param module the WASM module
+ *
+ * @return the number of exports (zero for none), or -1 for failure
+ */
+WASM_RUNTIME_API_EXTERN int32_t
+wasm_runtime_get_export_count(const wasm_module_t module);
+
+/**
+ * Get information about a specific WASM module export
+ *
+ * @param module the WASM module
+ * @param export_index the desired export index
+ * @param export_type the location to store information about the export
+ */
+WASM_RUNTIME_API_EXTERN void
+wasm_runtime_get_export_type(const wasm_module_t module, int32_t export_index,
+                             wasm_export_type *export_type);
+
 /**
  * Register native functions with same module name
  *
@@ -1176,7 +1276,8 @@ wasm_runtime_get_native_addr_range(wasm_module_inst_t module_inst,
  *          'I': the parameter is i64 type
  *          'f': the parameter is f32 type
  *          'F': the parameter is f64 type
- *          'r': the parameter is externref type, it should be a uintptr_t in host
+ *          'r': the parameter is externref type, it should be a uintptr_t
+ *               in host
  *          '*': the parameter is a pointer (i32 in WASM), and runtime will
  *               auto check its boundary before calling the native function.
  *               If it is followed by '~', the checked length of the pointer
@@ -1210,7 +1311,6 @@ wasm_runtime_register_natives_raw(const char *module_name,
                                   NativeSymbol *native_symbols,
                                   uint32_t n_native_symbols);
 
-
 /**
  * Undo wasm_runtime_register_natives or wasm_runtime_register_natives_raw
  *
@@ -1287,7 +1387,7 @@ 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.
+ * 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
@@ -1366,8 +1466,8 @@ wasm_runtime_join_thread(wasm_thread_t tid, void **retval);
  * @return true if success, false otherwise
  */
 WASM_RUNTIME_API_EXTERN bool
-wasm_externref_obj2ref(wasm_module_inst_t module_inst,
-                       void *extern_obj, uint32_t *p_externref_idx);
+wasm_externref_obj2ref(wasm_module_inst_t module_inst, void *extern_obj,
+                       uint32_t *p_externref_idx);
 
 /**
  * Delete external object registered by `wasm_externref_obj2ref`.
@@ -1494,7 +1594,6 @@ WASM_RUNTIME_API_EXTERN const uint8_t *
 wasm_runtime_get_custom_section(wasm_module_t const module_comm,
                                 const char *name, uint32_t *len);
 
-
 /**
  * Get WAMR semantic version
  */
@@ -1510,8 +1609,8 @@ wasm_runtime_is_import_func_linked(const char *module_name,
                                    const char *func_name);
 
 /**
- * Check whether an import global `(import <module_name> <global_name> (global ...))`
- * is linked or not with runtime registered natvie globals
+ * Check whether an import global `(import <module_name> <global_name>
+ * (global ...))` is linked or not with runtime registered natvie globals
  */
 WASM_RUNTIME_API_EXTERN bool
 wasm_runtime_is_import_global_linked(const char *module_name,
@@ -1525,8 +1624,7 @@ typedef enum {
 typedef void (*enlarge_memory_error_callback_t)(
     uint32_t inc_page_count, uint64_t current_memory_size,
     uint32_t memory_index, enlarge_memory_error_reason_t failure_reason,
-    wasm_module_inst_t instance, wasm_exec_env_t exec_env,
-    void* user_data);
+    wasm_module_inst_t instance, wasm_exec_env_t exec_env, void *user_data);
 
 /**
  * Setup callback invoked when memory.grow fails
@@ -1588,8 +1686,8 @@ wasm_runtime_set_enlarge_mem_error_callback(
  */
 
 WASM_RUNTIME_API_EXTERN void *
-wasm_runtime_create_context_key(
-    void (*dtor)(wasm_module_inst_t inst, void *ctx));
+wasm_runtime_create_context_key(void (*dtor)(wasm_module_inst_t inst,
+                                             void *ctx));
 
 WASM_RUNTIME_API_EXTERN void
 wasm_runtime_destroy_context_key(void *key);
@@ -1650,7 +1748,64 @@ wasm_runtime_begin_blocking_op(wasm_exec_env_t exec_env);
 WASM_RUNTIME_API_EXTERN void
 wasm_runtime_end_blocking_op(wasm_exec_env_t exec_env);
 
-/* clang-format on */
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_set_module_name(wasm_module_t module, const char *name,
+                             char *error_buf, uint32_t error_buf_size);
+
+/* return the most recently set module name or "" if never set before */
+WASM_RUNTIME_API_EXTERN const char *
+wasm_runtime_get_module_name(wasm_module_t module);
+
+/*
+ * wasm_runtime_detect_native_stack_overflow
+ *
+ * Detect native stack shortage.
+ * Ensure that the calling thread still has a reasonable amount of
+ * native stack (WASM_STACK_GUARD_SIZE bytes) available.
+ *
+ * If enough stack is left, this function returns true.
+ * Otherwise, this function raises a "native stack overflow" trap and
+ * returns false.
+ *
+ * Note: please do not expect a very strict detection. it's a good idea
+ * to give some margins. wasm_runtime_detect_native_stack_overflow itself
+ * requires a small amount of stack to run.
+ */
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_detect_native_stack_overflow(wasm_exec_env_t exec_env);
+
+/*
+ * wasm_runtime_detect_native_stack_overflow_size
+ *
+ * Similar to wasm_runtime_detect_native_stack_overflow,
+ * but use the caller-specified size instead of WASM_STACK_GUARD_SIZE.
+ *
+ * An expected usage:
+ * ```c
+ * __attribute__((noinline))  // inlining can break the stack check
+ * void stack_hog(void)
+ * {
+ *     // consume a lot of stack here
+ * }
+ *
+ * void
+ * stack_hog_wrapper(exec_env) {
+ *     // the amount of stack stack_hog would consume,
+ *     // plus a small margin
+ *     uint32_t size = 10000000;
+ *
+ *     if (!wasm_runtime_detect_native_stack_overflow_size(exec_env, size)) {
+ *         // wasm_runtime_detect_native_stack_overflow_size has raised
+ *         // a trap.
+ *         return;
+ *     }
+ *     stack_hog();
+ * }
+ * ```
+ */
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_detect_native_stack_overflow_size(wasm_exec_env_t exec_env,
+                                               uint32_t required_size);
 
 #ifdef __cplusplus
 }

+ 54 - 13
core/iwasm/interpreter/wasm.h

@@ -90,8 +90,22 @@ extern "C" {
  */
 #define VALUE_TYPE_GC_REF 0x43
 
+#define MAX_PAGE_COUNT_FLAG 0x01
+#define SHARED_MEMORY_FLAG 0x02
+#define MEMORY64_FLAG 0x04
+
 #define DEFAULT_NUM_BYTES_PER_PAGE 65536
 #define DEFAULT_MAX_PAGES 65536
+#define DEFAULT_MEM64_MAX_PAGES UINT32_MAX
+
+/* Max size of linear memory */
+#define MAX_LINEAR_MEMORY_SIZE (4 * (uint64)BH_GB)
+/* Roughly 274 TB */
+#define MAX_LINEAR_MEM64_MEMORY_SIZE \
+    (DEFAULT_MEM64_MAX_PAGES * (uint64)64 * (uint64)BH_KB)
+/* Macro to check memory flag and return appropriate memory size */
+#define GET_MAX_LINEAR_MEMORY_SIZE(is_memory64) \
+    (is_memory64 ? MAX_LINEAR_MEM64_MEMORY_SIZE : MAX_LINEAR_MEMORY_SIZE)
 
 #if WASM_ENABLE_GC == 0
 typedef uintptr_t table_elem_type_t;
@@ -260,7 +274,7 @@ typedef struct InitializerExpression {
  */
 typedef struct RefHeapType_TypeIdx {
     /* ref_type is REF_TYPE_HT_NULLABLE or
-       REF_TYPE_HT_NON_NULLABLE, (0x6C or 0x6B) */
+       REF_TYPE_HT_NON_NULLABLE, (0x63 or 0x64) */
     uint8 ref_type;
     /* true if ref_type is REF_TYPE_HT_NULLABLE */
     bool nullable;
@@ -274,7 +288,7 @@ typedef struct RefHeapType_TypeIdx {
  */
 typedef struct RefHeapType_Common {
     /* ref_type is REF_TYPE_HT_NULLABLE or
-       REF_TYPE_HT_NON_NULLABLE (0x6C or 0x6B) */
+       REF_TYPE_HT_NON_NULLABLE (0x63 or 0x64) */
     uint8 ref_type;
     /* true if ref_type is REF_TYPE_HT_NULLABLE */
     bool nullable;
@@ -324,18 +338,24 @@ typedef struct WASMType {
     uint16 type_flag;
 
     bool is_sub_final;
+    /* How many types are referring to this type */
+    uint16 ref_count;
     /* The inheritance depth */
-    uint32 inherit_depth;
+    uint16 inherit_depth;
     /* The root type */
     struct WASMType *root_type;
     /* The parent type */
     struct WASMType *parent_type;
     uint32 parent_type_idx;
 
-    /* number of internal types in the current rec group, if the type is not in
-     * a recursive group, rec_count = 0 */
+    /* The number of internal types in the current rec group, and if
+       the type is not in a recursive group, rec_count is 1 since a
+       single type definition is reinterpreted as a short-hand for a
+       recursive group containing just one type */
     uint16 rec_count;
     uint16 rec_idx;
+    /* The index of the begin type of this group */
+    uint32 rec_begin_type_idx;
 } WASMType, *WASMTypePtr;
 #endif /* end of WASM_ENABLE_GC */
 
@@ -361,9 +381,6 @@ typedef struct WASMFuncType {
     uint16 ref_type_map_count;
     WASMRefTypeMap *ref_type_maps;
     WASMRefTypeMap *result_ref_type_maps;
-    /* minimal type index of the type equal to this type,
-       used in type equal check in call_indirect opcode */
-    uint32 min_type_idx_normalized;
 #else
     uint16 ref_count;
 #endif
@@ -481,6 +498,12 @@ typedef struct WASMTable {
 #endif
 } WASMTable;
 
+#if WASM_ENABLE_MEMORY64 != 0
+typedef uint64 mem_offset_t;
+#else
+typedef uint32 mem_offset_t;
+#endif
+
 typedef struct WASMMemory {
     uint32 flags;
     uint32 num_bytes_per_page;
@@ -870,19 +893,19 @@ struct WASMModule {
        -1 means unexported */
     uint32 aux_data_end_global_index;
     /* auxiliary __data_end exported by wasm app */
-    uint32 aux_data_end;
+    uint64 aux_data_end;
 
     /* the index of auxiliary __heap_base global,
        -1 means unexported */
     uint32 aux_heap_base_global_index;
     /* auxiliary __heap_base exported by wasm app */
-    uint32 aux_heap_base;
+    uint64 aux_heap_base;
 
     /* the index of auxiliary stack top global,
        -1 means unexported */
     uint32 aux_stack_top_global_index;
     /* auxiliary stack bottom resolved */
-    uint32 aux_stack_bottom;
+    uint64 aux_stack_bottom;
     /* auxiliary stack size resolved */
     uint32 aux_stack_size;
 
@@ -1045,6 +1068,9 @@ struct WASMModule {
     bool is_ref_types_used;
     bool is_bulk_memory_used;
 #endif
+
+    /* user defined name */
+    char *name;
 };
 
 typedef struct BlockType {
@@ -1091,6 +1117,21 @@ align_uint(unsigned v, unsigned b)
     return (v + m) & ~m;
 }
 
+/**
+ * Align an 64 bit unsigned value on a alignment boundary.
+ *
+ * @param v the value to be aligned
+ * @param b the alignment boundary (2, 4, 8, ...)
+ *
+ * @return the aligned value
+ */
+inline static uint64
+align_uint64(uint64 v, uint64 b)
+{
+    uint64 m = b - 1;
+    return (v + m) & ~m;
+}
+
 /**
  * Check whether a piece of data is out of range
  *
@@ -1291,8 +1332,8 @@ block_type_get_param_types(BlockType *block_type, uint8 **p_param_types,
         param_count = func_type->param_count;
 #if WASM_ENABLE_GC != 0
         *p_param_reftype_maps = func_type->ref_type_maps;
-        *p_param_reftype_map_count =
-            func_type->result_ref_type_maps - func_type->ref_type_maps;
+        *p_param_reftype_map_count = (uint32)(func_type->result_ref_type_maps
+                                              - func_type->ref_type_maps);
 #endif
     }
     else {

File diff suppressed because it is too large
+ 345 - 177
core/iwasm/interpreter/wasm_interp_classic.c


+ 81 - 50
core/iwasm/interpreter/wasm_interp_fast.c

@@ -42,16 +42,15 @@ typedef float64 CellType_F64;
 
 #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
-#define CHECK_MEMORY_OVERFLOW(bytes)                             \
-    do {                                                         \
-        uint64 offset1 = (uint64)offset + (uint64)addr;          \
-        if (disable_bounds_checks                                \
-            || offset1 + bytes <= (uint64)get_linear_mem_size()) \
-            /* If offset1 is in valid range, maddr must also     \
-                be in valid range, no need to check it again. */ \
-            maddr = memory->memory_data + offset1;               \
-        else                                                     \
-            goto out_of_bounds;                                  \
+#define CHECK_MEMORY_OVERFLOW(bytes)                                           \
+    do {                                                                       \
+        uint64 offset1 = (uint64)offset + (uint64)addr;                        \
+        if (disable_bounds_checks || offset1 + bytes <= get_linear_mem_size()) \
+            /* If offset1 is in valid range, maddr must also                   \
+                be in valid range, no need to check it again. */               \
+            maddr = memory->memory_data + offset1;                             \
+        else                                                                   \
+            goto out_of_bounds;                                                \
     } while (0)
 
 #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr)                        \
@@ -1171,6 +1170,10 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
     all_cell_num += (local_cell_num + 3) / 4;
 #endif
 
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
+        return;
+    }
+
     if (!(frame =
               ALLOC_FRAME(exec_env, wasm_interp_interp_frame_size(all_cell_num),
                           prev_frame)))
@@ -1191,9 +1194,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
     if (!func_import->call_conv_wasm_c_api) {
         native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
     }
-    else if (module_inst->e->common.c_api_func_imports) {
-        c_api_func_import =
-            module_inst->e->common.c_api_func_imports + cur_func_index;
+    else if (module_inst->c_api_func_imports) {
+        c_api_func_import = module_inst->c_api_func_imports + cur_func_index;
         native_func_pointer = c_api_func_import->func_ptr_linked;
     }
 
@@ -1277,8 +1279,16 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
     uint8 *ip = prev_frame->ip;
     char buf[128];
     WASMExecEnv *sub_module_exec_env = NULL;
-    uint32 aux_stack_origin_boundary = 0;
-    uint32 aux_stack_origin_bottom = 0;
+    uintptr_t aux_stack_origin_boundary = 0;
+    uintptr_t aux_stack_origin_bottom = 0;
+
+    /*
+     * perform stack overflow check before calling
+     * wasm_interp_call_func_bytecode recursively.
+     */
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
+        return;
+    }
 
     if (!sub_func_inst) {
         snprintf(buf, sizeof(buf),
@@ -1301,13 +1311,11 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
     wasm_exec_env_set_module_inst(exec_env,
                                   (WASMModuleInstanceCommon *)sub_module_inst);
     /* - aux_stack_boundary */
-    aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
-    exec_env->aux_stack_boundary.boundary =
-        sub_module_exec_env->aux_stack_boundary.boundary;
+    aux_stack_origin_boundary = exec_env->aux_stack_boundary;
+    exec_env->aux_stack_boundary = sub_module_exec_env->aux_stack_boundary;
     /* - aux_stack_bottom */
-    aux_stack_origin_bottom = exec_env->aux_stack_bottom.bottom;
-    exec_env->aux_stack_bottom.bottom =
-        sub_module_exec_env->aux_stack_bottom.bottom;
+    aux_stack_origin_bottom = exec_env->aux_stack_bottom;
+    exec_env->aux_stack_bottom = sub_module_exec_env->aux_stack_bottom;
 
     /* set ip NULL to make call_func_bytecode return after executing
        this function */
@@ -1319,8 +1327,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
 
     /* restore ip and other replaced */
     prev_frame->ip = ip;
-    exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
-    exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
+    exec_env->aux_stack_boundary = aux_stack_origin_boundary;
+    exec_env->aux_stack_bottom = aux_stack_origin_bottom;
     wasm_exec_env_restore_module_inst(exec_env,
                                       (WASMModuleInstanceCommon *)module_inst);
 }
@@ -1458,7 +1466,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #if !defined(OS_ENABLE_HW_BOUND_CHECK)              \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
     || WASM_ENABLE_BULK_MEMORY != 0
-    uint32 linear_mem_size = 0;
+    uint64 linear_mem_size = 0;
     if (memory)
 #if WASM_ENABLE_THREAD_MGR == 0
         linear_mem_size = memory->memory_data_size;
@@ -1519,6 +1527,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
     WASMStringviewIterObjectRef stringview_iter_obj;
 #endif
 #endif
+#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
+    bool is_return_call = false;
+#endif
 
 #if WASM_ENABLE_LABELS_AS_VALUES != 0
 #define HANDLE_OPCODE(op) &&HANDLE_##op
@@ -1711,7 +1722,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
                 /* clang-format off */
 #if WASM_ENABLE_GC == 0
-                fidx = tbl_inst->elems[val];
+                fidx = (uint32)tbl_inst->elems[val];
                 if (fidx == (uint32)-1) {
                     wasm_set_exception(module, "uninitialized element");
                     goto got_exception;
@@ -1751,8 +1762,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                     goto got_exception;
                 }
 #else
-                if (cur_type->min_type_idx_normalized
-                        != cur_func_type->min_type_idx_normalized) {
+                if (!wasm_func_type_is_super_of(cur_type, cur_func_type)) {
                     wasm_set_exception(module, "indirect call type mismatch");
                     goto got_exception;
                 }
@@ -3541,27 +3551,29 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
             HANDLE_OP(WASM_OP_SET_GLOBAL_AUX_STACK)
             {
-                uint32 aux_stack_top;
+                uint64 aux_stack_top;
 
                 global_idx = read_uint32(frame_ip);
                 bh_assert(global_idx < module->e->global_count);
                 global = globals + global_idx;
                 global_addr = get_global_addr(global_data, global);
-                aux_stack_top = frame_lp[GET_OFFSET()];
-                if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) {
+                /* TODO: Memory64 the data type depends on mem idx type */
+                aux_stack_top = (uint64)frame_lp[GET_OFFSET()];
+                if (aux_stack_top <= (uint64)exec_env->aux_stack_boundary) {
                     wasm_set_exception(module, "wasm auxiliary stack overflow");
                     goto got_exception;
                 }
-                if (aux_stack_top > exec_env->aux_stack_bottom.bottom) {
+                if (aux_stack_top > (uint64)exec_env->aux_stack_bottom) {
                     wasm_set_exception(module,
                                        "wasm auxiliary stack underflow");
                     goto got_exception;
                 }
-                *(int32 *)global_addr = aux_stack_top;
+                *(int32 *)global_addr = (uint32)aux_stack_top;
 #if WASM_ENABLE_MEMORY_PROFILING != 0
                 if (module->module->aux_stack_top_global_index != (uint32)-1) {
-                    uint32 aux_stack_used = module->module->aux_stack_bottom
-                                            - *(uint32 *)global_addr;
+                    uint32 aux_stack_used =
+                        (uint32)(module->module->aux_stack_bottom
+                                 - *(uint32 *)global_addr);
                     if (aux_stack_used > module->e->max_aux_stack_used)
                         module->e->max_aux_stack_used = aux_stack_used;
                 }
@@ -4982,8 +4994,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #ifndef OS_ENABLE_HW_BOUND_CHECK
                         CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
 #else
-                        if ((uint64)(uint32)addr + bytes
-                            > (uint64)linear_mem_size)
+                        if ((uint64)(uint32)addr + bytes > linear_mem_size)
                             goto out_of_bounds;
                         maddr = memory->memory_data + (uint32)addr;
 #endif
@@ -5001,7 +5012,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         if (offset + bytes > seg_len)
                             goto out_of_bounds;
 
-                        bh_memcpy_s(maddr, linear_mem_size - addr,
+                        bh_memcpy_s(maddr, (uint32)(linear_mem_size - addr),
                                     data + offset, (uint32)bytes);
                         break;
                     }
@@ -5031,17 +5042,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc);
                         CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
 #else
-                        if ((uint64)(uint32)src + len > (uint64)linear_mem_size)
+                        if ((uint64)(uint32)src + len > linear_mem_size)
                             goto out_of_bounds;
                         msrc = memory->memory_data + (uint32)src;
 
-                        if ((uint64)(uint32)dst + len > (uint64)linear_mem_size)
+                        if ((uint64)(uint32)dst + len > linear_mem_size)
                             goto out_of_bounds;
                         mdst = memory->memory_data + (uint32)dst;
 #endif
 
                         /* allowing the destination and source to overlap */
-                        bh_memmove_s(mdst, linear_mem_size - dst, msrc, len);
+                        bh_memmove_s(mdst, (uint32)(linear_mem_size - dst),
+                                     msrc, len);
                         break;
                     }
                     case WASM_OP_MEMORY_FILL:
@@ -5060,7 +5072,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #ifndef OS_ENABLE_HW_BOUND_CHECK
                         CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
 #else
-                        if ((uint64)(uint32)dst + len > (uint64)linear_mem_size)
+                        if ((uint64)(uint32)dst + len > linear_mem_size)
                             goto out_of_bounds;
                         mdst = memory->memory_data + (uint32)dst;
 #endif
@@ -5634,6 +5646,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             {
                 frame = prev_frame;
                 frame_ip = frame->ip;
+#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
+                is_return_call = false;
+#endif
                 goto call_func_from_entry;
             }
 
@@ -5782,6 +5797,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
         FREE_FRAME(exec_env, frame);
         frame_ip += cur_func->param_count * sizeof(int16);
         wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
+        is_return_call = true;
         goto call_func_from_entry;
     }
 #endif /* WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0 */
@@ -5854,6 +5870,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
         }
         SYNC_ALL_TO_FRAME();
         prev_frame = frame;
+#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
+        is_return_call = false;
+#endif
     }
 
     call_func_from_entry:
@@ -5871,9 +5890,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                                              prev_frame);
             }
 
-            prev_frame = frame->prev_frame;
-            cur_func = frame->function;
-            UPDATE_ALL_FROM_FRAME();
+#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
+            if (is_return_call) {
+                /* the frame was freed before tail calling and
+                   the prev_frame was set as exec_env's cur_frame,
+                   so here we recover context from prev_frame */
+                RECOVER_CONTEXT(prev_frame);
+            }
+            else
+#endif
+            {
+                prev_frame = frame->prev_frame;
+                cur_func = frame->function;
+                UPDATE_ALL_FROM_FRAME();
+            }
 
             /* update memory size, no need to update memory ptr as
                it isn't changed in wasm_enlarge_memory */
@@ -6077,12 +6107,13 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
     }
     argc = function->param_cell_num;
 
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&prev_frame);
-#if !(defined(OS_ENABLE_HW_BOUND_CHECK) \
-      && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0)
-    if ((uint8 *)&prev_frame < exec_env->native_stack_boundary) {
-        wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
-                           "native stack overflow");
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+    /*
+     * wasm_runtime_detect_native_stack_overflow is done by
+     * call_wasm_with_hw_bound_check.
+     */
+#else
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         return;
     }
 #endif

File diff suppressed because it is too large
+ 305 - 256
core/iwasm/interpreter/wasm_loader.c


+ 1 - 1
core/iwasm/interpreter/wasm_loader.h

@@ -28,7 +28,7 @@ wasm_loader_load(uint8 *buf, uint32 size,
 #if WASM_ENABLE_MULTI_MODULE != 0
                  bool main_module,
 #endif
-                 char *error_buf, uint32 error_buf_size);
+                 const LoadArgs *args, char *error_buf, uint32 error_buf_size);
 
 /**
  * Load a WASM module from a specified WASM section list.

File diff suppressed because it is too large
+ 318 - 198
core/iwasm/interpreter/wasm_mini_loader.c


+ 10 - 10
core/iwasm/interpreter/wasm_opcode.h

@@ -593,8 +593,8 @@ typedef enum WASMSimdEXTOpcode {
     /* placeholder            = 0xa2 */
     SIMD_i32x4_all_true = 0xa3,
     SIMD_i32x4_bitmask = 0xa4,
-    SIMD_i32x4_narrow_i64x2_s = 0xa5,
-    SIMD_i32x4_narrow_i64x2_u = 0xa6,
+    /* placeholder     = 0xa5 */
+    /* placeholder     = 0xa6 */
     SIMD_i32x4_extend_low_i16x8_s = 0xa7,
     SIMD_i32x4_extend_high_i16x8_s = 0xa8,
     SIMD_i32x4_extend_low_i16x8_u = 0xa9,
@@ -603,19 +603,19 @@ typedef enum WASMSimdEXTOpcode {
     SIMD_i32x4_shr_s = 0xac,
     SIMD_i32x4_shr_u = 0xad,
     SIMD_i32x4_add = 0xae,
-    SIMD_i32x4_add_sat_s = 0xaf,
-    SIMD_i32x4_add_sat_u = 0xb0,
+    /* placeholder = 0xaf */
+    /* placeholder = 0xb0 */
     SIMD_i32x4_sub = 0xb1,
-    SIMD_i32x4_sub_sat_s = 0xb2,
-    SIMD_i32x4_sub_sat_u = 0xb3,
-    /* placeholder            = 0xb4 */
+    /* placeholder = 0xb2 */
+    /* placeholder = 0xb3 */
+    /* placeholder = 0xb4 */
     SIMD_i32x4_mul = 0xb5,
     SIMD_i32x4_min_s = 0xb6,
     SIMD_i32x4_min_u = 0xb7,
     SIMD_i32x4_max_s = 0xb8,
     SIMD_i32x4_max_u = 0xb9,
     SIMD_i32x4_dot_i16x8_s = 0xba,
-    SIMD_i32x4_avgr_u = 0xbb,
+    /* placeholder         = 0xbb */
     SIMD_i32x4_extmul_low_i16x8_s = 0xbc,
     SIMD_i32x4_extmul_high_i16x8_s = 0xbd,
     SIMD_i32x4_extmul_low_i16x8_u = 0xbe,
@@ -658,7 +658,7 @@ typedef enum WASMSimdEXTOpcode {
     /* f32x4 operation */
     SIMD_f32x4_abs = 0xe0,
     SIMD_f32x4_neg = 0xe1,
-    SIMD_f32x4_round = 0xe2,
+    /* placeholder = 0xe2 */
     SIMD_f32x4_sqrt = 0xe3,
     SIMD_f32x4_add = 0xe4,
     SIMD_f32x4_sub = 0xe5,
@@ -672,7 +672,7 @@ typedef enum WASMSimdEXTOpcode {
     /* f64x2 operation */
     SIMD_f64x2_abs = 0xec,
     SIMD_f64x2_neg = 0xed,
-    SIMD_f64x2_round = 0xee,
+    /* placeholder = 0xee */
     SIMD_f64x2_sqrt = 0xef,
     SIMD_f64x2_add = 0xf0,
     SIMD_f64x2_sub = 0xf1,

+ 400 - 120
core/iwasm/interpreter/wasm_runtime.c

@@ -60,13 +60,13 @@ wasm_load(uint8 *buf, uint32 size,
 #if WASM_ENABLE_MULTI_MODULE != 0
           bool main_module,
 #endif
-          char *error_buf, uint32 error_buf_size)
+          const LoadArgs *name, char *error_buf, uint32 error_buf_size)
 {
     return wasm_loader_load(buf, size,
 #if WASM_ENABLE_MULTI_MODULE != 0
                             main_module,
 #endif
-                            error_buf, error_buf_size);
+                            name, error_buf, error_buf_size);
 }
 
 WASMModule *
@@ -162,15 +162,16 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
                    char *error_buf, uint32 error_buf_size)
 {
     WASMModule *module = module_inst->module;
-    uint64 memory_data_size, max_memory_data_size;
-    uint32 heap_offset = num_bytes_per_page * init_page_count;
-    uint32 inc_page_count, aux_heap_base, global_idx;
+    uint32 inc_page_count, global_idx, default_max_page;
     uint32 bytes_of_last_page, bytes_to_page_end;
+    uint64 aux_heap_base,
+        heap_offset = (uint64)num_bytes_per_page * init_page_count;
+    uint64 memory_data_size, max_memory_data_size;
     uint8 *global_addr;
 
     bool is_shared_memory = false;
 #if WASM_ENABLE_SHARED_MEMORY != 0
-    is_shared_memory = flags & 0x02 ? true : false;
+    is_shared_memory = flags & SHARED_MEMORY_FLAG ? true : false;
 
     /* shared memory */
     if (is_shared_memory && parent != NULL) {
@@ -185,6 +186,14 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
     (void)flags;
 #endif /* end of WASM_ENABLE_SHARED_MEMORY */
 
+#if WASM_ENABLE_MEMORY64 != 0
+    if (flags & MEMORY64_FLAG) {
+        memory->is_memory64 = 1;
+    }
+#endif
+    default_max_page =
+        memory->is_memory64 ? DEFAULT_MEM64_MAX_PAGES : DEFAULT_MAX_PAGES;
+
     if (heap_size > 0 && module_inst->module->malloc_function != (uint32)-1
         && module_inst->module->free_function != (uint32)-1) {
         /* Disable app heap, use malloc/free function exported
@@ -192,6 +201,16 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
         heap_size = 0;
     }
 
+    /* If initial memory is the largest size allowed, disallowing insert host
+     * managed heap */
+    if (heap_size > 0
+        && heap_offset == GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64)) {
+        set_error_buf(error_buf, error_buf_size,
+                      "failed to insert app heap into linear memory, "
+                      "try using `--heap-size=0` option");
+        return NULL;
+    }
+
     if (init_page_count == max_page_count && init_page_count == 1) {
         /* If only one page and at most one page, we just append
            the app heap to the end of linear memory, enlarge the
@@ -215,7 +234,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
         }
         else if (module->aux_heap_base_global_index != (uint32)-1
                  && module->aux_heap_base
-                        < num_bytes_per_page * init_page_count) {
+                        < (uint64)num_bytes_per_page * init_page_count) {
             /* Insert app heap before __heap_base */
             aux_heap_base = module->aux_heap_base;
             bytes_of_last_page = aux_heap_base % num_bytes_per_page;
@@ -243,54 +262,58 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
                       && global_idx < module_inst->e->global_count);
             global_addr = module_inst->global_data
                           + module_inst->e->globals[global_idx].data_offset;
-            *(uint32 *)global_addr = aux_heap_base;
-            LOG_VERBOSE("Reset __heap_base global to %u", aux_heap_base);
+#if WASM_ENABLE_MEMORY64 != 0
+            if (memory->is_memory64) {
+                /* For memory64, the global value should be i64 */
+                *(uint64 *)global_addr = aux_heap_base;
+            }
+            else
+#endif
+            {
+                /* For memory32, the global value should be i32 */
+                *(uint32 *)global_addr = (uint32)aux_heap_base;
+            }
+            LOG_VERBOSE("Reset __heap_base global to %" PRIu64, aux_heap_base);
         }
         else {
             /* Insert app heap before new page */
             inc_page_count =
                 (heap_size + num_bytes_per_page - 1) / num_bytes_per_page;
-            heap_offset = num_bytes_per_page * init_page_count;
-            heap_size = num_bytes_per_page * inc_page_count;
+            heap_offset = (uint64)num_bytes_per_page * init_page_count;
+            heap_size = (uint64)num_bytes_per_page * inc_page_count;
             if (heap_size > 0)
                 heap_size -= 1 * BH_KB;
         }
         init_page_count += inc_page_count;
         max_page_count += inc_page_count;
-        if (init_page_count > DEFAULT_MAX_PAGES) {
+        if (init_page_count > default_max_page) {
             set_error_buf(error_buf, error_buf_size,
                           "failed to insert app heap into linear memory, "
                           "try using `--heap-size=0` option");
             return NULL;
         }
-        else if (init_page_count == DEFAULT_MAX_PAGES) {
-            num_bytes_per_page = UINT32_MAX;
-            init_page_count = max_page_count = 1;
-        }
-        if (max_page_count > DEFAULT_MAX_PAGES)
-            max_page_count = DEFAULT_MAX_PAGES;
-    }
-    else { /* heap_size == 0 */
-        if (init_page_count == DEFAULT_MAX_PAGES) {
-            num_bytes_per_page = UINT32_MAX;
-            init_page_count = max_page_count = 1;
-        }
+
+        if (max_page_count > default_max_page)
+            max_page_count = default_max_page;
     }
 
     LOG_VERBOSE("Memory instantiate:");
     LOG_VERBOSE("  page bytes: %u, init pages: %u, max pages: %u",
                 num_bytes_per_page, init_page_count, max_page_count);
-    LOG_VERBOSE("  heap offset: %u, heap size: %d\n", heap_offset, heap_size);
+    LOG_VERBOSE("  heap offset: %" PRIu64 ", heap size: %u\n", heap_offset,
+                heap_size);
 
     max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
-    bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB);
+    bh_assert(max_memory_data_size
+              <= GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64));
     (void)max_memory_data_size;
 
     bh_assert(memory != NULL);
 
     if (wasm_allocate_linear_memory(&memory->memory_data, is_shared_memory,
-                                    num_bytes_per_page, init_page_count,
-                                    max_page_count, &memory_data_size)
+                                    memory->is_memory64, 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");
@@ -301,11 +324,11 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
     memory->num_bytes_per_page = num_bytes_per_page;
     memory->cur_page_count = init_page_count;
     memory->max_page_count = max_page_count;
-    memory->memory_data_size = (uint32)memory_data_size;
+    memory->memory_data_size = memory_data_size;
 
     memory->heap_data = memory->memory_data + heap_offset;
     memory->heap_data_end = memory->heap_data + heap_size;
-    memory->memory_data_end = memory->memory_data + (uint32)memory_data_size;
+    memory->memory_data_end = memory->memory_data + memory_data_size;
 
     /* Initialize heap */
     if (heap_size > 0) {
@@ -353,7 +376,8 @@ fail1:
 static WASMMemoryInstance **
 memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
                      WASMModuleInstance *parent, uint32 heap_size,
-                     char *error_buf, uint32 error_buf_size)
+                     uint32 max_memory_pages, char *error_buf,
+                     uint32 error_buf_size)
 {
     WASMImport *import;
     uint32 mem_index = 0, i,
@@ -374,7 +398,9 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
     for (i = 0; i < module->import_memory_count; i++, import++, memory++) {
         uint32 num_bytes_per_page = import->u.memory.num_bytes_per_page;
         uint32 init_page_count = import->u.memory.init_page_count;
-        uint32 max_page_count = import->u.memory.max_page_count;
+        uint32 max_page_count = wasm_runtime_get_max_mem(
+            max_memory_pages, import->u.memory.init_page_count,
+            import->u.memory.max_page_count);
         uint32 flags = import->u.memory.flags;
         uint32 actual_heap_size = heap_size;
 
@@ -412,12 +438,15 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
 
     /* instantiate memories from memory section */
     for (i = 0; i < module->memory_count; i++, memory++) {
+        uint32 max_page_count = wasm_runtime_get_max_mem(
+            max_memory_pages, module->memories[i].init_page_count,
+            module->memories[i].max_page_count);
         if (!(memories[mem_index] = memory_instantiate(
                   module_inst, parent, memory, mem_index,
                   module->memories[i].num_bytes_per_page,
-                  module->memories[i].init_page_count,
-                  module->memories[i].max_page_count, heap_size,
-                  module->memories[i].flags, error_buf, error_buf_size))) {
+                  module->memories[i].init_page_count, max_page_count,
+                  heap_size, module->memories[i].flags, error_buf,
+                  error_buf_size))) {
             memories_deinstantiate(module_inst, memories, memory_count);
             return NULL;
         }
@@ -650,7 +679,7 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
             if (function->import_module_inst) {
                 function->import_func_inst =
                     wasm_lookup_function(function->import_module_inst,
-                                         import->u.function.field_name, NULL);
+                                         import->u.function.field_name);
             }
         }
 #endif /* WASM_ENABLE_MULTI_MODULE */
@@ -1214,7 +1243,7 @@ lookup_post_instantiate_func(WASMModuleInstance *module_inst,
     WASMFunctionInstance *func;
     WASMFuncType *func_type;
 
-    if (!(func = wasm_lookup_function(module_inst, func_name, NULL)))
+    if (!(func = wasm_lookup_function(module_inst, func_name)))
         /* Not found */
         return NULL;
 
@@ -1371,30 +1400,39 @@ fail:
 static bool
 execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
                         WASMFunctionInstance *malloc_func,
-                        WASMFunctionInstance *retain_func, uint32 size,
-                        uint32 *p_result)
+                        WASMFunctionInstance *retain_func, uint64 size,
+                        uint64 *p_result)
 {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
     WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
 #endif
     WASMExecEnv *exec_env_created = NULL;
     WASMModuleInstanceCommon *module_inst_old = NULL;
-    uint32 argv[2], argc;
+    uint32 argv[3], argc;
     bool ret;
-
-    argv[0] = size;
-    argc = 1;
+#if WASM_ENABLE_MEMORY64 != 0
+    bool is_memory64 = module_inst->memories[0]->is_memory64;
+    if (is_memory64) {
+        argc = 2;
+        PUT_I64_TO_ADDR(&argv[0], size);
+    }
+    else
+#endif
+    {
+        argc = 1;
+        argv[0] = (uint32)size;
+    }
 
     /* if __retain is exported, then this module is compiled by
         assemblyscript, the memory should be managed by as's runtime,
         in this case we need to call the retain function after malloc
         the memory */
     if (retain_func) {
-        /* the malloc functino from assemblyscript is:
+        /* the malloc function from assemblyscript is:
             function __new(size: usize, id: u32)
             id = 0 means this is an ArrayBuffer object */
-        argv[1] = 0;
-        argc = 2;
+        argv[argc] = 0;
+        argc++;
     }
 
     if (exec_env) {
@@ -1446,24 +1484,42 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
     if (exec_env_created)
         wasm_exec_env_destroy(exec_env_created);
 
-    if (ret)
-        *p_result = argv[0];
+    if (ret) {
+#if WASM_ENABLE_MEMORY64 != 0
+        if (is_memory64)
+            *p_result = GET_I64_FROM_ADDR(&argv[0]);
+        else
+#endif
+        {
+            *p_result = argv[0];
+        }
+    }
     return ret;
 }
 
 static bool
 execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
-                      WASMFunctionInstance *free_func, uint32 offset)
+                      WASMFunctionInstance *free_func, uint64 offset)
 {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
     WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
 #endif
     WASMExecEnv *exec_env_created = NULL;
     WASMModuleInstanceCommon *module_inst_old = NULL;
-    uint32 argv[2];
+    uint32 argv[2], argc;
     bool ret;
 
-    argv[0] = offset;
+#if WASM_ENABLE_MEMORY64 != 0
+    if (module_inst->memories[0]->is_memory64) {
+        PUT_I64_TO_ADDR(&argv[0], offset);
+        argc = 2;
+    }
+    else
+#endif
+    {
+        argv[0] = (uint32)offset;
+        argc = 1;
+    }
 
     if (exec_env) {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
@@ -1502,7 +1558,7 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
         }
     }
 
-    ret = wasm_call_function(exec_env, free_func, 1, argv);
+    ret = wasm_call_function(exec_env, free_func, argc, argv);
 
     if (module_inst_old)
         /* Restore the existing exec_env's module inst */
@@ -1934,13 +1990,15 @@ wasm_set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode)
 WASMModuleInstance *
 wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
                  WASMExecEnv *exec_env_main, uint32 stack_size,
-                 uint32 heap_size, char *error_buf, uint32 error_buf_size)
+                 uint32 heap_size, uint32 max_memory_pages, char *error_buf,
+                 uint32 error_buf_size)
 {
     WASMModuleInstance *module_inst;
     WASMGlobalInstance *globals = NULL, *global;
     WASMTableInstance *first_table;
     uint32 global_count, i;
-    uint32 base_offset, length, extra_info_offset;
+    uint32 length, extra_info_offset;
+    mem_offset_t base_offset;
     uint32 module_inst_struct_size =
         offsetof(WASMModuleInstance, global_table_data.bytes);
     uint64 module_inst_mem_inst_size;
@@ -2022,7 +2080,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
         &module_inst->e->sub_module_inst_list_head;
     ret = wasm_runtime_sub_module_instantiate(
         (WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst,
-        stack_size, heap_size, error_buf, error_buf_size);
+        stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
     if (!ret) {
         LOG_DEBUG("build a sub module list failed");
         goto fail;
@@ -2131,9 +2189,9 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
 
     /* Instantiate memories/tables/functions/tags */
     if ((module_inst->memory_count > 0
-         && !(module_inst->memories =
-                  memories_instantiate(module, module_inst, parent, heap_size,
-                                       error_buf, error_buf_size)))
+         && !(module_inst->memories = memories_instantiate(
+                  module, module_inst, parent, heap_size, max_memory_pages,
+                  error_buf, error_buf_size)))
         || (module_inst->table_count > 0
             && !(module_inst->tables =
                      tables_instantiate(module, module_inst, first_table,
@@ -2298,10 +2356,12 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
             (uint64)memory->num_bytes_per_page * memory->cur_page_count;
         bh_assert(memory_data || memory_size == 0);
 
-        bh_assert(data_seg->base_offset.init_expr_type
-                      == INIT_EXPR_TYPE_I32_CONST
-                  || data_seg->base_offset.init_expr_type
-                         == INIT_EXPR_TYPE_GET_GLOBAL);
+        bh_assert(
+            data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
+            || (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
+                && !memory->is_memory64)
+            || (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I64_CONST
+                && memory->is_memory64));
 
         if (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
             if (!check_global_init_expr(module,
@@ -2312,23 +2372,48 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
 
             if (!globals
                 || globals[data_seg->base_offset.u.global_index].type
-                       != VALUE_TYPE_I32) {
+                       != (memory->is_memory64 ? VALUE_TYPE_I64
+                                               : VALUE_TYPE_I32)) {
                 set_error_buf(error_buf, error_buf_size,
                               "data segment does not fit");
                 goto fail;
             }
 
-            base_offset =
-                globals[data_seg->base_offset.u.global_index].initial_value.i32;
+#if WASM_ENABLE_MEMORY64 != 0
+            if (memory->is_memory64) {
+                base_offset =
+                    (uint64)globals[data_seg->base_offset.u.global_index]
+                        .initial_value.i64;
+            }
+            else
+#endif
+            {
+                base_offset =
+                    (uint32)globals[data_seg->base_offset.u.global_index]
+                        .initial_value.i32;
+            }
         }
         else {
-            base_offset = (uint32)data_seg->base_offset.u.i32;
+#if WASM_ENABLE_MEMORY64 != 0
+            if (memory->is_memory64) {
+                base_offset = (uint64)data_seg->base_offset.u.i64;
+            }
+            else
+#endif
+            {
+                base_offset = (uint32)data_seg->base_offset.u.i32;
+            }
         }
 
         /* check offset */
         if (base_offset > memory_size) {
-            LOG_DEBUG("base_offset(%d) > memory_size(%d)", base_offset,
+#if WASM_ENABLE_MEMORY64 != 0
+            LOG_DEBUG("base_offset(%" PRIu64 ") > memory_size(%" PRIu64 ")",
+                      base_offset, memory_size);
+#else
+            LOG_DEBUG("base_offset(%u) > memory_size(%" PRIu64 ")", base_offset,
                       memory_size);
+#endif
 #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
             set_error_buf(error_buf, error_buf_size,
                           "out of bounds memory access");
@@ -2342,8 +2427,14 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
         /* check offset + length(could be zero) */
         length = data_seg->data_length;
         if ((uint64)base_offset + length > memory_size) {
-            LOG_DEBUG("base_offset(%d) + length(%d) > memory_size(%d)",
+#if WASM_ENABLE_MEMORY64 != 0
+            LOG_DEBUG("base_offset(%" PRIu64
+                      ") + length(%d) > memory_size(%" PRIu64 ")",
+                      base_offset, length, memory_size);
+#else
+            LOG_DEBUG("base_offset(%u) + length(%d) > memory_size(%" PRIu64 ")",
                       base_offset, length, memory_size);
+#endif
 #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
             set_error_buf(error_buf, error_buf_size,
                           "out of bounds memory access");
@@ -2960,8 +3051,8 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
     }
 #endif
 
-    if (module_inst->e->common.c_api_func_imports)
-        wasm_runtime_free(module_inst->e->common.c_api_func_imports);
+    if (module_inst->c_api_func_imports)
+        wasm_runtime_free(module_inst->c_api_func_imports);
 
     if (!is_sub_inst) {
 #if WASM_ENABLE_WASI_NN != 0
@@ -2981,14 +3072,12 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
 }
 
 WASMFunctionInstance *
-wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name,
-                     const char *signature)
+wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name)
 {
     uint32 i;
     for (i = 0; i < module_inst->export_func_count; i++)
         if (!strcmp(module_inst->export_functions[i].name, name))
             return module_inst->export_functions[i].function;
-    (void)signature;
     return NULL;
 }
 
@@ -3050,8 +3139,6 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
 {
     WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
-    uint32 page_size = os_getpagesize();
-    uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
     WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
     uint8 *prev_top = exec_env->wasm_stack.top;
 #ifdef BH_PLATFORM_WINDOWS
@@ -3064,10 +3151,7 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
     /* Check native stack overflow firstly to ensure we have enough
        native stack to run the following codes before actually calling
        the aot function in invokeNative function. */
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&exec_env_tls);
-    if ((uint8 *)&exec_env_tls < exec_env->native_stack_boundary
-                                     + page_size * (guard_page_count + 1)) {
-        wasm_set_exception(module_inst, "native stack overflow");
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         return;
     }
 
@@ -3162,8 +3246,8 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
        hw bound check is enabled */
 #endif
 
-    /* Set exec env so it can be later retrieved from instance */
-    module_inst->e->common.cur_exec_env = exec_env;
+    /* Set exec env, so it can be later retrieved from instance */
+    module_inst->cur_exec_env = exec_env;
 
     interp_call_wasm(module_inst, exec_env, function, argc, argv);
     return !wasm_copy_exception(module_inst, NULL);
@@ -3267,14 +3351,17 @@ wasm_get_wasm_func_exec_time(const WASMModuleInstance *inst,
 }
 #endif /*WASM_ENABLE_PERF_PROFILING != 0*/
 
-uint32
+uint64
 wasm_module_malloc_internal(WASMModuleInstance *module_inst,
-                            WASMExecEnv *exec_env, uint32 size,
+                            WASMExecEnv *exec_env, uint64 size,
                             void **p_native_addr)
 {
     WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
     uint8 *addr = NULL;
-    uint32 offset = 0;
+    uint64 offset = 0;
+
+    /* TODO: Memory64 size check based on memory idx type */
+    bh_assert(size <= UINT32_MAX);
 
     if (!memory) {
         wasm_set_exception(module_inst, "uninitialized memory");
@@ -3282,7 +3369,7 @@ wasm_module_malloc_internal(WASMModuleInstance *module_inst,
     }
 
     if (memory->heap_handle) {
-        addr = mem_allocator_malloc(memory->heap_handle, size);
+        addr = mem_allocator_malloc(memory->heap_handle, (uint32)size);
     }
     else if (module_inst->e->malloc_function && module_inst->e->free_function) {
         if (!execute_malloc_function(
@@ -3303,24 +3390,29 @@ wasm_module_malloc_internal(WASMModuleInstance *module_inst,
             wasm_set_exception(module_inst, "app heap corrupted");
         }
         else {
-            LOG_WARNING("warning: allocate %u bytes memory failed", size);
+            LOG_WARNING("warning: allocate %" PRIu64 " bytes memory failed",
+                        size);
         }
         return 0;
     }
     if (p_native_addr)
         *p_native_addr = addr;
 
-    return (uint32)(addr - memory->memory_data);
+    return (uint64)(addr - memory->memory_data);
 }
 
-uint32
+uint64
 wasm_module_realloc_internal(WASMModuleInstance *module_inst,
-                             WASMExecEnv *exec_env, uint32 ptr, uint32 size,
+                             WASMExecEnv *exec_env, uint64 ptr, uint64 size,
                              void **p_native_addr)
 {
     WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
     uint8 *addr = NULL;
 
+    /* TODO: Memory64 ptr and size check based on memory idx type */
+    bh_assert(ptr <= UINT32_MAX);
+    bh_assert(size <= UINT32_MAX);
+
     if (!memory) {
         wasm_set_exception(module_inst, "uninitialized memory");
         return 0;
@@ -3328,7 +3420,9 @@ wasm_module_realloc_internal(WASMModuleInstance *module_inst,
 
     if (memory->heap_handle) {
         addr = mem_allocator_realloc(
-            memory->heap_handle, ptr ? memory->memory_data + ptr : NULL, size);
+            memory->heap_handle,
+            (uint32)ptr ? memory->memory_data + (uint32)ptr : NULL,
+            (uint32)size);
     }
 
     /* Only support realloc in WAMR's app heap */
@@ -3347,21 +3441,24 @@ wasm_module_realloc_internal(WASMModuleInstance *module_inst,
     if (p_native_addr)
         *p_native_addr = addr;
 
-    return (uint32)(addr - memory->memory_data);
+    return (uint64)(addr - memory->memory_data);
 }
 
 void
 wasm_module_free_internal(WASMModuleInstance *module_inst,
-                          WASMExecEnv *exec_env, uint32 ptr)
+                          WASMExecEnv *exec_env, uint64 ptr)
 {
     WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
 
+    /* TODO: Memory64 ptr and size check based on memory idx type */
+    bh_assert(ptr <= UINT32_MAX);
+
     if (!memory) {
         return;
     }
 
     if (ptr) {
-        uint8 *addr = memory->memory_data + ptr;
+        uint8 *addr = memory->memory_data + (uint32)ptr;
         uint8 *memory_data_end;
 
         /* memory->memory_data_end may be changed in memory grow */
@@ -3382,15 +3479,15 @@ wasm_module_free_internal(WASMModuleInstance *module_inst,
     }
 }
 
-uint32
-wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
+uint64
+wasm_module_malloc(WASMModuleInstance *module_inst, uint64 size,
                    void **p_native_addr)
 {
     return wasm_module_malloc_internal(module_inst, NULL, size, p_native_addr);
 }
 
-uint32
-wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size,
+uint64
+wasm_module_realloc(WASMModuleInstance *module_inst, uint64 ptr, uint64 size,
                     void **p_native_addr)
 {
     return wasm_module_realloc_internal(module_inst, NULL, ptr, size,
@@ -3398,22 +3495,27 @@ wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size,
 }
 
 void
-wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr)
+wasm_module_free(WASMModuleInstance *module_inst, uint64 ptr)
 {
     wasm_module_free_internal(module_inst, NULL, ptr);
 }
 
-uint32
+uint64
 wasm_module_dup_data(WASMModuleInstance *module_inst, const char *src,
-                     uint32 size)
+                     uint64 size)
 {
     char *buffer;
-    uint32 buffer_offset =
-        wasm_module_malloc(module_inst, size, (void **)&buffer);
+    uint64 buffer_offset;
+
+    /* TODO: Memory64 size check based on memory idx type */
+    bh_assert(size <= UINT32_MAX);
+
+    buffer_offset = wasm_module_malloc(module_inst, size, (void **)&buffer);
+
     if (buffer_offset != 0) {
         buffer = wasm_runtime_addr_app_to_native(
             (WASMModuleInstanceCommon *)module_inst, buffer_offset);
-        bh_memcpy_s(buffer, size, src, size);
+        bh_memcpy_s(buffer, (uint32)size, src, (uint32)size);
     }
     return buffer_offset;
 }
@@ -3488,7 +3590,7 @@ call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 tbl_elem_idx,
     }
 
 #if WASM_ENABLE_GC == 0
-    func_idx = tbl_elem_val;
+    func_idx = (uint32)tbl_elem_val;
 #else
     func_idx =
         wasm_func_obj_get_func_idx_bound((WASMFuncObjectRef)tbl_elem_val);
@@ -3536,7 +3638,7 @@ wasm_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
 
 #if WASM_ENABLE_THREAD_MGR != 0
 bool
-wasm_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
+wasm_set_aux_stack(WASMExecEnv *exec_env, uint64 start_offset, uint32 size)
 {
     WASMModuleInstance *module_inst =
         (WASMModuleInstance *)exec_env->module_inst;
@@ -3544,8 +3646,8 @@ wasm_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
 
 #if WASM_ENABLE_HEAP_AUX_STACK_ALLOCATION == 0
     /* Check the aux stack space */
-    uint32 data_end = module_inst->module->aux_data_end;
-    uint32 stack_bottom = module_inst->module->aux_stack_bottom;
+    uint64 data_end = module_inst->module->aux_data_end;
+    uint64 stack_bottom = module_inst->module->aux_stack_bottom;
     bool is_stack_before_data = stack_bottom < data_end ? true : false;
     if ((is_stack_before_data && (size > start_offset))
         || ((!is_stack_before_data) && (start_offset - data_end < size)))
@@ -3558,11 +3660,11 @@ wasm_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
         uint8 *global_addr =
             module_inst->global_data
             + module_inst->e->globals[stack_top_idx].data_offset;
-        *(int32 *)global_addr = start_offset;
+        *(int32 *)global_addr = (uint32)start_offset;
         /* The aux stack boundary is a constant value,
             set the value to exec_env */
-        exec_env->aux_stack_boundary.boundary = start_offset - size;
-        exec_env->aux_stack_bottom.bottom = start_offset;
+        exec_env->aux_stack_boundary = (uintptr_t)start_offset - size;
+        exec_env->aux_stack_bottom = (uintptr_t)start_offset;
         return true;
     }
 
@@ -3570,14 +3672,14 @@ wasm_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
 }
 
 bool
-wasm_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, uint32 *size)
+wasm_get_aux_stack(WASMExecEnv *exec_env, uint64 *start_offset, uint32 *size)
 {
     WASMModuleInstance *module_inst =
         (WASMModuleInstance *)exec_env->module_inst;
 
     /* The aux stack information is resolved in loader
         and store in module */
-    uint32 stack_bottom = module_inst->module->aux_stack_bottom;
+    uint64 stack_bottom = module_inst->module->aux_stack_bottom;
     uint32 total_aux_stack_size = module_inst->module->aux_stack_size;
 
     if (stack_bottom != 0 && total_aux_stack_size != 0) {
@@ -3671,7 +3773,8 @@ void
 wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst,
                                      WASMModuleInstMemConsumption *mem_conspn)
 {
-    uint32 i, size;
+    uint32 i;
+    uint64 size;
 
     memset(mem_conspn, 0, sizeof(*mem_conspn));
 
@@ -3951,7 +4054,7 @@ jit_set_exception_with_id(WASMModuleInstance *module_inst, uint32 id)
 
 bool
 jit_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
-                               uint32 app_buf_addr, uint32 app_buf_size,
+                               uint64 app_buf_addr, uint64 app_buf_size,
                                void **p_native_addr)
 {
     bool ret = wasm_check_app_addr_and_convert(
@@ -4025,9 +4128,8 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
 
     import_func = &module->import_functions[func_idx].u.function;
     if (import_func->call_conv_wasm_c_api) {
-        if (module_inst->e->common.c_api_func_imports) {
-            c_api_func_import =
-                module_inst->e->common.c_api_func_imports + func_idx;
+        if (module_inst->c_api_func_imports) {
+            c_api_func_import = module_inst->c_api_func_imports + func_idx;
             func_ptr = c_api_func_import->func_ptr_linked;
         }
         else {
@@ -4097,7 +4199,7 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
     }
 
     if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
-                                        dst, len))
+                                        (uint64)dst, (uint64)len))
         return false;
 
     if ((uint64)offset + (uint64)len > seg_len) {
@@ -4106,10 +4208,11 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
     }
 
     maddr = wasm_runtime_addr_app_to_native(
-        (WASMModuleInstanceCommon *)module_inst, dst);
+        (WASMModuleInstanceCommon *)module_inst, (uint64)dst);
 
     SHARED_MEMORY_LOCK(memory_inst);
-    bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
+    bh_memcpy_s(maddr, (uint32)(memory_inst->memory_data_size - dst),
+                data + offset, len);
     SHARED_MEMORY_UNLOCK(memory_inst);
     return true;
 }
@@ -4272,11 +4375,21 @@ llvm_jit_table_grow(WASMModuleInstance *module_inst, uint32 tbl_idx,
     }
 
     if (tbl_inst->cur_size > UINT32_MAX - inc_size) { /* integer overflow */
+#if WASM_ENABLE_SPEC_TEST == 0
+        LOG_WARNING("table grow (%" PRIu32 "-> %" PRIu32
+                    ") failed because of integer overflow",
+                    tbl_inst->cur_size, inc_size);
+#endif
         return (uint32)-1;
     }
 
     total_size = tbl_inst->cur_size + inc_size;
     if (total_size > tbl_inst->max_size) {
+#if WASM_ENABLE_SPEC_TEST == 0
+        LOG_WARNING("table grow (%" PRIu32 "-> %" PRIu32
+                    ") failed because of over max size",
+                    tbl_inst->cur_size, inc_size);
+#endif
         return (uint32)-1;
     }
 
@@ -4313,6 +4426,22 @@ llvm_jit_obj_is_instance_of(WASMModuleInstance *module_inst,
     return wasm_obj_is_instance_of(gc_obj, type_index, types, type_count);
 }
 
+bool
+llvm_jit_func_type_is_super_of(WASMModuleInstance *module_inst,
+                               uint32 type_idx1, uint32 type_idx2)
+{
+    WASMModule *module = module_inst->module;
+    WASMType **types = module->types;
+
+    if (type_idx1 == type_idx2)
+        return true;
+
+    bh_assert(types[type_idx1]->type_flag == WASM_TYPE_FUNC);
+    bh_assert(types[type_idx2]->type_flag == WASM_TYPE_FUNC);
+    return wasm_func_type_is_super_of((WASMFuncType *)types[type_idx1],
+                                      (WASMFuncType *)types[type_idx2]);
+}
+
 WASMRttTypeRef
 llvm_jit_rtt_type_new(WASMModuleInstance *module_inst, uint32 type_index)
 {
@@ -4377,3 +4506,154 @@ wasm_propagate_wasi_args(WASMModule *module)
     }
 }
 #endif
+
+bool
+wasm_check_utf8_str(const uint8 *str, uint32 len)
+{
+    /* The valid ranges are taken from page 125, below link
+       https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */
+    const uint8 *p = str, *p_end = str + len;
+    uint8 chr;
+
+    while (p < p_end) {
+        chr = *p;
+
+        if (chr == 0) {
+            LOG_WARNING(
+                "LIMITATION: a string which contains '\\00' is unsupported");
+            return false;
+        }
+        else if (chr < 0x80) {
+            p++;
+        }
+        else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
+            if (p[1] < 0x80 || p[1] > 0xBF) {
+                return false;
+            }
+            p += 2;
+        }
+        else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) {
+            if (chr == 0xE0) {
+                if (p[1] < 0xA0 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
+                    return false;
+                }
+            }
+            else if (chr == 0xED) {
+                if (p[1] < 0x80 || p[1] > 0x9F || p[2] < 0x80 || p[2] > 0xBF) {
+                    return false;
+                }
+            }
+            else { /* chr >= 0xE1 && chr <= 0xEF */
+                if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
+                    return false;
+                }
+            }
+            p += 3;
+        }
+        else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) {
+            if (chr == 0xF0) {
+                if (p[1] < 0x90 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
+                    || p[3] < 0x80 || p[3] > 0xBF) {
+                    return false;
+                }
+            }
+            else if (chr <= 0xF3) { /* and also chr >= 0xF1 */
+                if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
+                    || p[3] < 0x80 || p[3] > 0xBF) {
+                    return false;
+                }
+            }
+            else { /* chr == 0xF4 */
+                if (p[1] < 0x80 || p[1] > 0x8F || p[2] < 0x80 || p[2] > 0xBF
+                    || p[3] < 0x80 || p[3] > 0xBF) {
+                    return false;
+                }
+            }
+            p += 4;
+        }
+        else {
+            return false;
+        }
+    }
+    return (p == p_end);
+}
+
+char *
+wasm_const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
+                           bool is_load_from_file_buf, char *error_buf,
+                           uint32 error_buf_size)
+{
+    StringNode *node, *node_next;
+
+    if (!wasm_check_utf8_str(str, len)) {
+        set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding");
+        return NULL;
+    }
+
+    if (len == 0) {
+        return "";
+    }
+    else if (is_load_from_file_buf) {
+        /* As the file buffer can be referred to after loading, we use
+           the previous byte of leb encoded size to adjust the string:
+           move string 1 byte backward and then append '\0' */
+        char *c_str = (char *)str - 1;
+        bh_memmove_s(c_str, len + 1, c_str + 1, len);
+        c_str[len] = '\0';
+        return c_str;
+    }
+
+    /* Search const str list */
+    node = module->const_str_list;
+    while (node) {
+        node_next = node->next;
+        if (strlen(node->str) == len && !memcmp(node->str, str, len))
+            break;
+        node = node_next;
+    }
+
+    if (node) {
+        return node->str;
+    }
+
+    if (!(node = runtime_malloc(sizeof(StringNode) + len + 1, error_buf,
+                                error_buf_size))) {
+        return NULL;
+    }
+
+    node->str = ((char *)node) + sizeof(StringNode);
+    bh_memcpy_s(node->str, len + 1, str, len);
+    node->str[len] = '\0';
+
+    if (!module->const_str_list) {
+        /* set as head */
+        module->const_str_list = node;
+        node->next = NULL;
+    }
+    else {
+        /* insert it */
+        node->next = module->const_str_list;
+        module->const_str_list = node;
+    }
+
+    return node->str;
+}
+
+bool
+wasm_set_module_name(WASMModule *module, const char *name, char *error_buf,
+                     uint32_t error_buf_size)
+{
+    if (!name)
+        return false;
+
+    module->name =
+        wasm_const_str_list_insert((const uint8 *)name, (uint32)strlen(name),
+                                   module, false, error_buf, error_buf_size);
+    return module->name != NULL;
+}
+
+const char *
+wasm_get_module_name(WASMModule *module)
+{
+    return module->name;
+}

+ 57 - 30
core/iwasm/interpreter/wasm_runtime.h

@@ -103,13 +103,17 @@ struct WASMMemoryInstance {
     /* Whether the memory is shared */
     uint8 is_shared_memory;
 
-    /* One byte padding */
-    uint8 __padding__;
+    /* Whether the memory has 64-bit memory addresses */
+    uint8 is_memory64;
 
     /* Reference count of the memory instance:
          0: non-shared memory, > 0: shared memory */
     bh_atomic_16_t ref_count;
 
+    /* Four-byte paddings to ensure the layout of WASMMemoryInstance is the same
+     * in both 64-bit and 32-bit */
+    uint8 __paddings[4];
+
     /* Number bytes per page */
     uint32 num_bytes_per_page;
     /* Current page count */
@@ -117,7 +121,7 @@ struct WASMMemoryInstance {
     /* Maximum page count */
     uint32 max_page_count;
     /* Memory data size */
-    uint32 memory_data_size;
+    uint64 memory_data_size;
     /**
      * Memory data begin address, Note:
      *   the app-heap might be inserted in to the linear memory,
@@ -134,6 +138,8 @@ struct WASMMemoryInstance {
     DefPointer(uint8 *, heap_data_end);
     /* The heap created */
     DefPointer(void *, heap_handle);
+    /* TODO: use it to replace the g_shared_memory_lock */
+    DefPointer(korp_mutex *, memory_lock);
 
 #if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
     || WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_AOT != 0
@@ -175,7 +181,8 @@ struct WASMGlobalInstance {
     uint8 type;
     /* mutable or constant */
     bool is_mutable;
-    /* data offset to base_addr of WASMMemoryInstance */
+    /* data offset to the address of initial_value, started from the end of
+     * WASMMemoryInstance(start of WASMGlobalInstance)*/
     uint32 data_offset;
     /* initial value */
     WASMValue initial_value;
@@ -292,10 +299,9 @@ typedef struct CApiFuncImport {
 
 /* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */
 typedef struct WASMModuleInstanceExtraCommon {
-    CApiFuncImport *c_api_func_imports;
+#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
     void *contexts[WASM_MAX_INSTANCE_CONTEXTS];
-    /* pointer to the exec env currently used */
-    WASMExecEnv *cur_exec_env;
+#endif
 #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
     /* Disable bounds checks or not */
     bool disable_bounds_checks;
@@ -401,8 +407,6 @@ struct WASMModuleInstance {
        it denotes `AOTModule *` */
     DefPointer(WASMModule *, module);
 
-    DefPointer(void *, used_to_be_wasi_ctx); /* unused */
-
     DefPointer(WASMExecEnv *, exec_env_singleton);
     /* Array of function pointers to import functions,
        not available in AOTModuleInstance */
@@ -421,13 +425,16 @@ struct WASMModuleInstance {
     /* Function performance profiling info list, only available
        in AOTModuleInstance */
     DefPointer(struct AOTFuncPerfProfInfo *, func_perf_profilings);
+    DefPointer(CApiFuncImport *, c_api_func_imports);
+    /* Pointer to the exec env currently used */
+    DefPointer(WASMExecEnv *, cur_exec_env);
     /* WASM/AOT module extra info, for AOTModuleInstance,
        it denotes `AOTModuleInstanceExtra *` */
     DefPointer(WASMModuleInstanceExtra *, e);
 
     /* Default WASM operand stack size */
     uint32 default_wasm_stack_size;
-    uint32 reserved[3];
+    uint32 reserved[7];
 
     /*
      * +------------------------------+ <-- memories
@@ -501,7 +508,7 @@ wasm_load(uint8 *buf, uint32 size,
 #if WASM_ENABLE_MULTI_MODULE != 0
           bool main_module,
 #endif
-          char *error_buf, uint32 error_buf_size);
+          const LoadArgs *args, char *error_buf, uint32 error_buf_size);
 
 WASMModule *
 wasm_load_from_sections(WASMSection *section_list, char *error_buf,
@@ -513,7 +520,8 @@ wasm_unload(WASMModule *module);
 WASMModuleInstance *
 wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
                  WASMExecEnv *exec_env_main, uint32 stack_size,
-                 uint32 heap_size, char *error_buf, uint32 error_buf_size);
+                 uint32 heap_size, uint32 max_memory_pages, char *error_buf,
+                 uint32 error_buf_size);
 
 void
 wasm_dump_perf_profiling(const WASMModuleInstance *module_inst);
@@ -533,8 +541,7 @@ wasm_set_running_mode(WASMModuleInstance *module_inst,
                       RunningMode running_mode);
 
 WASMFunctionInstance *
-wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name,
-                     const char *signature);
+wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name);
 
 #if WASM_ENABLE_MULTI_MODULE != 0
 WASMGlobalInstance *
@@ -576,34 +583,34 @@ wasm_get_exception(WASMModuleInstance *module);
 bool
 wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf);
 
-uint32
+uint64
 wasm_module_malloc_internal(WASMModuleInstance *module_inst,
-                            WASMExecEnv *exec_env, uint32 size,
+                            WASMExecEnv *exec_env, uint64 size,
                             void **p_native_addr);
 
-uint32
+uint64
 wasm_module_realloc_internal(WASMModuleInstance *module_inst,
-                             WASMExecEnv *exec_env, uint32 ptr, uint32 size,
+                             WASMExecEnv *exec_env, uint64 ptr, uint64 size,
                              void **p_native_addr);
 
 void
 wasm_module_free_internal(WASMModuleInstance *module_inst,
-                          WASMExecEnv *exec_env, uint32 ptr);
+                          WASMExecEnv *exec_env, uint64 ptr);
 
-uint32
-wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
+uint64
+wasm_module_malloc(WASMModuleInstance *module_inst, uint64 size,
                    void **p_native_addr);
 
-uint32
-wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size,
+uint64
+wasm_module_realloc(WASMModuleInstance *module_inst, uint64 ptr, uint64 size,
                     void **p_native_addr);
 
 void
-wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr);
+wasm_module_free(WASMModuleInstance *module_inst, uint64 ptr);
 
-uint32
+uint64
 wasm_module_dup_data(WASMModuleInstance *module_inst, const char *src,
-                     uint32 size);
+                     uint64 size);
 
 /**
  * Check whether the app address and the buf is inside the linear memory,
@@ -611,7 +618,7 @@ wasm_module_dup_data(WASMModuleInstance *module_inst, const char *src,
  */
 bool
 wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
-                                uint32 app_buf_addr, uint32 app_buf_size,
+                                uint64 app_buf_addr, uint64 app_buf_size,
                                 void **p_native_addr);
 
 WASMMemoryInstance *
@@ -626,10 +633,10 @@ wasm_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
 
 #if WASM_ENABLE_THREAD_MGR != 0
 bool
-wasm_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size);
+wasm_set_aux_stack(WASMExecEnv *exec_env, uint64 start_offset, uint32 size);
 
 bool
-wasm_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, uint32 *size);
+wasm_get_aux_stack(WASMExecEnv *exec_env, uint64 *start_offset, uint32 *size);
 #endif
 
 void
@@ -726,7 +733,7 @@ jit_set_exception_with_id(WASMModuleInstance *module_inst, uint32 id);
  */
 bool
 jit_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
-                               uint32 app_buf_addr, uint32 app_buf_size,
+                               uint64 app_buf_addr, uint64 app_buf_size,
                                void **p_native_addr);
 #endif /* end of WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
           || WASM_ENABLE_WAMR_COMPILER != 0 */
@@ -804,6 +811,11 @@ bool
 llvm_jit_obj_is_instance_of(WASMModuleInstance *module_inst,
                             WASMObjectRef gc_obj, uint32 type_index);
 
+/* Whether func type1 is one of super types of func type2 */
+bool
+llvm_jit_func_type_is_super_of(WASMModuleInstance *module_inst,
+                               uint32 type_idx1, uint32 type_idx2);
+
 WASMRttTypeRef
 llvm_jit_rtt_type_new(WASMModuleInstance *module_inst, uint32 type_index);
 
@@ -829,6 +841,21 @@ exception_unlock(WASMModuleInstance *module_inst);
 #define exception_unlock(module_inst) (void)(module_inst)
 #endif
 
+bool
+wasm_check_utf8_str(const uint8 *str, uint32 len);
+
+char *
+wasm_const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
+                           bool is_load_from_file_buf, char *error_buf,
+                           uint32 error_buf_size);
+
+bool
+wasm_set_module_name(WASMModule *module, const char *name, char *error_buf,
+                     uint32_t error_buf_size);
+
+const char *
+wasm_get_module_name(WASMModule *module);
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 2
core/iwasm/libraries/debug-engine/debug_engine.c

@@ -408,7 +408,7 @@ wasm_debug_instance_create(WASMCluster *cluster, int32 port)
      * expressions */
     instance->exec_mem_info.size = DEBUG_EXECUTION_MEMORY_SIZE;
     instance->exec_mem_info.start_offset = wasm_runtime_module_malloc(
-        module_inst, instance->exec_mem_info.size, NULL);
+        module_inst, (uint64)instance->exec_mem_info.size, NULL);
     if (instance->exec_mem_info.start_offset == 0) {
         LOG_WARNING(
             "WASM Debug Engine warning: failed to allocate linear memory for "
@@ -1392,7 +1392,7 @@ wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size,
         return 0;
     }
 
-    if ((uint64)instance->exec_mem_info.current_pos
+    if (instance->exec_mem_info.current_pos
             - instance->exec_mem_info.start_offset + size
         <= (uint64)instance->exec_mem_info.size) {
         offset = instance->exec_mem_info.current_pos;

+ 2 - 2
core/iwasm/libraries/debug-engine/debug_engine.h

@@ -53,9 +53,9 @@ typedef enum debug_state_t {
 } debug_state_t;
 
 typedef struct WASMDebugExecutionMemory {
-    uint32 start_offset;
+    uint64 start_offset;
+    uint64 current_pos;
     uint32 size;
-    uint32 current_pos;
 } WASMDebugExecutionMemory;
 
 struct WASMDebugInstance {

+ 3 - 1
core/iwasm/libraries/debug-engine/handler.c

@@ -309,9 +309,11 @@ handle_general_query(WASMGDBServer *server, char *payload)
     }
 
     if (!strcmp(name, "WasmData")) {
+        write_packet(server, "");
     }
 
     if (!strcmp(name, "WasmMem")) {
+        write_packet(server, "");
     }
 
     if (!strcmp(name, "Symbol")) {
@@ -447,7 +449,7 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
                             "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
                             pc_string, "trace");
         }
-        else if (status > 0) {
+        else { /* status > 0 (== 0 is checked at the function beginning) */
             len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
                             "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
                             pc_string, "signal");

+ 8 - 6
core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c

@@ -558,7 +558,8 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
     ThreadRoutineArgs *routine_args = NULL;
     uint32 thread_handle;
     uint32 stack_size = 8192;
-    uint32 aux_stack_start = 0, aux_stack_size;
+    uint32 aux_stack_size;
+    uint64 aux_stack_start = 0;
     int32 ret = -1;
 
     bh_assert(module);
@@ -579,7 +580,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
 #endif
 
     if (!(new_module_inst = wasm_runtime_instantiate_internal(
-              module, module_inst, exec_env, stack_size, 0, NULL, 0)))
+              module, module_inst, exec_env, stack_size, 0, 0, NULL, 0)))
         return -1;
 
     /* Set custom_data to new module instance */
@@ -669,14 +670,14 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
 
     /* validate addr, we can use current thread's
        module instance here as the memory is shared */
-    if (!validate_app_addr(retval_offset, sizeof(int32))) {
+    if (!validate_app_addr((uint64)retval_offset, (uint64)sizeof(int32))) {
         /* Join failed, but we don't want to terminate all threads,
            do not spread exception here */
         wasm_runtime_set_exception(module_inst, NULL);
         return -1;
     }
 
-    retval = (void **)addr_app_to_native(retval_offset);
+    retval = (void **)addr_app_to_native((uint64)retval_offset);
 
     node = get_thread_info(exec_env, thread);
     if (!node) {
@@ -1123,7 +1124,8 @@ posix_memalign_wrapper(wasm_exec_env_t exec_env, void **memptr, int32 align,
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     void *p = NULL;
 
-    *((int32 *)memptr) = module_malloc(size, (void **)&p);
+    /* TODO: for memory 64, module_malloc may return uint64 offset */
+    *((uint32 *)memptr) = (uint32)module_malloc(size, (void **)&p);
     if (!p)
         return -1;
 
@@ -1264,7 +1266,7 @@ sem_getvalue_wrapper(wasm_exec_env_t exec_env, uint32 sem, int32 *sval)
     (void)exec_env;
     SemCallbackArgs args = { sem, NULL };
 
-    if (validate_native_addr(sval, sizeof(int32))) {
+    if (validate_native_addr(sval, (uint64)sizeof(int32))) {
 
         bh_hash_map_traverse(sem_info_map, sem_fetch_cb, &args);
 

+ 1 - 1
core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake

@@ -3,7 +3,7 @@
 
 cmake_minimum_required (VERSION 2.8...3.16)
 
-project(socket_wasi_ext)
+project(socket_wasi_ext LANGUAGES C)
 
 add_library(${PROJECT_NAME} STATIC ${CMAKE_CURRENT_LIST_DIR}/src/wasi/wasi_socket_ext.c)
 target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/inc/)

+ 3 - 3
core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c

@@ -87,7 +87,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
     stack_size = ((WASMModuleInstance *)module_inst)->default_wasm_stack_size;
 
     if (!(new_module_inst = wasm_runtime_instantiate_internal(
-              module, module_inst, exec_env, stack_size, 0, NULL, 0)))
+              module, module_inst, exec_env, stack_size, 0, 0, NULL, 0)))
         return -1;
 
     wasm_runtime_set_custom_data_internal(
@@ -98,8 +98,8 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
 
     wasm_native_inherit_contexts(new_module_inst, module_inst);
 
-    start_func = wasm_runtime_lookup_function(new_module_inst,
-                                              THREAD_START_FUNCTION, NULL);
+    start_func =
+        wasm_runtime_lookup_function(new_module_inst, THREAD_START_FUNCTION);
     if (!start_func) {
         LOG_ERROR("Failed to find thread start function %s",
                   THREAD_START_FUNCTION);

+ 34 - 34
core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c

@@ -17,7 +17,7 @@ void
 wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
 
 uint32
-wasm_runtime_module_realloc(wasm_module_inst_t module, uint32 ptr, uint32 size,
+wasm_runtime_module_realloc(wasm_module_inst_t module, uint64 ptr, uint64 size,
                             void **p_native_addr);
 
 /* clang-format off */
@@ -233,7 +233,7 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
                         return false;
                     }
 
-                    s = start = addr_app_to_native(s_offset);
+                    s = start = addr_app_to_native((uint64)s_offset);
 
                     str_len = (uint32)strlen(start);
                     if (str_len >= UINT32_MAX - 64) {
@@ -401,7 +401,7 @@ printf_wrapper(wasm_exec_env_t exec_env, const char *format, _va_list va_args)
     struct str_context ctx = { NULL, 0, 0 };
 
     /* format has been checked by runtime */
-    if (!validate_native_addr(va_args, sizeof(int32)))
+    if (!validate_native_addr(va_args, (uint64)sizeof(int32)))
         return 0;
 
     if (!_vprintf_wa((out_func_t)printf_out, &ctx, format, va_args,
@@ -420,13 +420,13 @@ sprintf_wrapper(wasm_exec_env_t exec_env, char *str, const char *format,
     struct str_context ctx;
 
     /* str and format have been checked by runtime */
-    if (!validate_native_addr(va_args, sizeof(uint32)))
+    if (!validate_native_addr(va_args, (uint64)sizeof(uint32)))
         return 0;
 
     if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)str, NULL,
                                             &native_end_offset)) {
         wasm_runtime_set_exception(module_inst, "out of bounds memory access");
-        return false;
+        return 0;
     }
 
     ctx.str = str;
@@ -452,7 +452,7 @@ snprintf_wrapper(wasm_exec_env_t exec_env, char *str, uint32 size,
     struct str_context ctx;
 
     /* str and format have been checked by runtime */
-    if (!validate_native_addr(va_args, sizeof(uint32)))
+    if (!validate_native_addr(va_args, (uint64)sizeof(uint32)))
         return 0;
 
     ctx.str = str;
@@ -499,7 +499,7 @@ strdup_wrapper(wasm_exec_env_t exec_env, const char *str)
     if (str) {
         len = (uint32)strlen(str) + 1;
 
-        str_ret_offset = module_malloc(len, (void **)&str_ret);
+        str_ret_offset = (uint32)module_malloc((uint64)len, (void **)&str_ret);
         if (str_ret_offset) {
             bh_memcpy_s(str_ret, len, str, len);
         }
@@ -521,7 +521,7 @@ memcmp_wrapper(wasm_exec_env_t exec_env, const void *s1, const void *s2,
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
 
     /* s2 has been checked by runtime */
-    if (!validate_native_addr((void *)s1, size))
+    if (!validate_native_addr((void *)s1, (uint64)size))
         return 0;
 
     return memcmp(s1, s2, size);
@@ -532,13 +532,13 @@ memcpy_wrapper(wasm_exec_env_t exec_env, void *dst, const void *src,
                uint32 size)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
-    uint32 dst_offset = addr_native_to_app(dst);
+    uint32 dst_offset = (uint32)addr_native_to_app(dst);
 
     if (size == 0)
         return dst_offset;
 
     /* src has been checked by runtime */
-    if (!validate_native_addr(dst, size))
+    if (!validate_native_addr(dst, (uint64)size))
         return dst_offset;
 
     bh_memcpy_s(dst, size, src, size);
@@ -549,13 +549,13 @@ static uint32
 memmove_wrapper(wasm_exec_env_t exec_env, void *dst, void *src, uint32 size)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
-    uint32 dst_offset = addr_native_to_app(dst);
+    uint32 dst_offset = (uint32)addr_native_to_app(dst);
 
     if (size == 0)
         return dst_offset;
 
     /* src has been checked by runtime */
-    if (!validate_native_addr(dst, size))
+    if (!validate_native_addr(dst, (uint64)size))
         return dst_offset;
 
     memmove(dst, src, size);
@@ -566,9 +566,9 @@ static uint32
 memset_wrapper(wasm_exec_env_t exec_env, void *s, int32 c, uint32 size)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
-    uint32 s_offset = addr_native_to_app(s);
+    uint32 s_offset = (uint32)addr_native_to_app(s);
 
-    if (!validate_native_addr(s, size))
+    if (!validate_native_addr(s, (uint64)size))
         return s_offset;
 
     memset(s, c, size);
@@ -583,7 +583,7 @@ strchr_wrapper(wasm_exec_env_t exec_env, const char *s, int32 c)
 
     /* s has been checked by runtime */
     ret = strchr(s, c);
-    return ret ? addr_native_to_app(ret) : 0;
+    return ret ? (uint32)addr_native_to_app(ret) : 0;
 }
 
 static int32
@@ -602,7 +602,7 @@ strncmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
 
     /* s2 has been checked by runtime */
-    if (!validate_native_addr((void *)s1, size))
+    if (!validate_native_addr((void *)s1, (uint64)size))
         return 0;
 
     return strncmp(s1, s2, size);
@@ -615,7 +615,7 @@ strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src)
     uint32 len = (uint32)strlen(src) + 1;
 
     /* src has been checked by runtime */
-    if (!validate_native_addr(dst, len))
+    if (!validate_native_addr(dst, (uint64)len))
         return 0;
 
 #ifndef BH_PLATFORM_WINDOWS
@@ -623,7 +623,7 @@ strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src)
 #else
     strncpy_s(dst, len, src, len);
 #endif
-    return addr_native_to_app(dst);
+    return (uint32)addr_native_to_app(dst);
 }
 
 static uint32
@@ -633,7 +633,7 @@ strncpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src,
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
 
     /* src has been checked by runtime */
-    if (!validate_native_addr(dst, size))
+    if (!validate_native_addr(dst, (uint64)size))
         return 0;
 
 #ifndef BH_PLATFORM_WINDOWS
@@ -641,7 +641,7 @@ strncpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src,
 #else
     strncpy_s(dst, size, src, size);
 #endif
-    return addr_native_to_app(dst);
+    return (uint32)addr_native_to_app(dst);
 }
 
 static uint32
@@ -657,7 +657,7 @@ static uint32
 malloc_wrapper(wasm_exec_env_t exec_env, uint32 size)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
-    return module_malloc(size, NULL);
+    return (uint32)module_malloc((uint64)size, NULL);
 }
 
 static uint32
@@ -671,7 +671,7 @@ calloc_wrapper(wasm_exec_env_t exec_env, uint32 nmemb, uint32 size)
     if (total_size >= UINT32_MAX)
         return 0;
 
-    ret_offset = module_malloc((uint32)total_size, (void **)&ret_ptr);
+    ret_offset = (uint32)module_malloc(total_size, (void **)&ret_ptr);
     if (ret_offset) {
         memset(ret_ptr, 0, (uint32)total_size);
     }
@@ -692,7 +692,7 @@ free_wrapper(wasm_exec_env_t exec_env, void *ptr)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
 
-    if (!validate_native_addr(ptr, sizeof(uint32)))
+    if (!validate_native_addr(ptr, (uint64)sizeof(uint32)))
         return;
 
     module_free(addr_native_to_app(ptr));
@@ -723,11 +723,11 @@ strtol_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr,
     int32 num = 0;
 
     /* nptr has been checked by runtime */
-    if (!validate_native_addr(endptr, sizeof(uint32)))
+    if (!validate_native_addr(endptr, (uint64)sizeof(uint32)))
         return 0;
 
     num = (int32)strtol(nptr, endptr, base);
-    *(uint32 *)endptr = addr_native_to_app(*endptr);
+    *(uint32 *)endptr = (uint32)addr_native_to_app(*endptr);
 
     return num;
 }
@@ -740,11 +740,11 @@ strtoul_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr,
     uint32 num = 0;
 
     /* nptr has been checked by runtime */
-    if (!validate_native_addr(endptr, sizeof(uint32)))
+    if (!validate_native_addr(endptr, (uint64)sizeof(uint32)))
         return 0;
 
     num = (uint32)strtoul(nptr, endptr, base);
-    *(uint32 *)endptr = addr_native_to_app(*endptr);
+    *(uint32 *)endptr = (uint32)addr_native_to_app(*endptr);
 
     return num;
 }
@@ -755,11 +755,11 @@ memchr_wrapper(wasm_exec_env_t exec_env, const void *s, int32 c, uint32 n)
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     void *res;
 
-    if (!validate_native_addr((void *)s, n))
+    if (!validate_native_addr((void *)s, (uint64)n))
         return 0;
 
     res = memchr(s, c, n);
-    return addr_native_to_app(res);
+    return (uint32)addr_native_to_app(res);
 }
 
 static int32
@@ -796,7 +796,7 @@ strstr_wrapper(wasm_exec_env_t exec_env, const char *s, const char *find)
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     /* s and find have been checked by runtime */
     char *res = strstr(s, find);
-    return addr_native_to_app(res);
+    return (uint32)addr_native_to_app(res);
 }
 
 static int32
@@ -884,10 +884,10 @@ emscripten_memcpy_big_wrapper(wasm_exec_env_t exec_env, void *dst,
                               const void *src, uint32 size)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
-    uint32 dst_offset = addr_native_to_app(dst);
+    uint32 dst_offset = (uint32)addr_native_to_app(dst);
 
     /* src has been checked by runtime */
-    if (!validate_native_addr(dst, size))
+    if (!validate_native_addr(dst, (uint64)size))
         return dst_offset;
 
     bh_memcpy_s(dst, size, src, size);
@@ -925,7 +925,7 @@ static uint32
 __cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, uint32 thrown_size)
 {
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
-    uint32 exception = module_malloc(thrown_size, NULL);
+    uint32 exception = (uint32)module_malloc((uint64)thrown_size, NULL);
     if (!exception)
         return 0;
 
@@ -968,7 +968,7 @@ clock_gettime_wrapper(wasm_exec_env_t exec_env, uint32 clk_id,
 
     (void)clk_id;
 
-    if (!validate_native_addr(ts_app, sizeof(struct timespec_app)))
+    if (!validate_native_addr(ts_app, (uint64)sizeof(struct timespec_app)))
         return (uint32)-1;
 
     time = os_time_get_boot_us();

Some files were not shown because too many files changed in this diff