mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-07-15 16:58:34 +00:00
Merge branch 'main' into feature/user_classified_mem_mng
This commit is contained in:
commit
acce5b74b4
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
|
#!/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 update
|
||||||
|
|
||||||
sudo apt install -y build-essential cmake g++-multilib libgcc-11-dev lib32gcc-11-dev ccache ninja-build ccache
|
sudo apt install -y build-essential cmake g++-multilib libgcc-11-dev lib32gcc-11-dev ccache ninja-build ccache
|
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():
|
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)
|
p = subprocess.run(shlex.split(list_tag_cmd), capture_output=True, check=True)
|
||||||
|
|
||||||
all_tags = p.stdout.decode().strip()
|
all_tags = p.stdout.decode().strip()
|
||||||
|
|
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
|
- name: install utils macos
|
||||||
if: steps.lldb_build_cache.outputs.cache-hit != 'true' && contains(inputs.runner, 'macos')
|
if: steps.lldb_build_cache.outputs.cache-hit != 'true' && contains(inputs.runner, 'macos')
|
||||||
run: |
|
run: |
|
||||||
brew remove swig
|
brew install swig cmake ninja libedit
|
||||||
brew install swig@4.1 cmake ninja libedit
|
|
||||||
brew link --overwrite swig@4.1
|
|
||||||
sudo rm -rf /Library/Developer/CommandLineTools
|
sudo rm -rf /Library/Developer/CommandLineTools
|
||||||
|
|
||||||
- name: install utils ubuntu
|
- 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 rm ${basename}
|
||||||
sudo mv wasi-sdk-* wasi-sdk
|
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
|
- name: generate wamr-sdk release
|
||||||
run: |
|
run: |
|
||||||
cd ./wamr-app-framework/wamr-sdk
|
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
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Use Node.js 16.x
|
- name: Use Node.js 16.x
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 16.x
|
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.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
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.
|
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||||
|
|
||||||
- run: |
|
- run: |
|
||||||
./.github/workflows/codeql_buildscript.sh
|
./.github/scripts/codeql_buildscript.sh
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
with:
|
with:
|
||||||
category: "/language:${{matrix.language}}"
|
category: "/language:${{matrix.language}}"
|
||||||
upload: false
|
upload: false
|
||||||
|
@ -95,14 +95,14 @@ jobs:
|
||||||
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
|
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
|
||||||
|
|
||||||
- name: Upload CodeQL results to code scanning
|
- name: Upload CodeQL results to code scanning
|
||||||
uses: github/codeql-action/upload-sarif@v2
|
uses: github/codeql-action/upload-sarif@v3
|
||||||
with:
|
with:
|
||||||
sarif_file: ${{ steps.step1.outputs.sarif-output }}
|
sarif_file: ${{ steps.step1.outputs.sarif-output }}
|
||||||
category: "/language:${{matrix.language}}"
|
category: "/language:${{matrix.language}}"
|
||||||
|
|
||||||
- name: Upload CodeQL results as an artifact
|
- name: Upload CodeQL results as an artifact
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: codeql-results
|
name: codeql-results
|
||||||
path: ${{ steps.step1.outputs.sarif-output }}
|
path: ${{ steps.step1.outputs.sarif-output }}
|
||||||
|
@ -110,5 +110,8 @@ jobs:
|
||||||
|
|
||||||
- name: Fail if an error is found
|
- name: Fail if an error is found
|
||||||
run: |
|
run: |
|
||||||
./.github/workflows/codeql_fail_on_error.py \
|
./.github/scripts/codeql_fail_on_error.py \
|
||||||
${{ steps.step1.outputs.sarif-output }}/cpp.sarif
|
${{ 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)
|
|
|
@ -389,14 +389,14 @@ jobs:
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wasi_sdk_release }}
|
sudo wget ${{ matrix.wasi_sdk_release }}
|
||||||
sudo tar -xzf wasi-sdk-*.tar.gz
|
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
|
- name: download and install wabt
|
||||||
run: |
|
run: |
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wabt_release }}
|
sudo wget ${{ matrix.wabt_release }}
|
||||||
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
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
|
- name: Get LLVM libraries
|
||||||
id: retrieve_llvm_libs
|
id: retrieve_llvm_libs
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
|
4
.github/workflows/compilation_on_macos.yml
vendored
4
.github/workflows/compilation_on_macos.yml
vendored
|
@ -273,14 +273,14 @@ jobs:
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wasi_sdk_release }}
|
sudo wget ${{ matrix.wasi_sdk_release }}
|
||||||
sudo tar -xzf wasi-sdk-*.tar.gz
|
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
|
- name: download and install wabt
|
||||||
run: |
|
run: |
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wabt_release }}
|
sudo wget ${{ matrix.wabt_release }}
|
||||||
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
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]
|
- name: Build Sample [basic]
|
||||||
run: |
|
run: |
|
||||||
|
|
18
.github/workflows/create_tag.yml
vendored
18
.github/workflows/create_tag.yml
vendored
|
@ -32,8 +32,22 @@ jobs:
|
||||||
- name: prepare
|
- name: prepare
|
||||||
id: preparation
|
id: preparation
|
||||||
run: |
|
run: |
|
||||||
# show latest 3 versions
|
# show latest 3 versions on the branch that create release
|
||||||
git tag --list WAMR-*.*.* --sort=committerdate --format="%(refname:short)" | tail -n 3
|
# 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
|
# compare latest git tag and semantic version definition
|
||||||
result=$(python3 ./.github/scripts/fetch_and_compare_version.py)
|
result=$(python3 ./.github/scripts/fetch_and_compare_version.py)
|
||||||
echo "script result is ${result}"
|
echo "script result is ${result}"
|
||||||
|
|
4
.github/workflows/nightly_run.yml
vendored
4
.github/workflows/nightly_run.yml
vendored
|
@ -459,13 +459,13 @@ jobs:
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wasi_sdk_release }}
|
sudo wget ${{ matrix.wasi_sdk_release }}
|
||||||
sudo tar -xzf wasi-sdk-*.tar.gz
|
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
|
- name: download and install wabt
|
||||||
run: |
|
run: |
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wabt_release }}
|
sudo wget ${{ matrix.wabt_release }}
|
||||||
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
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
|
- name: Get LLVM libraries
|
||||||
id: retrieve_llvm_libs
|
id: retrieve_llvm_libs
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
|
|
||||||
cmake_minimum_required (VERSION 3.0)
|
cmake_minimum_required (VERSION 3.0)
|
||||||
|
|
||||||
|
if(ESP_PLATFORM)
|
||||||
|
include (${COMPONENT_DIR}/build-scripts/esp-idf/wamr/CMakeLists.txt)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
project (iwasm)
|
project (iwasm)
|
||||||
|
|
||||||
set (CMAKE_VERBOSE_MAKEFILE OFF)
|
set (CMAKE_VERBOSE_MAKEFILE OFF)
|
||||||
|
|
|
@ -67,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)
|
- [Port WAMR to a new platform](./doc/port_wamr.md)
|
||||||
- [VS Code development container](./doc/devcontainer.md)
|
- [VS Code development container](./doc/devcontainer.md)
|
||||||
- [Samples](./samples) and [Benchmarks](./tests/benchmarks)
|
- [Samples](./samples) and [Benchmarks](./tests/benchmarks)
|
||||||
|
- [End-user APIs documentation](https://bytecodealliance.github.io/wamr.dev/apis/)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,9 @@ endif ()
|
||||||
|
|
||||||
# Sanitizers
|
# Sanitizers
|
||||||
|
|
||||||
|
if (NOT DEFINED WAMR_BUILD_SANITIZER)
|
||||||
set(WAMR_BUILD_SANITIZER $ENV{WAMR_BUILD_SANITIZER})
|
set(WAMR_BUILD_SANITIZER $ENV{WAMR_BUILD_SANITIZER})
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (NOT DEFINED WAMR_BUILD_SANITIZER)
|
if (NOT DEFINED WAMR_BUILD_SANITIZER)
|
||||||
set(WAMR_BUILD_SANITIZER "")
|
set(WAMR_BUILD_SANITIZER "")
|
||||||
|
@ -557,3 +559,6 @@ endif ()
|
||||||
if (WAMR_BUILD_ALLOC_WITH_USAGE EQUAL 1)
|
if (WAMR_BUILD_ALLOC_WITH_USAGE EQUAL 1)
|
||||||
add_definitions(-DWASM_MEM_ALLOC_WITH_USAGE=1)
|
add_definitions(-DWASM_MEM_ALLOC_WITH_USAGE=1)
|
||||||
endif()
|
endif()
|
||||||
|
if (NOT WAMR_BUILD_SANITIZER STREQUAL "")
|
||||||
|
message (" Sanitizer ${WAMR_BUILD_SANITIZER} enabled")
|
||||||
|
endif ()
|
||||||
|
|
|
@ -1526,29 +1526,41 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 WASM_ENABLE_GC != 0
|
||||||
if (types[i]->type_flag == WASM_TYPE_FUNC) {
|
if (type->ref_count > 1) {
|
||||||
AOTFuncType *func_type = (AOTFuncType *)types[i];
|
/* 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) {
|
if (func_type->ref_type_maps != NULL) {
|
||||||
bh_assert(func_type->ref_type_map_count > 0);
|
bh_assert(func_type->ref_type_map_count > 0);
|
||||||
wasm_runtime_free(func_type->ref_type_maps);
|
wasm_runtime_free(func_type->ref_type_maps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (types[i]->type_flag == WASM_TYPE_STRUCT) {
|
else if (type->type_flag == WASM_TYPE_STRUCT) {
|
||||||
AOTStructType *struct_type = (AOTStructType *)types[i];
|
AOTStructType *struct_type = (AOTStructType *)type;
|
||||||
if (struct_type->ref_type_maps != NULL) {
|
if (struct_type->ref_type_maps != NULL) {
|
||||||
bh_assert(struct_type->ref_type_map_count > 0);
|
bh_assert(struct_type->ref_type_map_count > 0);
|
||||||
wasm_runtime_free(struct_type->ref_type_maps);
|
wasm_runtime_free(struct_type->ref_type_maps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
wasm_runtime_free(types);
|
||||||
|
@ -1556,14 +1568,17 @@ destroy_types(AOTType **types, uint32 count)
|
||||||
|
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
static void
|
static void
|
||||||
init_base_type(AOTType *base_type, uint16 type_flag, bool is_sub_final,
|
init_base_type(AOTType *base_type, uint32 type_idx, uint16 type_flag,
|
||||||
uint32 parent_type_idx, uint16 rec_count, uint16 rec_idx)
|
bool is_sub_final, uint32 parent_type_idx, uint16 rec_count,
|
||||||
|
uint16 rec_idx)
|
||||||
{
|
{
|
||||||
base_type->type_flag = type_flag;
|
base_type->type_flag = type_flag;
|
||||||
|
base_type->ref_count = 1;
|
||||||
base_type->is_sub_final = is_sub_final;
|
base_type->is_sub_final = is_sub_final;
|
||||||
base_type->parent_type_idx = parent_type_idx;
|
base_type->parent_type_idx = parent_type_idx;
|
||||||
base_type->rec_count = rec_count;
|
base_type->rec_count = rec_count;
|
||||||
base_type->rec_idx = rec_idx;
|
base_type->rec_idx = rec_idx;
|
||||||
|
base_type->rec_begin_type_idx = type_idx - rec_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -1576,7 +1591,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
uint32 i, j;
|
uint32 i, j;
|
||||||
uint32 type_flag, param_cell_num, ret_cell_num;
|
uint32 type_flag, param_cell_num, ret_cell_num;
|
||||||
uint16 param_count, result_count, ref_type_map_count, rec_count, rec_idx;
|
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;
|
uint32 parent_type_idx;
|
||||||
WASMRefType ref_type;
|
WASMRefType ref_type;
|
||||||
|
|
||||||
|
@ -1590,12 +1605,31 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
|
|
||||||
/* Create each type */
|
/* Create each type */
|
||||||
for (i = 0; i < module->type_count; i++) {
|
for (i = 0; i < module->type_count; i++) {
|
||||||
|
|
||||||
buf = align_ptr(buf, 4);
|
buf = align_ptr(buf, 4);
|
||||||
|
|
||||||
/* Read base type info */
|
/* Read base type info */
|
||||||
read_uint16(buf, buf_end, type_flag);
|
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_uint32(buf, buf_end, parent_type_idx);
|
||||||
read_uint16(buf, buf_end, rec_count);
|
read_uint16(buf, buf_end, rec_count);
|
||||||
read_uint16(buf, buf_end, rec_idx);
|
read_uint16(buf, buf_end, rec_idx);
|
||||||
|
@ -1620,7 +1654,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
|
|
||||||
types[i] = (AOTType *)func_type;
|
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);
|
parent_type_idx, rec_count, rec_idx);
|
||||||
func_type->param_count = param_count;
|
func_type->param_count = param_count;
|
||||||
func_type->result_count = result_count;
|
func_type->result_count = result_count;
|
||||||
|
@ -1726,7 +1760,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
offset = (uint32)offsetof(WASMStructObject, field_data);
|
offset = (uint32)offsetof(WASMStructObject, field_data);
|
||||||
types[i] = (AOTType *)struct_type;
|
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);
|
parent_type_idx, rec_count, rec_idx);
|
||||||
struct_type->field_count = field_count;
|
struct_type->field_count = field_count;
|
||||||
struct_type->ref_type_map_count = ref_type_map_count;
|
struct_type->ref_type_map_count = ref_type_map_count;
|
||||||
|
@ -1812,7 +1846,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
|
|
||||||
types[i] = (AOTType *)array_type;
|
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);
|
parent_type_idx, rec_count, rec_idx);
|
||||||
read_uint16(buf, buf_end, array_type->elem_flags);
|
read_uint16(buf, buf_end, array_type->elem_flags);
|
||||||
read_uint8(buf, buf_end, array_type->elem_type);
|
read_uint8(buf, buf_end, array_type->elem_type);
|
||||||
|
@ -1841,7 +1875,6 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
if (rec_count == 0) {
|
if (rec_count == 0) {
|
||||||
bh_assert(rec_idx == 0);
|
bh_assert(rec_idx == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = i - rec_idx; j <= i; j++) {
|
for (j = i - rec_idx; j <= i; j++) {
|
||||||
AOTType *cur_type = module->types[j];
|
AOTType *cur_type = module->types[j];
|
||||||
parent_type_idx = cur_type->parent_type_idx;
|
parent_type_idx = cur_type->parent_type_idx;
|
||||||
|
@ -1850,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]->parent_type = parent_type;
|
||||||
module->types[j]->root_type = parent_type->root_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 =
|
module->types[j]->inherit_depth =
|
||||||
parent_type->inherit_depth + 1;
|
parent_type->inherit_depth + 1;
|
||||||
}
|
}
|
||||||
|
@ -1867,7 +1905,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
AOTType *parent_type = module->types[parent_type_idx];
|
AOTType *parent_type = module->types[parent_type_idx];
|
||||||
/* subtyping has been checked during compilation */
|
/* subtyping has been checked during compilation */
|
||||||
bh_assert(wasm_type_is_subtype_of(
|
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;
|
(void)parent_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,7 @@ typedef struct {
|
||||||
REG_SYM(aot_array_init_with_data), \
|
REG_SYM(aot_array_init_with_data), \
|
||||||
REG_SYM(aot_create_func_obj), \
|
REG_SYM(aot_create_func_obj), \
|
||||||
REG_SYM(aot_obj_is_instance_of), \
|
REG_SYM(aot_obj_is_instance_of), \
|
||||||
|
REG_SYM(aot_func_type_is_super_of), \
|
||||||
REG_SYM(aot_rtt_type_new), \
|
REG_SYM(aot_rtt_type_new), \
|
||||||
REG_SYM(wasm_array_obj_copy), \
|
REG_SYM(wasm_array_obj_copy), \
|
||||||
REG_SYM(wasm_array_obj_new), \
|
REG_SYM(wasm_array_obj_new), \
|
||||||
|
|
|
@ -1721,6 +1721,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
|
||||||
|
|
||||||
bh_assert(table_init_data);
|
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];
|
table = module_inst->tables[table_init_data->table_index];
|
||||||
bh_assert(table);
|
bh_assert(table);
|
||||||
|
|
||||||
|
@ -1728,8 +1729,9 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
|
||||||
bh_assert(table_data);
|
bh_assert(table_data);
|
||||||
|
|
||||||
wasm_runtime_get_table_inst_elem_type(
|
wasm_runtime_get_table_inst_elem_type(
|
||||||
(WASMModuleInstanceCommon *)module_inst, i, &tbl_elem_type,
|
(WASMModuleInstanceCommon *)module_inst,
|
||||||
&tbl_elem_ref_type, &tbl_init_size, &tbl_max_size);
|
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)
|
if (!wasm_elem_is_declarative(table_init_data->mode)
|
||||||
&& !wasm_reftype_is_subtype_of(
|
&& !wasm_reftype_is_subtype_of(
|
||||||
|
@ -3366,39 +3368,49 @@ aot_table_fill(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 length,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx,
|
aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 inc_size,
|
||||||
uint32 inc_entries, table_elem_type_t init_val)
|
table_elem_type_t init_val)
|
||||||
{
|
{
|
||||||
uint32 entry_count, i, orig_tbl_sz;
|
|
||||||
AOTTableInstance *tbl_inst;
|
AOTTableInstance *tbl_inst;
|
||||||
|
uint32 i, orig_size, total_size;
|
||||||
|
|
||||||
tbl_inst = module_inst->tables[tbl_idx];
|
tbl_inst = module_inst->tables[tbl_idx];
|
||||||
if (!tbl_inst) {
|
if (!tbl_inst) {
|
||||||
return (uint32)-1;
|
return (uint32)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
orig_tbl_sz = tbl_inst->cur_size;
|
orig_size = tbl_inst->cur_size;
|
||||||
|
|
||||||
if (!inc_entries) {
|
if (!inc_size) {
|
||||||
return orig_tbl_sz;
|
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;
|
return (uint32)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_count = tbl_inst->cur_size + inc_entries;
|
total_size = tbl_inst->cur_size + inc_size;
|
||||||
if (entry_count > tbl_inst->max_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;
|
return (uint32)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill in */
|
/* 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->elems[tbl_inst->cur_size + i] = init_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbl_inst->cur_size = entry_count;
|
tbl_inst->cur_size = total_size;
|
||||||
return orig_tbl_sz;
|
return orig_size;
|
||||||
}
|
}
|
||||||
#endif /* WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
|
#endif /* WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
|
||||||
|
|
||||||
|
@ -4477,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);
|
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
|
WASMRttTypeRef
|
||||||
aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index)
|
aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -752,6 +752,11 @@ bool
|
||||||
aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
|
aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
|
||||||
uint32 type_index);
|
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
|
WASMRttTypeRef
|
||||||
aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index);
|
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
|
#endif
|
||||||
#if WASM_ENABLE_AOT != 0
|
#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
|
#endif
|
||||||
|
|
||||||
bh_assert(types);
|
bh_assert(types);
|
||||||
|
|
|
@ -250,6 +250,51 @@ wasm_value_types_is_subtype_of(const uint8 *types1,
|
||||||
return true;
|
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
|
bool
|
||||||
wasm_func_type_equal(const WASMFuncType *type1, const WASMFuncType *type2,
|
wasm_func_type_equal(const WASMFuncType *type1, const WASMFuncType *type2,
|
||||||
const WASMTypePtr *types, uint32 type_count)
|
const WASMTypePtr *types, uint32 type_count)
|
||||||
|
@ -277,9 +322,11 @@ wasm_func_type_equal(const WASMFuncType *type1, const WASMFuncType *type2,
|
||||||
|
|
||||||
ref_type1 = type1->ref_type_maps[j].ref_type;
|
ref_type1 = type1->ref_type_maps[j].ref_type;
|
||||||
ref_type2 = type2->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,
|
if (!rec_ref_type_equal(
|
||||||
type_count))
|
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;
|
return false;
|
||||||
|
|
||||||
j++;
|
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_type1 = type1->ref_type_maps[j].ref_type;
|
||||||
ref_type2 = type2->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,
|
if (!rec_ref_type_equal(
|
||||||
type_count))
|
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;
|
return false;
|
||||||
|
|
||||||
j++;
|
j++;
|
||||||
|
@ -338,21 +387,67 @@ wasm_array_type_equal(const WASMArrayType *type1, const WASMArrayType *type2,
|
||||||
if (type1->elem_flags != type2->elem_flags)
|
if (type1->elem_flags != type2->elem_flags)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return wasm_reftype_equal(type1->elem_type, type1->elem_ref_type,
|
if (type1->elem_type != type2->elem_type)
|
||||||
type2->elem_type, type2->elem_ref_type, types,
|
return false;
|
||||||
type_count);
|
|
||||||
|
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
|
bool
|
||||||
wasm_type_equal(const WASMType *type1, const WASMType *type2,
|
wasm_type_equal(const WASMType *type1, const WASMType *type2,
|
||||||
const WASMTypePtr *types, uint32 type_count)
|
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)
|
if (type1 == type2)
|
||||||
return true;
|
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;
|
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))
|
if (wasm_type_is_func_type(type1))
|
||||||
return wasm_func_type_equal((WASMFuncType *)type1,
|
return wasm_func_type_equal((WASMFuncType *)type1,
|
||||||
(WASMFuncType *)type2, types, type_count);
|
(WASMFuncType *)type2, types, type_count);
|
||||||
|
@ -653,12 +748,6 @@ wasm_reftype_struct_size(const WASMRefType *ref_type)
|
||||||
return (uint32)sizeof(RefHeapType_Common);
|
return (uint32)sizeof(RefHeapType_Common);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
type_idx_equal(uint32 type_idx1, uint32 type_idx2)
|
|
||||||
{
|
|
||||||
return (type_idx1 == type_idx2) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_refheaptype_equal(const RefHeapType_Common *ref_heap_type1,
|
wasm_refheaptype_equal(const RefHeapType_Common *ref_heap_type1,
|
||||||
const RefHeapType_Common *ref_heap_type2,
|
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 (ref_heap_type1->heap_type != ref_heap_type2->heap_type) {
|
||||||
if (wasm_is_refheaptype_typeidx(ref_heap_type1)
|
if (wasm_is_refheaptype_typeidx(ref_heap_type1)
|
||||||
&& wasm_is_refheaptype_typeidx(ref_heap_type2)) {
|
&& wasm_is_refheaptype_typeidx(ref_heap_type2)) {
|
||||||
return type_idx_equal(ref_heap_type1->heap_type,
|
if (ref_heap_type1->heap_type == ref_heap_type2->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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -835,6 +932,13 @@ wasm_type_is_supers_of(const WASMType *type1, const WASMType *type2)
|
||||||
return false;
|
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
|
bool
|
||||||
wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
|
wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
|
||||||
uint8 type2, const WASMRefType *ref_type2,
|
uint8 type2, const WASMRefType *ref_type2,
|
||||||
|
@ -914,12 +1018,13 @@ wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
|
||||||
#endif
|
#endif
|
||||||
else if (type1 == REF_TYPE_HT_NULLABLE) {
|
else if (type1 == REF_TYPE_HT_NULLABLE) {
|
||||||
if (wasm_is_refheaptype_typeidx(&ref_type1->ref_ht_common)) {
|
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) */
|
/* reftype1 is (ref null $t) */
|
||||||
if (type2 == REF_TYPE_HT_NULLABLE && ref_type2 != NULL
|
if (type2 == REF_TYPE_HT_NULLABLE && ref_type2 != NULL
|
||||||
&& wasm_is_refheaptype_typeidx(&ref_type2->ref_ht_common)) {
|
&& wasm_is_refheaptype_typeidx(&ref_type2->ref_ht_common)) {
|
||||||
return type_idx_equal(ref_type1->ref_ht_typeidx.type_idx,
|
bh_assert((uint32)ref_type2->ref_ht_typeidx.type_idx
|
||||||
ref_type2->ref_ht_typeidx.type_idx)
|
< type_count);
|
||||||
|| wasm_type_is_supers_of(
|
return wasm_type_is_supers_of(
|
||||||
types[ref_type2->ref_ht_typeidx.type_idx],
|
types[ref_type2->ref_ht_typeidx.type_idx],
|
||||||
types[ref_type1->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) {
|
else if (type1 == REF_TYPE_HT_NON_NULLABLE) {
|
||||||
bh_assert(ref_type1);
|
bh_assert(ref_type1);
|
||||||
if (wasm_is_refheaptype_typeidx(&ref_type1->ref_ht_common)) {
|
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) */
|
/* reftype1 is (ref $t) */
|
||||||
if ((type2 == REF_TYPE_HT_NULLABLE
|
if ((type2 == REF_TYPE_HT_NULLABLE
|
||||||
|| type2 == REF_TYPE_HT_NON_NULLABLE)
|
|| type2 == REF_TYPE_HT_NON_NULLABLE)
|
||||||
&& ref_type2 != NULL
|
&& ref_type2 != NULL
|
||||||
&& wasm_is_refheaptype_typeidx(&ref_type2->ref_ht_common)) {
|
&& wasm_is_refheaptype_typeidx(&ref_type2->ref_ht_common)) {
|
||||||
return type_idx_equal(ref_type1->ref_ht_typeidx.type_idx,
|
bh_assert((uint32)ref_type2->ref_ht_typeidx.type_idx
|
||||||
ref_type2->ref_ht_typeidx.type_idx)
|
< type_count);
|
||||||
|| wasm_type_is_supers_of(
|
return wasm_type_is_supers_of(
|
||||||
types[ref_type2->ref_ht_typeidx.type_idx],
|
types[ref_type2->ref_ht_typeidx.type_idx],
|
||||||
types[ref_type1->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 WASMFuncType *type2,
|
||||||
const WASMTypePtr *types, uint32 type_count);
|
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
|
/* Whether func type1's result types are subtype of
|
||||||
func type2's result types */
|
func type2's result types */
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -578,8 +578,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
is_anyref = true;
|
is_anyref = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasm_is_type_multi_byte_type(
|
if (wasm_is_type_multi_byte_type(type->types[i])) {
|
||||||
type->types[type->param_count + i])) {
|
|
||||||
WASMRefType *ref_type = ref_type_map->ref_type;
|
WASMRefType *ref_type = ref_type_map->ref_type;
|
||||||
if (wasm_is_refheaptype_common(
|
if (wasm_is_refheaptype_common(
|
||||||
&ref_type->ref_ht_common)) {
|
&ref_type->ref_ht_common)) {
|
||||||
|
|
|
@ -84,9 +84,9 @@ compare_type_with_signautre(uint8 type, const char signature)
|
||||||
if ('r' == signature
|
if ('r' == signature
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
#if WASM_ENABLE_STRINGREF != 0
|
#if WASM_ENABLE_STRINGREF != 0
|
||||||
&& (type >= REF_TYPE_STRINGVIEWITER && type <= REF_TYPE_FUNCREF)
|
&& (type >= REF_TYPE_STRINGVIEWITER && type <= REF_TYPE_NULLFUNCREF)
|
||||||
#else
|
#else
|
||||||
&& (type >= REF_TYPE_NULLREF && type <= REF_TYPE_FUNCREF)
|
&& (type >= REF_TYPE_HT_NULLABLE && type <= REF_TYPE_NULLFUNCREF)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
&& type == VALUE_TYPE_EXTERNREF
|
&& type == VALUE_TYPE_EXTERNREF
|
||||||
|
|
|
@ -3452,16 +3452,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
break;
|
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_low_i16x8_s:
|
||||||
case SIMD_i32x4_extend_high_i16x8_s:
|
case SIMD_i32x4_extend_high_i16x8_s:
|
||||||
{
|
{
|
||||||
|
@ -3501,16 +3491,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
break;
|
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:
|
case SIMD_i32x4_sub:
|
||||||
{
|
{
|
||||||
if (!aot_compile_simd_i32x4_arith(comp_ctx, func_ctx,
|
if (!aot_compile_simd_i32x4_arith(comp_ctx, func_ctx,
|
||||||
|
@ -3519,16 +3499,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
break;
|
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:
|
case SIMD_i32x4_mul:
|
||||||
{
|
{
|
||||||
if (!aot_compile_simd_i32x4_arith(comp_ctx, func_ctx,
|
if (!aot_compile_simd_i32x4_arith(comp_ctx, func_ctx,
|
||||||
|
@ -3565,13 +3535,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
break;
|
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_low_i16x8_s:
|
||||||
case SIMD_i32x4_extmul_high_i16x8_s:
|
case SIMD_i32x4_extmul_high_i16x8_s:
|
||||||
{
|
{
|
||||||
|
@ -3728,13 +3691,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SIMD_f32x4_round:
|
|
||||||
{
|
|
||||||
if (!aot_compile_simd_f32x4_round(comp_ctx, func_ctx))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SIMD_f32x4_sqrt:
|
case SIMD_f32x4_sqrt:
|
||||||
{
|
{
|
||||||
if (!aot_compile_simd_f32x4_sqrt(comp_ctx, func_ctx))
|
if (!aot_compile_simd_f32x4_sqrt(comp_ctx, func_ctx))
|
||||||
|
@ -3788,13 +3744,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SIMD_f64x2_round:
|
|
||||||
{
|
|
||||||
if (!aot_compile_simd_f64x2_round(comp_ctx, func_ctx))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SIMD_f64x2_sqrt:
|
case SIMD_f64x2_sqrt:
|
||||||
{
|
{
|
||||||
if (!aot_compile_simd_f64x2_sqrt(comp_ctx, func_ctx))
|
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)
|
get_func_type_size(AOTCompContext *comp_ctx, AOTFuncType *func_type)
|
||||||
{
|
{
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
/* type flag + is_sub_final + parent_type_idx + rec_count + rec_idx + param
|
/* type flag + equivalence type flag + is_sub_final + parent_type_idx
|
||||||
* count + result count
|
+ rec_count + rec_idx + param count + result count
|
||||||
* + ref_type_map_count + types + context of ref_type_map */
|
+ ref_type_map_count + types + context of ref_type_map */
|
||||||
if (comp_ctx->enable_gc) {
|
if (comp_ctx->enable_gc) {
|
||||||
uint32 size = 0;
|
uint32 size = 0;
|
||||||
|
|
||||||
/* type flag */
|
/* type flag */
|
||||||
size += sizeof(func_type->base_type.type_flag);
|
size += sizeof(func_type->base_type.type_flag);
|
||||||
/* is_sub_final */
|
/* equivalence type flag + is_sub_final */
|
||||||
size += sizeof(uint16);
|
size += sizeof(uint16);
|
||||||
/* parent_type_idx */
|
/* parent_type_idx */
|
||||||
size += sizeof(func_type->base_type.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)
|
get_struct_type_size(AOTCompContext *comp_ctx, AOTStructType *struct_type)
|
||||||
{
|
{
|
||||||
uint32 size = 0;
|
uint32 size = 0;
|
||||||
/* type flag + is_sub_final + parent_type_idx + rec_count + rec_idx + field
|
/* type flag + equivalence type flag + is_sub_final + parent_type_idx
|
||||||
* count + fields */
|
+ rec_count + rec_idx + field count + fields */
|
||||||
|
|
||||||
/* type flag */
|
/* type flag */
|
||||||
size += sizeof(struct_type->base_type.type_flag);
|
size += sizeof(struct_type->base_type.type_flag);
|
||||||
/* is_sub_final */
|
/* equivalence type flag + is_sub_final */
|
||||||
size += sizeof(uint16);
|
size += sizeof(uint16);
|
||||||
/* parent_type_idx */
|
/* parent_type_idx */
|
||||||
size += sizeof(struct_type->base_type.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)
|
get_array_type_size(AOTCompContext *comp_ctx, AOTArrayType *array_type)
|
||||||
{
|
{
|
||||||
uint32 size = 0;
|
uint32 size = 0;
|
||||||
/* type flag + is_sub_final + parent_type_idx + rec_count + rec_idx +
|
/* type flag + equivalence type flag + is_sub_final + parent_type_idx
|
||||||
elem_flags + elem_type + elem_ref_type */
|
+ rec_count + rec_idx + elem_flags + elem_type + elem_ref_type */
|
||||||
|
|
||||||
/* type flag */
|
/* type flag */
|
||||||
size += sizeof(array_type->base_type.type_flag);
|
size += sizeof(array_type->base_type.type_flag);
|
||||||
/* is_sub_final */
|
/* equivalence type flag + is_sub_final */
|
||||||
size += sizeof(uint16);
|
size += sizeof(uint16);
|
||||||
/* parent_type_idx (u32) */
|
/* parent_type_idx (u32) */
|
||||||
size += sizeof(array_type->base_type.parent_type_idx);
|
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 WASM_ENABLE_GC != 0
|
||||||
if (comp_ctx->enable_gc) {
|
if (comp_ctx->enable_gc) {
|
||||||
for (i = 0; i < comp_data->type_count; i++) {
|
for (i = 0; i < comp_data->type_count; i++) {
|
||||||
|
uint32 j;
|
||||||
|
|
||||||
size = align_uint(size, 4);
|
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)
|
if (comp_data->types[i]->type_flag == WASM_TYPE_FUNC)
|
||||||
size += get_func_type_size(comp_ctx,
|
size += get_func_type_size(comp_ctx,
|
||||||
(AOTFuncType *)comp_data->types[i]);
|
(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 WASM_ENABLE_GC != 0
|
||||||
if (comp_ctx->enable_gc) {
|
if (comp_ctx->enable_gc) {
|
||||||
int32 idx;
|
|
||||||
AOTType **types = comp_data->types;
|
AOTType **types = comp_data->types;
|
||||||
|
int32 idx;
|
||||||
|
uint32 j;
|
||||||
|
|
||||||
for (i = 0; i < comp_data->type_count; i++) {
|
for (i = 0; i < comp_data->type_count; i++) {
|
||||||
offset = align_uint(offset, 4);
|
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]->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_U32(types[i]->parent_type_idx);
|
||||||
|
|
||||||
EMIT_U16(types[i]->rec_count);
|
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) {
|
if (comp_ctx->enable_gc) {
|
||||||
/* emit func_local_ref_flag arrays for both import and AOTed funcs */
|
/* emit func_local_ref_flag arrays for both import and AOTed funcs */
|
||||||
AOTFuncType *func_type;
|
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++) {
|
for (i = 0; i < comp_data->import_func_count; i++) {
|
||||||
func_type = comp_data->import_funcs[i].func_type;
|
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(
|
local_ref_flags_cell_num += wasm_value_type_cell_num_internal(
|
||||||
func_type->types[j], comp_ctx->pointer_size);
|
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 =
|
||||||
local_ref_flags_cell_num > 2 ? local_ref_flags_cell_num : 2;
|
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]))
|
func_type->types[j]))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (; j < 2; j++)
|
for (j = 0; j < paddings; j++)
|
||||||
EMIT_U8(0);
|
EMIT_U8(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1826,6 +1826,52 @@ fail:
|
||||||
return ret;
|
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
|
static bool
|
||||||
call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
AOTFuncType *aot_func_type,
|
AOTFuncType *aot_func_type,
|
||||||
|
@ -2018,15 +2064,23 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!comp_ctx->enable_gc) {
|
||||||
/* Find the equivalent function type whose type index is the smallest:
|
/* Find the equivalent function type whose type index is the smallest:
|
||||||
the callee function's type index is also converted to 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
|
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),
|
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,
|
we don't need to check whether the whole function types are equal,
|
||||||
including param types and result types. */
|
including param types and result types. */
|
||||||
type_idx =
|
type_idx = wasm_get_smallest_type_idx(
|
||||||
wasm_get_smallest_type_idx((WASMTypePtr *)comp_ctx->comp_data->types,
|
(WASMTypePtr *)comp_ctx->comp_data->types,
|
||||||
comp_ctx->comp_data->type_count, type_idx);
|
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);
|
ftype_idx_const = I32_CONST(type_idx);
|
||||||
CHECK_LLVM_CONST(ftype_idx_const);
|
CHECK_LLVM_CONST(ftype_idx_const);
|
||||||
|
|
||||||
|
@ -2254,12 +2308,24 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
goto fail;
|
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 */
|
/* 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"))) {
|
ftype_idx_const, "cmp_ftype_idx"))) {
|
||||||
aot_set_last_error("llvm build icmp failed.");
|
aot_set_last_error("llvm build icmp failed.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Throw exception if ftype_idx != ftype_idx_const */
|
/* Throw exception if ftype_idx != ftype_idx_const */
|
||||||
if (!(check_ftype_idx_succ = LLVMAppendBasicBlockInContext(
|
if (!(check_ftype_idx_succ = LLVMAppendBasicBlockInContext(
|
||||||
|
|
|
@ -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 {
|
enum integer_extend_type {
|
||||||
e_ext_i8x16,
|
e_ext_i8x16,
|
||||||
e_ext_i16x8,
|
e_ext_i16x8,
|
||||||
|
|
|
@ -20,10 +20,6 @@ bool
|
||||||
aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
|
aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
|
||||||
AOTFuncContext *func_ctx, bool is_signed);
|
AOTFuncContext *func_ctx, bool is_signed);
|
||||||
|
|
||||||
bool
|
|
||||||
aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx,
|
|
||||||
AOTFuncContext *func_ctx, bool is_signed);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx,
|
aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx,
|
||||||
AOTFuncContext *func_ctx, bool is_low,
|
AOTFuncContext *func_ctx, bool is_low,
|
||||||
|
|
|
@ -129,20 +129,6 @@ aot_compile_simd_f64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||||
"llvm.fabs.v2f64");
|
"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
|
bool
|
||||||
aot_compile_simd_f32x4_sqrt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
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
|
bool
|
||||||
aot_compile_simd_f64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
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
|
bool
|
||||||
aot_compile_simd_f32x4_sqrt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
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 {
|
enum integer_avgr_u {
|
||||||
e_avgr_u_i8x16,
|
e_avgr_u_i8x16,
|
||||||
e_avgr_u_i16x8,
|
e_avgr_u_i16x8,
|
||||||
e_avgr_u_i32x4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO: try int_x86_mmx_pavg_b and int_x86_mmx_pavg_w */
|
/* 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[] = {
|
LLVMTypeRef vector_type[] = {
|
||||||
V128_i8x16_TYPE,
|
V128_i8x16_TYPE,
|
||||||
V128_i16x8_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,
|
if (!(rhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
|
||||||
vector_type[itype], "rhs"))
|
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);
|
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
|
bool
|
||||||
aot_compile_simd_i32x4_dot_i16x8(AOTCompContext *comp_ctx,
|
aot_compile_simd_i32x4_dot_i16x8(AOTCompContext *comp_ctx,
|
||||||
AOTFuncContext *func_ctx)
|
AOTFuncContext *func_ctx)
|
||||||
|
|
|
@ -76,10 +76,6 @@ bool
|
||||||
aot_compile_simd_i16x8_avgr_u(AOTCompContext *comp_ctx,
|
aot_compile_simd_i16x8_avgr_u(AOTCompContext *comp_ctx,
|
||||||
AOTFuncContext *func_ctx);
|
AOTFuncContext *func_ctx);
|
||||||
|
|
||||||
bool
|
|
||||||
aot_compile_simd_i32x4_avgr_u(AOTCompContext *comp_ctx,
|
|
||||||
AOTFuncContext *func_ctx);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
aot_compile_simd_i32x4_dot_i16x8(AOTCompContext *comp_ctx,
|
aot_compile_simd_i32x4_dot_i16x8(AOTCompContext *comp_ctx,
|
||||||
AOTFuncContext *func_ctx);
|
AOTFuncContext *func_ctx);
|
||||||
|
|
|
@ -64,18 +64,3 @@ aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
|
||||||
is_signed ? intrinsics[arith_op][0]
|
is_signed ? intrinsics[arith_op][0]
|
||||||
: intrinsics[arith_op][1]);
|
: 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,
|
AOTFuncContext *func_ctx,
|
||||||
V128Arithmetic arith_op, bool is_signed);
|
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
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
* 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
|
#ifndef _AOT_EXPORT_H
|
||||||
#define _AOT_EXPORT_H
|
#define _AOT_EXPORT_H
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
* 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
|
#ifndef _GC_EXPORT_H
|
||||||
#define _GC_EXPORT_H
|
#define _GC_EXPORT_H
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file lib_export.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _LIB_EXPORT_H_
|
#ifndef _LIB_EXPORT_H_
|
||||||
#define _LIB_EXPORT_H_
|
#define _LIB_EXPORT_H_
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
// WebAssembly C API
|
// WebAssembly C API
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file wasm_c_api.h
|
||||||
|
*
|
||||||
|
* @brief This file defines the WebAssembly C APIs
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _WASM_C_API_H_
|
#ifndef _WASM_C_API_H_
|
||||||
#define _WASM_C_API_H_
|
#define _WASM_C_API_H_
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
* 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
|
#ifndef _WASM_EXPORT_H
|
||||||
#define _WASM_EXPORT_H
|
#define _WASM_EXPORT_H
|
||||||
|
|
||||||
|
|
|
@ -274,7 +274,7 @@ typedef struct InitializerExpression {
|
||||||
*/
|
*/
|
||||||
typedef struct RefHeapType_TypeIdx {
|
typedef struct RefHeapType_TypeIdx {
|
||||||
/* ref_type is REF_TYPE_HT_NULLABLE or
|
/* 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;
|
uint8 ref_type;
|
||||||
/* true if ref_type is REF_TYPE_HT_NULLABLE */
|
/* true if ref_type is REF_TYPE_HT_NULLABLE */
|
||||||
bool nullable;
|
bool nullable;
|
||||||
|
@ -288,7 +288,7 @@ typedef struct RefHeapType_TypeIdx {
|
||||||
*/
|
*/
|
||||||
typedef struct RefHeapType_Common {
|
typedef struct RefHeapType_Common {
|
||||||
/* ref_type is REF_TYPE_HT_NULLABLE or
|
/* 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;
|
uint8 ref_type;
|
||||||
/* true if ref_type is REF_TYPE_HT_NULLABLE */
|
/* true if ref_type is REF_TYPE_HT_NULLABLE */
|
||||||
bool nullable;
|
bool nullable;
|
||||||
|
@ -338,18 +338,24 @@ typedef struct WASMType {
|
||||||
uint16 type_flag;
|
uint16 type_flag;
|
||||||
|
|
||||||
bool is_sub_final;
|
bool is_sub_final;
|
||||||
|
/* How many types are referring to this type */
|
||||||
|
uint16 ref_count;
|
||||||
/* The inheritance depth */
|
/* The inheritance depth */
|
||||||
uint32 inherit_depth;
|
uint16 inherit_depth;
|
||||||
/* The root type */
|
/* The root type */
|
||||||
struct WASMType *root_type;
|
struct WASMType *root_type;
|
||||||
/* The parent type */
|
/* The parent type */
|
||||||
struct WASMType *parent_type;
|
struct WASMType *parent_type;
|
||||||
uint32 parent_type_idx;
|
uint32 parent_type_idx;
|
||||||
|
|
||||||
/* number of internal types in the current rec group, if the type is not in
|
/* The number of internal types in the current rec group, and if
|
||||||
* a recursive group, rec_count = 0 */
|
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_count;
|
||||||
uint16 rec_idx;
|
uint16 rec_idx;
|
||||||
|
/* The index of the begin type of this group */
|
||||||
|
uint32 rec_begin_type_idx;
|
||||||
} WASMType, *WASMTypePtr;
|
} WASMType, *WASMTypePtr;
|
||||||
#endif /* end of WASM_ENABLE_GC */
|
#endif /* end of WASM_ENABLE_GC */
|
||||||
|
|
||||||
|
@ -375,9 +381,6 @@ typedef struct WASMFuncType {
|
||||||
uint16 ref_type_map_count;
|
uint16 ref_type_map_count;
|
||||||
WASMRefTypeMap *ref_type_maps;
|
WASMRefTypeMap *ref_type_maps;
|
||||||
WASMRefTypeMap *result_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
|
#else
|
||||||
uint16 ref_count;
|
uint16 ref_count;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1509,6 +1509,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
WASMStringviewIterObjectRef stringview_iter_obj;
|
WASMStringviewIterObjectRef stringview_iter_obj;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||||
|
bool is_return_call = false;
|
||||||
|
#endif
|
||||||
#if WASM_ENABLE_MEMORY64 != 0
|
#if WASM_ENABLE_MEMORY64 != 0
|
||||||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||||
* across multi-memories */
|
* across multi-memories */
|
||||||
|
@ -2209,6 +2212,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
WASMFuncType *cur_type, *cur_func_type;
|
WASMFuncType *cur_type, *cur_func_type;
|
||||||
WASMTableInstance *tbl_inst;
|
WASMTableInstance *tbl_inst;
|
||||||
uint32 tbl_idx;
|
uint32 tbl_idx;
|
||||||
|
|
||||||
#if WASM_ENABLE_TAIL_CALL != 0
|
#if WASM_ENABLE_TAIL_CALL != 0
|
||||||
opcode = *(frame_ip - 1);
|
opcode = *(frame_ip - 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2279,8 +2283,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (cur_type->min_type_idx_normalized
|
if (!wasm_func_type_is_super_of(cur_type, cur_func_type)) {
|
||||||
!= cur_func_type->min_type_idx_normalized) {
|
|
||||||
wasm_set_exception(module, "indirect call type mismatch");
|
wasm_set_exception(module, "indirect call type mismatch");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
|
@ -6227,6 +6230,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
frame_ip = frame->ip;
|
frame_ip = frame->ip;
|
||||||
frame_sp = frame->sp;
|
frame_sp = frame->sp;
|
||||||
frame_csp = frame->csp;
|
frame_csp = frame->csp;
|
||||||
|
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||||
|
is_return_call = false;
|
||||||
|
#endif
|
||||||
goto call_func_from_entry;
|
goto call_func_from_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6320,6 +6326,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
}
|
}
|
||||||
FREE_FRAME(exec_env, frame);
|
FREE_FRAME(exec_env, frame);
|
||||||
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
|
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
|
||||||
|
is_return_call = true;
|
||||||
goto call_func_from_entry;
|
goto call_func_from_entry;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -6333,6 +6340,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
}
|
}
|
||||||
SYNC_ALL_TO_FRAME();
|
SYNC_ALL_TO_FRAME();
|
||||||
prev_frame = frame;
|
prev_frame = frame;
|
||||||
|
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||||
|
is_return_call = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
call_func_from_entry:
|
call_func_from_entry:
|
||||||
|
@ -6342,15 +6352,27 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
if (cur_func->import_func_inst) {
|
if (cur_func->import_func_inst) {
|
||||||
wasm_interp_call_func_import(module, exec_env, cur_func,
|
wasm_interp_call_func_import(module, exec_env, cur_func,
|
||||||
prev_frame);
|
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
|
#if WASM_ENABLE_EXCE_HANDLING != 0
|
||||||
char uncaught_exception[128] = { 0 };
|
char uncaught_exception[128] = { 0 };
|
||||||
bool has_exception =
|
bool has_exception =
|
||||||
wasm_copy_exception(module, uncaught_exception);
|
wasm_copy_exception(module, uncaught_exception);
|
||||||
if (has_exception
|
if (has_exception
|
||||||
&& strstr(uncaught_exception, "uncaught wasm exception")) {
|
&& strstr(uncaught_exception, "uncaught wasm exception")) {
|
||||||
/* fix framesp */
|
|
||||||
UPDATE_ALL_FROM_FRAME();
|
|
||||||
|
|
||||||
uint32 import_exception;
|
uint32 import_exception;
|
||||||
/* initialize imported exception index to be invalid */
|
/* initialize imported exception index to be invalid */
|
||||||
SET_INVALID_TAGINDEX(import_exception);
|
SET_INVALID_TAGINDEX(import_exception);
|
||||||
|
@ -6392,11 +6414,21 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
{
|
{
|
||||||
wasm_interp_call_func_native(module, exec_env, cur_func,
|
wasm_interp_call_func_native(module, exec_env, cur_func,
|
||||||
prev_frame);
|
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;
|
prev_frame = frame->prev_frame;
|
||||||
cur_func = frame->function;
|
cur_func = frame->function;
|
||||||
UPDATE_ALL_FROM_FRAME();
|
UPDATE_ALL_FROM_FRAME();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* update memory size, no need to update memory ptr as
|
/* update memory size, no need to update memory ptr as
|
||||||
it isn't changed in wasm_enlarge_memory */
|
it isn't changed in wasm_enlarge_memory */
|
||||||
|
|
|
@ -1501,6 +1501,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
WASMStringviewIterObjectRef stringview_iter_obj;
|
WASMStringviewIterObjectRef stringview_iter_obj;
|
||||||
#endif
|
#endif
|
||||||
#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
|
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||||
#define HANDLE_OPCODE(op) &&HANDLE_##op
|
#define HANDLE_OPCODE(op) &&HANDLE_##op
|
||||||
|
@ -1733,8 +1736,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (cur_type->min_type_idx_normalized
|
if (!wasm_func_type_is_super_of(cur_type, cur_func_type)) {
|
||||||
!= cur_func_type->min_type_idx_normalized) {
|
|
||||||
wasm_set_exception(module, "indirect call type mismatch");
|
wasm_set_exception(module, "indirect call type mismatch");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
|
@ -5618,6 +5620,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
{
|
{
|
||||||
frame = prev_frame;
|
frame = prev_frame;
|
||||||
frame_ip = frame->ip;
|
frame_ip = frame->ip;
|
||||||
|
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||||
|
is_return_call = false;
|
||||||
|
#endif
|
||||||
goto call_func_from_entry;
|
goto call_func_from_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5766,6 +5771,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
FREE_FRAME(exec_env, frame);
|
FREE_FRAME(exec_env, frame);
|
||||||
frame_ip += cur_func->param_count * sizeof(int16);
|
frame_ip += cur_func->param_count * sizeof(int16);
|
||||||
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
|
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
|
||||||
|
is_return_call = true;
|
||||||
goto call_func_from_entry;
|
goto call_func_from_entry;
|
||||||
}
|
}
|
||||||
#endif /* WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0 */
|
#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();
|
SYNC_ALL_TO_FRAME();
|
||||||
prev_frame = frame;
|
prev_frame = frame;
|
||||||
|
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||||
|
is_return_call = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
call_func_from_entry:
|
call_func_from_entry:
|
||||||
|
@ -5855,9 +5864,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
prev_frame);
|
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;
|
prev_frame = frame->prev_frame;
|
||||||
cur_func = frame->function;
|
cur_func = frame->function;
|
||||||
UPDATE_ALL_FROM_FRAME();
|
UPDATE_ALL_FROM_FRAME();
|
||||||
|
}
|
||||||
|
|
||||||
/* update memory size, no need to update memory ptr as
|
/* update memory size, no need to update memory ptr as
|
||||||
it isn't changed in wasm_enlarge_memory */
|
it isn't changed in wasm_enlarge_memory */
|
||||||
|
|
|
@ -394,10 +394,10 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new, char *error_buf,
|
||||||
|
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
static bool
|
static bool
|
||||||
check_type_index(const WASMModule *module, uint32 type_index, char *error_buf,
|
check_type_index(const WASMModule *module, uint32 type_count, uint32 type_index,
|
||||||
uint32 error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
if (type_index >= module->type_count) {
|
if (type_index >= type_count) {
|
||||||
set_error_buf_v(error_buf, error_buf_size, "unknown type %d",
|
set_error_buf_v(error_buf, error_buf_size, "unknown type %d",
|
||||||
type_index);
|
type_index);
|
||||||
return false;
|
return false;
|
||||||
|
@ -409,7 +409,8 @@ static bool
|
||||||
check_array_type(const WASMModule *module, uint32 type_index, char *error_buf,
|
check_array_type(const WASMModule *module, uint32 type_index, char *error_buf,
|
||||||
uint32 error_buf_size)
|
uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
if (!check_type_index(module, type_index, error_buf, error_buf_size)) {
|
if (!check_type_index(module, module->type_count, type_index, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (module->types[type_index]->type_flag != WASM_TYPE_ARRAY) {
|
if (module->types[type_index]->type_flag != WASM_TYPE_ARRAY) {
|
||||||
|
@ -775,8 +776,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
if (!is_byte_a_type(type1)) {
|
if (!is_byte_a_type(type1)) {
|
||||||
p--;
|
p--;
|
||||||
read_leb_uint32(p, p_end, type_idx);
|
read_leb_uint32(p, p_end, type_idx);
|
||||||
if (!check_type_index(module, type_idx, error_buf,
|
if (!check_type_index(module, module->type_count, type_idx,
|
||||||
error_buf_size))
|
error_buf, error_buf_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
wasm_set_refheaptype_typeidx(&cur_ref_type.ref_ht_typeidx,
|
wasm_set_refheaptype_typeidx(&cur_ref_type.ref_ht_typeidx,
|
||||||
|
@ -902,7 +903,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
uint32 field_count;
|
uint32 field_count;
|
||||||
read_leb_uint32(p, p_end, type_idx);
|
read_leb_uint32(p, p_end, type_idx);
|
||||||
|
|
||||||
if (!check_type_index(module, type_idx, error_buf,
|
if (!check_type_index(module, module->type_count,
|
||||||
|
type_idx, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -966,7 +968,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
read_leb_uint32(p, p_end, cur_value.type_index);
|
read_leb_uint32(p, p_end, cur_value.type_index);
|
||||||
type_idx = cur_value.type_index;
|
type_idx = cur_value.type_index;
|
||||||
|
|
||||||
if (!check_type_index(module, type_idx, error_buf,
|
if (!check_type_index(module, module->type_count,
|
||||||
|
type_idx, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1001,7 +1004,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
read_leb_uint32(p, p_end, cur_value.type_index);
|
read_leb_uint32(p, p_end, cur_value.type_index);
|
||||||
type_idx = cur_value.type_index;
|
type_idx = cur_value.type_index;
|
||||||
|
|
||||||
if (!check_type_index(module, type_idx, error_buf,
|
if (!check_type_index(module, module->type_count,
|
||||||
|
type_idx, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1275,6 +1279,13 @@ destroy_array_type(WASMArrayType *type)
|
||||||
static void
|
static void
|
||||||
destroy_wasm_type(WASMType *type)
|
destroy_wasm_type(WASMType *type)
|
||||||
{
|
{
|
||||||
|
if (type->ref_count > 1) {
|
||||||
|
/* The type is referenced by other types
|
||||||
|
of current wasm module */
|
||||||
|
type->ref_count--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (type->type_flag == WASM_TYPE_FUNC)
|
if (type->type_flag == WASM_TYPE_FUNC)
|
||||||
destroy_func_type((WASMFuncType *)type);
|
destroy_func_type((WASMFuncType *)type);
|
||||||
else if (type->type_flag == WASM_TYPE_STRUCT)
|
else if (type->type_flag == WASM_TYPE_STRUCT)
|
||||||
|
@ -1289,8 +1300,9 @@ destroy_wasm_type(WASMType *type)
|
||||||
/* Resolve (ref null ht) or (ref ht) */
|
/* Resolve (ref null ht) or (ref ht) */
|
||||||
static bool
|
static bool
|
||||||
resolve_reftype_htref(const uint8 **p_buf, const uint8 *buf_end,
|
resolve_reftype_htref(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
WASMModule *module, bool nullable, WASMRefType *ref_type,
|
WASMModule *module, uint32 type_count, bool nullable,
|
||||||
char *error_buf, uint32 error_buf_size)
|
WASMRefType *ref_type, char *error_buf,
|
||||||
|
uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||||
|
|
||||||
|
@ -1301,8 +1313,9 @@ resolve_reftype_htref(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
|
|
||||||
if (wasm_is_refheaptype_typeidx(&ref_type->ref_ht_common)) {
|
if (wasm_is_refheaptype_typeidx(&ref_type->ref_ht_common)) {
|
||||||
/* heap type is (type i), i : typeidx, >= 0 */
|
/* heap type is (type i), i : typeidx, >= 0 */
|
||||||
if (!check_type_index(module, ref_type->ref_ht_typeidx.type_idx,
|
if (!check_type_index(module, type_count,
|
||||||
error_buf, error_buf_size)) {
|
ref_type->ref_ht_typeidx.type_idx, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1320,9 +1333,10 @@ fail:
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
resolve_value_type(const uint8 **p_buf, const uint8 *buf_end,
|
resolve_value_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
WASMModule *module, bool *p_need_ref_type_map,
|
WASMModule *module, uint32 type_count,
|
||||||
WASMRefType *ref_type, bool allow_packed_type,
|
bool *p_need_ref_type_map, WASMRefType *ref_type,
|
||||||
char *error_buf, uint32 error_buf_size)
|
bool allow_packed_type, char *error_buf,
|
||||||
|
uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||||
uint8 type;
|
uint8 type;
|
||||||
|
@ -1334,8 +1348,8 @@ resolve_value_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
|
|
||||||
if (wasm_is_reftype_htref_nullable(type)) {
|
if (wasm_is_reftype_htref_nullable(type)) {
|
||||||
/* (ref null ht) */
|
/* (ref null ht) */
|
||||||
if (!resolve_reftype_htref(&p, p_end, module, true, ref_type, error_buf,
|
if (!resolve_reftype_htref(&p, p_end, module, type_count, true,
|
||||||
error_buf_size))
|
ref_type, error_buf, error_buf_size))
|
||||||
return false;
|
return false;
|
||||||
if (!wasm_is_refheaptype_common(&ref_type->ref_ht_common))
|
if (!wasm_is_refheaptype_common(&ref_type->ref_ht_common))
|
||||||
*p_need_ref_type_map = true;
|
*p_need_ref_type_map = true;
|
||||||
|
@ -1351,8 +1365,8 @@ resolve_value_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
}
|
}
|
||||||
else if (wasm_is_reftype_htref_non_nullable(type)) {
|
else if (wasm_is_reftype_htref_non_nullable(type)) {
|
||||||
/* (ref ht) */
|
/* (ref ht) */
|
||||||
if (!resolve_reftype_htref(&p, p_end, module, false, ref_type,
|
if (!resolve_reftype_htref(&p, p_end, module, type_count, false,
|
||||||
error_buf, error_buf_size))
|
ref_type, error_buf, error_buf_size))
|
||||||
return false;
|
return false;
|
||||||
*p_need_ref_type_map = true;
|
*p_need_ref_type_map = true;
|
||||||
#if WASM_ENABLE_STRINGREF != 0
|
#if WASM_ENABLE_STRINGREF != 0
|
||||||
|
@ -1401,7 +1415,8 @@ reftype_set_insert(HashMap *ref_type_set, const WASMRefType *ref_type,
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
resolve_func_type(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
resolve_func_type(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||||
uint32 type_idx, char *error_buf, uint32 error_buf_size)
|
uint32 type_count, uint32 type_idx, char *error_buf,
|
||||||
|
uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
|
const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
|
||||||
uint32 param_count, result_count, i, j = 0;
|
uint32 param_count, result_count, i, j = 0;
|
||||||
|
@ -1417,8 +1432,9 @@ resolve_func_type(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||||
read_leb_uint32(p, p_end, param_count);
|
read_leb_uint32(p, p_end, param_count);
|
||||||
p_org = p;
|
p_org = p;
|
||||||
for (i = 0; i < param_count; i++) {
|
for (i = 0; i < param_count; i++) {
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, module, type_count,
|
||||||
&ref_type, false, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (need_ref_type_map)
|
if (need_ref_type_map)
|
||||||
|
@ -1427,8 +1443,9 @@ resolve_func_type(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||||
|
|
||||||
read_leb_uint32(p, p_end, result_count);
|
read_leb_uint32(p, p_end, result_count);
|
||||||
for (i = 0; i < result_count; i++) {
|
for (i = 0; i < result_count; i++) {
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, module, type_count,
|
||||||
&ref_type, false, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (need_ref_type_map) {
|
if (need_ref_type_map) {
|
||||||
|
@ -1468,8 +1485,9 @@ resolve_func_type(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < param_count; i++) {
|
for (i = 0; i < param_count; i++) {
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, module, type_count,
|
||||||
&ref_type, false, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
type->types[i] = ref_type.ref_type;
|
type->types[i] = ref_type.ref_type;
|
||||||
|
@ -1485,8 +1503,9 @@ resolve_func_type(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||||
|
|
||||||
read_leb_uint32(p, p_end, result_count);
|
read_leb_uint32(p, p_end, result_count);
|
||||||
for (i = 0; i < result_count; i++) {
|
for (i = 0; i < result_count; i++) {
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, module, type_count,
|
||||||
&ref_type, false, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
type->types[param_count + i] = ref_type.ref_type;
|
type->types[param_count + i] = ref_type.ref_type;
|
||||||
|
@ -1527,18 +1546,6 @@ resolve_func_type(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate the minimal type index of the type equal to this type */
|
|
||||||
type->min_type_idx_normalized = type_idx;
|
|
||||||
for (i = 0; i < type_idx; i++) {
|
|
||||||
WASMFuncType *func_type = (WASMFuncType *)module->types[i];
|
|
||||||
if (func_type->base_type.type_flag == WASM_TYPE_FUNC
|
|
||||||
&& wasm_func_type_equal(type, func_type, module->types,
|
|
||||||
type_idx + 1)) {
|
|
||||||
type->min_type_idx_normalized = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*p_buf = p;
|
*p_buf = p;
|
||||||
|
|
||||||
module->types[type_idx] = (WASMType *)type;
|
module->types[type_idx] = (WASMType *)type;
|
||||||
|
@ -1552,8 +1559,8 @@ fail:
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
resolve_struct_type(const uint8 **p_buf, const uint8 *buf_end,
|
resolve_struct_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
WASMModule *module, uint32 type_idx, char *error_buf,
|
WASMModule *module, uint32 type_count, uint32 type_idx,
|
||||||
uint32 error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
|
const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
|
||||||
uint32 field_count, ref_type_map_count = 0, ref_field_count = 0;
|
uint32 field_count, ref_type_map_count = 0, ref_field_count = 0;
|
||||||
|
@ -1569,8 +1576,9 @@ resolve_struct_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
read_leb_uint32(p, p_end, field_count);
|
read_leb_uint32(p, p_end, field_count);
|
||||||
p_org = p;
|
p_org = p;
|
||||||
for (i = 0; i < field_count; i++) {
|
for (i = 0; i < field_count; i++) {
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, module, type_count,
|
||||||
&ref_type, true, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, true, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (need_ref_type_map)
|
if (need_ref_type_map)
|
||||||
|
@ -1617,8 +1625,9 @@ resolve_struct_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
|
|
||||||
offset = (uint32)offsetof(WASMStructObject, field_data);
|
offset = (uint32)offsetof(WASMStructObject, field_data);
|
||||||
for (i = 0; i < field_count; i++) {
|
for (i = 0; i < field_count; i++) {
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, module, type_count,
|
||||||
&ref_type, true, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, true, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
type->fields[i].field_type = ref_type.ref_type;
|
type->fields[i].field_type = ref_type.ref_type;
|
||||||
|
@ -1671,8 +1680,8 @@ fail:
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
resolve_array_type(const uint8 **p_buf, const uint8 *buf_end,
|
resolve_array_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
WASMModule *module, uint32 type_idx, char *error_buf,
|
WASMModule *module, uint32 type_count, uint32 type_idx,
|
||||||
uint32 error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||||
uint8 mutable;
|
uint8 mutable;
|
||||||
|
@ -1680,8 +1689,8 @@ resolve_array_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
WASMRefType ref_type;
|
WASMRefType ref_type;
|
||||||
WASMArrayType *type = NULL;
|
WASMArrayType *type = NULL;
|
||||||
|
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map, &ref_type,
|
if (!resolve_value_type(&p, p_end, module, type_count, &need_ref_type_map,
|
||||||
true, error_buf, error_buf_size)) {
|
&ref_type, true, error_buf, error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1730,7 +1739,8 @@ init_ref_type(WASMModule *module, WASMRefType *ref_type, bool nullable,
|
||||||
int32 heap_type, char *error_buf, uint32 error_buf_size)
|
int32 heap_type, char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
if (heap_type >= 0) {
|
if (heap_type >= 0) {
|
||||||
if (!check_type_index(module, heap_type, error_buf, error_buf_size)) {
|
if (!check_type_index(module, module->type_count, heap_type, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
wasm_set_refheaptype_typeidx(&ref_type->ref_ht_typeidx, nullable,
|
wasm_set_refheaptype_typeidx(&ref_type->ref_ht_typeidx, nullable,
|
||||||
|
@ -2010,6 +2020,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
|
|
||||||
if (flag == DEFINED_TYPE_FUNC) {
|
if (flag == DEFINED_TYPE_FUNC) {
|
||||||
if (!resolve_func_type(&p, buf_end, module,
|
if (!resolve_func_type(&p, buf_end, module,
|
||||||
|
processed_type_count + rec_count,
|
||||||
processed_type_count + j, error_buf,
|
processed_type_count + j, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2017,6 +2028,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
}
|
}
|
||||||
else if (flag == DEFINED_TYPE_STRUCT) {
|
else if (flag == DEFINED_TYPE_STRUCT) {
|
||||||
if (!resolve_struct_type(&p, buf_end, module,
|
if (!resolve_struct_type(&p, buf_end, module,
|
||||||
|
processed_type_count + rec_count,
|
||||||
processed_type_count + j,
|
processed_type_count + j,
|
||||||
error_buf, error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2024,6 +2036,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
}
|
}
|
||||||
else if (flag == DEFINED_TYPE_ARRAY) {
|
else if (flag == DEFINED_TYPE_ARRAY) {
|
||||||
if (!resolve_array_type(&p, buf_end, module,
|
if (!resolve_array_type(&p, buf_end, module,
|
||||||
|
processed_type_count + rec_count,
|
||||||
processed_type_count + j, error_buf,
|
processed_type_count + j, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2037,13 +2050,13 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
|
|
||||||
cur_type = module->types[processed_type_count + j];
|
cur_type = module->types[processed_type_count + j];
|
||||||
|
|
||||||
|
cur_type->ref_count = 1;
|
||||||
cur_type->parent_type_idx = parent_type_idx;
|
cur_type->parent_type_idx = parent_type_idx;
|
||||||
cur_type->is_sub_final = is_sub_final;
|
cur_type->is_sub_final = is_sub_final;
|
||||||
|
|
||||||
if (rec_count > 1) {
|
|
||||||
cur_type->rec_count = rec_count;
|
cur_type->rec_count = rec_count;
|
||||||
cur_type->rec_idx = j;
|
cur_type->rec_idx = j;
|
||||||
}
|
cur_type->rec_begin_type_idx = processed_type_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* resolve subtyping relationship in current rec group */
|
/* resolve subtyping relationship in current rec group */
|
||||||
|
@ -2055,6 +2068,11 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
module->types[cur_type->parent_type_idx];
|
module->types[cur_type->parent_type_idx];
|
||||||
cur_type->parent_type = parent_type;
|
cur_type->parent_type = parent_type;
|
||||||
cur_type->root_type = parent_type->root_type;
|
cur_type->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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
cur_type->inherit_depth = parent_type->inherit_depth + 1;
|
cur_type->inherit_depth = parent_type->inherit_depth + 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2080,6 +2098,49 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there is already an equivalence type or a group of equivalence
|
||||||
|
recursive types created, use it or them instead */
|
||||||
|
for (j = 0; j < processed_type_count;) {
|
||||||
|
WASMType *src_type = module->types[j];
|
||||||
|
WASMType *cur_type = module->types[processed_type_count];
|
||||||
|
uint32 k, src_rec_count;
|
||||||
|
|
||||||
|
src_rec_count = src_type->rec_count;
|
||||||
|
if (src_rec_count != rec_count) {
|
||||||
|
/* no type equivalence */
|
||||||
|
j += src_rec_count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = 0; k < rec_count; k++) {
|
||||||
|
src_type = module->types[j + k];
|
||||||
|
cur_type = module->types[processed_type_count + k];
|
||||||
|
if (!wasm_type_equal(src_type, cur_type, module->types,
|
||||||
|
module->type_count)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (k < rec_count) {
|
||||||
|
/* no type equivalence */
|
||||||
|
j += src_rec_count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* type equivalence */
|
||||||
|
for (k = 0; k < rec_count; k++) {
|
||||||
|
if (module->types[j + k]->ref_count == UINT16_MAX) {
|
||||||
|
set_error_buf(error_buf, error_buf_size,
|
||||||
|
"wasm type's ref count too large");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
destroy_wasm_type(module->types[processed_type_count + k]);
|
||||||
|
module->types[processed_type_count + k] =
|
||||||
|
module->types[j + k];
|
||||||
|
module->types[j + k]->ref_count++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (rec_count > 1) {
|
if (rec_count > 1) {
|
||||||
LOG_VERBOSE("Finished processing rec group [%d-%d]",
|
LOG_VERBOSE("Finished processing rec group [%d-%d]",
|
||||||
processed_type_count,
|
processed_type_count,
|
||||||
|
@ -2511,8 +2572,9 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else /* else of WASM_ENABLE_GC == 0 */
|
#else /* else of WASM_ENABLE_GC == 0 */
|
||||||
if (!resolve_value_type(&p, p_end, parent_module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, parent_module, parent_module->type_count,
|
||||||
&ref_type, false, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (wasm_is_reftype_htref_non_nullable(ref_type.ref_type)) {
|
if (wasm_is_reftype_htref_non_nullable(ref_type.ref_type)) {
|
||||||
|
@ -2947,8 +3009,9 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
declare_type = read_uint8(p);
|
declare_type = read_uint8(p);
|
||||||
declare_mutable = read_uint8(p);
|
declare_mutable = read_uint8(p);
|
||||||
#else
|
#else
|
||||||
if (!resolve_value_type(&p, p_end, parent_module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, parent_module, parent_module->type_count,
|
||||||
&ref_type, false, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
declare_type = ref_type.ref_type;
|
declare_type = ref_type.ref_type;
|
||||||
|
@ -3050,8 +3113,9 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else /* else of WASM_ENABLE_GC == 0 */
|
#else /* else of WASM_ENABLE_GC == 0 */
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map, &ref_type,
|
if (!resolve_value_type(&p, p_end, module, module->type_count,
|
||||||
false, error_buf, error_buf_size)) {
|
&need_ref_type_map, &ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
table->elem_type = ref_type.ref_type;
|
table->elem_type = ref_type.ref_type;
|
||||||
|
@ -3536,7 +3600,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
type_index_org = type_index;
|
type_index_org = type_index;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0)
|
#if (WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0) \
|
||||||
|
&& WASM_ENABLE_GC == 0
|
||||||
type_index = wasm_get_smallest_type_idx(
|
type_index = wasm_get_smallest_type_idx(
|
||||||
module->types, module->type_count, type_index);
|
module->types, module->type_count, type_index);
|
||||||
#endif
|
#endif
|
||||||
|
@ -3577,8 +3642,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
if (!resolve_value_type(&p_code, buf_code_end, module,
|
if (!resolve_value_type(&p_code, buf_code_end, module,
|
||||||
&need_ref_type_map, &ref_type, false,
|
module->type_count, &need_ref_type_map,
|
||||||
error_buf, error_buf_size)) {
|
&ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
local_count += sub_local_count;
|
local_count += sub_local_count;
|
||||||
|
@ -3664,8 +3730,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (!resolve_value_type(&p_code, buf_code_end, module,
|
if (!resolve_value_type(&p_code, buf_code_end, module,
|
||||||
&need_ref_type_map, &ref_type, false,
|
module->type_count, &need_ref_type_map,
|
||||||
error_buf, error_buf_size)) {
|
&ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (need_ref_type_map) {
|
if (need_ref_type_map) {
|
||||||
|
@ -3923,9 +3990,9 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
global->type = read_uint8(p);
|
global->type = read_uint8(p);
|
||||||
mutable = read_uint8(p);
|
mutable = read_uint8(p);
|
||||||
#else
|
#else
|
||||||
if (!resolve_value_type(&p, p_end, module, &need_ref_type_map,
|
if (!resolve_value_type(&p, p_end, module, module->type_count,
|
||||||
&ref_type, false, error_buf,
|
&need_ref_type_map, &ref_type, false,
|
||||||
error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
global->type = ref_type.ref_type;
|
global->type = ref_type.ref_type;
|
||||||
|
@ -4231,8 +4298,8 @@ load_elem_type(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
#else
|
#else
|
||||||
p--;
|
p--;
|
||||||
if (!resolve_value_type((const uint8 **)&p, p_end, module,
|
if (!resolve_value_type((const uint8 **)&p, p_end, module,
|
||||||
&need_ref_type_map, &elem_ref_type, false,
|
module->type_count, &need_ref_type_map,
|
||||||
error_buf, error_buf_size)) {
|
&elem_ref_type, false, error_buf, error_buf_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!wasm_is_type_reftype(elem_ref_type.ref_type)) {
|
if (!wasm_is_type_reftype(elem_ref_type.ref_type)) {
|
||||||
|
@ -10827,7 +10894,8 @@ re_scan:
|
||||||
p_org = p;
|
p_org = p;
|
||||||
p--;
|
p--;
|
||||||
if (!resolve_value_type((const uint8 **)&p, p_end,
|
if (!resolve_value_type((const uint8 **)&p, p_end,
|
||||||
module, &need_ref_type_map,
|
module, module->type_count,
|
||||||
|
&need_ref_type_map,
|
||||||
&wasm_ref_type, false,
|
&wasm_ref_type, false,
|
||||||
error_buf, error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -11303,8 +11371,8 @@ re_scan:
|
||||||
bh_memcpy_s(loader_ctx->frame_offset, size,
|
bh_memcpy_s(loader_ctx->frame_offset, size,
|
||||||
block->param_frame_offsets, size);
|
block->param_frame_offsets, size);
|
||||||
loader_ctx->frame_offset += (size / sizeof(int16));
|
loader_ctx->frame_offset += (size / sizeof(int16));
|
||||||
loader_ctx->dynamic_offset = block->start_dynamic_offset;
|
|
||||||
}
|
}
|
||||||
|
loader_ctx->dynamic_offset = block->start_dynamic_offset;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -11598,6 +11666,15 @@ re_scan:
|
||||||
if (opcode == WASM_OP_CALL_REF
|
if (opcode == WASM_OP_CALL_REF
|
||||||
|| opcode == WASM_OP_RETURN_CALL_REF) {
|
|| opcode == WASM_OP_RETURN_CALL_REF) {
|
||||||
read_leb_uint32(p, p_end, type_idx1);
|
read_leb_uint32(p, p_end, type_idx1);
|
||||||
|
if (!check_type_index(module, module->type_count, type_idx1,
|
||||||
|
error_buf, error_buf_size)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (module->types[type_idx1]->type_flag != WASM_TYPE_FUNC) {
|
||||||
|
set_error_buf(error_buf, error_buf_size,
|
||||||
|
"unkown function type");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
if (!wasm_loader_pop_nullable_typeidx(loader_ctx, &type,
|
if (!wasm_loader_pop_nullable_typeidx(loader_ctx, &type,
|
||||||
&type_idx, error_buf,
|
&type_idx, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
|
@ -11606,8 +11683,8 @@ re_scan:
|
||||||
if (type == VALUE_TYPE_ANY) {
|
if (type == VALUE_TYPE_ANY) {
|
||||||
type_idx = type_idx1;
|
type_idx = type_idx1;
|
||||||
}
|
}
|
||||||
if (!check_type_index(module, type_idx, error_buf,
|
if (!check_type_index(module, module->type_count, type_idx,
|
||||||
error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (module->types[type_idx]->type_flag != WASM_TYPE_FUNC) {
|
if (module->types[type_idx]->type_flag != WASM_TYPE_FUNC) {
|
||||||
|
@ -11615,7 +11692,9 @@ re_scan:
|
||||||
"unkown function type");
|
"unkown function type");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (type_idx != type_idx1) {
|
if (!wasm_func_type_is_super_of(
|
||||||
|
(WASMFuncType *)module->types[type_idx1],
|
||||||
|
(WASMFuncType *)module->types[type_idx])) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"function type mismatch");
|
"function type mismatch");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -12055,8 +12134,9 @@ re_scan:
|
||||||
#else
|
#else
|
||||||
p_org = p + 1;
|
p_org = p + 1;
|
||||||
if (!resolve_value_type((const uint8 **)&p, p_end, module,
|
if (!resolve_value_type((const uint8 **)&p, p_end, module,
|
||||||
&need_ref_type_map, &wasm_ref_type,
|
module->type_count, &need_ref_type_map,
|
||||||
false, error_buf, error_buf_size)) {
|
&wasm_ref_type, false, error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
type = wasm_ref_type.ref_type;
|
type = wasm_ref_type.ref_type;
|
||||||
|
@ -12223,8 +12303,8 @@ re_scan:
|
||||||
#else
|
#else
|
||||||
read_leb_int32(p, p_end, heap_type);
|
read_leb_int32(p, p_end, heap_type);
|
||||||
if (heap_type >= 0) {
|
if (heap_type >= 0) {
|
||||||
if (!check_type_index(module, heap_type, error_buf,
|
if (!check_type_index(module, module->type_count, heap_type,
|
||||||
error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
wasm_set_refheaptype_typeidx(&wasm_ref_type.ref_ht_typeidx,
|
wasm_set_refheaptype_typeidx(&wasm_ref_type.ref_ht_typeidx,
|
||||||
|
@ -13008,6 +13088,7 @@ re_scan:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_F32_CONST:
|
case WASM_OP_F32_CONST:
|
||||||
|
CHECK_BUF(p, p_end, sizeof(float32));
|
||||||
p += sizeof(float32);
|
p += sizeof(float32);
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
skip_label();
|
skip_label();
|
||||||
|
@ -13026,6 +13107,7 @@ re_scan:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_F64_CONST:
|
case WASM_OP_F64_CONST:
|
||||||
|
CHECK_BUF(p, p_end, sizeof(float64));
|
||||||
p += sizeof(float64);
|
p += sizeof(float64);
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
skip_label();
|
skip_label();
|
||||||
|
@ -13286,7 +13368,8 @@ re_scan:
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
emit_uint32(loader_ctx, type_idx);
|
emit_uint32(loader_ctx, type_idx);
|
||||||
#endif
|
#endif
|
||||||
if (!check_type_index(module, type_idx, error_buf,
|
if (!check_type_index(module, module->type_count,
|
||||||
|
type_idx, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -13372,7 +13455,8 @@ re_scan:
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
emit_uint32(loader_ctx, type_idx);
|
emit_uint32(loader_ctx, type_idx);
|
||||||
#endif
|
#endif
|
||||||
if (!check_type_index(module, type_idx, error_buf,
|
if (!check_type_index(module, module->type_count,
|
||||||
|
type_idx, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -13785,7 +13869,8 @@ re_scan:
|
||||||
emit_uint32(loader_ctx, (uint32)heap_type);
|
emit_uint32(loader_ctx, (uint32)heap_type);
|
||||||
#endif
|
#endif
|
||||||
if (heap_type >= 0) {
|
if (heap_type >= 0) {
|
||||||
if (!check_type_index(module, heap_type, error_buf,
|
if (!check_type_index(module, module->type_count,
|
||||||
|
heap_type, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -14356,6 +14441,7 @@ re_scan:
|
||||||
}
|
}
|
||||||
case WASM_OP_MEMORY_COPY:
|
case WASM_OP_MEMORY_COPY:
|
||||||
{
|
{
|
||||||
|
CHECK_BUF(p, p_end, sizeof(int16));
|
||||||
/* both src and dst memory index should be 0 */
|
/* both src and dst memory index should be 0 */
|
||||||
if (*(int16 *)p != 0x0000)
|
if (*(int16 *)p != 0x0000)
|
||||||
goto fail_zero_byte_expected;
|
goto fail_zero_byte_expected;
|
||||||
|
@ -15129,13 +15215,6 @@ re_scan:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SIMD_i32x4_narrow_i64x2_s:
|
|
||||||
case SIMD_i32x4_narrow_i64x2_u:
|
|
||||||
{
|
|
||||||
POP2_AND_PUSH(VALUE_TYPE_V128, VALUE_TYPE_V128);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SIMD_i32x4_extend_low_i16x8_s:
|
case SIMD_i32x4_extend_low_i16x8_s:
|
||||||
case SIMD_i32x4_extend_high_i16x8_s:
|
case SIMD_i32x4_extend_high_i16x8_s:
|
||||||
case SIMD_i32x4_extend_low_i16x8_u:
|
case SIMD_i32x4_extend_low_i16x8_u:
|
||||||
|
@ -15162,7 +15241,6 @@ re_scan:
|
||||||
case SIMD_i32x4_max_s:
|
case SIMD_i32x4_max_s:
|
||||||
case SIMD_i32x4_max_u:
|
case SIMD_i32x4_max_u:
|
||||||
case SIMD_i32x4_dot_i16x8_s:
|
case SIMD_i32x4_dot_i16x8_s:
|
||||||
case SIMD_i32x4_avgr_u:
|
|
||||||
case SIMD_i32x4_extmul_low_i16x8_s:
|
case SIMD_i32x4_extmul_low_i16x8_s:
|
||||||
case SIMD_i32x4_extmul_high_i16x8_s:
|
case SIMD_i32x4_extmul_high_i16x8_s:
|
||||||
case SIMD_i32x4_extmul_low_i16x8_u:
|
case SIMD_i32x4_extmul_low_i16x8_u:
|
||||||
|
@ -15226,7 +15304,6 @@ re_scan:
|
||||||
/* f32x4 operation */
|
/* f32x4 operation */
|
||||||
case SIMD_f32x4_abs:
|
case SIMD_f32x4_abs:
|
||||||
case SIMD_f32x4_neg:
|
case SIMD_f32x4_neg:
|
||||||
case SIMD_f32x4_round:
|
|
||||||
case SIMD_f32x4_sqrt:
|
case SIMD_f32x4_sqrt:
|
||||||
{
|
{
|
||||||
POP_AND_PUSH(VALUE_TYPE_V128, VALUE_TYPE_V128);
|
POP_AND_PUSH(VALUE_TYPE_V128, VALUE_TYPE_V128);
|
||||||
|
@ -15249,7 +15326,6 @@ re_scan:
|
||||||
/* f64x2 operation */
|
/* f64x2 operation */
|
||||||
case SIMD_f64x2_abs:
|
case SIMD_f64x2_abs:
|
||||||
case SIMD_f64x2_neg:
|
case SIMD_f64x2_neg:
|
||||||
case SIMD_f64x2_round:
|
|
||||||
case SIMD_f64x2_sqrt:
|
case SIMD_f64x2_sqrt:
|
||||||
{
|
{
|
||||||
POP_AND_PUSH(VALUE_TYPE_V128, VALUE_TYPE_V128);
|
POP_AND_PUSH(VALUE_TYPE_V128, VALUE_TYPE_V128);
|
||||||
|
|
|
@ -6226,8 +6226,8 @@ re_scan:
|
||||||
bh_memcpy_s(loader_ctx->frame_offset, size,
|
bh_memcpy_s(loader_ctx->frame_offset, size,
|
||||||
block->param_frame_offsets, size);
|
block->param_frame_offsets, size);
|
||||||
loader_ctx->frame_offset += (size / sizeof(int16));
|
loader_ctx->frame_offset += (size / sizeof(int16));
|
||||||
loader_ctx->dynamic_offset = block->start_dynamic_offset;
|
|
||||||
}
|
}
|
||||||
|
loader_ctx->dynamic_offset = block->start_dynamic_offset;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -7351,6 +7351,7 @@ re_scan:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_F32_CONST:
|
case WASM_OP_F32_CONST:
|
||||||
|
CHECK_BUF(p, p_end, sizeof(float32));
|
||||||
p += sizeof(float32);
|
p += sizeof(float32);
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
skip_label();
|
skip_label();
|
||||||
|
@ -7369,6 +7370,7 @@ re_scan:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_F64_CONST:
|
case WASM_OP_F64_CONST:
|
||||||
|
CHECK_BUF(p, p_end, sizeof(float64));
|
||||||
p += sizeof(float64);
|
p += sizeof(float64);
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
skip_label();
|
skip_label();
|
||||||
|
@ -7676,6 +7678,7 @@ re_scan:
|
||||||
}
|
}
|
||||||
case WASM_OP_MEMORY_COPY:
|
case WASM_OP_MEMORY_COPY:
|
||||||
{
|
{
|
||||||
|
CHECK_BUF(p, p_end, sizeof(int16));
|
||||||
/* both src and dst memory index should be 0 */
|
/* both src and dst memory index should be 0 */
|
||||||
bh_assert(*(int16 *)p == 0x0000);
|
bh_assert(*(int16 *)p == 0x0000);
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
|
@ -593,8 +593,8 @@ typedef enum WASMSimdEXTOpcode {
|
||||||
/* placeholder = 0xa2 */
|
/* placeholder = 0xa2 */
|
||||||
SIMD_i32x4_all_true = 0xa3,
|
SIMD_i32x4_all_true = 0xa3,
|
||||||
SIMD_i32x4_bitmask = 0xa4,
|
SIMD_i32x4_bitmask = 0xa4,
|
||||||
SIMD_i32x4_narrow_i64x2_s = 0xa5,
|
/* placeholder = 0xa5 */
|
||||||
SIMD_i32x4_narrow_i64x2_u = 0xa6,
|
/* placeholder = 0xa6 */
|
||||||
SIMD_i32x4_extend_low_i16x8_s = 0xa7,
|
SIMD_i32x4_extend_low_i16x8_s = 0xa7,
|
||||||
SIMD_i32x4_extend_high_i16x8_s = 0xa8,
|
SIMD_i32x4_extend_high_i16x8_s = 0xa8,
|
||||||
SIMD_i32x4_extend_low_i16x8_u = 0xa9,
|
SIMD_i32x4_extend_low_i16x8_u = 0xa9,
|
||||||
|
@ -603,11 +603,11 @@ typedef enum WASMSimdEXTOpcode {
|
||||||
SIMD_i32x4_shr_s = 0xac,
|
SIMD_i32x4_shr_s = 0xac,
|
||||||
SIMD_i32x4_shr_u = 0xad,
|
SIMD_i32x4_shr_u = 0xad,
|
||||||
SIMD_i32x4_add = 0xae,
|
SIMD_i32x4_add = 0xae,
|
||||||
SIMD_i32x4_add_sat_s = 0xaf,
|
/* placeholder = 0xaf */
|
||||||
SIMD_i32x4_add_sat_u = 0xb0,
|
/* placeholder = 0xb0 */
|
||||||
SIMD_i32x4_sub = 0xb1,
|
SIMD_i32x4_sub = 0xb1,
|
||||||
SIMD_i32x4_sub_sat_s = 0xb2,
|
/* placeholder = 0xb2 */
|
||||||
SIMD_i32x4_sub_sat_u = 0xb3,
|
/* placeholder = 0xb3 */
|
||||||
/* placeholder = 0xb4 */
|
/* placeholder = 0xb4 */
|
||||||
SIMD_i32x4_mul = 0xb5,
|
SIMD_i32x4_mul = 0xb5,
|
||||||
SIMD_i32x4_min_s = 0xb6,
|
SIMD_i32x4_min_s = 0xb6,
|
||||||
|
@ -615,7 +615,7 @@ typedef enum WASMSimdEXTOpcode {
|
||||||
SIMD_i32x4_max_s = 0xb8,
|
SIMD_i32x4_max_s = 0xb8,
|
||||||
SIMD_i32x4_max_u = 0xb9,
|
SIMD_i32x4_max_u = 0xb9,
|
||||||
SIMD_i32x4_dot_i16x8_s = 0xba,
|
SIMD_i32x4_dot_i16x8_s = 0xba,
|
||||||
SIMD_i32x4_avgr_u = 0xbb,
|
/* placeholder = 0xbb */
|
||||||
SIMD_i32x4_extmul_low_i16x8_s = 0xbc,
|
SIMD_i32x4_extmul_low_i16x8_s = 0xbc,
|
||||||
SIMD_i32x4_extmul_high_i16x8_s = 0xbd,
|
SIMD_i32x4_extmul_high_i16x8_s = 0xbd,
|
||||||
SIMD_i32x4_extmul_low_i16x8_u = 0xbe,
|
SIMD_i32x4_extmul_low_i16x8_u = 0xbe,
|
||||||
|
@ -658,7 +658,7 @@ typedef enum WASMSimdEXTOpcode {
|
||||||
/* f32x4 operation */
|
/* f32x4 operation */
|
||||||
SIMD_f32x4_abs = 0xe0,
|
SIMD_f32x4_abs = 0xe0,
|
||||||
SIMD_f32x4_neg = 0xe1,
|
SIMD_f32x4_neg = 0xe1,
|
||||||
SIMD_f32x4_round = 0xe2,
|
/* placeholder = 0xe2 */
|
||||||
SIMD_f32x4_sqrt = 0xe3,
|
SIMD_f32x4_sqrt = 0xe3,
|
||||||
SIMD_f32x4_add = 0xe4,
|
SIMD_f32x4_add = 0xe4,
|
||||||
SIMD_f32x4_sub = 0xe5,
|
SIMD_f32x4_sub = 0xe5,
|
||||||
|
@ -672,7 +672,7 @@ typedef enum WASMSimdEXTOpcode {
|
||||||
/* f64x2 operation */
|
/* f64x2 operation */
|
||||||
SIMD_f64x2_abs = 0xec,
|
SIMD_f64x2_abs = 0xec,
|
||||||
SIMD_f64x2_neg = 0xed,
|
SIMD_f64x2_neg = 0xed,
|
||||||
SIMD_f64x2_round = 0xee,
|
/* placeholder = 0xee */
|
||||||
SIMD_f64x2_sqrt = 0xef,
|
SIMD_f64x2_sqrt = 0xef,
|
||||||
SIMD_f64x2_add = 0xf0,
|
SIMD_f64x2_add = 0xf0,
|
||||||
SIMD_f64x2_sub = 0xf1,
|
SIMD_f64x2_sub = 0xf1,
|
||||||
|
|
|
@ -4353,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 (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;
|
return (uint32)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_size = tbl_inst->cur_size + inc_size;
|
total_size = tbl_inst->cur_size + inc_size;
|
||||||
if (total_size > tbl_inst->max_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;
|
return (uint32)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4394,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);
|
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
|
WASMRttTypeRef
|
||||||
llvm_jit_rtt_type_new(WASMModuleInstance *module_inst, uint32 type_index)
|
llvm_jit_rtt_type_new(WASMModuleInstance *module_inst, uint32 type_index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -811,6 +811,11 @@ bool
|
||||||
llvm_jit_obj_is_instance_of(WASMModuleInstance *module_inst,
|
llvm_jit_obj_is_instance_of(WASMModuleInstance *module_inst,
|
||||||
WASMObjectRef gc_obj, uint32 type_index);
|
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
|
WASMRttTypeRef
|
||||||
llvm_jit_rtt_type_new(WASMModuleInstance *module_inst, uint32 type_index);
|
llvm_jit_rtt_type_new(WASMModuleInstance *module_inst, uint32 type_index);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
int ret = posix_fadvise(handle, (off_t)offset, (off_t)length, nadvice);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret != 0)
|
||||||
return convert_errno(ret);
|
return convert_errno(ret);
|
||||||
|
|
||||||
return __WASI_ESUCCESS;
|
return __WASI_ESUCCESS;
|
||||||
|
|
|
@ -55,7 +55,24 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
#else
|
#else
|
||||||
uint32_t mem_caps = MALLOC_CAP_8BIT;
|
uint32_t mem_caps = MALLOC_CAP_8BIT;
|
||||||
#endif
|
#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_vmcore.h"
|
||||||
#include "platform_api_extension.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
|
int
|
||||||
bh_platform_init()
|
bh_platform_init()
|
||||||
{
|
{
|
||||||
|
@ -234,7 +240,13 @@ unlinkat(int fd, const char *path, int flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -257,7 +269,13 @@ ftruncate(int fd, off_t length)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
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;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -578,3 +578,33 @@ os_thread_get_stack_boundary()
|
||||||
void
|
void
|
||||||
os_thread_jit_write_protect_np(bool enabled)
|
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;
|
||||||
|
}
|
||||||
|
|
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)
|
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)
|
project(wamr-simple)
|
|
@ -2,5 +2,4 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
idf_component_register(SRCS "main.c"
|
idf_component_register(SRCS "main.c"
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS ".")
|
||||||
REQUIRES wamr)
|
|
||||||
|
|
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"
|
#include "esp_log.h"
|
||||||
|
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
|
||||||
#define IWASM_MAIN_STACK_SIZE 5120
|
#define IWASM_MAIN_STACK_SIZE 5120
|
||||||
#else
|
|
||||||
#define IWASM_MAIN_STACK_SIZE 4096
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LOG_TAG "wamr"
|
#define LOG_TAG "wamr"
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,14 @@ include(CheckPIESupported)
|
||||||
|
|
||||||
project(debug_tools_sample)
|
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 ################
|
################ runtime settings ################
|
||||||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
@ -61,7 +69,30 @@ include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||||
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||||
|
|
||||||
################ wasm application ################
|
################ 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 ################
|
################ wamr runtime ################
|
||||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||||
|
|
|
@ -80,6 +80,39 @@ $ python3 ../../../test-tools/addr2line/addr2line.py \
|
||||||
call_stack.txt --no-addr
|
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
|
### 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.
|
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.
|
||||||
|
@ -97,4 +130,4 @@ Then the output should be something like
|
||||||
Exception: unreachable
|
Exception: unreachable
|
||||||
```
|
```
|
||||||
|
|
||||||
Also, it is able to use *addr2line.py* to add file and line info to the stack trace.
|
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.
|
# Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
if (APPLE)
|
cmake_minimum_required (VERSION 3.14)
|
||||||
set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
|
|
||||||
set (CMAKE_C_LINK_FLAGS "")
|
|
||||||
set (CMAKE_CXX_LINK_FLAGS "")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (NOT DEFINED WASI_SDK_DIR)
|
project (debut_tools_wasm)
|
||||||
set (WASI_SDK_DIR "/opt/wasi-sdk")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (DEFINED WASI_SYSROOT)
|
set (CMAKE_BUILD_TYPE Debug) # Otherwise no debug symbols (addr2line)
|
||||||
set (CMAKE_SYSROOT "${WASI_SYSROOT}")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang")
|
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../cmake)
|
||||||
set (CMAKE_ASM_COMPILER "${WASI_SDK_DIR}/bin/clang")
|
find_package (WAMRC REQUIRED)
|
||||||
set (CMAKE_EXE_LINKER_FLAGS "-target wasm32-wasi")
|
|
||||||
|
|
||||||
################ wabt and wamrc dependencies ################
|
option(SOURCE_MAP_DEMO "Enable source map demo" OFF)
|
||||||
message(CHECK_START "Detecting WABT")
|
if (SOURCE_MAP_DEMO)
|
||||||
if(NOT (DEFINED WABT_DIR OR DEFINED CACHE{WABT_DIR}))
|
find_package(EMSCRIPTEN 3.1.50 REQUIRED)
|
||||||
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 ()
|
endif ()
|
||||||
|
|
||||||
################ wasm and aot compilation ################
|
################ wasm and aot compilation ################
|
||||||
function (compile_sample SOURCE_FILE)
|
function (compile_sample SOURCE_FILE)
|
||||||
get_filename_component (FILE_NAME ${SOURCE_FILE} NAME_WLE)
|
get_filename_component (FILE_NAME ${SOURCE_FILE} NAME_WLE)
|
||||||
set (WASM_MODULE ${FILE_NAME}.wasm)
|
|
||||||
add_executable (${WASM_MODULE} ${SOURCE_FILE})
|
|
||||||
|
|
||||||
|
## 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 (
|
add_custom_target (
|
||||||
wasm_to_aot
|
${FILE_NAME}_aot
|
||||||
ALL
|
ALL
|
||||||
DEPENDS ${WAMR_COMPILER} ${WASM_MODULE}
|
DEPENDS ${WAMRC_BIN} ${WASM_FILE}
|
||||||
# Use --enable-dump-call-stack to generate stack trace (addr2line)
|
# 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
|
COMMAND ${WAMRC_BIN} --size-level=0 --enable-dump-call-stack -o ${AOT_FILE} ${WASM_FILE}
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
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 ()
|
endfunction ()
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE Debug) # Otherwise no debug symbols (addr2line)
|
|
||||||
compile_sample(trap.c)
|
compile_sample(trap.c)
|
|
@ -43,6 +43,28 @@ For example, there is a call-stack dump:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def locate_sourceMappingURL_section(wasm_objdump: Path, wasm_file: Path) -> bool:
|
||||||
|
"""
|
||||||
|
Figure out if the wasm file has a sourceMappingURL section.
|
||||||
|
"""
|
||||||
|
cmd = f"{wasm_objdump} -h {wasm_file}"
|
||||||
|
p = subprocess.run(
|
||||||
|
shlex.split(cmd),
|
||||||
|
check=True,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
universal_newlines=True,
|
||||||
|
)
|
||||||
|
outputs = p.stdout.split(os.linesep)
|
||||||
|
|
||||||
|
for line in outputs:
|
||||||
|
line = line.strip()
|
||||||
|
if "sourceMappingURL" in line:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
||||||
"""
|
"""
|
||||||
Find the start offset of Code section in a wasm file.
|
Find the start offset of Code section in a wasm file.
|
||||||
|
@ -62,15 +84,6 @@ def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
||||||
)
|
)
|
||||||
outputs = p.stdout.split(os.linesep)
|
outputs = p.stdout.split(os.linesep)
|
||||||
|
|
||||||
# if there is no .debug section, return -1
|
|
||||||
for line in outputs:
|
|
||||||
line = line.strip()
|
|
||||||
if ".debug_info" in line:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
print(f"No .debug_info section found {wasm_file}")
|
|
||||||
return -1
|
|
||||||
|
|
||||||
for line in outputs:
|
for line in outputs:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if "Code" in line:
|
if "Code" in line:
|
||||||
|
@ -79,7 +92,7 @@ def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
def get_line_info_from_function_addr(
|
def get_line_info_from_function_addr_dwarf(
|
||||||
dwarf_dump: Path, wasm_file: Path, offset: int
|
dwarf_dump: Path, wasm_file: Path, offset: int
|
||||||
) -> tuple[str, str, str, str]:
|
) -> tuple[str, str, str, str]:
|
||||||
"""
|
"""
|
||||||
|
@ -126,7 +139,7 @@ def get_dwarf_tag_value(tag: str, line: str) -> str:
|
||||||
return m.groups()[0]
|
return m.groups()[0]
|
||||||
|
|
||||||
|
|
||||||
def get_line_info_from_function_name(
|
def get_line_info_from_function_name_dwarf(
|
||||||
dwarf_dump: Path, wasm_file: Path, function_name: str
|
dwarf_dump: Path, wasm_file: Path, function_name: str
|
||||||
) -> tuple[str, str, str]:
|
) -> tuple[str, str, str]:
|
||||||
"""
|
"""
|
||||||
|
@ -160,6 +173,51 @@ def get_line_info_from_function_name(
|
||||||
return (function_name, function_file, function_line)
|
return (function_name, function_file, function_line)
|
||||||
|
|
||||||
|
|
||||||
|
def get_line_info_from_function_addr_sourcemapping(
|
||||||
|
emsymbolizer: Path, wasm_file: Path, offset: int
|
||||||
|
) -> tuple[str, str, str, str]:
|
||||||
|
"""
|
||||||
|
Find the location info of a given offset in a wasm file which is compiled with emcc.
|
||||||
|
|
||||||
|
{emsymbolizer} {wasm_file} {offset of file}
|
||||||
|
|
||||||
|
there usually are two lines:
|
||||||
|
??
|
||||||
|
relative path to source file:line:column
|
||||||
|
"""
|
||||||
|
debug_info_source = wasm_file.with_name(f"{wasm_file.name}.map")
|
||||||
|
cmd = f"{emsymbolizer} -t code -f {debug_info_source} {wasm_file} {offset}"
|
||||||
|
p = subprocess.run(
|
||||||
|
shlex.split(cmd),
|
||||||
|
check=False,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
universal_newlines=True,
|
||||||
|
cwd=Path.cwd(),
|
||||||
|
)
|
||||||
|
outputs = p.stdout.split(os.linesep)
|
||||||
|
|
||||||
|
function_name, function_file = "<unknown>", "unknown"
|
||||||
|
function_line, function_column = "?", "?"
|
||||||
|
|
||||||
|
for line in outputs:
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = re.match("(.*):(\d+):(\d+)", line)
|
||||||
|
if m:
|
||||||
|
function_file, function_line, function_column = m.groups()
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
# it's always ??, not sure about that
|
||||||
|
if "??" != line:
|
||||||
|
function_name = line
|
||||||
|
|
||||||
|
return (function_name, function_file, function_line, function_column)
|
||||||
|
|
||||||
|
|
||||||
def parse_line_info(line_info: str) -> tuple[str, str, str]:
|
def parse_line_info(line_info: str) -> tuple[str, str, str]:
|
||||||
"""
|
"""
|
||||||
line_info -> [file, line, column]
|
line_info -> [file, line, column]
|
||||||
|
@ -250,6 +308,7 @@ def main():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="use call stack without addresses or from fast interpreter mode",
|
help="use call stack without addresses or from fast interpreter mode",
|
||||||
)
|
)
|
||||||
|
parser.add_argument("--emsdk", type=Path, help="path to emsdk")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
wasm_objdump = args.wabt.joinpath("bin/wasm-objdump")
|
wasm_objdump = args.wabt.joinpath("bin/wasm-objdump")
|
||||||
|
@ -261,6 +320,15 @@ def main():
|
||||||
llvm_cxxfilt = args.wasi_sdk.joinpath("bin/llvm-cxxfilt")
|
llvm_cxxfilt = args.wasi_sdk.joinpath("bin/llvm-cxxfilt")
|
||||||
assert llvm_cxxfilt.exists()
|
assert llvm_cxxfilt.exists()
|
||||||
|
|
||||||
|
emcc_production = locate_sourceMappingURL_section(wasm_objdump, args.wasm_file)
|
||||||
|
if emcc_production:
|
||||||
|
if args.emsdk is None:
|
||||||
|
print("Please provide the path to emsdk via --emsdk")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
emsymbolizer = args.emsdk.joinpath("upstream/emscripten/emsymbolizer")
|
||||||
|
assert emsymbolizer.exists()
|
||||||
|
|
||||||
code_section_start = get_code_section_start(wasm_objdump, args.wasm_file)
|
code_section_start = get_code_section_start(wasm_objdump, args.wasm_file)
|
||||||
if code_section_start == -1:
|
if code_section_start == -1:
|
||||||
return -1
|
return -1
|
||||||
|
@ -281,6 +349,7 @@ def main():
|
||||||
|
|
||||||
_, offset, index = splitted
|
_, offset, index = splitted
|
||||||
if args.no_addr:
|
if args.no_addr:
|
||||||
|
# FIXME: w/ emcc production
|
||||||
if not index.startswith("$f"): # E.g. _start or Text format
|
if not index.startswith("$f"): # E.g. _start or Text format
|
||||||
print(f"{i}: {index}")
|
print(f"{i}: {index}")
|
||||||
continue
|
continue
|
||||||
|
@ -290,19 +359,37 @@ def main():
|
||||||
print(f"{i}: {line}")
|
print(f"{i}: {line}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
line_info = get_line_info_from_function_name(
|
if not emcc_production:
|
||||||
llvm_dwarf_dump, args.wasm_file, function_index_to_name[index]
|
_, function_file, function_line = (
|
||||||
|
get_line_info_from_function_name_dwarf(
|
||||||
|
llvm_dwarf_dump,
|
||||||
|
args.wasm_file,
|
||||||
|
function_index_to_name[index],
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_, function_file, function_line = _, "unknown", "?"
|
||||||
|
|
||||||
_, function_file, function_line = line_info
|
|
||||||
function_name = demangle(llvm_cxxfilt, function_index_to_name[index])
|
function_name = demangle(llvm_cxxfilt, function_index_to_name[index])
|
||||||
print(f"{i}: {function_name}")
|
print(f"{i}: {function_name}")
|
||||||
print(f"\tat {function_file}:{function_line}")
|
print(f"\tat {function_file}:{function_line}")
|
||||||
else:
|
else:
|
||||||
offset = int(offset, 16)
|
offset = int(offset, 16)
|
||||||
|
# match the algorithm in wasm_interp_create_call_stack()
|
||||||
|
# either a *offset* to *code* section start
|
||||||
|
# or a *offset* in a file
|
||||||
|
assert offset > code_section_start
|
||||||
offset = offset - code_section_start
|
offset = offset - code_section_start
|
||||||
|
|
||||||
|
if emcc_production:
|
||||||
function_name, function_file, function_line, function_column = (
|
function_name, function_file, function_line, function_column = (
|
||||||
get_line_info_from_function_addr(
|
get_line_info_from_function_addr_sourcemapping(
|
||||||
|
emsymbolizer, args.wasm_file, offset
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
function_name, function_file, function_line, function_column = (
|
||||||
|
get_line_info_from_function_addr_dwarf(
|
||||||
llvm_dwarf_dump, args.wasm_file, offset
|
llvm_dwarf_dump, args.wasm_file, offset
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -95,7 +95,7 @@ def ignore_the_case(
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if gc_flag:
|
if gc_flag:
|
||||||
if case_name in ["type-equivalence", "type-rec", "array_init_elem", "array_init_data"]:
|
if case_name in ["array_init_elem", "array_init_data"]:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if sgx_flag:
|
if sgx_flag:
|
||||||
|
|
|
@ -9,78 +9,6 @@ index 335496f0..5b975028 100644
|
||||||
- "integer representation too long"
|
- "integer representation too long"
|
||||||
+ "invalid type flag" ;; In GC extension, the first byte in rectype define is just one byte, not LEB128 encoded.
|
+ "invalid type flag" ;; In GC extension, the first byte in rectype define is just one byte, not LEB128 encoded.
|
||||||
)
|
)
|
||||||
diff --git a/test/core/binary.wast b/test/core/binary.wast
|
|
||||||
index 1661a1c6..84c716b9 100644
|
|
||||||
--- a/test/core/binary.wast
|
|
||||||
+++ b/test/core/binary.wast
|
|
||||||
@@ -1082,7 +1082,7 @@
|
|
||||||
)
|
|
||||||
|
|
||||||
;; 1 br_table target declared, 2 given
|
|
||||||
-(assert_malformed
|
|
||||||
+(;assert_malformed
|
|
||||||
(module binary
|
|
||||||
"\00asm" "\01\00\00\00"
|
|
||||||
"\01\04\01" ;; type section
|
|
||||||
@@ -1132,3 +1132,4 @@
|
|
||||||
)
|
|
||||||
"unexpected content after last section"
|
|
||||||
)
|
|
||||||
+;)
|
|
||||||
diff --git a/test/core/data.wast b/test/core/data.wast
|
|
||||||
index a5c87fbb..6f948bae 100644
|
|
||||||
--- a/test/core/data.wast
|
|
||||||
+++ b/test/core/data.wast
|
|
||||||
@@ -306,9 +306,10 @@
|
|
||||||
"\02\01\41\00\0b" ;; active data segment 0 for memory 1
|
|
||||||
"\00" ;; empty vec(byte)
|
|
||||||
)
|
|
||||||
- "unknown memory 1"
|
|
||||||
+ "unknown memory"
|
|
||||||
)
|
|
||||||
|
|
||||||
+(; not supported by wat2wasm
|
|
||||||
;; Data segment with memory index 0 (no memory section)
|
|
||||||
(assert_invalid
|
|
||||||
(module binary
|
|
||||||
@@ -317,7 +318,7 @@
|
|
||||||
"\00\41\00\0b" ;; active data segment 0 for memory 0
|
|
||||||
"\00" ;; empty vec(byte)
|
|
||||||
)
|
|
||||||
- "unknown memory 0"
|
|
||||||
+ "unknown memory"
|
|
||||||
)
|
|
||||||
|
|
||||||
;; Data segment with memory index 1 (no memory section)
|
|
||||||
@@ -328,7 +329,7 @@
|
|
||||||
"\02\01\41\00\0b" ;; active data segment 0 for memory 1
|
|
||||||
"\00" ;; empty vec(byte)
|
|
||||||
)
|
|
||||||
- "unknown memory 1"
|
|
||||||
+ "unknown memory"
|
|
||||||
)
|
|
||||||
|
|
||||||
;; Data segment with memory index 1 and vec(byte) as above,
|
|
||||||
@@ -348,7 +349,7 @@
|
|
||||||
"\20\21\22\23\24\25\26\27\28\29\2a\2b\2c\2d\2e\2f"
|
|
||||||
"\30\31\32\33\34\35\36\37\38\39\3a\3b\3c\3d"
|
|
||||||
)
|
|
||||||
- "unknown memory 1"
|
|
||||||
+ "unknown memory"
|
|
||||||
)
|
|
||||||
|
|
||||||
;; Data segment with memory index 1 and specially crafted vec(byte) after.
|
|
||||||
@@ -368,8 +369,9 @@
|
|
||||||
"\20\21\22\23\24\25\26\27\28\29\2a\2b\2c\2d\2e\2f"
|
|
||||||
"\30\31\32\33\34\35\36\37\38\39\3a\3b\3c\3d"
|
|
||||||
)
|
|
||||||
- "unknown memory 1"
|
|
||||||
+ "unknown memory"
|
|
||||||
)
|
|
||||||
+;)
|
|
||||||
|
|
||||||
|
|
||||||
;; Invalid offsets
|
|
||||||
diff --git a/test/core/elem.wast b/test/core/elem.wast
|
diff --git a/test/core/elem.wast b/test/core/elem.wast
|
||||||
index df1610f6..32c1d8b3 100644
|
index df1610f6..32c1d8b3 100644
|
||||||
--- a/test/core/elem.wast
|
--- a/test/core/elem.wast
|
||||||
|
@ -268,196 +196,11 @@ index 00000000..32650644
|
||||||
+ )
|
+ )
|
||||||
+ "unsupported initializer expression for table"
|
+ "unsupported initializer expression for table"
|
||||||
+)
|
+)
|
||||||
diff --git a/test/core/gc/ref_test.wast b/test/core/gc/ref_test.wast
|
|
||||||
index 590b81b8..e0aa49ed 100644
|
|
||||||
--- a/test/core/gc/ref_test.wast
|
|
||||||
+++ b/test/core/gc/ref_test.wast
|
|
||||||
@@ -310,15 +310,16 @@
|
|
||||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 11)))))
|
|
||||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 12)))))
|
|
||||||
|
|
||||||
- (br_if $l (i32.eqz (ref.test (ref $t1') (table.get (i32.const 1)))))
|
|
||||||
- (br_if $l (i32.eqz (ref.test (ref $t1') (table.get (i32.const 2)))))
|
|
||||||
+ ;; Must have explicit sub relationship
|
|
||||||
+ ;; (br_if $l (i32.eqz (ref.test (ref $t1') (table.get (i32.const 1)))))
|
|
||||||
+ ;; (br_if $l (i32.eqz (ref.test (ref $t1') (table.get (i32.const 2)))))
|
|
||||||
|
|
||||||
- (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 11)))))
|
|
||||||
- (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 12)))))
|
|
||||||
+ ;; (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 11)))))
|
|
||||||
+ ;; (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 12)))))
|
|
||||||
|
|
||||||
- (br_if $l (i32.eqz (ref.test (ref $t2') (table.get (i32.const 2)))))
|
|
||||||
+ ;; (br_if $l (i32.eqz (ref.test (ref $t2') (table.get (i32.const 2)))))
|
|
||||||
|
|
||||||
- (br_if $l (i32.eqz (ref.test (ref $t2) (table.get (i32.const 12)))))
|
|
||||||
+ ;; (br_if $l (i32.eqz (ref.test (ref $t2) (table.get (i32.const 12)))))
|
|
||||||
|
|
||||||
(return)
|
|
||||||
)
|
|
||||||
diff --git a/test/core/gc/type-subtyping.wast b/test/core/gc/type-subtyping.wast
|
diff --git a/test/core/gc/type-subtyping.wast b/test/core/gc/type-subtyping.wast
|
||||||
index a9022fc3..4e22e91b 100644
|
index a9022fc3..4aa36e2a 100644
|
||||||
--- a/test/core/gc/type-subtyping.wast
|
--- a/test/core/gc/type-subtyping.wast
|
||||||
+++ b/test/core/gc/type-subtyping.wast
|
+++ b/test/core/gc/type-subtyping.wast
|
||||||
@@ -112,6 +112,8 @@
|
@@ -740,7 +740,7 @@
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
+;; don't support recursive type equality and subtype check
|
|
||||||
+(;
|
|
||||||
(module
|
|
||||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
|
||||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
|
||||||
@@ -135,6 +137,7 @@
|
|
||||||
(func $g (type $g2))
|
|
||||||
(global (ref $g1) (ref.func $g))
|
|
||||||
)
|
|
||||||
+;)
|
|
||||||
|
|
||||||
(assert_invalid
|
|
||||||
(module
|
|
||||||
@@ -156,6 +159,8 @@
|
|
||||||
(global (ref $f1) (ref.func $g))
|
|
||||||
)
|
|
||||||
|
|
||||||
+;; don't support recursive type equality and subtype check
|
|
||||||
+(;
|
|
||||||
(module
|
|
||||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
|
||||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
|
||||||
@@ -201,6 +206,7 @@
|
|
||||||
(global (ref $g12) (ref.func $g12))
|
|
||||||
(global (ref $g22) (ref.func $g12))
|
|
||||||
)
|
|
||||||
+;)
|
|
||||||
|
|
||||||
(assert_invalid
|
|
||||||
(module
|
|
||||||
@@ -226,6 +232,8 @@
|
|
||||||
|
|
||||||
;; Runtime types
|
|
||||||
|
|
||||||
+;; don't support recursive type equality and subtype check
|
|
||||||
+(;
|
|
||||||
(module
|
|
||||||
(type $t0 (sub (func (result (ref null func)))))
|
|
||||||
(rec (type $t1 (sub $t0 (func (result (ref null $t1))))))
|
|
||||||
@@ -286,6 +294,7 @@
|
|
||||||
(assert_trap (invoke "fail4") "cast")
|
|
||||||
(assert_trap (invoke "fail5") "cast")
|
|
||||||
(assert_trap (invoke "fail6") "cast")
|
|
||||||
+;)
|
|
||||||
|
|
||||||
(module
|
|
||||||
(type $t1 (sub (func)))
|
|
||||||
@@ -316,7 +325,8 @@
|
|
||||||
(assert_trap (invoke "fail3") "cast")
|
|
||||||
(assert_trap (invoke "fail4") "cast")
|
|
||||||
|
|
||||||
-
|
|
||||||
+;; don't support recursive type equality and subtype check
|
|
||||||
+(;
|
|
||||||
(module
|
|
||||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
|
||||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
|
||||||
@@ -346,6 +356,7 @@
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(assert_return (invoke "run") (i32.const 1))
|
|
||||||
+;)
|
|
||||||
|
|
||||||
(module
|
|
||||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
|
||||||
@@ -370,6 +381,8 @@
|
|
||||||
)
|
|
||||||
(assert_return (invoke "run") (i32.const 1))
|
|
||||||
|
|
||||||
+;; don't support recursive type equality and subtype check
|
|
||||||
+(;
|
|
||||||
(module
|
|
||||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
|
||||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
|
||||||
@@ -390,7 +403,6 @@
|
|
||||||
)
|
|
||||||
(assert_return (invoke "run") (i32.const 1) (i32.const 1))
|
|
||||||
|
|
||||||
-
|
|
||||||
(module
|
|
||||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
|
||||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
|
||||||
@@ -429,7 +441,9 @@
|
|
||||||
(i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1)
|
|
||||||
(i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1)
|
|
||||||
)
|
|
||||||
+;)
|
|
||||||
|
|
||||||
+(; we use normalized function type index
|
|
||||||
(module
|
|
||||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f11 (func))))
|
|
||||||
(rec (type $f21 (sub (func))) (type $f22 (sub $f11 (func))))
|
|
||||||
@@ -439,6 +453,7 @@
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(assert_return (invoke "run") (i32.const 0))
|
|
||||||
+;)
|
|
||||||
|
|
||||||
(module
|
|
||||||
(rec (type $f01 (sub (func))) (type $f02 (sub $f01 (func))))
|
|
||||||
@@ -547,15 +562,15 @@
|
|
||||||
(func (import "M3" "g") (type $g1))
|
|
||||||
)
|
|
||||||
|
|
||||||
-(module
|
|
||||||
- (rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
|
||||||
- (rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
|
||||||
- (rec
|
|
||||||
- (type $g2 (sub $f2 (func)))
|
|
||||||
- (type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
|
||||||
- )
|
|
||||||
- (func (export "g") (type $g2))
|
|
||||||
-)
|
|
||||||
+;; (module
|
|
||||||
+;; (rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
|
||||||
+;; (rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
|
||||||
+;; (rec
|
|
||||||
+;; (type $g2 (sub $f2 (func)))
|
|
||||||
+;; (type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
|
||||||
+;; )
|
|
||||||
+;; (func (export "g") (type $g2))
|
|
||||||
+;; )
|
|
||||||
(register "M4")
|
|
||||||
(module
|
|
||||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
|
||||||
@@ -597,17 +612,17 @@
|
|
||||||
(func (import "M6" "g") (type $f1))
|
|
||||||
)
|
|
||||||
|
|
||||||
-(module
|
|
||||||
- (rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
|
||||||
- (rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
|
||||||
- (rec
|
|
||||||
- (type $g2 (sub $f2 (func)))
|
|
||||||
- (type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
|
||||||
- )
|
|
||||||
- (rec (type $h (sub $g2 (func))) (type (struct)))
|
|
||||||
- (func (export "h") (type $h))
|
|
||||||
-)
|
|
||||||
-(register "M7")
|
|
||||||
+;; (module
|
|
||||||
+;; (rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
|
||||||
+;; (rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
|
||||||
+;; (rec
|
|
||||||
+;; (type $g2 (sub $f2 (func)))
|
|
||||||
+;; (type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
|
||||||
+;; )
|
|
||||||
+;; (rec (type $h (sub $g2 (func))) (type (struct)))
|
|
||||||
+;; (func (export "h") (type $h))
|
|
||||||
+;; )
|
|
||||||
+;; (register "M7")
|
|
||||||
(module
|
|
||||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
|
||||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
|
||||||
@@ -740,7 +755,7 @@
|
|
||||||
"sub type"
|
"sub type"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -466,7 +209,7 @@ index a9022fc3..4e22e91b 100644
|
||||||
(module
|
(module
|
||||||
(type $f0 (sub (func (param i32) (result i32))))
|
(type $f0 (sub (func (param i32) (result i32))))
|
||||||
(type $s0 (sub $f0 (struct)))
|
(type $s0 (sub $f0 (struct)))
|
||||||
@@ -764,7 +779,7 @@
|
@@ -764,7 +764,7 @@
|
||||||
"sub type"
|
"sub type"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -475,7 +218,7 @@ index a9022fc3..4e22e91b 100644
|
||||||
(module
|
(module
|
||||||
(type $s0 (sub (struct)))
|
(type $s0 (sub (struct)))
|
||||||
(type $f0 (sub $s0 (func (param i32) (result i32))))
|
(type $f0 (sub $s0 (func (param i32) (result i32))))
|
||||||
@@ -772,7 +787,7 @@
|
@@ -772,7 +772,7 @@
|
||||||
"sub type"
|
"sub type"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1262,29 +1005,3 @@ index 0b2d26f7..bdab6a01 100644
|
||||||
(table $t0 30 30 funcref)
|
(table $t0 30 30 funcref)
|
||||||
(table $t1 30 30 funcref)
|
(table $t1 30 30 funcref)
|
||||||
(elem (table $t1) (i32.const 2) func 3 1 4 1)
|
(elem (table $t1) (i32.const 2) func 3 1 4 1)
|
||||||
diff --git a/test/core/unreached-valid.wast b/test/core/unreached-valid.wast
|
|
||||||
index f3feb0f3..d8ef8743 100644
|
|
||||||
--- a/test/core/unreached-valid.wast
|
|
||||||
+++ b/test/core/unreached-valid.wast
|
|
||||||
@@ -60,7 +60,7 @@
|
|
||||||
|
|
||||||
;; Validation after unreachable
|
|
||||||
|
|
||||||
-(module
|
|
||||||
+(;module
|
|
||||||
(func (export "meet-bottom")
|
|
||||||
(block (result f64)
|
|
||||||
(block (result f32)
|
|
||||||
@@ -76,7 +76,6 @@
|
|
||||||
|
|
||||||
(assert_trap (invoke "meet-bottom") "unreachable")
|
|
||||||
|
|
||||||
-
|
|
||||||
;; Bottom heap type
|
|
||||||
|
|
||||||
(module
|
|
||||||
@@ -106,3 +105,4 @@
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
+;)
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user