mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-07-15 16:58:34 +00:00
Merge branch 'bytecodealliance:main' into zephyr-socket-support
This commit is contained in:
commit
214345aa42
35
.github/dependabot.yml
vendored
Normal file
35
.github/dependabot.yml
vendored
Normal file
|
@ -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"
|
|
@ -1,5 +1,10 @@
|
|||
#!/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
|
||||
|
@ -101,6 +106,26 @@ if [[ $? != 0 ]]; then
|
|||
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
|
124
.github/scripts/codeql_fail_on_error.py
vendored
Executable file
124
.github/scripts/codeql_fail_on_error.py
vendored
Executable file
|
@ -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)
|
9
.github/scripts/fetch_and_compare_version.py
vendored
9
.github/scripts/fetch_and_compare_version.py
vendored
|
@ -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()
|
||||
|
|
8
.github/workflows/build_llvm_libraries.yml
vendored
8
.github/workflows/build_llvm_libraries.yml
vendored
|
@ -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
|
||||
|
|
4
.github/workflows/build_wamr_lldb.yml
vendored
4
.github/workflows/build_wamr_lldb.yml
vendored
|
@ -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
.github/workflows/build_wamr_sdk.yml
vendored
6
.github/workflows/build_wamr_sdk.yml
vendored
|
@ -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
|
||||
|
|
2
.github/workflows/build_wamr_vscode_ext.yml
vendored
2
.github/workflows/build_wamr_vscode_ext.yml
vendored
|
@ -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
|
||||
|
||||
|
|
15
.github/workflows/codeql.yml
vendored
15
.github/workflows/codeql.yml
vendored
|
@ -49,7 +49,7 @@ jobs:
|
|||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
|
@ -64,9 +64,9 @@ jobs:
|
|||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
- run: |
|
||||
./.github/workflows/codeql_buildscript.sh
|
||||
./.github/scripts/codeql_buildscript.sh
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
upload: false
|
||||
|
@ -95,14 +95,14 @@ jobs:
|
|||
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
|
||||
|
||||
- name: Upload CodeQL results to code scanning
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
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@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: codeql-results
|
||||
path: ${{ steps.step1.outputs.sarif-output }}
|
||||
|
@ -110,5 +110,8 @@ jobs:
|
|||
|
||||
- name: Fail if an error is found
|
||||
run: |
|
||||
./.github/workflows/codeql_fail_on_error.py \
|
||||
./.github/scripts/codeql_fail_on_error.py \
|
||||
${{ steps.step1.outputs.sarif-output }}/cpp.sarif
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
|
|
34
.github/workflows/codeql_fail_on_error.py
vendored
34
.github/workflows/codeql_fail_on_error.py
vendored
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
# Return whether SARIF file contains error-level results
|
||||
def codeql_sarif_contain_error(filename):
|
||||
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
|
||||
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':
|
||||
return True
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
if codeql_sarif_contain_error(sys.argv[1]):
|
||||
sys.exit(1)
|
|
@ -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,6 +204,21 @@ 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"
|
||||
# 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
|
||||
|
@ -372,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
|
||||
|
@ -503,6 +520,7 @@ jobs:
|
|||
$THREADS_TEST_OPTIONS,
|
||||
$WASI_TEST_OPTIONS,
|
||||
$GC_TEST_OPTIONS,
|
||||
$MEMORY64_TEST_OPTIONS,
|
||||
]
|
||||
wasi_sdk_release:
|
||||
[
|
||||
|
@ -541,19 +559,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'
|
||||
|
@ -617,13 +646,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 }}
|
||||
|
|
4
.github/workflows/compilation_on_macos.yml
vendored
4
.github/workflows/compilation_on_macos.yml
vendored
|
@ -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: |
|
||||
|
|
18
.github/workflows/create_tag.yml
vendored
18
.github/workflows/create_tag.yml
vendored
|
@ -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}"
|
||||
|
|
26
.github/workflows/nightly_run.yml
vendored
26
.github/workflows/nightly_run.yml
vendored
|
@ -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,6 +189,21 @@ 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"
|
||||
# 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
|
||||
|
@ -271,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
|
||||
|
@ -299,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
|
||||
|
@ -437,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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -41,9 +41,8 @@ WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm)
|
|||
- [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:
|
||||
|
@ -68,6 +67,7 @@ The following platforms are supported, click each link below for how to build iw
|
|||
- [Port WAMR to a new platform](./doc/port_wamr.md)
|
||||
- [VS Code development container](./doc/devcontainer.md)
|
||||
- [Samples](./samples) and [Benchmarks](./tests/benchmarks)
|
||||
- [End-user APIs documentation](https://bytecodealliance.github.io/wamr.dev/apis/)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 ()
|
||||
|
@ -529,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 ()
|
||||
|
|
|
@ -415,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 */
|
||||
|
@ -445,7 +445,29 @@
|
|||
#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
|
||||
*
|
||||
* - stack check wrapper functions generated by the aot compiler
|
||||
* (--stack-bounds-checks=1)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef WASM_STACK_GUARD_SIZE
|
||||
#if WASM_ENABLE_UVWASI != 0
|
||||
/* UVWASI requires larger native stack */
|
||||
|
@ -564,14 +586,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_ */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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@"
|
||||
|
@ -1430,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
|
||||
|
@ -1511,29 +1526,41 @@ fail:
|
|||
}
|
||||
|
||||
static void
|
||||
destroy_types(AOTType **types, uint32 count)
|
||||
destroy_type(AOTType *type)
|
||||
{
|
||||
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 (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 (types[i]->type_flag == WASM_TYPE_STRUCT) {
|
||||
AOTStructType *struct_type = (AOTStructType *)types[i];
|
||||
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(types[i]);
|
||||
wasm_runtime_free(type);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_types(AOTType **types, uint32 count)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (types[i]) {
|
||||
destroy_type(types[i]);
|
||||
}
|
||||
}
|
||||
wasm_runtime_free(types);
|
||||
|
@ -1541,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
|
||||
|
@ -1561,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;
|
||||
|
||||
|
@ -1575,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);
|
||||
|
@ -1605,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;
|
||||
|
@ -1711,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;
|
||||
|
@ -1797,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);
|
||||
|
@ -1826,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;
|
||||
|
@ -1835,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;
|
||||
}
|
||||
|
@ -1852,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;
|
||||
}
|
||||
}
|
||||
|
@ -3590,104 +3643,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,
|
||||
|
@ -3878,7 +3833,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);
|
||||
|
@ -3890,7 +3845,7 @@ create_module(char *error_buf, uint32 error_buf_size)
|
|||
|
||||
module->module_type = Wasm_Module_AoT;
|
||||
|
||||
module->name = "";
|
||||
module->name = name;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
module->import_module_list = &module->import_module_list_head;
|
||||
|
@ -3926,7 +3881,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;
|
||||
|
@ -4172,7 +4127,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
|
||||
|
||||
|
@ -4182,10 +4137,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;
|
||||
|
@ -4379,7 +4334,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
core/iwasm/aot/aot_perf_map.c
Normal file
120
core/iwasm/aot/aot_perf_map.c
Normal file
|
@ -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
core/iwasm/aot/aot_perf_map.h
Normal file
15
core/iwasm/aot/aot_perf_map.h
Normal file
|
@ -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_ */
|
|
@ -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), \
|
||||
|
|
|
@ -880,7 +880,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
global_addr = module_inst->global_data
|
||||
+ module->globals[global_idx].data_offset;
|
||||
*(uint32 *)global_addr = (uint32)aux_heap_base;
|
||||
LOG_VERBOSE("Reset __heap_base global to %u", aux_heap_base);
|
||||
LOG_VERBOSE("Reset __heap_base global to %" PRIu64, aux_heap_base);
|
||||
}
|
||||
else {
|
||||
/* Insert app heap before new page */
|
||||
|
@ -906,17 +906,19 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
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 <= 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");
|
||||
|
@ -1069,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");
|
||||
|
@ -1084,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,
|
||||
|
@ -1718,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);
|
||||
|
||||
|
@ -1725,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(
|
||||
|
@ -2522,7 +2527,8 @@ 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;
|
||||
}
|
||||
|
@ -2805,7 +2811,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);
|
||||
|
@ -3362,39 +3368,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 */
|
||||
|
||||
|
@ -3696,14 +3712,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];
|
||||
}
|
||||
|
@ -4473,6 +4489,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)
|
||||
{
|
||||
|
@ -4720,8 +4752,11 @@ aot_set_module_name(AOTModule *module, const char *name, char *error_buf,
|
|||
if (!name)
|
||||
return false;
|
||||
|
||||
module->name =
|
||||
aot_const_str_set_insert((const uint8 *)name, strlen(name) + 1, module,
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -444,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.
|
||||
|
@ -752,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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,12 +1018,13 @@ 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(
|
||||
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]);
|
||||
}
|
||||
|
@ -963,14 +1068,15 @@ 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(
|
||||
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]);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
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) {
|
||||
|
@ -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;
|
||||
|
@ -218,11 +223,21 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
|
|||
p += strlen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
argc1 = 2;
|
||||
argv1[0] = (uint32)argc;
|
||||
/* TODO: memory64 uint64 when the memory idx is i64 */
|
||||
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);
|
||||
|
@ -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)) {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -3987,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
|
||||
|
||||
|
@ -3998,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
|
||||
|
||||
|
|
|
@ -117,6 +117,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
|
||||
|
|
|
@ -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) {
|
||||
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||
return malloc_func(allocator_user_data, size);
|
||||
#else
|
||||
return malloc_func(size);
|
||||
return malloc_func(
|
||||
#if WASM_MEM_ALLOC_WITH_USAGE != 0
|
||||
Alloc_For_Runtime,
|
||||
#endif
|
||||
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||
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)
|
||||
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||
return realloc_func(allocator_user_data, ptr, size);
|
||||
#else
|
||||
return realloc_func(ptr, size);
|
||||
return realloc_func(
|
||||
#if WASM_MEM_ALLOC_WITH_USAGE != 0
|
||||
Alloc_For_Runtime, false,
|
||||
#endif
|
||||
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||
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) {
|
||||
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||
free_func(allocator_user_data, ptr);
|
||||
#else
|
||||
free_func(ptr);
|
||||
free_func(
|
||||
#if WASM_MEM_ALLOC_WITH_USAGE != 0
|
||||
Alloc_For_Runtime,
|
||||
#endif
|
||||
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||
allocator_user_data,
|
||||
#endif
|
||||
ptr);
|
||||
}
|
||||
else {
|
||||
os_free(ptr);
|
||||
|
@ -286,6 +314,7 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
|
|||
{
|
||||
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,9 +328,13 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#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) {
|
||||
if (size > max_linear_memory_size
|
||||
|| app_offset > max_linear_memory_size - size) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -324,7 +357,7 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
|
|||
uint64 app_str_offset)
|
||||
{
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
uint64 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
|
||||
|
@ -338,10 +371,14 @@ 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)
|
||||
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);
|
||||
|
@ -364,6 +401,7 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
|
|||
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);
|
||||
|
@ -377,8 +415,12 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#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) {
|
||||
if (size > max_linear_memory_size || (uintptr_t)addr > UINTPTR_MAX - size) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -748,12 +790,36 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
|||
goto return_func;
|
||||
}
|
||||
|
||||
bh_assert(total_size_new <= MAX_LINEAR_MEMORY_SIZE);
|
||||
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;
|
||||
|
@ -761,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;
|
||||
|
@ -808,6 +874,7 @@ 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;
|
||||
|
@ -888,15 +955,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;
|
||||
|
||||
|
@ -925,13 +1004,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;
|
||||
|
||||
#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);
|
||||
align_as_and_cast(*memory_data_size, page_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;
|
||||
|
|
|
@ -64,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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
/**
|
||||
* A safety insurance to prevent
|
||||
* circular depencies which leads stack overflow
|
||||
* circular dependencies which leads stack overflow
|
||||
* try to break early
|
||||
*/
|
||||
typedef struct LoadingModule {
|
||||
|
@ -275,11 +275,11 @@ decode_insn(uint8 *insn)
|
|||
buffer, sizeof(buffer),
|
||||
runtime_address);
|
||||
|
||||
#if 0
|
||||
/* Print current instruction */
|
||||
/*
|
||||
os_printf("%012" PRIX64 " ", runtime_address);
|
||||
puts(buffer);
|
||||
*/
|
||||
#endif
|
||||
|
||||
return instruction.length;
|
||||
}
|
||||
|
@ -564,8 +564,20 @@ wasm_runtime_exec_env_check(WASMExecEnv *exec_env)
|
|||
&& exec_env->wasm_stack.top <= exec_env->wasm_stack.top_boundary;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_init()
|
||||
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
||||
/**
|
||||
* lock for wasm_runtime_init/wasm_runtime_full_init and runtime_ref_count
|
||||
* Note: if the platform has mutex initializer, we use a global lock to
|
||||
* lock the operations of runtime init/full_init, otherwise when there are
|
||||
* operations happening simultaneously in multiple threads, developer
|
||||
* must create the lock by himself, and use it to lock the operations
|
||||
*/
|
||||
static korp_mutex runtime_lock = OS_THREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
static int32 runtime_ref_count = 0;
|
||||
|
||||
static bool
|
||||
wasm_runtime_init_internal()
|
||||
{
|
||||
if (!wasm_runtime_memory_init(Alloc_With_System_Allocator, NULL))
|
||||
return false;
|
||||
|
@ -578,8 +590,32 @@ wasm_runtime_init()
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_destroy()
|
||||
bool
|
||||
wasm_runtime_init()
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
||||
os_mutex_lock(&runtime_lock);
|
||||
#endif
|
||||
|
||||
bh_assert(runtime_ref_count >= 0);
|
||||
if (runtime_ref_count == 0) {
|
||||
ret = wasm_runtime_init_internal();
|
||||
}
|
||||
if (ret) {
|
||||
runtime_ref_count++;
|
||||
}
|
||||
|
||||
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
||||
os_mutex_unlock(&runtime_lock);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
wasm_runtime_destroy_internal()
|
||||
{
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
wasm_externref_map_destroy();
|
||||
|
@ -640,6 +676,24 @@ wasm_runtime_destroy()
|
|||
wasm_runtime_memory_destroy();
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_destroy()
|
||||
{
|
||||
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
||||
os_mutex_lock(&runtime_lock);
|
||||
#endif
|
||||
|
||||
bh_assert(runtime_ref_count > 0);
|
||||
runtime_ref_count--;
|
||||
if (runtime_ref_count == 0) {
|
||||
wasm_runtime_destroy_internal();
|
||||
}
|
||||
|
||||
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
||||
os_mutex_unlock(&runtime_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
RunningMode
|
||||
wasm_runtime_get_default_running_mode(void)
|
||||
{
|
||||
|
@ -662,8 +716,8 @@ wasm_runtime_get_gc_heap_size_default(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_runtime_full_init(RuntimeInitArgs *init_args)
|
||||
static bool
|
||||
wasm_runtime_full_init_internal(RuntimeInitArgs *init_args)
|
||||
{
|
||||
if (!wasm_runtime_memory_init(init_args->mem_alloc_type,
|
||||
&init_args->mem_alloc_option))
|
||||
|
@ -725,6 +779,30 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_full_init(RuntimeInitArgs *init_args)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
||||
os_mutex_lock(&runtime_lock);
|
||||
#endif
|
||||
|
||||
bh_assert(runtime_ref_count >= 0);
|
||||
if (runtime_ref_count == 0) {
|
||||
ret = wasm_runtime_full_init_internal(init_args);
|
||||
}
|
||||
if (ret) {
|
||||
runtime_ref_count++;
|
||||
}
|
||||
|
||||
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
||||
os_mutex_unlock(&runtime_lock);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_log_level(log_level_t level)
|
||||
{
|
||||
|
@ -965,7 +1043,7 @@ wasm_runtime_register_module_internal(const char *module_name,
|
|||
/* module hasn't been registered */
|
||||
node = runtime_malloc(sizeof(WASMRegisteredModule), NULL, NULL, 0);
|
||||
if (!node) {
|
||||
LOG_DEBUG("malloc WASMRegisteredModule failed. SZ=%d",
|
||||
LOG_DEBUG("malloc WASMRegisteredModule failed. SZ=%zu",
|
||||
sizeof(WASMRegisteredModule));
|
||||
return false;
|
||||
}
|
||||
|
@ -1255,11 +1333,15 @@ register_module_with_null_name(WASMModuleCommon *module_common, char *error_buf,
|
|||
}
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
wasm_runtime_load_ex(uint8 *buf, uint32 size, const LoadArgs *args,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleCommon *module_common = NULL;
|
||||
|
||||
if (!args) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (get_package_type(buf, size) == Wasm_Module_Bytecode) {
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
module_common =
|
||||
|
@ -1267,13 +1349,13 @@ wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
|||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
true,
|
||||
#endif
|
||||
error_buf, error_buf_size);
|
||||
args, error_buf, error_buf_size);
|
||||
#endif
|
||||
}
|
||||
else if (get_package_type(buf, size) == Wasm_Module_AoT) {
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
module_common = (WASMModuleCommon *)aot_load_from_aot_file(
|
||||
buf, size, error_buf, error_buf_size);
|
||||
buf, size, args, error_buf, error_buf_size);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
@ -1289,10 +1371,21 @@ wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
|||
LOG_DEBUG("WASM module load failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*TODO: use file name as name and register with name? */
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
}
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
LoadArgs args = { 0 };
|
||||
args.name = "";
|
||||
return wasm_runtime_load_ex(buf, size, &args, error_buf, error_buf_size);
|
||||
}
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
|
@ -1702,7 +1795,7 @@ wasm_runtime_dump_mem_consumption(WASMExecEnv *exec_env)
|
|||
wasm_runtime_dump_module_inst_mem_consumption(module_inst_common);
|
||||
wasm_runtime_dump_exec_env_mem_consumption(exec_env);
|
||||
os_printf("\nTotal memory consumption of module, module inst and "
|
||||
"exec env: %u\n",
|
||||
"exec env: %" PRIu64 "\n",
|
||||
total_size);
|
||||
os_printf("Total interpreter stack used: %u\n",
|
||||
exec_env->max_wasm_stack_used);
|
||||
|
@ -3668,7 +3761,7 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|||
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
||||
typedef void (*NativeRawFuncPtr)(WASMExecEnv *, uint64 *);
|
||||
NativeRawFuncPtr invoke_native_raw = (NativeRawFuncPtr)func_ptr;
|
||||
uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size;
|
||||
uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size, arg_i64;
|
||||
uint32 *argv_src = argv, i, argc1, ptr_len;
|
||||
uint32 arg_i32;
|
||||
bool ret = false;
|
||||
|
@ -3692,9 +3785,11 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case VALUE_TYPE_FUNCREF:
|
||||
#endif
|
||||
{
|
||||
/* TODO: memory64 the data type of ptr_len and argc depends on
|
||||
* mem idx type */
|
||||
*(uint32 *)argv_dst = arg_i32 = *argv_src++;
|
||||
/* TODO: memory64 if future there is a way for supporting
|
||||
* wasm64 and wasm32 in libc at the same time, remove the
|
||||
* macro control */
|
||||
#if WASM_ENABLE_MEMORY64 == 0
|
||||
if (signature) {
|
||||
if (signature[i + 1] == '*') {
|
||||
/* param is a pointer */
|
||||
|
@ -3724,9 +3819,49 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|||
module, (uint64)arg_i32);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case VALUE_TYPE_I64:
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
{
|
||||
PUT_I64_TO_ADDR((uint32 *)argv_dst,
|
||||
GET_I64_FROM_ADDR(argv_src));
|
||||
argv_src += 2;
|
||||
arg_i64 = *argv_dst;
|
||||
if (signature) {
|
||||
/* TODO: memory64 pointer with length need a new symbol
|
||||
* to represent type i64, with '~' still represent i32
|
||||
* length */
|
||||
if (signature[i + 1] == '*') {
|
||||
/* param is a pointer */
|
||||
if (signature[i + 2] == '~')
|
||||
/* pointer with length followed */
|
||||
ptr_len = *argv_src;
|
||||
else
|
||||
/* pointer without length followed */
|
||||
ptr_len = 1;
|
||||
|
||||
if (!wasm_runtime_validate_app_addr(module, arg_i64,
|
||||
(uint64)ptr_len))
|
||||
goto fail;
|
||||
|
||||
*argv_dst = (uint64)wasm_runtime_addr_app_to_native(
|
||||
module, arg_i64);
|
||||
}
|
||||
else if (signature[i + 1] == '$') {
|
||||
/* param is a string */
|
||||
if (!wasm_runtime_validate_app_str_addr(module,
|
||||
arg_i64))
|
||||
goto fail;
|
||||
|
||||
*argv_dst = (uint64)wasm_runtime_addr_app_to_native(
|
||||
module, arg_i64);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case VALUE_TYPE_F64:
|
||||
bh_memcpy_s(argv_dst, sizeof(uint64), argv_src,
|
||||
sizeof(uint32) * 2);
|
||||
|
@ -3855,6 +3990,9 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|||
fail:
|
||||
if (argv1 != argv_buf)
|
||||
wasm_runtime_free(argv1);
|
||||
#if WASM_ENABLE_MEMORY64 == 0
|
||||
(void)arg_i64;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -4117,8 +4255,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
{
|
||||
arg_i32 = *argv_src++;
|
||||
|
||||
/* TODO: memory64 the data type of ptr_len and argc depends on
|
||||
* mem idx type */
|
||||
if (signature) {
|
||||
if (signature[i + 1] == '*') {
|
||||
/* param is a pointer */
|
||||
|
@ -4494,8 +4630,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
{
|
||||
arg_i32 = *argv++;
|
||||
|
||||
/* TODO: memory64 the data type of ptr_len and argc depends on
|
||||
* mem idx type */
|
||||
if (signature) {
|
||||
if (signature[i + 1] == '*') {
|
||||
/* param is a pointer */
|
||||
|
@ -4811,8 +4945,10 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
{
|
||||
arg_i32 = *argv_src++;
|
||||
arg_i64 = arg_i32;
|
||||
/* TODO: memory64 the data type of ptr_len and argc depends on
|
||||
* mem idx type */
|
||||
/* TODO: memory64 if future there is a way for supporting
|
||||
* wasm64 and wasm32 in libc at the same time, remove the
|
||||
* macro control */
|
||||
#if WASM_ENABLE_MEMORY64 == 0
|
||||
if (signature) {
|
||||
if (signature[i + 1] == '*') {
|
||||
/* param is a pointer */
|
||||
|
@ -4840,6 +4976,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
module, (uint64)arg_i32);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (n_ints < MAX_REG_INTS)
|
||||
ints[n_ints++] = arg_i64;
|
||||
else
|
||||
|
@ -4847,6 +4984,47 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
break;
|
||||
}
|
||||
case VALUE_TYPE_I64:
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
{
|
||||
arg_i64 = GET_I64_FROM_ADDR(argv_src);
|
||||
argv_src += 2;
|
||||
if (signature) {
|
||||
/* TODO: memory64 pointer with length need a new symbol
|
||||
* to represent type i64, with '~' still represent i32
|
||||
* length */
|
||||
if (signature[i + 1] == '*') {
|
||||
/* param is a pointer */
|
||||
if (signature[i + 2] == '~')
|
||||
/* pointer with length followed */
|
||||
ptr_len = *argv_src;
|
||||
else
|
||||
/* pointer without length followed */
|
||||
ptr_len = 1;
|
||||
|
||||
if (!wasm_runtime_validate_app_addr(module, arg_i64,
|
||||
(uint64)ptr_len))
|
||||
goto fail;
|
||||
|
||||
arg_i64 = (uint64)wasm_runtime_addr_app_to_native(
|
||||
module, arg_i64);
|
||||
}
|
||||
else if (signature[i + 1] == '$') {
|
||||
/* param is a string */
|
||||
if (!wasm_runtime_validate_app_str_addr(module,
|
||||
arg_i64))
|
||||
goto fail;
|
||||
|
||||
arg_i64 = (uint64)wasm_runtime_addr_app_to_native(
|
||||
module, arg_i64);
|
||||
}
|
||||
}
|
||||
if (n_ints < MAX_REG_INTS)
|
||||
ints[n_ints++] = arg_i64;
|
||||
else
|
||||
stacks[n_stacks++] = arg_i64;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_GC != 0
|
||||
case REF_TYPE_FUNCREF:
|
||||
case REF_TYPE_EXTERNREF:
|
||||
|
@ -5325,6 +5503,7 @@ wasm_externref_set_cleanup(WASMModuleInstanceCommon *module_inst,
|
|||
if (lookup_user_data.found) {
|
||||
void *key = (void *)(uintptr_t)lookup_user_data.externref_idx;
|
||||
ExternRefMapNode *node = bh_hash_map_find(externref_map, key);
|
||||
bh_assert(node);
|
||||
node->cleanup = extern_obj_cleanup;
|
||||
ok = true;
|
||||
}
|
||||
|
@ -6337,6 +6516,7 @@ wasm_runtime_load_depended_module(const WASMModuleCommon *parent_module,
|
|||
bool ret = false;
|
||||
uint8 *buffer = NULL;
|
||||
uint32 buffer_size = 0;
|
||||
LoadArgs args = { 0 };
|
||||
|
||||
/* check the registered module list of the parent */
|
||||
sub_module = wasm_runtime_search_sub_module(parent_module, sub_module_name);
|
||||
|
@ -6376,23 +6556,25 @@ wasm_runtime_load_depended_module(const WASMModuleCommon *parent_module,
|
|||
if (!ret) {
|
||||
LOG_DEBUG("read the file of %s failed", sub_module_name);
|
||||
set_error_buf_v(parent_module, error_buf, error_buf_size,
|
||||
"unknown import", sub_module_name);
|
||||
"unknown import %s", sub_module_name);
|
||||
goto delete_loading_module;
|
||||
}
|
||||
if (get_package_type(buffer, buffer_size) != parent_module->module_type) {
|
||||
LOG_DEBUG("moudle %s type error", sub_module_name);
|
||||
goto delete_loading_module;
|
||||
goto destroy_file_buffer;
|
||||
}
|
||||
|
||||
args.name = (char *)sub_module_name;
|
||||
if (get_package_type(buffer, buffer_size) == Wasm_Module_Bytecode) {
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
sub_module = (WASMModuleCommon *)wasm_load(buffer, buffer_size, false,
|
||||
error_buf, error_buf_size);
|
||||
sub_module = (WASMModuleCommon *)wasm_load(
|
||||
buffer, buffer_size, false, &args, error_buf, error_buf_size);
|
||||
#endif
|
||||
}
|
||||
else if (get_package_type(buffer, buffer_size) == Wasm_Module_AoT) {
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
sub_module = (WASMModuleCommon *)aot_load_from_aot_file(
|
||||
buffer, buffer_size, error_buf, error_buf_size);
|
||||
buffer, buffer_size, &args, error_buf, error_buf_size);
|
||||
#endif
|
||||
}
|
||||
if (!sub_module) {
|
||||
|
@ -6487,7 +6669,7 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
|
|||
sub_module_inst_list_node = loader_malloc(sizeof(WASMSubModInstNode),
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module_inst_list_node) {
|
||||
LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ:%d",
|
||||
LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ: %zu",
|
||||
sizeof(WASMSubModInstNode));
|
||||
if (sub_module_inst)
|
||||
wasm_runtime_deinstantiate_internal(sub_module_inst, false);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
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))
|
||||
|
|
|
@ -484,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);
|
||||
|
@ -529,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);
|
||||
|
@ -558,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);
|
||||
|
@ -597,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]);
|
||||
|
@ -2093,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);
|
||||
EMIT_U16(types[i]->is_sub_final);
|
||||
/* 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);
|
||||
/* 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);
|
||||
|
@ -2593,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;
|
||||
|
@ -2603,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;
|
||||
|
||||
|
@ -2614,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -374,7 +374,9 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
}
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
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
|
||||
if (return_location != NULL) {
|
||||
LLVMInstructionSetDebugLoc(ret, return_location);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1265,6 +1269,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)
|
||||
|
@ -1290,6 +1295,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;
|
||||
|
|
|
@ -1826,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,
|
||||
|
@ -2018,15 +2064,23 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
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,
|
||||
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);
|
||||
|
||||
|
@ -2254,12 +2308,24 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
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,
|
||||
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 */
|
||||
if (!(check_ftype_idx_succ = LLVMAppendBasicBlockInContext(
|
||||
|
|
|
@ -85,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;
|
||||
|
@ -674,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;
|
||||
|
@ -2547,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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,28 +387,11 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
|
|||
LLVMDIBuilderCreateExpression(DIB, NULL, 0);
|
||||
auto variable_list =
|
||||
function.GetBlock().GetVariables(extractor->target, true, false, false);
|
||||
unsigned int variable_offset = 0;
|
||||
if (num_function_args != variable_list.GetSize()) {
|
||||
// A hack to detect C++ "this" pointer.
|
||||
//
|
||||
// REVISIT: is there a more reliable way?
|
||||
// At the DWARF level, we can probably look at DW_AT_object_pointer
|
||||
// and DW_AT_artificial. I'm not sure how it can be done via the
|
||||
// LLDB API though.
|
||||
if (num_function_args + 1 == variable_list.GetSize()) {
|
||||
SBValue variable(variable_list.GetValueAtIndex(0));
|
||||
const char *varname = variable.GetName();
|
||||
if (varname != NULL && !strcmp(varname, "this")) {
|
||||
variable_offset = 1;
|
||||
}
|
||||
}
|
||||
if (!variable_offset) {
|
||||
LOG_ERROR("function args number dismatch!:function %s %s value "
|
||||
"number=%d, function args=%d",
|
||||
function_name, function.GetMangledName(),
|
||||
LOG_ERROR(
|
||||
"function args number dismatch!:value number=%d, function args=%d",
|
||||
variable_list.GetSize(), num_function_args);
|
||||
}
|
||||
}
|
||||
|
||||
LLVMMetadataRef ParamLocation = LLVMDIBuilderCreateDebugLocation(
|
||||
comp_ctx->context, line_entry.GetLine(), 0, FunctionMetadata, NULL);
|
||||
|
@ -395,11 +411,10 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
|
|||
LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar, ParamExpression,
|
||||
ParamLocation, block_curr);
|
||||
|
||||
for (uint32_t function_arg_idx = 0; function_arg_idx < num_function_args;
|
||||
++function_arg_idx) {
|
||||
uint32_t variable_idx = variable_offset + function_arg_idx;
|
||||
SBValue variable(variable_list.GetValueAtIndex(variable_idx));
|
||||
if (variable.IsValid()) {
|
||||
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() && ParamTypes[function_arg_idx + 1] != NULL) {
|
||||
SBDeclaration dec(variable.GetDeclaration());
|
||||
auto valtype = variable.GetType();
|
||||
LLVMMetadataRef ParamLocation = LLVMDIBuilderCreateDebugLocation(
|
||||
|
@ -408,11 +423,12 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
|
|||
const char *varname = variable.GetName();
|
||||
LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable(
|
||||
DIB, FunctionMetadata, varname, varname ? strlen(varname) : 0,
|
||||
variable_idx + 1 + 1,
|
||||
function_arg_idx + 1 + 1,
|
||||
File, // starts form 1, and 1 is exenv,
|
||||
dec.GetLine(), ParamTypes[function_arg_idx + 1], true,
|
||||
LLVMDIFlagZero);
|
||||
LLVMValueRef Param = LLVMGetParam(func_ctx->func, variable_idx + 1);
|
||||
LLVMValueRef Param =
|
||||
LLVMGetParam(func_ctx->func, function_arg_idx + 1);
|
||||
LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar,
|
||||
ParamExpression, ParamLocation,
|
||||
block_curr);
|
||||
|
@ -491,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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,7 +9293,7 @@ jit_codegen_init()
|
|||
imm.setValue(INT32_MAX);
|
||||
a.jne(imm);
|
||||
|
||||
char *stream = (char *)a.code()->sectionById(0)->buffer().data()
|
||||
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,
|
||||
|
@ -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[] = {
|
||||
|
|
|
@ -636,7 +636,7 @@ wasm_init_memory(WASMModuleInstance *inst, uint32 mem_idx, uint32 seg_idx,
|
|||
|
||||
/* 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;
|
||||
|
||||
|
@ -724,8 +724,10 @@ wasm_copy_memory(WASMModuleInstance *inst, uint32 src_mem_idx,
|
|||
|
||||
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)
|
||||
|
@ -788,7 +790,7 @@ wasm_fill_memory(WASMModuleInstance *inst, uint32 mem_idx, uint32 len,
|
|||
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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
||||
|
@ -517,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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -107,6 +113,11 @@ 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 +125,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 +197,14 @@ 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 */
|
||||
|
@ -419,6 +441,13 @@ WASM_RUNTIME_API_EXTERN wasm_module_t
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -90,11 +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;
|
||||
|
@ -263,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;
|
||||
|
@ -277,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;
|
||||
|
@ -327,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 */
|
||||
|
||||
|
@ -364,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
|
||||
|
@ -484,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;
|
||||
|
@ -1312,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 {
|
||||
|
|
|
@ -46,8 +46,10 @@ typedef float64 CellType_F64;
|
|||
#define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
|
||||
#endif
|
||||
|
||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
|
||||
#if WASM_ENABLE_MEMORY64 == 0
|
||||
|
||||
#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; \
|
||||
|
@ -69,7 +71,8 @@ typedef float64 CellType_F64;
|
|||
else \
|
||||
goto out_of_bounds; \
|
||||
} while (0)
|
||||
#else
|
||||
#else /* else of !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; \
|
||||
|
@ -80,8 +83,37 @@ typedef float64 CellType_F64;
|
|||
do { \
|
||||
maddr = memory->memory_data + (uint32)(start); \
|
||||
} while (0)
|
||||
#endif /* !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */
|
||||
#endif /* end of !defined(OS_ENABLE_HW_BOUND_CHECK) || \
|
||||
WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */
|
||||
|
||||
#else /* else of WASM_ENABLE_MEMORY64 == 0 */
|
||||
|
||||
#define CHECK_MEMORY_OVERFLOW(bytes) \
|
||||
do { \
|
||||
uint64 offset1 = (uint64)offset + (uint64)addr; \
|
||||
/* If memory64 is enabled, offset1, offset1 + bytes can overflow */ \
|
||||
if (disable_bounds_checks \
|
||||
|| (offset1 >= offset && offset1 + bytes >= offset1 \
|
||||
&& offset1 + bytes <= get_linear_mem_size())) \
|
||||
maddr = memory->memory_data + offset1; \
|
||||
else \
|
||||
goto out_of_bounds; \
|
||||
} while (0)
|
||||
#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
|
||||
do { \
|
||||
uint64 offset1 = (uint64)(start); \
|
||||
/* If memory64 is enabled, offset1 + bytes can overflow */ \
|
||||
if (disable_bounds_checks \
|
||||
|| (offset1 + bytes >= offset1 \
|
||||
&& offset1 + bytes <= get_linear_mem_size())) \
|
||||
/* App heap space is not valid space for \
|
||||
bulk memory operation */ \
|
||||
maddr = memory->memory_data + offset1; \
|
||||
else \
|
||||
goto out_of_bounds; \
|
||||
} while (0)
|
||||
|
||||
#endif /* end of WASM_ENABLE_MEMORY64 == 0 */
|
||||
|
||||
#define CHECK_ATOMIC_MEMORY_ACCESS() \
|
||||
do { \
|
||||
|
@ -472,6 +504,23 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
|
|||
#define SET_LABEL_TYPE(_label_type) (void)0
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define PUSH_MEM_OFFSET(value) \
|
||||
do { \
|
||||
if (is_memory64) { \
|
||||
PUT_I64_TO_ADDR(frame_sp, value); \
|
||||
frame_sp += 2; \
|
||||
} \
|
||||
else { \
|
||||
*(int32 *)frame_sp++ = (int32)(value); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define PUSH_MEM_OFFSET(value) PUSH_I32(value)
|
||||
#endif
|
||||
|
||||
#define PUSH_PAGE_COUNT(value) PUSH_MEM_OFFSET(value)
|
||||
|
||||
#define PUSH_CSP(_label_type, param_cell_num, cell_num, _target_addr) \
|
||||
do { \
|
||||
bh_assert(frame_csp < frame->csp_boundary); \
|
||||
|
@ -501,6 +550,14 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
|
|||
GET_REF_FROM_ADDR(frame_sp))
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define POP_MEM_OFFSET() (is_memory64 ? POP_I64() : POP_I32())
|
||||
#else
|
||||
#define POP_MEM_OFFSET() POP_I32()
|
||||
#endif
|
||||
|
||||
#define POP_PAGE_COUNT() POP_MEM_OFFSET()
|
||||
|
||||
#define POP_CSP_CHECK_OVERFLOW(n) \
|
||||
do { \
|
||||
bh_assert(frame_csp - n >= frame->csp_bottom); \
|
||||
|
@ -576,11 +633,12 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
|
|||
/* sign extend */ \
|
||||
res |= 0xFFFFFFFFFFFFFF80LL; \
|
||||
p++; \
|
||||
break; \
|
||||
} \
|
||||
else { \
|
||||
uint32 _off = 0; \
|
||||
res = (int64)read_leb(p, &_off, 64, true); \
|
||||
p += _off; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define read_leb_uint32(p, p_end, res) \
|
||||
|
@ -589,11 +647,12 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
|
|||
if (!(_val & 0x80)) { \
|
||||
res = _val; \
|
||||
p++; \
|
||||
break; \
|
||||
} \
|
||||
else { \
|
||||
uint32 _off = 0; \
|
||||
res = (uint32)read_leb(p, &_off, 32, false); \
|
||||
p += _off; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define read_leb_int32(p, p_end, res) \
|
||||
|
@ -605,13 +664,33 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
|
|||
/* sign extend */ \
|
||||
res |= 0xFFFFFF80; \
|
||||
p++; \
|
||||
break; \
|
||||
} \
|
||||
else { \
|
||||
uint32 _off = 0; \
|
||||
res = (int32)read_leb(p, &_off, 32, true); \
|
||||
p += _off; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define read_leb_mem_offset(p, p_end, res) \
|
||||
do { \
|
||||
uint8 _val = *p; \
|
||||
if (!(_val & 0x80)) { \
|
||||
res = (mem_offset_t)_val; \
|
||||
p++; \
|
||||
} \
|
||||
else { \
|
||||
uint32 _off = 0; \
|
||||
res = (mem_offset_t)read_leb(p, &_off, is_memory64 ? 64 : 32, \
|
||||
false); \
|
||||
p += _off; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res)
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES == 0
|
||||
#define RECOVER_FRAME_IP_END() frame_ip_end = wasm_get_func_code_end(cur_func)
|
||||
#else
|
||||
|
@ -872,7 +951,7 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
|
|||
uint32 readv, sval; \
|
||||
\
|
||||
sval = POP_I32(); \
|
||||
addr = POP_I32(); \
|
||||
addr = POP_MEM_OFFSET(); \
|
||||
\
|
||||
if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##8_U) { \
|
||||
CHECK_MEMORY_OVERFLOW(1); \
|
||||
|
@ -912,7 +991,7 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
|
|||
uint64 readv, sval; \
|
||||
\
|
||||
sval = (uint64)POP_I64(); \
|
||||
addr = POP_I32(); \
|
||||
addr = POP_MEM_OFFSET(); \
|
||||
\
|
||||
if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##8_U) { \
|
||||
CHECK_MEMORY_OVERFLOW(1); \
|
||||
|
@ -1430,6 +1509,16 @@ 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_MEMORY64 != 0
|
||||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
bool is_memory64 = false;
|
||||
if (memory)
|
||||
is_memory64 = memory->is_memory64;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
uint8 *frame_ip_orig = NULL;
|
||||
|
@ -2123,6 +2212,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
WASMFuncType *cur_type, *cur_func_type;
|
||||
WASMTableInstance *tbl_inst;
|
||||
uint32 tbl_idx;
|
||||
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
opcode = *(frame_ip - 1);
|
||||
#endif
|
||||
|
@ -2193,8 +2283,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;
|
||||
}
|
||||
|
@ -4087,8 +4176,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
bh_assert(global_idx < module->e->global_count);
|
||||
global = globals + global_idx;
|
||||
global_addr = get_global_addr(global_data, global);
|
||||
/* TODO: Memory64 the data type depends on mem idx type */
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64) {
|
||||
aux_stack_top = *(uint64 *)(frame_sp - 2);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
aux_stack_top = (uint64)(*(uint32 *)(frame_sp - 1));
|
||||
}
|
||||
if (aux_stack_top <= (uint64)exec_env->aux_stack_boundary) {
|
||||
wasm_set_exception(module, "wasm auxiliary stack overflow");
|
||||
goto got_exception;
|
||||
|
@ -4098,8 +4194,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
"wasm auxiliary stack underflow");
|
||||
goto got_exception;
|
||||
}
|
||||
*(int32 *)global_addr = aux_stack_top;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64) {
|
||||
*(uint64 *)global_addr = aux_stack_top;
|
||||
frame_sp -= 2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
*(uint32 *)global_addr = aux_stack_top;
|
||||
frame_sp--;
|
||||
}
|
||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||
if (module->module->aux_stack_top_global_index != (uint32)-1) {
|
||||
uint32 aux_stack_used =
|
||||
|
@ -4126,11 +4231,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_I32_LOAD)
|
||||
HANDLE_OP(WASM_OP_F32_LOAD)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(4);
|
||||
PUSH_I32(LOAD_I32(maddr));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4141,11 +4247,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_I64_LOAD)
|
||||
HANDLE_OP(WASM_OP_F64_LOAD)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(8);
|
||||
PUSH_I64(LOAD_I64(maddr));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4155,11 +4262,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I32_LOAD8_S)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
PUSH_I32(sign_ext_8_32(*(int8 *)maddr));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4169,11 +4277,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I32_LOAD8_U)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
PUSH_I32((uint32)(*(uint8 *)maddr));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4183,11 +4292,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I32_LOAD16_S)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(2);
|
||||
PUSH_I32(sign_ext_16_32(LOAD_I16(maddr)));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4197,11 +4307,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I32_LOAD16_U)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(2);
|
||||
PUSH_I32((uint32)(LOAD_U16(maddr)));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4211,11 +4322,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I64_LOAD8_S)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
PUSH_I64(sign_ext_8_64(*(int8 *)maddr));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4225,11 +4337,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I64_LOAD8_U)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
PUSH_I64((uint64)(*(uint8 *)maddr));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4239,11 +4352,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I64_LOAD16_S)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(2);
|
||||
PUSH_I64(sign_ext_16_64(LOAD_I16(maddr)));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4253,11 +4367,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I64_LOAD16_U)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(2);
|
||||
PUSH_I64((uint64)(LOAD_U16(maddr)));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4267,12 +4382,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I64_LOAD32_S)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
opcode = *(frame_ip - 1);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(4);
|
||||
PUSH_I64(sign_ext_32_64(LOAD_I32(maddr)));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4282,11 +4398,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
HANDLE_OP(WASM_OP_I64_LOAD32_U)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(4);
|
||||
PUSH_I64((uint64)(LOAD_U32(maddr)));
|
||||
CHECK_READ_WATCHPOINT(addr, offset);
|
||||
|
@ -4298,14 +4415,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_I32_STORE)
|
||||
HANDLE_OP(WASM_OP_F32_STORE)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
frame_sp--;
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(4);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64) {
|
||||
STORE_U32(maddr, frame_sp[2]);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
STORE_U32(maddr, frame_sp[1]);
|
||||
}
|
||||
CHECK_WRITE_WATCHPOINT(addr, offset);
|
||||
(void)flags;
|
||||
HANDLE_OP_END();
|
||||
|
@ -4314,15 +4440,26 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_I64_STORE)
|
||||
HANDLE_OP(WASM_OP_F64_STORE)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
frame_sp -= 2;
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(8);
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64) {
|
||||
PUT_I64_TO_ADDR((mem_offset_t *)maddr,
|
||||
GET_I64_FROM_ADDR(frame_sp + 2));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
PUT_I64_TO_ADDR((uint32 *)maddr,
|
||||
GET_I64_FROM_ADDR(frame_sp + 1));
|
||||
}
|
||||
CHECK_WRITE_WATCHPOINT(addr, offset);
|
||||
(void)flags;
|
||||
HANDLE_OP_END();
|
||||
|
@ -4331,14 +4468,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_I32_STORE8)
|
||||
HANDLE_OP(WASM_OP_I32_STORE16)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
uint32 sval;
|
||||
|
||||
opcode = *(frame_ip - 1);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
sval = (uint32)POP_I32();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
|
||||
if (opcode == WASM_OP_I32_STORE8) {
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
|
@ -4357,14 +4495,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP(WASM_OP_I64_STORE16)
|
||||
HANDLE_OP(WASM_OP_I64_STORE32)
|
||||
{
|
||||
uint32 offset, flags, addr;
|
||||
uint32 flags;
|
||||
mem_offset_t offset, addr;
|
||||
uint64 sval;
|
||||
|
||||
opcode = *(frame_ip - 1);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
sval = (uint64)POP_I64();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
|
||||
if (opcode == WASM_OP_I64_STORE8) {
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
|
@ -4388,7 +4527,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
{
|
||||
uint32 reserved;
|
||||
read_leb_uint32(frame_ip, frame_ip_end, reserved);
|
||||
PUSH_I32(memory->cur_page_count);
|
||||
PUSH_PAGE_COUNT(memory->cur_page_count);
|
||||
(void)reserved;
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
|
@ -4399,15 +4538,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
prev_page_count = memory->cur_page_count;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, reserved);
|
||||
delta = (uint32)POP_I32();
|
||||
delta = (uint32)POP_PAGE_COUNT();
|
||||
|
||||
if (!wasm_enlarge_memory(module, delta)) {
|
||||
/* failed to memory.grow, return -1 */
|
||||
PUSH_I32(-1);
|
||||
PUSH_PAGE_COUNT(-1);
|
||||
}
|
||||
else {
|
||||
/* success, return previous page count */
|
||||
PUSH_I32(prev_page_count);
|
||||
PUSH_PAGE_COUNT(prev_page_count);
|
||||
/* update memory size, no need to update memory ptr as
|
||||
it isn't changed in wasm_enlarge_memory */
|
||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|
@ -5407,7 +5546,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
case WASM_OP_MEMORY_INIT:
|
||||
{
|
||||
uint32 addr, segment;
|
||||
uint32 segment;
|
||||
mem_offset_t addr;
|
||||
uint64 bytes, offset, seg_len;
|
||||
uint8 *data;
|
||||
|
||||
|
@ -5417,7 +5557,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
bytes = (uint64)(uint32)POP_I32();
|
||||
offset = (uint64)(uint32)POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
addr = (mem_offset_t)POP_MEM_OFFSET();
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
linear_mem_size = get_linear_mem_size();
|
||||
|
@ -5460,14 +5600,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
}
|
||||
case WASM_OP_MEMORY_COPY:
|
||||
{
|
||||
uint32 dst, src, len;
|
||||
mem_offset_t dst, src, len;
|
||||
uint8 *mdst, *msrc;
|
||||
|
||||
frame_ip += 2;
|
||||
|
||||
len = POP_I32();
|
||||
src = POP_I32();
|
||||
dst = POP_I32();
|
||||
len = POP_MEM_OFFSET();
|
||||
src = POP_MEM_OFFSET();
|
||||
dst = POP_MEM_OFFSET();
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
linear_mem_size = get_linear_mem_size();
|
||||
|
@ -5493,13 +5632,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
}
|
||||
case WASM_OP_MEMORY_FILL:
|
||||
{
|
||||
uint32 dst, len;
|
||||
mem_offset_t dst, len;
|
||||
uint8 fill_val, *mdst;
|
||||
frame_ip++;
|
||||
|
||||
len = POP_I32();
|
||||
len = POP_MEM_OFFSET();
|
||||
fill_val = POP_I32();
|
||||
dst = POP_I32();
|
||||
dst = POP_MEM_OFFSET();
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
linear_mem_size = get_linear_mem_size();
|
||||
|
@ -5729,7 +5868,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
HANDLE_OP(WASM_OP_ATOMIC_PREFIX)
|
||||
{
|
||||
uint32 offset = 0, align = 0, addr;
|
||||
mem_offset_t offset = 0, addr;
|
||||
uint32 align = 0;
|
||||
uint32 opcode1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, opcode1);
|
||||
|
@ -5739,7 +5879,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
if (opcode != WASM_OP_ATOMIC_FENCE) {
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
|
@ -5748,7 +5888,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
uint32 notify_count, ret;
|
||||
|
||||
notify_count = POP_I32();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(4);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
|
@ -5768,7 +5908,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
timeout = POP_I64();
|
||||
expect = POP_I32();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(4);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
|
@ -5792,7 +5932,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
timeout = POP_I64();
|
||||
expect = POP_I64();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
CHECK_MEMORY_OVERFLOW(8);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
|
@ -5823,7 +5963,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
{
|
||||
uint32 readv;
|
||||
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
|
||||
if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) {
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
|
@ -5858,7 +5998,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
{
|
||||
uint64 readv;
|
||||
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
|
||||
if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) {
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
|
@ -5900,7 +6040,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
uint32 sval;
|
||||
|
||||
sval = (uint32)POP_I32();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
|
||||
if (opcode == WASM_OP_ATOMIC_I32_STORE8) {
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
|
@ -5934,7 +6074,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
uint64 sval;
|
||||
|
||||
sval = (uint64)POP_I64();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
|
||||
if (opcode == WASM_OP_ATOMIC_I64_STORE8) {
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
|
@ -5961,7 +6101,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
CHECK_MEMORY_OVERFLOW(8);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
shared_memory_lock(memory);
|
||||
PUT_I64_TO_ADDR((uint32 *)maddr, sval);
|
||||
STORE_I64(maddr, sval);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
break;
|
||||
|
@ -5975,7 +6115,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
sval = POP_I32();
|
||||
expect = POP_I32();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
|
||||
if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG8_U) {
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
|
@ -6021,7 +6161,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
sval = (uint64)POP_I64();
|
||||
expect = (uint64)POP_I64();
|
||||
addr = POP_I32();
|
||||
addr = POP_MEM_OFFSET();
|
||||
|
||||
if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG8_U) {
|
||||
CHECK_MEMORY_OVERFLOW(1);
|
||||
|
@ -6090,6 +6230,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
frame_ip = frame->ip;
|
||||
frame_sp = frame->sp;
|
||||
frame_csp = frame->csp;
|
||||
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||
is_return_call = false;
|
||||
#endif
|
||||
goto call_func_from_entry;
|
||||
}
|
||||
|
||||
|
@ -6183,6 +6326,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
}
|
||||
FREE_FRAME(exec_env, frame);
|
||||
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
|
||||
is_return_call = true;
|
||||
goto call_func_from_entry;
|
||||
}
|
||||
#endif
|
||||
|
@ -6196,6 +6340,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:
|
||||
|
@ -6205,15 +6352,27 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
if (cur_func->import_func_inst) {
|
||||
wasm_interp_call_func_import(module, exec_env, cur_func,
|
||||
prev_frame);
|
||||
#if WASM_ENABLE_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();
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_EXCE_HANDLING != 0
|
||||
char uncaught_exception[128] = { 0 };
|
||||
bool has_exception =
|
||||
wasm_copy_exception(module, uncaught_exception);
|
||||
if (has_exception
|
||||
&& strstr(uncaught_exception, "uncaught wasm exception")) {
|
||||
/* fix framesp */
|
||||
UPDATE_ALL_FROM_FRAME();
|
||||
|
||||
uint32 import_exception;
|
||||
/* initialize imported exception index to be invalid */
|
||||
SET_INVALID_TAGINDEX(import_exception);
|
||||
|
@ -6255,11 +6414,21 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
{
|
||||
wasm_interp_call_func_native(module, exec_env, cur_func,
|
||||
prev_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 */
|
||||
|
|
|
@ -1501,6 +1501,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
|
||||
|
@ -1693,7 +1696,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;
|
||||
|
@ -1733,8 +1736,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;
|
||||
}
|
||||
|
@ -5618,6 +5620,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;
|
||||
}
|
||||
|
||||
|
@ -5766,6 +5771,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 */
|
||||
|
@ -5838,6 +5844,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:
|
||||
|
@ -5855,9 +5864,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
prev_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 */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
||||
|
|
|
@ -47,6 +47,7 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
|||
#define skip_leb_int64(p, p_end) skip_leb(p)
|
||||
#define skip_leb_uint32(p, p_end) skip_leb(p)
|
||||
#define skip_leb_int32(p, p_end) skip_leb(p)
|
||||
#define skip_leb_mem_offset(p, p_end) skip_leb(p)
|
||||
|
||||
static bool
|
||||
is_32bit_type(uint8 type)
|
||||
|
@ -116,7 +117,7 @@ read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
|
|||
}
|
||||
else if (sign && maxbits == 32) {
|
||||
if (shift < maxbits) {
|
||||
/* Sign extend, second highest bit is the sign bit */
|
||||
/* Sign extend, second-highest bit is the sign bit */
|
||||
if ((uint8)byte & 0x40)
|
||||
result |= (~((uint64)0)) << shift;
|
||||
}
|
||||
|
@ -132,7 +133,7 @@ read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
|
|||
}
|
||||
else if (sign && maxbits == 64) {
|
||||
if (shift < maxbits) {
|
||||
/* Sign extend, second highest bit is the sign bit */
|
||||
/* Sign extend, second-highest bit is the sign bit */
|
||||
if ((uint8)byte & 0x40)
|
||||
result |= (~((uint64)0)) << shift;
|
||||
}
|
||||
|
@ -180,6 +181,18 @@ read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
|
|||
res = (int32)res64; \
|
||||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define read_leb_mem_offset(p, p_end, res) \
|
||||
do { \
|
||||
uint64 res64; \
|
||||
read_leb((uint8 **)&p, p_end, is_memory64 ? 64 : 32, false, &res64, \
|
||||
error_buf, error_buf_size); \
|
||||
res = (mem_offset_t)res64; \
|
||||
} while (0)
|
||||
#else
|
||||
#define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res)
|
||||
#endif
|
||||
|
||||
static void *
|
||||
loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
|
@ -683,6 +696,38 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_memory_flag(const uint8 mem_flag)
|
||||
{
|
||||
/* Check whether certain features indicated by mem_flag are enabled in
|
||||
* runtime */
|
||||
if (mem_flag > MAX_PAGE_COUNT_FLAG) {
|
||||
#if WASM_ENABLE_SHARED_MEMORY == 0
|
||||
if (mem_flag & SHARED_MEMORY_FLAG) {
|
||||
LOG_VERBOSE("shared memory flag was found, please enable shared "
|
||||
"memory, lib-pthread or lib-wasi-threads");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_MEMORY64 == 0
|
||||
if (mem_flag & MEMORY64_FLAG) {
|
||||
LOG_VERBOSE("memory64 flag was found, please enable memory64");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mem_flag > MAX_PAGE_COUNT_FLAG + SHARED_MEMORY_FLAG + MEMORY64_FLAG) {
|
||||
return false;
|
||||
}
|
||||
else if ((mem_flag & SHARED_MEMORY_FLAG)
|
||||
&& !(mem_flag & MAX_PAGE_COUNT_FLAG)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMModule *parent_module, const char *sub_module_name,
|
||||
|
@ -695,20 +740,28 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
|
||||
/ DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
#else
|
||||
uint32 max_page_count = DEFAULT_MAX_PAGES;
|
||||
uint32 max_page_count;
|
||||
#endif /* WASM_ENABLE_APP_FRAMEWORK */
|
||||
uint32 declare_max_page_count_flag = 0;
|
||||
uint32 mem_flag = 0;
|
||||
bool is_memory64 = false;
|
||||
uint32 declare_init_page_count = 0;
|
||||
uint32 declare_max_page_count = 0;
|
||||
|
||||
read_leb_uint32(p, p_end, declare_max_page_count_flag);
|
||||
read_leb_uint32(p, p_end, declare_init_page_count);
|
||||
bh_assert(declare_init_page_count <= 65536);
|
||||
read_leb_uint32(p, p_end, mem_flag);
|
||||
bh_assert(check_memory_flag(mem_flag));
|
||||
|
||||
if (declare_max_page_count_flag & 1) {
|
||||
#if WASM_ENABLE_APP_FRAMEWORK == 0
|
||||
is_memory64 = mem_flag & MEMORY64_FLAG;
|
||||
max_page_count = is_memory64 ? DEFAULT_MEM64_MAX_PAGES : DEFAULT_MAX_PAGES;
|
||||
#endif
|
||||
|
||||
read_leb_uint32(p, p_end, declare_init_page_count);
|
||||
bh_assert(declare_init_page_count <= max_page_count);
|
||||
|
||||
if (mem_flag & MAX_PAGE_COUNT_FLAG) {
|
||||
read_leb_uint32(p, p_end, declare_max_page_count);
|
||||
bh_assert(declare_init_page_count <= declare_max_page_count);
|
||||
bh_assert(declare_max_page_count <= 65536);
|
||||
bh_assert(declare_max_page_count <= max_page_count);
|
||||
if (declare_max_page_count > max_page_count) {
|
||||
declare_max_page_count = max_page_count;
|
||||
}
|
||||
|
@ -719,12 +772,13 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
}
|
||||
|
||||
/* now we believe all declaration are ok */
|
||||
memory->flags = declare_max_page_count_flag;
|
||||
memory->flags = mem_flag;
|
||||
memory->init_page_count = declare_init_page_count;
|
||||
memory->max_page_count = declare_max_page_count;
|
||||
memory->num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
|
||||
*p_buf = p;
|
||||
(void)check_memory_flag;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -811,26 +865,28 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
|
|||
uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
|
||||
/ DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
#else
|
||||
uint32 max_page_count = DEFAULT_MAX_PAGES;
|
||||
uint32 max_page_count;
|
||||
bool is_memory64 = false;
|
||||
#endif
|
||||
|
||||
p_org = p;
|
||||
read_leb_uint32(p, p_end, memory->flags);
|
||||
bh_assert(p - p_org <= 1);
|
||||
(void)p_org;
|
||||
#if WASM_ENABLE_SHARED_MEMORY == 0
|
||||
bh_assert(memory->flags <= 1);
|
||||
#else
|
||||
bh_assert(memory->flags <= 3 && memory->flags != 2);
|
||||
bh_assert(check_memory_flag(memory->flags));
|
||||
|
||||
#if WASM_ENABLE_APP_FRAMEWORK == 0
|
||||
is_memory64 = memory->flags & MEMORY64_FLAG;
|
||||
max_page_count = is_memory64 ? DEFAULT_MEM64_MAX_PAGES : DEFAULT_MAX_PAGES;
|
||||
#endif
|
||||
|
||||
read_leb_uint32(p, p_end, memory->init_page_count);
|
||||
bh_assert(memory->init_page_count <= 65536);
|
||||
bh_assert(memory->init_page_count <= max_page_count);
|
||||
|
||||
if (memory->flags & 1) {
|
||||
read_leb_uint32(p, p_end, memory->max_page_count);
|
||||
bh_assert(memory->init_page_count <= memory->max_page_count);
|
||||
bh_assert(memory->max_page_count <= 65536);
|
||||
bh_assert(memory->max_page_count <= max_page_count);
|
||||
if (memory->max_page_count > max_page_count)
|
||||
memory->max_page_count = max_page_count;
|
||||
}
|
||||
|
@ -842,6 +898,7 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
|
|||
memory->num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
|
||||
*p_buf = p;
|
||||
(void)check_memory_flag;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1704,6 +1761,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
bool is_passive = false;
|
||||
uint32 mem_flag;
|
||||
#endif
|
||||
uint8 mem_offset_type;
|
||||
|
||||
read_leb_uint32(p, p_end, data_seg_count);
|
||||
|
||||
|
@ -1750,11 +1808,35 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
< module->import_memory_count + module->memory_count);
|
||||
#endif /* WASM_ENABLE_BULK_MEMORY */
|
||||
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
if (!is_passive)
|
||||
#endif /* WASM_ENABLE_BULK_MEMORY */
|
||||
{
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
/* This memory_flag is from memory instead of data segment */
|
||||
uint8 memory_flag;
|
||||
if (module->import_memory_count > 0) {
|
||||
memory_flag =
|
||||
module->import_memories[mem_index].u.memory.flags;
|
||||
}
|
||||
else {
|
||||
memory_flag =
|
||||
module
|
||||
->memories[mem_index - module->import_memory_count]
|
||||
.flags;
|
||||
}
|
||||
mem_offset_type = memory_flag & MEMORY64_FLAG ? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#else
|
||||
mem_offset_type = VALUE_TYPE_I32;
|
||||
#endif /* WASM_ENABLE_MEMORY64 */
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
if (!is_passive)
|
||||
#endif
|
||||
if (!load_init_expr(module, &p, p_end, &init_expr,
|
||||
VALUE_TYPE_I32, error_buf, error_buf_size))
|
||||
mem_offset_type, error_buf, error_buf_size))
|
||||
return false;
|
||||
|
||||
read_leb_uint32(p, p_end, data_seg_len);
|
||||
|
@ -2485,8 +2567,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
*buf_func = NULL, *buf_func_end = NULL;
|
||||
WASMGlobal *aux_data_end_global = NULL, *aux_heap_base_global = NULL;
|
||||
WASMGlobal *aux_stack_top_global = NULL, *global;
|
||||
uint64 aux_data_end = (uint64)-1, aux_heap_base = (uint64)-1,
|
||||
aux_stack_top = (uint64)-1;
|
||||
uint64 aux_data_end = (uint64)-1LL, aux_heap_base = (uint64)-1LL,
|
||||
aux_stack_top = (uint64)-1LL;
|
||||
uint32 global_index, func_index, i;
|
||||
uint32 aux_data_end_global_index = (uint32)-1;
|
||||
uint32 aux_heap_base_global_index = (uint32)-1;
|
||||
|
@ -2607,7 +2689,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
aux_heap_base_global = global;
|
||||
aux_heap_base = (uint64)(uint32)global->init_expr.u.i32;
|
||||
aux_heap_base_global_index = export->index;
|
||||
LOG_VERBOSE("Found aux __heap_base global, value: %d",
|
||||
LOG_VERBOSE("Found aux __heap_base global, value: %" PRIu64,
|
||||
aux_heap_base);
|
||||
}
|
||||
}
|
||||
|
@ -2620,7 +2702,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
aux_data_end_global = global;
|
||||
aux_data_end = (uint64)(uint32)global->init_expr.u.i32;
|
||||
aux_data_end_global_index = export->index;
|
||||
LOG_VERBOSE("Found aux __data_end global, value: %d",
|
||||
LOG_VERBOSE("Found aux __data_end global, value: %" PRIu64,
|
||||
aux_data_end);
|
||||
aux_data_end = align_uint64(aux_data_end, 16);
|
||||
}
|
||||
|
@ -2669,7 +2751,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
aux_stack_top > aux_data_end
|
||||
? (uint32)(aux_stack_top - aux_data_end)
|
||||
: (uint32)aux_stack_top;
|
||||
LOG_VERBOSE("Found aux stack top global, value: %d, "
|
||||
LOG_VERBOSE(
|
||||
"Found aux stack top global, value: %" PRIu64 ", "
|
||||
"global index: %d, stack size: %d",
|
||||
aux_stack_top, global_index,
|
||||
module->aux_stack_size);
|
||||
|
@ -2819,7 +2902,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
/* Reset memory info to decrease memory usage */
|
||||
memory_import->num_bytes_per_page = shrunk_memory_size;
|
||||
memory_import->init_page_count = 1;
|
||||
LOG_VERBOSE("Shrink import memory size to %d",
|
||||
LOG_VERBOSE("Shrink import memory size to %" PRIu64,
|
||||
shrunk_memory_size);
|
||||
}
|
||||
}
|
||||
|
@ -2832,7 +2915,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
/* Reset memory info to decrease memory usage */
|
||||
memory->num_bytes_per_page = shrunk_memory_size;
|
||||
memory->init_page_count = 1;
|
||||
LOG_VERBOSE("Shrink memory size to %d",
|
||||
LOG_VERBOSE("Shrink memory size to %" PRIu64,
|
||||
shrunk_memory_size);
|
||||
}
|
||||
}
|
||||
|
@ -2911,7 +2994,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
}
|
||||
|
||||
static WASMModule *
|
||||
create_module(char *error_buf, uint32 error_buf_size)
|
||||
create_module(char *name, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *module =
|
||||
loader_malloc(sizeof(WASMModule), error_buf, error_buf_size);
|
||||
|
@ -2926,7 +3009,7 @@ create_module(char *error_buf, uint32 error_buf_size)
|
|||
/* Set start_function to -1, means no start function */
|
||||
module->start_function = (uint32)-1;
|
||||
|
||||
module->name = "";
|
||||
module->name = name;
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
module->br_table_cache_list = &module->br_table_cache_list_head;
|
||||
|
@ -2952,7 +3035,7 @@ WASMModule *
|
|||
wasm_loader_load_from_sections(WASMSection *section_list, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *module = create_module(error_buf, error_buf_size);
|
||||
WASMModule *module = create_module("", error_buf, error_buf_size);
|
||||
if (!module)
|
||||
return NULL;
|
||||
|
||||
|
@ -3123,10 +3206,10 @@ load(const uint8 *buf, uint32 size, WASMModule *module, char *error_buf,
|
|||
}
|
||||
|
||||
WASMModule *
|
||||
wasm_loader_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
wasm_loader_load(uint8 *buf, uint32 size, const LoadArgs *args, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *module = create_module(error_buf, error_buf_size);
|
||||
WASMModule *module = create_module(args->name, error_buf, error_buf_size);
|
||||
if (!module) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3533,7 +3616,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case WASM_OP_I64_STORE16:
|
||||
case WASM_OP_I64_STORE32:
|
||||
skip_leb_uint32(p, p_end); /* align */
|
||||
skip_leb_uint32(p, p_end); /* offset */
|
||||
skip_leb_mem_offset(p, p_end); /* offset */
|
||||
break;
|
||||
|
||||
case WASM_OP_MEMORY_SIZE:
|
||||
|
@ -3748,6 +3831,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
case WASM_OP_ATOMIC_PREFIX:
|
||||
{
|
||||
/* TODO: memory64 offset type changes */
|
||||
uint32 opcode1;
|
||||
|
||||
/* atomic_op (u32_leb) + memarg (2 u32_leb) */
|
||||
|
@ -3758,7 +3842,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
|
||||
if (opcode != WASM_OP_ATOMIC_FENCE) {
|
||||
skip_leb_uint32(p, p_end); /* align */
|
||||
skip_leb_uint32(p, p_end); /* offset */
|
||||
skip_leb_mem_offset(p, p_end); /* offset */
|
||||
}
|
||||
else {
|
||||
/* atomic.fence doesn't have memarg */
|
||||
|
@ -4260,9 +4344,9 @@ wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf,
|
|||
wasm_loader_emit_ptr(loader_ctx, NULL); \
|
||||
} while (0)
|
||||
|
||||
#define emit_br_info(frame_csp) \
|
||||
#define emit_br_info(frame_csp, is_br) \
|
||||
do { \
|
||||
if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, error_buf, \
|
||||
if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, is_br, error_buf, \
|
||||
error_buf_size)) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
@ -4649,7 +4733,7 @@ apply_label_patch(WASMLoaderContext *ctx, uint8 depth, uint8 patch_type)
|
|||
|
||||
static bool
|
||||
wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
bool is_br, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
/* br info layout:
|
||||
* a) arity of target block
|
||||
|
@ -4698,6 +4782,8 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
|
|||
/* Part e */
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (is_br)
|
||||
ctx->dynamic_offset = dynamic_offset;
|
||||
for (i = (int32)arity - 1; i >= 0; i--) {
|
||||
cell = (uint8)wasm_value_type_cell_num(types[i]);
|
||||
dynamic_offset -= cell;
|
||||
|
@ -5073,6 +5159,11 @@ fail:
|
|||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define PUSH_MEM_OFFSET() PUSH_OFFSET_TYPE(mem_offset_type)
|
||||
#define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET()
|
||||
|
||||
#define POP_MEM_OFFSET() POP_OFFSET_TYPE(mem_offset_type)
|
||||
|
||||
#define POP_AND_PUSH(type_pop, type_push) \
|
||||
do { \
|
||||
if (!(wasm_loader_push_pop_frame_ref_offset( \
|
||||
|
@ -5127,6 +5218,15 @@ fail:
|
|||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define PUSH_MEM_OFFSET() \
|
||||
do { \
|
||||
if (!(wasm_loader_push_frame_ref(loader_ctx, mem_offset_type, \
|
||||
error_buf, error_buf_size))) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET()
|
||||
|
||||
#define POP_I32() \
|
||||
do { \
|
||||
if (!(wasm_loader_pop_frame_ref(loader_ctx, VALUE_TYPE_I32, error_buf, \
|
||||
|
@ -5162,6 +5262,13 @@ fail:
|
|||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define POP_MEM_OFFSET() \
|
||||
do { \
|
||||
if (!(wasm_loader_pop_frame_ref(loader_ctx, mem_offset_type, \
|
||||
error_buf, error_buf_size))) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define POP_AND_PUSH(type_pop, type_push) \
|
||||
do { \
|
||||
if (!(wasm_loader_push_pop_frame_ref(loader_ctx, 1, type_push, \
|
||||
|
@ -5382,8 +5489,8 @@ fail:
|
|||
} while (0)
|
||||
|
||||
static bool
|
||||
wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
|
||||
bool is_br_table, char *error_buf, uint32 error_buf_size)
|
||||
wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, uint8 opcode,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
BranchBlock *target_block, *cur_block;
|
||||
BlockType *target_block_type;
|
||||
|
@ -5441,7 +5548,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
|
|||
/* Backup stack data since it may be changed in the below
|
||||
push operations, and the stack data may be used when
|
||||
checking other target blocks of opcode br_table */
|
||||
if (is_br_table) {
|
||||
if (opcode == WASM_OP_BR_TABLE) {
|
||||
uint64 total_size;
|
||||
|
||||
frame_ref_after_popped = loader_ctx->frame_ref;
|
||||
|
@ -5479,13 +5586,13 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
|
|||
}
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_br_info(target_block);
|
||||
emit_br_info(target_block, opcode == WASM_OP_BR);
|
||||
#endif
|
||||
|
||||
/* Restore the stack data, note that frame_ref_bottom,
|
||||
frame_reftype_map_bottom, frame_offset_bottom may be
|
||||
re-allocated in the above push operations */
|
||||
if (is_br_table) {
|
||||
if (opcode == WASM_OP_BR_TABLE) {
|
||||
uint32 total_size;
|
||||
|
||||
/* The stack operand num should not be smaller than before
|
||||
|
@ -5529,7 +5636,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
|
|||
}
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_br_info(target_block);
|
||||
emit_br_info(target_block, opcode == WASM_OP_BR);
|
||||
#endif
|
||||
|
||||
ret = true;
|
||||
|
@ -5540,7 +5647,7 @@ fail:
|
|||
wasm_runtime_free(frame_ref_buf);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
if (frame_offset_buf && frame_offset_buf != frame_offset_tmp)
|
||||
wasm_runtime_free(frame_offset_tmp);
|
||||
wasm_runtime_free(frame_offset_buf);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
@ -5548,14 +5655,14 @@ fail:
|
|||
|
||||
static BranchBlock *
|
||||
check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
|
||||
bool is_br_table, char *error_buf, uint32 error_buf_size)
|
||||
uint8 opcode, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint8 *p = *p_buf, *p_end = buf_end;
|
||||
BranchBlock *frame_csp_tmp;
|
||||
uint32 depth;
|
||||
|
||||
read_leb_uint32(p, p_end, depth);
|
||||
if (!wasm_loader_check_br(loader_ctx, depth, is_br_table, error_buf,
|
||||
if (!wasm_loader_check_br(loader_ctx, depth, opcode, error_buf,
|
||||
error_buf_size)) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -5772,10 +5879,11 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
|||
{
|
||||
uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org;
|
||||
uint32 param_count, local_count, global_count;
|
||||
uint8 *param_types, *local_types, local_type, global_type;
|
||||
uint8 *param_types, *local_types, local_type, global_type, mem_offset_type;
|
||||
BlockType func_block_type;
|
||||
uint16 *local_offsets, local_offset;
|
||||
uint32 count, local_idx, global_idx, u32, align, mem_offset, i;
|
||||
uint32 count, local_idx, global_idx, u32, align, i;
|
||||
mem_offset_t mem_offset;
|
||||
int32 i32, i32_const = 0;
|
||||
int64 i64_const;
|
||||
uint8 opcode, u8;
|
||||
|
@ -5797,6 +5905,19 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
|||
LOG_OP("\nProcessing func | [%d] params | [%d] locals | [%d] return\n",
|
||||
func->param_cell_num, func->local_cell_num, func->ret_cell_num);
|
||||
#endif
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
bool is_memory64 = false;
|
||||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
if (module->import_memory_count > 0)
|
||||
is_memory64 = module->import_memories[0].u.memory.flags & MEMORY64_FLAG;
|
||||
else if (module->memory_count > 0)
|
||||
is_memory64 = module->memories[0].flags & MEMORY64_FLAG;
|
||||
|
||||
mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32;
|
||||
#else
|
||||
mem_offset_type = VALUE_TYPE_I32;
|
||||
#endif
|
||||
|
||||
global_count = module->import_global_count + module->global_count;
|
||||
|
||||
|
@ -6105,8 +6226,8 @@ re_scan:
|
|||
bh_memcpy_s(loader_ctx->frame_offset, size,
|
||||
block->param_frame_offsets, size);
|
||||
loader_ctx->frame_offset += (size / sizeof(int16));
|
||||
loader_ctx->dynamic_offset = block->start_dynamic_offset;
|
||||
}
|
||||
loader_ctx->dynamic_offset = block->start_dynamic_offset;
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
@ -6179,7 +6300,7 @@ re_scan:
|
|||
case WASM_OP_BR:
|
||||
{
|
||||
if (!(frame_csp_tmp =
|
||||
check_branch_block(loader_ctx, &p, p_end, false,
|
||||
check_branch_block(loader_ctx, &p, p_end, opcode,
|
||||
error_buf, error_buf_size)))
|
||||
goto fail;
|
||||
|
||||
|
@ -6193,7 +6314,7 @@ re_scan:
|
|||
POP_I32();
|
||||
|
||||
if (!(frame_csp_tmp =
|
||||
check_branch_block(loader_ctx, &p, p_end, false,
|
||||
check_branch_block(loader_ctx, &p, p_end, opcode,
|
||||
error_buf, error_buf_size)))
|
||||
goto fail;
|
||||
|
||||
|
@ -6223,7 +6344,7 @@ re_scan:
|
|||
#endif
|
||||
for (i = 0; i <= count; i++) {
|
||||
if (!(frame_csp_tmp =
|
||||
check_branch_block(loader_ctx, &p, p_end, true,
|
||||
check_branch_block(loader_ctx, &p, p_end, opcode,
|
||||
error_buf, error_buf_size)))
|
||||
goto fail;
|
||||
|
||||
|
@ -7106,7 +7227,7 @@ re_scan:
|
|||
#endif
|
||||
CHECK_MEMORY();
|
||||
read_leb_uint32(p, p_end, align); /* align */
|
||||
read_leb_uint32(p, p_end, mem_offset); /* offset */
|
||||
read_leb_mem_offset(p, p_end, mem_offset); /* offset */
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, mem_offset);
|
||||
#endif
|
||||
|
@ -7120,7 +7241,7 @@ re_scan:
|
|||
case WASM_OP_I32_LOAD8_U:
|
||||
case WASM_OP_I32_LOAD16_S:
|
||||
case WASM_OP_I32_LOAD16_U:
|
||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||
POP_AND_PUSH(mem_offset_type, VALUE_TYPE_I32);
|
||||
break;
|
||||
case WASM_OP_I64_LOAD:
|
||||
case WASM_OP_I64_LOAD8_S:
|
||||
|
@ -7129,35 +7250,35 @@ re_scan:
|
|||
case WASM_OP_I64_LOAD16_U:
|
||||
case WASM_OP_I64_LOAD32_S:
|
||||
case WASM_OP_I64_LOAD32_U:
|
||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I64);
|
||||
POP_AND_PUSH(mem_offset_type, VALUE_TYPE_I64);
|
||||
break;
|
||||
case WASM_OP_F32_LOAD:
|
||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F32);
|
||||
POP_AND_PUSH(mem_offset_type, VALUE_TYPE_F32);
|
||||
break;
|
||||
case WASM_OP_F64_LOAD:
|
||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F64);
|
||||
POP_AND_PUSH(mem_offset_type, VALUE_TYPE_F64);
|
||||
break;
|
||||
/* store */
|
||||
case WASM_OP_I32_STORE:
|
||||
case WASM_OP_I32_STORE8:
|
||||
case WASM_OP_I32_STORE16:
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
break;
|
||||
case WASM_OP_I64_STORE:
|
||||
case WASM_OP_I64_STORE8:
|
||||
case WASM_OP_I64_STORE16:
|
||||
case WASM_OP_I64_STORE32:
|
||||
POP_I64();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
break;
|
||||
case WASM_OP_F32_STORE:
|
||||
POP_F32();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
break;
|
||||
case WASM_OP_F64_STORE:
|
||||
POP_F64();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -7170,7 +7291,7 @@ re_scan:
|
|||
/* reserved byte 0x00 */
|
||||
bh_assert(*p == 0x00);
|
||||
p++;
|
||||
PUSH_I32();
|
||||
PUSH_PAGE_COUNT();
|
||||
|
||||
module->possible_memory_grow = true;
|
||||
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||
|
@ -7183,7 +7304,7 @@ re_scan:
|
|||
/* reserved byte 0x00 */
|
||||
bh_assert(*p == 0x00);
|
||||
p++;
|
||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||
POP_AND_PUSH(mem_offset_type, mem_offset_type);
|
||||
|
||||
module->possible_memory_grow = true;
|
||||
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
|
||||
|
@ -7230,6 +7351,7 @@ re_scan:
|
|||
break;
|
||||
|
||||
case WASM_OP_F32_CONST:
|
||||
CHECK_BUF(p, p_end, sizeof(float32));
|
||||
p += sizeof(float32);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
skip_label();
|
||||
|
@ -7248,6 +7370,7 @@ re_scan:
|
|||
break;
|
||||
|
||||
case WASM_OP_F64_CONST:
|
||||
CHECK_BUF(p, p_end, sizeof(float64));
|
||||
p += sizeof(float64);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
skip_label();
|
||||
|
@ -7534,7 +7657,7 @@ re_scan:
|
|||
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||
func->has_memory_operations = true;
|
||||
#endif
|
||||
|
@ -7555,6 +7678,7 @@ re_scan:
|
|||
}
|
||||
case WASM_OP_MEMORY_COPY:
|
||||
{
|
||||
CHECK_BUF(p, p_end, sizeof(int16));
|
||||
/* both src and dst memory index should be 0 */
|
||||
bh_assert(*(int16 *)p == 0x0000);
|
||||
p += 2;
|
||||
|
@ -7563,9 +7687,9 @@ re_scan:
|
|||
+ module->memory_count
|
||||
> 0);
|
||||
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
POP_MEM_OFFSET();
|
||||
POP_MEM_OFFSET();
|
||||
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||
func->has_memory_operations = true;
|
||||
#endif
|
||||
|
@ -7580,9 +7704,9 @@ re_scan:
|
|||
+ module->memory_count
|
||||
> 0);
|
||||
|
||||
POP_MEM_OFFSET();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||
func->has_memory_operations = true;
|
||||
#endif
|
||||
|
@ -7747,7 +7871,7 @@ re_scan:
|
|||
if (opcode1 != WASM_OP_ATOMIC_FENCE) {
|
||||
CHECK_MEMORY();
|
||||
read_leb_uint32(p, p_end, align); /* align */
|
||||
read_leb_uint32(p, p_end, mem_offset); /* offset */
|
||||
read_leb_mem_offset(p, p_end, mem_offset); /* offset */
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, mem_offset);
|
||||
#endif
|
||||
|
@ -7757,18 +7881,20 @@ re_scan:
|
|||
#endif
|
||||
switch (opcode1) {
|
||||
case WASM_OP_ATOMIC_NOTIFY:
|
||||
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
PUSH_I32();
|
||||
break;
|
||||
case WASM_OP_ATOMIC_WAIT32:
|
||||
POP_I64();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
PUSH_I32();
|
||||
break;
|
||||
case WASM_OP_ATOMIC_WAIT64:
|
||||
POP_I64();
|
||||
POP_I64();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
PUSH_I32();
|
||||
break;
|
||||
case WASM_OP_ATOMIC_FENCE:
|
||||
|
@ -7779,26 +7905,26 @@ re_scan:
|
|||
case WASM_OP_ATOMIC_I32_LOAD:
|
||||
case WASM_OP_ATOMIC_I32_LOAD8_U:
|
||||
case WASM_OP_ATOMIC_I32_LOAD16_U:
|
||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||
POP_AND_PUSH(mem_offset_type, VALUE_TYPE_I32);
|
||||
break;
|
||||
case WASM_OP_ATOMIC_I32_STORE:
|
||||
case WASM_OP_ATOMIC_I32_STORE8:
|
||||
case WASM_OP_ATOMIC_I32_STORE16:
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
break;
|
||||
case WASM_OP_ATOMIC_I64_LOAD:
|
||||
case WASM_OP_ATOMIC_I64_LOAD8_U:
|
||||
case WASM_OP_ATOMIC_I64_LOAD16_U:
|
||||
case WASM_OP_ATOMIC_I64_LOAD32_U:
|
||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I64);
|
||||
POP_AND_PUSH(mem_offset_type, VALUE_TYPE_I64);
|
||||
break;
|
||||
case WASM_OP_ATOMIC_I64_STORE:
|
||||
case WASM_OP_ATOMIC_I64_STORE8:
|
||||
case WASM_OP_ATOMIC_I64_STORE16:
|
||||
case WASM_OP_ATOMIC_I64_STORE32:
|
||||
POP_I64();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
break;
|
||||
case WASM_OP_ATOMIC_RMW_I32_ADD:
|
||||
case WASM_OP_ATOMIC_RMW_I32_ADD8_U:
|
||||
|
@ -7818,7 +7944,9 @@ re_scan:
|
|||
case WASM_OP_ATOMIC_RMW_I32_XCHG:
|
||||
case WASM_OP_ATOMIC_RMW_I32_XCHG8_U:
|
||||
case WASM_OP_ATOMIC_RMW_I32_XCHG16_U:
|
||||
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
PUSH_I32();
|
||||
break;
|
||||
case WASM_OP_ATOMIC_RMW_I64_ADD:
|
||||
case WASM_OP_ATOMIC_RMW_I64_ADD8_U:
|
||||
|
@ -7845,7 +7973,7 @@ re_scan:
|
|||
case WASM_OP_ATOMIC_RMW_I64_XCHG16_U:
|
||||
case WASM_OP_ATOMIC_RMW_I64_XCHG32_U:
|
||||
POP_I64();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
PUSH_I64();
|
||||
break;
|
||||
case WASM_OP_ATOMIC_RMW_I32_CMPXCHG:
|
||||
|
@ -7853,7 +7981,7 @@ re_scan:
|
|||
case WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U:
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
PUSH_I32();
|
||||
break;
|
||||
case WASM_OP_ATOMIC_RMW_I64_CMPXCHG:
|
||||
|
@ -7862,7 +7990,7 @@ re_scan:
|
|||
case WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U:
|
||||
POP_I64();
|
||||
POP_I64();
|
||||
POP_I32();
|
||||
POP_MEM_OFFSET();
|
||||
PUSH_I64();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -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,11 +603,11 @@ 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 = 0xb2 */
|
||||
/* placeholder = 0xb3 */
|
||||
/* placeholder = 0xb4 */
|
||||
SIMD_i32x4_mul = 0xb5,
|
||||
SIMD_i32x4_min_s = 0xb6,
|
||||
|
@ -615,7 +615,7 @@ typedef enum WASMSimdEXTOpcode {
|
|||
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,
|
||||
|
|
|
@ -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,7 +162,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *module = module_inst->module;
|
||||
uint32 inc_page_count, 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;
|
||||
|
@ -171,7 +171,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
|
||||
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) {
|
||||
|
@ -186,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
|
||||
|
@ -195,7 +203,8 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
|
||||
/* If initial memory is the largest size allowed, disallowing insert host
|
||||
* managed heap */
|
||||
if (heap_size > 0 && heap_offset == MAX_LINEAR_MEMORY_SIZE) {
|
||||
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");
|
||||
|
@ -253,8 +262,18 @@ 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;
|
||||
#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 %u", aux_heap_base);
|
||||
}
|
||||
LOG_VERBOSE("Reset __heap_base global to %" PRIu64, aux_heap_base);
|
||||
}
|
||||
else {
|
||||
/* Insert app heap before new page */
|
||||
|
@ -267,30 +286,34 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
}
|
||||
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;
|
||||
}
|
||||
if (max_page_count > DEFAULT_MAX_PAGES)
|
||||
max_page_count = DEFAULT_MAX_PAGES;
|
||||
|
||||
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 <= MAX_LINEAR_MEMORY_SIZE);
|
||||
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");
|
||||
|
@ -1947,7 +1970,8 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
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;
|
||||
|
@ -2305,10 +2329,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,
|
||||
|
@ -2319,23 +2345,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;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (memory->is_memory64) {
|
||||
base_offset =
|
||||
globals[data_seg->base_offset.u.global_index].initial_value.i32;
|
||||
(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 {
|
||||
#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");
|
||||
|
@ -2349,8 +2400,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");
|
||||
|
@ -3311,7 +3368,8 @@ 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;
|
||||
}
|
||||
|
@ -3510,7 +3568,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);
|
||||
|
@ -4295,11 +4353,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;
|
||||
}
|
||||
|
||||
|
@ -4336,6 +4404,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)
|
||||
{
|
||||
|
@ -4541,8 +4625,8 @@ wasm_set_module_name(WASMModule *module, const char *name, char *error_buf,
|
|||
return false;
|
||||
|
||||
module->name =
|
||||
wasm_const_str_list_insert((const uint8 *)name, strlen(name), module,
|
||||
false, error_buf, error_buf_size);
|
||||
wasm_const_str_list_insert((const uint8 *)name, (uint32)strlen(name),
|
||||
module, false, error_buf, error_buf_size);
|
||||
return module->name != NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ struct WASMMemoryInstance {
|
|||
/* Whether the memory is shared */
|
||||
uint8 is_shared_memory;
|
||||
|
||||
/* TODO: Memory64 whether the memory has 64-bit memory addresses */
|
||||
/* Whether the memory has 64-bit memory addresses */
|
||||
uint8 is_memory64;
|
||||
|
||||
/* Reference count of the memory instance:
|
||||
|
@ -508,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,
|
||||
|
@ -811,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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -1123,7 +1123,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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _BLOCKING_OP_H_
|
||||
#define _BLOCKING_OP_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
|
@ -57,3 +60,5 @@ __wasi_errno_t
|
|||
blocking_op_poll(wasm_exec_env_t exec_env, os_poll_file_handle *pfds, os_nfds_t nfds,
|
||||
int timeout, int *retp);
|
||||
#endif
|
||||
|
||||
#endif /* end of _BLOCKING_OP_H_ */
|
||||
|
|
|
@ -558,6 +558,7 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
|||
aux_stack_size)) {
|
||||
goto fail3;
|
||||
}
|
||||
new_exec_env->is_aux_stack_allocated = true;
|
||||
|
||||
/* Inherit suspend_flags of parent thread */
|
||||
new_exec_env->suspend_flags.flags =
|
||||
|
@ -603,7 +604,9 @@ wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env)
|
|||
exec_env_tls = exec_env;
|
||||
}
|
||||
|
||||
/* Free aux stack space */
|
||||
/* Free aux stack space which was allocated in
|
||||
wasm_cluster_spawn_exec_env */
|
||||
bh_assert(exec_env_tls->is_aux_stack_allocated);
|
||||
wasm_cluster_free_aux_stack(exec_env_tls,
|
||||
(uint64)exec_env->aux_stack_bottom);
|
||||
|
||||
|
@ -655,7 +658,9 @@ thread_manager_start_routine(void *arg)
|
|||
#endif
|
||||
|
||||
/* Free aux stack space */
|
||||
wasm_cluster_free_aux_stack(exec_env, (uint64)exec_env->aux_stack_bottom);
|
||||
if (exec_env->is_aux_stack_allocated)
|
||||
wasm_cluster_free_aux_stack(exec_env,
|
||||
(uint64)exec_env->aux_stack_bottom);
|
||||
|
||||
os_mutex_lock(&cluster_list_lock);
|
||||
|
||||
|
@ -723,11 +728,13 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env,
|
|||
aux_stack_size)) {
|
||||
goto fail2;
|
||||
}
|
||||
new_exec_env->is_aux_stack_allocated = true;
|
||||
}
|
||||
else {
|
||||
/* Disable aux stack */
|
||||
new_exec_env->aux_stack_boundary = 0;
|
||||
new_exec_env->aux_stack_bottom = UINTPTR_MAX;
|
||||
new_exec_env->is_aux_stack_allocated = false;
|
||||
}
|
||||
|
||||
/* Inherit suspend_flags of parent thread */
|
||||
|
@ -1049,7 +1056,9 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
|
|||
#endif
|
||||
|
||||
/* Free aux stack space */
|
||||
wasm_cluster_free_aux_stack(exec_env, (uint64)exec_env->aux_stack_bottom);
|
||||
if (exec_env->is_aux_stack_allocated)
|
||||
wasm_cluster_free_aux_stack(exec_env,
|
||||
(uint64)exec_env->aux_stack_bottom);
|
||||
|
||||
/* App exit the thread, free the resources before exit native thread */
|
||||
|
||||
|
|
|
@ -785,8 +785,8 @@ gc_alloc_wo_internal(void *vheap, gc_size_t size, const char *file, int line)
|
|||
if (!hmu)
|
||||
goto finish;
|
||||
|
||||
/* Do we need to memset the memory to 0? */
|
||||
/* memset((char *)hmu + sizeof(*hmu), 0, tot_size - sizeof(*hmu)); */
|
||||
/* Don't memset the memory to improve performance, the caller should
|
||||
decide whether to memset it or not */
|
||||
|
||||
bh_assert(hmu_get_size(hmu) >= tot_size);
|
||||
/* the total size allocated may be larger than
|
||||
|
|
|
@ -114,8 +114,8 @@ sweep_instance_heap(gc_heap_t *heap)
|
|||
else {
|
||||
/* current block is still live */
|
||||
if (last) {
|
||||
tot_free += (char *)cur - (char *)last;
|
||||
gci_add_fc(heap, last, (char *)cur - (char *)last);
|
||||
tot_free += (gc_size_t)((char *)cur - (char *)last);
|
||||
gci_add_fc(heap, last, (gc_size_t)((char *)cur - (char *)last));
|
||||
hmu_mark_pinuse(last);
|
||||
last = NULL;
|
||||
}
|
||||
|
@ -132,8 +132,8 @@ sweep_instance_heap(gc_heap_t *heap)
|
|||
bh_assert(cur == end);
|
||||
|
||||
if (last) {
|
||||
tot_free += (char *)cur - (char *)last;
|
||||
gci_add_fc(heap, last, (char *)cur - (char *)last);
|
||||
tot_free += (gc_size_t)((char *)cur - (char *)last);
|
||||
gci_add_fc(heap, last, (gc_size_t)((char *)cur - (char *)last));
|
||||
hmu_mark_pinuse(last);
|
||||
}
|
||||
|
||||
|
@ -449,7 +449,9 @@ gci_gc_heap(void *h)
|
|||
|
||||
LOG_VERBOSE("#reclaim instance heap %p", heap);
|
||||
|
||||
gct_vm_gc_prepare();
|
||||
/* TODO: get exec_env of current thread when GC multi-threading
|
||||
is enabled, and pass it to runtime */
|
||||
gct_vm_gc_prepare(NULL);
|
||||
|
||||
gct_vm_mutex_lock(&heap->lock);
|
||||
heap->is_doing_reclaim = 1;
|
||||
|
@ -459,7 +461,9 @@ gci_gc_heap(void *h)
|
|||
heap->is_doing_reclaim = 0;
|
||||
gct_vm_mutex_unlock(&heap->lock);
|
||||
|
||||
gct_vm_gc_finished();
|
||||
/* TODO: get exec_env of current thread when GC multi-threading
|
||||
is enabled, and pass it to runtime */
|
||||
gct_vm_gc_finished(NULL);
|
||||
|
||||
LOG_VERBOSE("#reclaim instance heap %p done", heap);
|
||||
|
||||
|
|
|
@ -77,13 +77,13 @@ mem_allocator_free_with_gc(mem_allocator_t allocator, void *ptr)
|
|||
void
|
||||
mem_allocator_enable_gc_reclaim(mem_allocator_t allocator, void *exec_env)
|
||||
{
|
||||
return gc_enable_gc_reclaim((gc_handle_t)allocator, exec_env);
|
||||
gc_enable_gc_reclaim((gc_handle_t)allocator, exec_env);
|
||||
}
|
||||
#else
|
||||
void
|
||||
mem_allocator_enable_gc_reclaim(mem_allocator_t allocator, void *cluster)
|
||||
{
|
||||
return gc_enable_gc_reclaim((gc_handle_t)allocator, cluster);
|
||||
gc_enable_gc_reclaim((gc_handle_t)allocator, cluster);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -823,7 +823,7 @@ os_fadvise(os_file_handle handle, __wasi_filesize_t offset,
|
|||
|
||||
int ret = posix_fadvise(handle, (off_t)offset, (off_t)length, nadvice);
|
||||
|
||||
if (ret < 0)
|
||||
if (ret != 0)
|
||||
return convert_errno(ret);
|
||||
|
||||
return __WASI_ESUCCESS;
|
||||
|
|
|
@ -65,9 +65,11 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
|||
/* integer overflow */
|
||||
return NULL;
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 == 0
|
||||
if (request_size > 16 * (uint64)UINT32_MAX)
|
||||
/* at most 16 G is allowed */
|
||||
/* at most 64 G is allowed */
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
if (prot & MMAP_PROT_READ)
|
||||
map_prot |= PROT_READ;
|
||||
|
|
|
@ -55,7 +55,24 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
|||
#else
|
||||
uint32_t mem_caps = MALLOC_CAP_8BIT;
|
||||
#endif
|
||||
return heap_caps_malloc(size, mem_caps);
|
||||
void *buf_origin =
|
||||
heap_caps_malloc(size + 4 + sizeof(uintptr_t), mem_caps);
|
||||
if (!buf_origin) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Memory allocation with MALLOC_CAP_SPIRAM or MALLOC_CAP_8BIT will
|
||||
// return 4-byte aligned Reserve extra 4 byte to fixup alignment and
|
||||
// size for the pointer to the originally allocated address
|
||||
void *buf_fixed = buf_origin + sizeof(void *);
|
||||
if ((uintptr_t)buf_fixed & (uintptr_t)0x7) {
|
||||
buf_fixed = (void *)((uintptr_t)(buf_fixed + 4) & (~(uintptr_t)7));
|
||||
}
|
||||
|
||||
uintptr_t *addr_field = buf_fixed - sizeof(uintptr_t);
|
||||
*addr_field = (uintptr_t)buf_origin;
|
||||
|
||||
return buf_fixed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
#include "platform_api_vmcore.h"
|
||||
#include "platform_api_extension.h"
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)) \
|
||||
&& (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0))
|
||||
#define UTIMENSAT_TIMESPEC_POINTER 1
|
||||
#define FUTIMENS_TIMESPEC_POINTER 1
|
||||
#endif
|
||||
|
||||
int
|
||||
bh_platform_init()
|
||||
{
|
||||
|
@ -234,7 +240,13 @@ unlinkat(int fd, const char *path, int flag)
|
|||
}
|
||||
|
||||
int
|
||||
utimensat(int fd, const char *path, const struct timespec ts[2], int flag)
|
||||
utimensat(int fd, const char *path,
|
||||
#if UTIMENSAT_TIMESPEC_POINTER
|
||||
const struct timespec *ts,
|
||||
#else
|
||||
const struct timespec ts[2],
|
||||
#endif
|
||||
int flag)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
|
@ -257,7 +269,13 @@ ftruncate(int fd, off_t length)
|
|||
#endif
|
||||
|
||||
int
|
||||
futimens(int fd, const struct timespec times[2])
|
||||
futimens(int fd,
|
||||
#if FUTIMENS_TIMESPEC_POINTER
|
||||
const struct timespec *times
|
||||
#else
|
||||
const struct timespec times[2]
|
||||
#endif
|
||||
)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
|
|
|
@ -8,6 +8,10 @@ add_definitions(-DBH_PLATFORM_NUTTX)
|
|||
include_directories(${PLATFORM_SHARED_DIR})
|
||||
include_directories(${PLATFORM_SHARED_DIR}/../include)
|
||||
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
|
||||
|
||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
|
||||
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
||||
|
||||
if (WAMR_BUILD_LIBC_WASI EQUAL 1)
|
||||
|
@ -16,6 +20,7 @@ if (WAMR_BUILD_LIBC_WASI EQUAL 1)
|
|||
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||
endif ()
|
||||
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE} ${PLATFORM_COMMON_MEMORY_SOURCE})
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE} ${PLATFORM_COMMON_POSIX_SOURCE} ${UNCOMMON_SHARED_SOURCE})
|
||||
# remove posix_memmap.c for NuttX
|
||||
list(REMOVE_ITEM ${PLATFORM_SHARED_SOURCE} ${PLATFORM_COMMON_POSIX_DIR}/posix_memmap.c)
|
||||
|
||||
|
|
|
@ -578,3 +578,33 @@ os_thread_get_stack_boundary()
|
|||
void
|
||||
os_thread_jit_write_protect_np(bool enabled)
|
||||
{}
|
||||
|
||||
int
|
||||
os_thread_detach(korp_tid thread)
|
||||
{
|
||||
(void)thread;
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
void
|
||||
os_thread_exit(void *retval)
|
||||
{
|
||||
(void)retval;
|
||||
os_thread_cleanup();
|
||||
k_thread_abort(k_current_get());
|
||||
}
|
||||
|
||||
int
|
||||
os_cond_broadcast(korp_cond *cond)
|
||||
{
|
||||
os_thread_wait_node *node;
|
||||
k_mutex_lock(&cond->wait_list_lock, K_FOREVER);
|
||||
node = cond->thread_wait_list;
|
||||
while (node) {
|
||||
os_thread_wait_node *next = node->next;
|
||||
k_sem_give(&node->sem);
|
||||
node = next;
|
||||
}
|
||||
k_mutex_unlock(&cond->wait_list_lock);
|
||||
return BHT_OK;
|
||||
}
|
||||
|
|
|
@ -394,7 +394,7 @@ handle_expired_timers(timer_ctx_t ctx, app_timer_t *expired)
|
|||
operation may change expired->next */
|
||||
expired = expired->next;
|
||||
if (t->is_periodic) {
|
||||
/* if it is repeating, then reschedule it; */
|
||||
/* if it is repeating, then reschedule it */
|
||||
reschedule_timer(ctx, t);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -76,6 +76,11 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
|
|||
#### **Enable bulk memory feature**
|
||||
- **WAMR_BUILD_BULK_MEMORY**=1/0, default to disable if not set
|
||||
|
||||
#### **Enable memory64 feature**
|
||||
- **WAMR_BUILD_MEMORY64**=1/0, default to disable if not set
|
||||
|
||||
> Note: Currently, the memory64 feature is only supported in classic interpreter running mode.
|
||||
|
||||
#### **Enable thread manager**
|
||||
- **WAMR_BUILD_THREAD_MGR**=1/0, default to disable if not set
|
||||
|
||||
|
@ -129,6 +134,14 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
|
|||
- **WAMR_BUILD_SIMD**=1/0, default to enable if not set
|
||||
> Note: only supported in AOT mode x86-64 target.
|
||||
|
||||
#### **Enable Exception Handling**
|
||||
- **WAMR_BUILD_EXCE_HANDLING**=1/0, default to disable if not set
|
||||
|
||||
> Note: Currently, the exception handling feature is only supported in classic interpreter running mode.
|
||||
|
||||
#### **Enable Garbage Collection**
|
||||
- **WAMR_BUILD_GC**=1/0, default to disable if not set
|
||||
|
||||
#### **Configure Debug**
|
||||
|
||||
- **WAMR_BUILD_CUSTOM_NAME_SECTION**=1/0, load the function name from custom name section, default to disable if not set
|
||||
|
@ -241,6 +254,10 @@ Currently we only profile the memory consumption of module, module_instance and
|
|||
|
||||
> See [Enable segue optimization for wamrc when generating the aot file](./perf_tune.md#3-enable-segue-optimization-for-wamrc-when-generating-the-aot-file) for more details.
|
||||
|
||||
#### **User defined linear memory allocator**
|
||||
- **WAMR_BUILD_ALLOC_WITH_USAGE**=1/0, default to disable if not set
|
||||
> Notes: by default, the linear memory is allocated by system. when it's set to 1 and Alloc_With_Allocator is selected, it will be allocated by customer.
|
||||
|
||||
#### **Enable running PGO(Profile-Guided Optimization) instrumented AOT file**
|
||||
- **WAMR_BUILD_STATIC_PGO**=1/0, default to disable if not set
|
||||
> Note: See [Use the AOT static PGO method](./perf_tune.md#5-use-the-aot-static-pgo-method) for more details.
|
||||
|
@ -264,6 +281,10 @@ Currently we only profile the memory consumption of module, module_instance and
|
|||
- **WAMR_BUILD_QUICK_AOT_ENTRY**=1/0, enable registering quick call entries to speedup the aot/jit func call process, default to enable if not set
|
||||
> Note: See [Refine callings to AOT/JIT functions from host native](./perf_tune.md#83-refine-callings-to-aotjit-functions-from-host-native) for more details.
|
||||
|
||||
#### **Enable AOT intrinsics**
|
||||
- **WAMR_BUILD_AOT_INTRINSICS**=1/0, enable the AOT intrinsic functions, default to enable if not set. These functions can be called from the AOT code when `--disable-llvm-intrinsics` flag or `--enable-builtin-intrinsics=<intr1,intr2,...>` flag is used by wamrc to generate the AOT file.
|
||||
> Note: See [Tuning the XIP intrinsic functions](./xip.md#tuning-the-xip-intrinsic-functions) for more details.
|
||||
|
||||
#### **Configurale memory access boundary check**
|
||||
- **WAMR_CONFIGUABLE_BOUNDS_CHECKS**=1/0, default to disable if not set
|
||||
> Note: If it is enabled, allow to run `iwasm --disable-bounds-checks` to disable the memory access boundary checks for interpreter mode.
|
||||
|
|
15
idf_component.yml
Normal file
15
idf_component.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
version: "2.0.0"
|
||||
description: WebAssembly Micro Runtime - A lightweight standalone WebAssembly (Wasm) runtime with small footprint, high performance and highly configurable features
|
||||
url: https://bytecodealliance.org/
|
||||
repository: https://github.com/bytecodealliance/wasm-micro-runtime.git
|
||||
documentation: https://wamr.gitbook.io/
|
||||
issues: https://github.com/bytecodealliance/wasm-micro-runtime/issues
|
||||
dependencies:
|
||||
idf: ">=4.4"
|
||||
targets:
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c6
|
||||
examples:
|
||||
- path: product-mini/platforms/esp-idf
|
|
@ -6,7 +6,4 @@ cmake_minimum_required(VERSION 3.5)
|
|||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
set (COMPONENTS ${IDF_TARGET} main freertos esptool_py wamr)
|
||||
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{WAMR_PATH}/build-scripts/esp-idf")
|
||||
|
||||
project(wamr-simple)
|
|
@ -2,5 +2,4 @@
|
|||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
idf_component_register(SRCS "main.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES wamr)
|
||||
INCLUDE_DIRS ".")
|
||||
|
|
7
product-mini/platforms/esp-idf/main/idf_component.yml
Normal file
7
product-mini/platforms/esp-idf/main/idf_component.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
wasm-micro-runtime:
|
||||
version: "^2"
|
||||
override_path: "../../../.."
|
||||
idf:
|
||||
version: ">=4.4"
|
|
@ -12,11 +12,7 @@
|
|||
|
||||
#include "esp_log.h"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
||||
#define IWASM_MAIN_STACK_SIZE 5120
|
||||
#else
|
||||
#define IWASM_MAIN_STACK_SIZE 4096
|
||||
#endif
|
||||
|
||||
#define LOG_TAG "wamr"
|
||||
|
||||
|
|
203
product-mini/platforms/nuttx/CMakeLists.txt
Normal file
203
product-mini/platforms/nuttx/CMakeLists.txt
Normal file
|
@ -0,0 +1,203 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
# select platform configuration setting WAMR_BUILD_TARGET
|
||||
set(WAMR_BUILD_PLATFORM nuttx)
|
||||
|
||||
if(CONFIG_ARCH_ARMV6M)
|
||||
set(WAMR_BUILD_TARGET THUMBV6M)
|
||||
elseif(CONFIG_ARCH_ARMV7A)
|
||||
set(WAMR_BUILD_TARGET THUMBV7)
|
||||
elseif(CONFIG_ARCH_ARMV7M)
|
||||
set(WAMR_BUILD_TARGET THUMBV7EM)
|
||||
elseif(CONFIG_ARCH_ARMV8M)
|
||||
set(WAMR_BUILD_TARGET THUMBV8M)
|
||||
elseif(CONFIG_ARCH_X86)
|
||||
set(WAMR_BUILD_TARGET X86_32)
|
||||
elseif(CONFIG_ARCH_X86_64)
|
||||
set(WAMR_BUILD_TARGET X86_64)
|
||||
elseif(CONFIG_ARCH_XTENSA)
|
||||
set(WAMR_BUILD_TARGET XTENSA)
|
||||
elseif(CONFIG_ARCH_RV64GC OR CONFIG_ARCH_RV64)
|
||||
set(WAMR_BUILD_TARGET RISCV64)
|
||||
elseif(CONFIG_ARCH_RV32IM OR CONFIG_ARCH_RV32)
|
||||
set(WAMR_BUILD_TARGET RISCV32)
|
||||
elseif(CONFIG_ARCH_SIM)
|
||||
if(CONFIG_SIM_M32 OR CONFIG_HOST_X86)
|
||||
set(WAMR_BUILD_TARGET X86_32)
|
||||
elseif(CONFIG_HOST_ARM)
|
||||
set(WAMR_BUILD_TARGET ARM)
|
||||
elseif(CONFIG_HOST_ARM64)
|
||||
set(WAMR_BUILD_TARGET AARCH64)
|
||||
else()
|
||||
set(WAMR_BUILD_TARGET X86_64)
|
||||
endif()
|
||||
if(CONFIG_HOST_MACOS)
|
||||
add_definitions(-DBH_PLATFORM_DARWIN)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_LOG)
|
||||
add_definitions(-DWASM_ENABLE_LOG=1)
|
||||
else()
|
||||
add_definitions(-DWASM_ENABLE_LOG=0)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_AOT_WORD_ALIGN_READ)
|
||||
add_definitions(-DWASM_ENABLE_WORD_ALIGN_READ=1)
|
||||
else()
|
||||
add_definitions(-DWASM_ENABLE_WORD_ALIGN_READ=0)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_STACK_GUARD_SIZE)
|
||||
add_definitions(-DWASM_STACK_GUARD_SIZE=0)
|
||||
else()
|
||||
add_definitions(
|
||||
-DWASM_STACK_GUARD_SIZE=${CONFIG_INTERPRETERS_WAMR_STACK_GUARD_SIZE})
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_MEMORY_TRACING)
|
||||
add_definitions(-DWASM_ENABLE_MEMORY_TRACING=1)
|
||||
else()
|
||||
add_definitions(-DWASM_ENABLE_MEMORY_TRACING=0)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_SHARED_MEMORY)
|
||||
set(WAMR_BUILD_SHARED_MEMORY 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_BULK_MEMORY)
|
||||
set(WAMR_BUILD_BULK_MEMORY 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_AOT_STACK_FRAME)
|
||||
set(WAMR_BUILD_AOT_STACK_FRAME 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_PERF_PROFILING)
|
||||
set(WAMR_BUILD_PERF_PROFILING 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_GC)
|
||||
set(WAMR_BUILD_GC 1)
|
||||
set(WAMR_BUILD_STRINGREF 1)
|
||||
set(WAMR_BUILD_REF_TYPES 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_GC_MANUALLY)
|
||||
add_definitions(-DWASM_GC_MANUALLY=1)
|
||||
else()
|
||||
add_definitions(-DWASM_GC_MANUALLY=0)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_GC_PERF_PROFILING)
|
||||
set(WAMR_BUILD_GC_PERF_PROFILING 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_ENABLE_EXCE_HANDLING)
|
||||
set(WAMR_BUILD_EXCE_HANDLING 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_TAIL_CALL)
|
||||
set(WAMR_BUILD_TAIL_CALL 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_MEMORY_PROFILING)
|
||||
set(WAMR_BUILD_MEMORY_PROFILING 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_MULTI_MODULE)
|
||||
set(WAMR_BUILD_MULTI_MODULE 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_LIB_PTHREAD_SEMAPHORE)
|
||||
set(WAMR_BUILD_LIB_PTHREAD_SEMAPHORE 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_DISABLE_HW_BOUND_CHECK)
|
||||
set(WAMR_DISABLE_HW_BOUND_CHECK 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_CUSTOM_NAME_SECTIONS)
|
||||
set(WAMR_BUILD_CUSTOM_NAME_SECTION 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_GLOBAL_HEAP_POOL)
|
||||
set(WAMR_BUILD_GLOBAL_HEAP_POOL 1)
|
||||
math(EXPR _HEAP_SIZE_
|
||||
"${CONFIG_INTERPRETERS_WAMR_GLOBAL_HEAP_POOL_SIZE} * 1024")
|
||||
set(WAMR_BUILD_GLOBAL_HEAP_SIZE ${_HEAP_SIZE_})
|
||||
endif()
|
||||
|
||||
if (CONFIG_INTERPRETERS_WAMR_MEM_ALLOC_WITH_USAGE)
|
||||
set(WAMR_BUILD_MEM_ALLOC_WITH_USAGE 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST)
|
||||
set(WAMR_BUILD_SPEC_TEST 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_REF_TYPES)
|
||||
set(WAMR_BUILD_REF_TYPES 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_CLASSIC)
|
||||
# include iwasm_interp.cmake
|
||||
set(WAMR_BUILD_INTERP 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_FAST)
|
||||
# enable iwasm_interp.cmake
|
||||
set(WAMR_BUILD_FAST_INTERP 1)
|
||||
endif()
|
||||
|
||||
if((CONFIG_INTERPRETERS_WAMR_FAST OR CONFIG_INTERPRETERS_WAMR_CLASSIC)
|
||||
AND CONFIG_INTERPRETERS_WAMR_MINILOADER)
|
||||
# enable iwasm_interp.cmake
|
||||
set(WAMR_BUILD_MINI_LOADER 1)
|
||||
else()
|
||||
set(WAMR_BUILD_MINI_LOADER 0)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_AOT)
|
||||
# include iwasm_aot.cmake
|
||||
set(WAMR_BUILD_AOT 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_DEBUG_INTERP)
|
||||
# include debug_engine.cmake
|
||||
set(WAMR_BUILD_DEBUG_INTERP 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN)
|
||||
# include libc_builtin.cmake
|
||||
set(WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_LIBC_WASI)
|
||||
# include libc_wasi.cmake
|
||||
set(WAMR_BUILD_LIBC_WASI 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_THREAD_MGR)
|
||||
# include thread_mgr.cmake
|
||||
set(WAMR_BUILD_THREAD_MGR 1)
|
||||
endif()
|
||||
|
||||
if(CONFIG_INTERPRETERS_WAMR_LIB_PTHREAD)
|
||||
# include lib_pthread.cmake
|
||||
set(WAMR_BUILD_LIB_PTHREAD 1)
|
||||
endif()
|
||||
|
||||
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..)
|
||||
|
||||
# enable WAMR build system
|
||||
include(${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
|
||||
# NuttX wamr lib complie required: `WAMR_SOURCES` `WAMR_CFLAGS` `WAMR_INCDIRS`
|
||||
# `WAMR_DEFINITIONS`
|
||||
set(WAMR_SOURCES ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
set(WAMR_CFLAGS -Wno-strict-prototypes -Wno-shadow -Wno-unused-variable
|
||||
-Wno-int-conversion -Wno-implicit-function-declaration)
|
||||
get_directory_property(WAMR_INCDIRS INCLUDE_DIRECTORIES)
|
||||
get_directory_property(WAMR_DEFINITIONS COMPILE_DEFINITIONS)
|
|
@ -373,6 +373,11 @@ CFLAGS += -DWASM_ENABLE_GLOBAL_HEAP_POOL=1
|
|||
CFLAGS += -DWASM_GLOBAL_HEAP_SIZE="$(CONFIG_INTERPRETERS_WAMR_GLOBAL_HEAP_POOL_SIZE) * 1024"
|
||||
else
|
||||
CFLAGS += -DWASM_ENABLE_GLOBAL_HEAP_POOL=0
|
||||
ifeq ($(CONFIG_INTERPRETERS_WAMR_MEM_ALLOC_WITH_USAGE),y)
|
||||
CFLAGS += -DWASM_MEM_ALLOC_WITH_USAGE=1
|
||||
else
|
||||
CFLAGS += -DWASM_MEM_ALLOC_WITH_USAGE=0
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST),y)
|
||||
|
|
|
@ -445,6 +445,9 @@ static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
|
|||
#else
|
||||
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
|
||||
|
@ -455,6 +458,9 @@ malloc_func(
|
|||
|
||||
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
|
||||
|
@ -465,6 +471,9 @@ realloc_func(
|
|||
|
||||
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
|
||||
|
@ -675,7 +684,7 @@ main(int argc, char *argv[])
|
|||
#endif
|
||||
#if WASM_ENABLE_GC != 0
|
||||
else if (!strncmp(argv[0], "--gc-heap-size=", 15)) {
|
||||
if (argv[0][21] == '\0')
|
||||
if (argv[0][15] == '\0')
|
||||
return print_help();
|
||||
gc_heap_size = atoi(argv[0] + 15);
|
||||
}
|
||||
|
@ -851,7 +860,8 @@ main(int argc, char *argv[])
|
|||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
init_args.instance_port = instance_port;
|
||||
if (ip_addr)
|
||||
strcpy(init_args.ip_addr, ip_addr);
|
||||
/* ensure that init_args.ip_addr is null terminated */
|
||||
strncpy(init_args.ip_addr, ip_addr, sizeof(init_args.ip_addr) - 1);
|
||||
#endif
|
||||
|
||||
/* initialize runtime environment */
|
||||
|
|
|
@ -464,7 +464,9 @@ main(int argc, char *argv[])
|
|||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
init_args.instance_port = instance_port;
|
||||
if (ip_addr)
|
||||
strcpy(init_args.ip_addr, ip_addr);
|
||||
/* ensure that init_args.ip_addr is null terminated */
|
||||
strncpy_s(init_args.ip_addr, sizeof(init_args.ip_addr) - 1, ip_addr,
|
||||
strlen(ip_addr));
|
||||
#endif
|
||||
|
||||
/* initialize runtime environment */
|
||||
|
|
|
@ -7,6 +7,14 @@ include(CheckPIESupported)
|
|||
|
||||
project(debug_tools_sample)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
find_package(WASISDK REQUIRED)
|
||||
|
||||
option(SOURCE_MAP_DEMO "Enable source map demo" OFF)
|
||||
if (SOURCE_MAP_DEMO)
|
||||
find_package(EMSCRIPTEN 3.1.50 REQUIRED)
|
||||
endif ()
|
||||
|
||||
################ runtime settings ################
|
||||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||
if (APPLE)
|
||||
|
@ -61,7 +69,30 @@ include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
|||
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
|
||||
################ wasm application ################
|
||||
add_subdirectory(wasm-apps)
|
||||
include(ExternalProject)
|
||||
|
||||
# wasm32-wasi
|
||||
ExternalProject_Add(wasm33-wasi
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps"
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps -B build
|
||||
-DWASI_SDK_PREFIX=${WASISDK_HOME}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${WASISDK_TOOLCHAIN}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build build
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
if (EMSCRIPTEN_FOUND)
|
||||
# wasm32-emscripten
|
||||
ExternalProject_Add(wasm32-emscripten
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps"
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps -B build
|
||||
-DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN_TOOLCHAIN}
|
||||
-DCMAKE_VERBOSE_MAKEFILE=On
|
||||
-DSOURCE_MAP_DEMO=On
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build build
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}/emscripten
|
||||
)
|
||||
endif ()
|
||||
|
||||
################ wamr runtime ################
|
||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
|
|
|
@ -63,7 +63,7 @@ The output should be something like:
|
|||
at wasm-micro-runtime/samples/debug-tools/wasm-apps/trap.c:17:12
|
||||
3: main
|
||||
at wasm-micro-runtime/samples/debug-tools/wasm-apps/trap.c:24:5
|
||||
4: <unknown>
|
||||
4: __main_void
|
||||
at unknown:?:?
|
||||
5: _start
|
||||
```
|
||||
|
@ -79,3 +79,55 @@ $ python3 ../../../test-tools/addr2line/addr2line.py \
|
|||
--wasm-file wasm-apps/trap.wasm \
|
||||
call_stack.txt --no-addr
|
||||
```
|
||||
|
||||
#### sourcemap
|
||||
|
||||
This script also supports _sourcemap_ which is produced by [_emscripten_](https://emscripten.org/docs/tools_reference/emcc.html). The _sourcemap_ is used to map the wasm function to the original source file. To use it, add `-gsource-map` option to _emcc_ command line. The output should be a section named "sourceMappingURL" and a separated file named "_.map_.
|
||||
|
||||
If the wasm file is with _sourcemap_, the script will use it to get the source file and line info. It needs an extra command line option `--emsdk` to specify the path of _emsdk_. The script will use _emsymbolizer_ to query the source file and line info.
|
||||
|
||||
````bash
|
||||
$ python3 ../../../test-tools/addr2line/addr2line.py \
|
||||
--wasi-sdk /opt/wasi-sdk \
|
||||
--wabt /opt/wabt \
|
||||
--wasm-file emscripten/wasm-apps/trap.wasm \
|
||||
--emsdk /opt/emsdk \
|
||||
call_stack.from_wasm_w_sourcemap.txt
|
||||
|
||||
The output should be something like:
|
||||
|
||||
```text
|
||||
1: c
|
||||
at ../../../../../wasm-apps/trap.c:5:1
|
||||
2: b
|
||||
at ../../../../../wasm-apps/trap.c:11:12
|
||||
3: a
|
||||
at ../../../../../wasm-apps/trap.c:17:12
|
||||
4: main
|
||||
at ../../../../../wasm-apps/trap.c:24:5
|
||||
5: __main_void
|
||||
at ../../../../../../../../../emsdk/emscripten/system/lib/standalone/__main_void.c:53:10
|
||||
6: _start
|
||||
at ../../../../../../../../../emsdk/emscripten/system/lib/libc/crt1.c:27:3
|
||||
````
|
||||
|
||||
> The script assume the separated map file _.map_ is in the same directory as the wasm file.
|
||||
|
||||
### Another approach
|
||||
|
||||
If the wasm file is with "name" section, it is able to output function name in the stack trace. To achieve that, need to enable `WAMR_BUILD_LOAD_CUSTOM_SECTION` and `WAMR_BUILD_CUSTOM_NAME_SECTION`. If using .aot file, need to add `--emit-custom-sections=name` into wamrc command line options.
|
||||
|
||||
Then the output should be something like
|
||||
|
||||
```text
|
||||
#00: 0x0159 - c
|
||||
#01: 0x01b2 - b
|
||||
#02: 0x0200 - a
|
||||
#03: 0x026b - main
|
||||
#04: 0x236b - __main_void
|
||||
#05: 0x011f - _start
|
||||
|
||||
Exception: unreachable
|
||||
```
|
||||
|
||||
Also, it is able to use _addr2line.py_ to add file and line info to the stack trace.
|
||||
|
|
45
samples/debug-tools/cmake/FindEMSCRIPTEN.cmake
Normal file
45
samples/debug-tools/cmake/FindEMSCRIPTEN.cmake
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(EMSCRIPTEN_HOME
|
||||
NAMES upstream/emscripten
|
||||
PATHS /opt/emsdk
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_PATH
|
||||
NO_CMAKE_SYSTEM_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
find_file(EMSCRIPTEN_VERSION_FILE
|
||||
NAMES emscripten-version.txt
|
||||
PATHS ${EMSCRIPTEN_HOME}/upstream/emscripten
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_PATH
|
||||
NO_CMAKE_SYSTEM_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
file(READ ${EMSCRIPTEN_VERSION_FILE} EMSCRIPTEN_VERSION_FILE_CONTENT)
|
||||
|
||||
string(REGEX
|
||||
MATCH
|
||||
"[0-9]+\.[0-9]+(\.[0-9]+)*"
|
||||
EMSCRIPTEN_VERSION
|
||||
${EMSCRIPTEN_VERSION_FILE_CONTENT}
|
||||
)
|
||||
|
||||
find_package_handle_standard_args(EMSCRIPTEN
|
||||
REQUIRED_VARS EMSCRIPTEN_HOME
|
||||
VERSION_VAR EMSCRIPTEN_VERSION
|
||||
HANDLE_VERSION_RANGE
|
||||
)
|
||||
|
||||
if(EMSCRIPTEN_FOUND)
|
||||
set(EMSCRIPTEN_TOOLCHAIN ${EMSCRIPTEN_HOME}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake)
|
||||
set(EMCC ${EMSCRIPTEN_HOME}/upstream/emscripten/emcc)
|
||||
endif()
|
||||
mark_as_advanced(EMSCRIPTEN_TOOLCHAIN EMCC)
|
27
samples/debug-tools/cmake/FindWAMRC.cmake
Normal file
27
samples/debug-tools/cmake/FindWAMRC.cmake
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(WAMRC_HOME
|
||||
wamr-compiler
|
||||
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../..
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_PATH
|
||||
NO_CMAKE_SYSTEM_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
find_file(WAMRC_BIN
|
||||
wamrc
|
||||
HINTS ${WAMRC_HOME}/wamr-compiler/build
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_PATH
|
||||
NO_CMAKE_SYSTEM_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
find_package_handle_standard_args(WAMRC REQUIRED_VARS WAMRC_BIN)
|
||||
mark_as_advanced(WAMRC_BIN)
|
24
samples/debug-tools/cmake/FindWASISDK.cmake
Normal file
24
samples/debug-tools/cmake/FindWASISDK.cmake
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
file(GLOB WASISDK_SEARCH_PATH "/opt/wasi-sdk-*")
|
||||
find_path(WASISDK_HOME
|
||||
NAMES share/wasi-sysroot
|
||||
PATHS ${WASISDK_SEARCH_PATH}
|
||||
NO_DEFAULT_PATH
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
string(REGEX MATCH [0-9]+\.[0-9]+\.*[0-9]* WASISDK_VERSION ${WASISDK_HOME})
|
||||
|
||||
find_package_handle_standard_args(WASISDK REQUIRED_VARS WASISDK_HOME VERSION_VAR WASISDK_VERSION)
|
||||
|
||||
if(WASISDK_FOUND)
|
||||
set(WASISDK_CC_COMMAND ${WASISDK_HOME}/bin/clang)
|
||||
set(WASISDK_CXX_COMMAND ${WASISDK_HOME}/bin/clang++)
|
||||
set(WASISDK_TOOLCHAIN ${WASISDK_HOME}/share/cmake/wasi-sdk.cmake)
|
||||
set(WASISDK_SYSROOT ${WASISDK_HOME}/share/wasi-sysroot)
|
||||
endif()
|
||||
mark_as_advanced(WASISDK_CC_COMMAND WASISDK_CXX_COMMAND WASISDK_TOOLCHAIN WASISDK_SYSROOT WASISDK_HOME)
|
|
@ -1,91 +1,58 @@
|
|||
# Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
if (APPLE)
|
||||
set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
|
||||
set (CMAKE_C_LINK_FLAGS "")
|
||||
set (CMAKE_CXX_LINK_FLAGS "")
|
||||
cmake_minimum_required (VERSION 3.14)
|
||||
|
||||
project (debut_tools_wasm)
|
||||
|
||||
set (CMAKE_BUILD_TYPE Debug) # Otherwise no debug symbols (addr2line)
|
||||
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../cmake)
|
||||
find_package (WAMRC REQUIRED)
|
||||
|
||||
option(SOURCE_MAP_DEMO "Enable source map demo" OFF)
|
||||
if (SOURCE_MAP_DEMO)
|
||||
find_package(EMSCRIPTEN 3.1.50 REQUIRED)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WASI_SDK_DIR)
|
||||
set (WASI_SDK_DIR "/opt/wasi-sdk")
|
||||
endif ()
|
||||
|
||||
if (DEFINED WASI_SYSROOT)
|
||||
set (CMAKE_SYSROOT "${WASI_SYSROOT}")
|
||||
endif ()
|
||||
|
||||
set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang")
|
||||
set (CMAKE_ASM_COMPILER "${WASI_SDK_DIR}/bin/clang")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "-target wasm32-wasi")
|
||||
|
||||
################ wabt and wamrc dependencies ################
|
||||
message(CHECK_START "Detecting WABT")
|
||||
if(NOT (DEFINED WABT_DIR OR DEFINED CACHE{WABT_DIR}))
|
||||
find_path(WABT_DIR
|
||||
wabt
|
||||
PATHS /opt
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
if(DEFINED WABT_DIR)
|
||||
set(WABT_DIR ${WABT_DIR}/wabt)
|
||||
endif()
|
||||
endif()
|
||||
if(WABT_DIR)
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(CHECK_FAIL "not found")
|
||||
endif()
|
||||
|
||||
message(CHECK_START "Detecting WASM_OBJDUMP at ${WABT_DIR}")
|
||||
find_program(WASM_OBJDUMP
|
||||
wasm-objdump
|
||||
PATHS "${WABT_DIR}/bin"
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
if(WASM_OBJDUMP)
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(CHECK_FAIL "not found")
|
||||
endif()
|
||||
if((NOT EXISTS ${WASM_OBJDUMP}) )
|
||||
message(FATAL_ERROR "Please make sure to have wasm-objdump under the path=${WABT_DIR}/bin ")
|
||||
endif()
|
||||
|
||||
set(WAMR_COMPILER_DIR ${CMAKE_CURRENT_LIST_DIR}/../../wamr-compiler/build)
|
||||
message(CHECK_START "Detecting WAMR_COMPILER at ${WAMR_COMPILER_DIR}")
|
||||
find_file(WAMR_COMPILER
|
||||
wamrc
|
||||
PATHS "${CMAKE_CURRENT_LIST_DIR}/../../../wamr-compiler/build"
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
if(WAMR_COMPILER)
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(CHECK_FAIL "not found")
|
||||
endif()
|
||||
if((NOT EXISTS ${WAMR_COMPILER}) )
|
||||
message(FATAL_ERROR "Please build wamrc under the path=${WAMR_ROOT_DIR}/wamr-compiler/")
|
||||
endif()
|
||||
|
||||
################ wasm and aot compilation ################
|
||||
function (compile_sample SOURCE_FILE)
|
||||
get_filename_component (FILE_NAME ${SOURCE_FILE} NAME_WLE)
|
||||
set (WASM_MODULE ${FILE_NAME}.wasm)
|
||||
add_executable (${WASM_MODULE} ${SOURCE_FILE})
|
||||
|
||||
add_custom_target(
|
||||
wasm_to_aot
|
||||
## wasm
|
||||
set (WASM_FILE ${FILE_NAME}.wasm)
|
||||
add_executable (${FILE_NAME} ${SOURCE_FILE})
|
||||
set_target_properties (${FILE_NAME} PROPERTIES SUFFIX .wasm)
|
||||
|
||||
## aot
|
||||
set (AOT_FILE ${FILE_NAME}.aot)
|
||||
add_custom_target (
|
||||
${FILE_NAME}_aot
|
||||
ALL
|
||||
DEPENDS ${WAMR_COMPILER} ${WASM_MODULE}
|
||||
DEPENDS ${WAMRC_BIN} ${WASM_FILE}
|
||||
# Use --enable-dump-call-stack to generate stack trace (addr2line)
|
||||
COMMAND ${WAMR_COMPILER} --size-level=0 --enable-dump-call-stack -o wasm-apps/trap.aot wasm-apps/trap.wasm
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND ${WAMRC_BIN} --size-level=0 --enable-dump-call-stack -o ${AOT_FILE} ${WASM_FILE}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
## wasm + sourcemap
|
||||
if (DEFINED EMSCRIPTEN)
|
||||
add_custom_target(
|
||||
${FILE_NAME}_w_sourcemap
|
||||
ALL
|
||||
DEPENDS ${SOURCE_FILE}
|
||||
COMMAND ${EMCC} -O0 -gsource-map -o ${FILE_NAME}.sourcemap.wasm ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
endif ()
|
||||
|
||||
## install both
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${WASM_FILE} DESTINATION wasm-apps)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${AOT_FILE} DESTINATION wasm-apps)
|
||||
if (DEFINED EMSCRIPTEN)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.sourcemap.wasm DESTINATION wasm-apps)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.sourcemap.wasm.map DESTINATION wasm-apps)
|
||||
endif ()
|
||||
endfunction ()
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug) # Otherwise no debug symbols (addr2line)
|
||||
compile_sample(trap.c)
|
63
samples/linux-perf/CMakeLists.txt
Normal file
63
samples/linux-perf/CMakeLists.txt
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required (VERSION 3.14)
|
||||
|
||||
project(linux_perf_sample)
|
||||
|
||||
if(NOT CMAKE_HOST_LINUX)
|
||||
message(FATAL_ERROR "This sample only works on linux")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
find_package(WASISDK REQUIRED)
|
||||
|
||||
################ runtime settings ################
|
||||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||
include(CheckPIESupported)
|
||||
|
||||
# AOT and JIT byd default
|
||||
set(WAMR_BUILD_AOT 1)
|
||||
set(WAMR_BUILD_INTERP 0)
|
||||
set(WAMR_BUILD_JIT 1)
|
||||
# wasm32-wasi
|
||||
set(WAMR_BUILD_LIBC_BUILTIN 0)
|
||||
set(WAMR_BUILD_LIBC_WASI 1)
|
||||
# mvp
|
||||
set(WAMR_BUILD_BULK_MEMORY 1)
|
||||
set(WAMR_BUILD_REF_TYPES 1)
|
||||
set(WAMR_BUILD_SIMD 1)
|
||||
set(WAMR_BUILD_TAIL_CALL 1)
|
||||
# trap information
|
||||
set(WAMR_BUILD_DUMP_CALL_STACK 1)
|
||||
# linux perf
|
||||
set(WAMR_BUILD_LINUX_PERF 1)
|
||||
#
|
||||
#set(WAMR_BUILD_THREAD_MGR 0)
|
||||
|
||||
# vmlib
|
||||
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
include(${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
add_library(vmlib SHARED ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
target_include_directories(vmlib INTERFACE ${WAMR_ROOT_DIR}/core/iwasm/include)
|
||||
target_link_libraries (vmlib ${LLVM_AVAILABLE_LIBS} -lm -ldl)
|
||||
|
||||
################ host ################
|
||||
add_executable(${PROJECT_NAME} host/demo.c)
|
||||
target_link_libraries(${PROJECT_NAME} vmlib)
|
||||
|
||||
################ aot + wasm ################
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(wasm
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wasm"
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/wasm -B build
|
||||
-DCMAKE_TOOLCHAIN_FILE=${WASISDK_TOOLCHAIN}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build build
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
90
samples/linux-perf/README.md
Normal file
90
samples/linux-perf/README.md
Normal file
|
@ -0,0 +1,90 @@
|
|||
# linux perf sample introduction
|
||||
|
||||
This is a sample to show how to use the Linux perf tool to profile the execution of a WebAssembly application. And how to use the [Flamegraph](https://www.brendangregg.com/flamegraphs.html) tool to visualize the profiling result.
|
||||
|
||||
## Build and run the sample
|
||||
|
||||
There are two Wasm modules and their instance will be created and run in the sample. [The first module](./wasm/fib.c) is a simple Wasm module that calculates the Fibonacci number. [The second module](./wasm/ackermann.c) is a simple Wasm module that execute the Ackermann function. The target is enable to profile the execution of both two modules separately.
|
||||
|
||||
```bash
|
||||
$ cmake -S . -B build
|
||||
$ cmake --build build
|
||||
```
|
||||
|
||||
### Profile the execution
|
||||
|
||||
```bash
|
||||
$ cd build
|
||||
$ perf record -k mono -g --output=perf.data -- ./linux_perf_sample
|
||||
```
|
||||
|
||||
Enable to use `perf report --stdio` to do a quick analysis of the profiling result.
|
||||
|
||||
### Visualize the profiling result
|
||||
|
||||
Need to download Flamegraph tool from [Flamegraph](https://github.com/brendangregg/FlameGraph/releases/tag/v1.0) firstly.
|
||||
|
||||
```bash
|
||||
$ perf script > out.perf
|
||||
$ ./FlameGraph/stackcollapse-perf.pl out.perf > out.folded
|
||||
$ ./FlameGraph/flamegraph.pl out.folded > perf.svg
|
||||
```
|
||||
|
||||
In this result, you'll see two modules's profiling result and all wasm functions are named as "aot_func#N" which is a little hard to distinguish.
|
||||
|
||||

|
||||
|
||||
### Separate profiling result
|
||||
|
||||
[process_folded_data.py](../../test-tools/flame-graph-helper/process_folded_data.py) is a script can a) translate "aot_func#N" into its original function name in name sections, b) separate the profiling result of different modules.
|
||||
|
||||
In this sample, we want to separate `fib` and `ackermann` profiling data from _out.folded_. In [demo](host/demo.c), we decide to name the module of `fib1.wasm` as `fib2` and the module of `ackermann1.wasm` as `ackermann2`.
|
||||
|
||||
```bash
|
||||
$ python process_folded_data.py --wabt_home /opt/wabt --wasm_names fib2=./fib1.wasm,ackermann2=./ackermann1.wasm out.folded
|
||||
-> write into out.fib2.translated
|
||||
-> write into out.ackermann2.translated
|
||||
-> write into out.translated
|
||||
```
|
||||
|
||||
More scenarios:
|
||||
|
||||
if only using one wasm during profiling, the script can be used like this:
|
||||
|
||||
```bash
|
||||
$ python process_folded_data.py --wabt_home /opt/wabt --wasm <wasm_file> --folded <folded_file>
|
||||
```
|
||||
|
||||
if only using one wasm during profiling and specify the module name via APIs, the script can be used like this:
|
||||
|
||||
```bash
|
||||
$ python process_folded_data.py --wabt_home /opt/wabt --wasm_names <module name>=<wasm_file> --folded <folded_file>
|
||||
```
|
||||
|
||||
if only using one wasm during profiling and specify the module name, which is same with the basename of wasm file, via APIs, the script can be used like this:
|
||||
|
||||
```bash
|
||||
$ python process_folded_data.py --wabt_home /opt/wabt --wasm <wasm_file> --folded <folded_file>
|
||||
```
|
||||
|
||||
if using multiple wasm during profiling and specify module names, which are same with basename of wasm files, via APIs, the script can be used like this:
|
||||
|
||||
```bash
|
||||
$ python process_folded_data.py --wabt_home /opt/wabt --wasm <wasm_file> --wasm <wasm_file> --wasm <wasm_file> --folded <folded_file>
|
||||
```
|
||||
|
||||
if using multiple wasm during profiling and specify module names via APIs, the script can be used like this:
|
||||
|
||||
```bash
|
||||
$ python process_folded_data.py --wabt_home /opt/wabt --wasm_names <module_name>=<wasm_file>,<module_name>=<wasm_file>,<module_name>=<wasm_file> --folded <folded_file>
|
||||
```
|
||||
|
||||
Now we have two flame-graphs for two wasm modules:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Reference
|
||||
|
||||
- [perf_tune](../../doc/perf_tune.md)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user