mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-11 12:11:14 +00:00
Merge pull request #3465 from bytecodealliance/main
Merge branch main into dev/checkpoint_and_restore
This commit is contained in:
commit
17ff9435c6
4
.github/scripts/codeql_buildscript.sh
vendored
4
.github/scripts/codeql_buildscript.sh
vendored
|
@ -7,7 +7,7 @@
|
|||
|
||||
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-12-dev lib32gcc-12-dev ccache ninja-build
|
||||
|
||||
WAMR_DIR=${PWD}
|
||||
|
||||
|
@ -264,7 +264,7 @@ fi
|
|||
# build iwasm with configurable bounds checks enabled
|
||||
cd ${WAMR_DIR}/product-mini/platforms/linux
|
||||
rm -rf build && mkdir build && cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_CONFIGUABLE_BOUNDS_CHECKS=1
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_CONFIGURABLE_BOUNDS_CHECKS=1
|
||||
make -j
|
||||
if [[ $? != 0 ]]; then
|
||||
echo "Failed to build iwasm with configurable bounds checks enabled!"
|
||||
|
|
2
.github/workflows/build_iwasm_release.yml
vendored
2
.github/workflows/build_iwasm_release.yml
vendored
|
@ -11,7 +11,7 @@ on:
|
|||
required: false
|
||||
default: x86_64
|
||||
cwd:
|
||||
description: workfing directory
|
||||
description: working directory
|
||||
type: string
|
||||
required: true
|
||||
llvm_cache_key:
|
||||
|
|
2
.github/workflows/build_llvm_libraries.yml
vendored
2
.github/workflows/build_llvm_libraries.yml
vendored
|
@ -43,7 +43,7 @@ jobs:
|
|||
run: /usr/bin/env python3 -m pip install -r requirements.txt --break-system-packages
|
||||
working-directory: build-scripts
|
||||
|
||||
- name: retrive the last commit ID
|
||||
- name: retrieve the last commit ID
|
||||
id: get_last_commit
|
||||
run: echo "last_commit=$(GH_TOKEN=${{ secrets.GITHUB_TOKEN }} /usr/bin/env python3 ./build_llvm.py --llvm-ver)" >> $GITHUB_OUTPUT
|
||||
working-directory: build-scripts
|
||||
|
|
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
|
@ -28,7 +28,7 @@ jobs:
|
|||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners
|
||||
# Consider using larger runners for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-13') || 'ubuntu-20.04' }}
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-13') || 'ubuntu-22.04' }}
|
||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
||||
permissions:
|
||||
actions: read
|
||||
|
|
|
@ -150,8 +150,8 @@ jobs:
|
|||
os: [ubuntu-22.04]
|
||||
platform: [android, linux]
|
||||
exclude:
|
||||
# uncompatiable feature and platform
|
||||
# uncompatiable mode and feature
|
||||
# incompatible feature and platform
|
||||
# incompatible mode and feature
|
||||
# MULTI_MODULE only on INTERP mode and AOT mode
|
||||
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
|
||||
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
|
||||
|
@ -542,7 +542,7 @@ jobs:
|
|||
running_mode: aot
|
||||
test_option: $WAMR_COMPILER_TEST_OPTIONS
|
||||
exclude:
|
||||
# uncompatiable modes and features
|
||||
# incompatible modes and features
|
||||
# classic-interp and fast-interp don't support simd
|
||||
- running_mode: "classic-interp"
|
||||
test_option: $SIMD_TEST_OPTIONS
|
||||
|
@ -566,9 +566,7 @@ jobs:
|
|||
test_option: $GC_TEST_OPTIONS
|
||||
- running_mode: "multi-tier-jit"
|
||||
test_option: $GC_TEST_OPTIONS
|
||||
# aot, fast-interp, fast-jit, llvm-jit, multi-tier-jit don't support Memory64
|
||||
- running_mode: "aot"
|
||||
test_option: $MEMORY64_TEST_OPTIONS
|
||||
# fast-interp, fast-jit, llvm-jit, multi-tier-jit don't support Memory64
|
||||
- running_mode: "fast-interp"
|
||||
test_option: $MEMORY64_TEST_OPTIONS
|
||||
- running_mode: "fast-jit"
|
||||
|
@ -616,6 +614,7 @@ jobs:
|
|||
if: >
|
||||
((matrix.test_option == '$DEFAULT_TEST_OPTIONS' || matrix.test_option == '$THREADS_TEST_OPTIONS'
|
||||
|| matrix.test_option == '$WASI_TEST_OPTIONS' || matrix.test_option == '$GC_TEST_OPTIONS')
|
||||
&& matrix.test_option != '$MEMORY64_TEST_OPTIONS'
|
||||
&& matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit')
|
||||
run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV
|
||||
|
||||
|
|
4
.github/workflows/compilation_on_macos.yml
vendored
4
.github/workflows/compilation_on_macos.yml
vendored
|
@ -134,8 +134,8 @@ jobs:
|
|||
os: [macos-13]
|
||||
platform: [darwin]
|
||||
exclude:
|
||||
# uncompatiable feature and platform
|
||||
# uncompatiable mode and feature
|
||||
# incompatible feature and platform
|
||||
# incompatible mode and feature
|
||||
# MULTI_MODULE only on INTERP mode and AOT mode
|
||||
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
|
||||
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
|
||||
|
|
20
.github/workflows/compilation_on_sgx.yml
vendored
20
.github/workflows/compilation_on_sgx.yml
vendored
|
@ -99,7 +99,7 @@ jobs:
|
|||
os: [ubuntu-20.04]
|
||||
platform: [linux-sgx]
|
||||
exclude:
|
||||
# uncompatiable mode and feature
|
||||
# incompatible mode and feature
|
||||
# MINI_LOADER only on INTERP mode
|
||||
- make_options_run_mode: $AOT_BUILD_OPTIONS
|
||||
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
|
||||
|
@ -269,23 +269,24 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
running_mode: ["classic-interp", "fast-interp", "aot", "fast-jit"]
|
||||
test_option: ["-x -p -s spec -b -P", "-x -p -s spec -S -b -P", "-x -p -s spec -X -b -P"]
|
||||
# FIXME: use binary release(adding -b) instead of building from source after upgrading to 22.04
|
||||
test_option: ["-x -p -s spec -P", "-x -p -s spec -S -P", "-x -p -s spec -X -P"]
|
||||
llvm_cache_key: ["${{ needs.build_llvm_libraries.outputs.cache_key }}"]
|
||||
exclude:
|
||||
# classic-interp, fast-interp and fast-jit don't support simd
|
||||
- running_mode: "classic-interp"
|
||||
test_option: "-x -p -s spec -S -b -P"
|
||||
test_option: "-x -p -s spec -S -P"
|
||||
- running_mode: "fast-interp"
|
||||
test_option: "-x -p -s spec -S -b -P"
|
||||
test_option: "-x -p -s spec -S -P"
|
||||
- running_mode: "fast-jit"
|
||||
test_option: "-x -p -s spec -S -b -P"
|
||||
test_option: "-x -p -s spec -S -P"
|
||||
# classic-interp, fast-interp and fast jit don't support XIP
|
||||
- running_mode: "classic-interp"
|
||||
test_option: "-x -p -s spec -X -b -P"
|
||||
test_option: "-x -p -s spec -X -P"
|
||||
- running_mode: "fast-interp"
|
||||
test_option: "-x -p -s spec -X -b -P"
|
||||
test_option: "-x -p -s spec -X -P"
|
||||
- running_mode: "fast-jit"
|
||||
test_option: "-x -p -s spec -X -b -P"
|
||||
test_option: "-x -p -s spec -X -P"
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
|
@ -320,6 +321,9 @@ jobs:
|
|||
sudo apt update
|
||||
sudo apt install -y libsgx-launch libsgx-urts
|
||||
|
||||
- name: install for wabt compilation
|
||||
run: sudo apt update && sudo apt install -y ninja-build
|
||||
|
||||
- name: run spec tests
|
||||
run: |
|
||||
source /opt/intel/sgxsdk/environment
|
||||
|
|
22
.github/workflows/nightly_run.yml
vendored
22
.github/workflows/nightly_run.yml
vendored
|
@ -36,10 +36,11 @@ env:
|
|||
LLVM_EAGER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_FAST_JIT=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0"
|
||||
MULTI_TIER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1"
|
||||
# For Spec Test
|
||||
DEFAULT_TEST_OPTIONS: "-s spec -b -P"
|
||||
MULTI_MODULES_TEST_OPTIONS: "-s spec -b -M -P"
|
||||
SIMD_TEST_OPTIONS: "-s spec -b -S -P"
|
||||
THREADS_TEST_OPTIONS: "-s spec -b -p -P"
|
||||
# FIXME: use binary release(adding -b) instead of building from source after upgrading to 22.04
|
||||
DEFAULT_TEST_OPTIONS: "-s spec -P"
|
||||
MULTI_MODULES_TEST_OPTIONS: "-s spec -M -P"
|
||||
SIMD_TEST_OPTIONS: "-s spec -S -P"
|
||||
THREADS_TEST_OPTIONS: "-s spec -p -P"
|
||||
X86_32_TARGET_TEST_OPTIONS: "-m x86_32 -P"
|
||||
WASI_TEST_OPTIONS: "-s wasi_certification -w"
|
||||
|
||||
|
@ -135,8 +136,8 @@ jobs:
|
|||
os: [ubuntu-20.04]
|
||||
platform: [android, linux]
|
||||
exclude:
|
||||
# uncompatiable feature and platform
|
||||
# uncompatiable mode and feature
|
||||
# incompatible feature and platform
|
||||
# incompatible mode and feature
|
||||
# MULTI_MODULE only on INTERP mode and AOT mode
|
||||
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
|
||||
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
|
||||
|
@ -290,8 +291,8 @@ jobs:
|
|||
"-DWAMR_BUILD_MEMORY64=1",
|
||||
]
|
||||
exclude:
|
||||
# uncompatiable feature and platform
|
||||
# uncompatiable mode and feature
|
||||
# incompatible feature and platform
|
||||
# incompatible mode and feature
|
||||
# MULTI_MODULE only on INTERP mode and AOT mode
|
||||
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
|
||||
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
|
||||
|
@ -619,7 +620,7 @@ jobs:
|
|||
ubuntu_version: "22.04"
|
||||
|
||||
exclude:
|
||||
# uncompatiable modes and features
|
||||
# incompatible modes and features
|
||||
- os: ubuntu-20.04
|
||||
sanitizer: tsan
|
||||
# asan works only for aot now
|
||||
|
@ -719,6 +720,9 @@ jobs:
|
|||
if: matrix.running_mode == 'aot' && matrix.test_option == '$WASI_TEST_OPTIONS'
|
||||
run: sudo apt-get update && sudo apt install -y jq
|
||||
|
||||
- name: install for wabt compilation
|
||||
run: sudo apt update && sudo apt install -y ninja-build
|
||||
|
||||
- name: Build WASI thread tests
|
||||
if: matrix.test_option == '$WASI_TEST_OPTIONS'
|
||||
run: bash build.sh --sysroot "$SYSROOT_PATH"
|
||||
|
|
|
@ -16,6 +16,13 @@ if (NOT DEFINED WAMR_BUILD_PLATFORM)
|
|||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_STATIC)
|
||||
set (WAMR_BUILD_STATIC 1)
|
||||
endif ()
|
||||
if (NOT DEFINED WAMR_BUILD_SHARED)
|
||||
set (WAMR_BUILD_SHARED 1)
|
||||
endif ()
|
||||
|
||||
# Reset default linker flags
|
||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||
|
@ -136,30 +143,34 @@ endif ()
|
|||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
|
||||
# STATIC LIBRARY
|
||||
add_library(iwasm_static STATIC ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
set_target_properties (iwasm_static PROPERTIES OUTPUT_NAME vmlib)
|
||||
target_include_directories(iwasm_static INTERFACE ${WAMR_ROOT_DIR}/core/iwasm/include)
|
||||
target_link_libraries (iwasm_static INTERFACE ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
|
||||
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
|
||||
target_link_libraries(iwasm_static INTERFACE boringssl_crypto)
|
||||
endif ()
|
||||
if (WAMR_BUILD_STATIC)
|
||||
add_library(iwasm_static STATIC ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
set_target_properties (iwasm_static PROPERTIES OUTPUT_NAME vmlib)
|
||||
target_include_directories(iwasm_static INTERFACE ${WAMR_ROOT_DIR}/core/iwasm/include)
|
||||
target_link_libraries (iwasm_static INTERFACE ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
|
||||
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
|
||||
target_link_libraries(iwasm_static INTERFACE boringssl_crypto)
|
||||
endif ()
|
||||
|
||||
install (TARGETS iwasm_static ARCHIVE DESTINATION lib)
|
||||
install (TARGETS iwasm_static ARCHIVE DESTINATION lib)
|
||||
endif ()
|
||||
|
||||
# SHARED LIBRARY
|
||||
add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm)
|
||||
target_include_directories(iwasm_shared INTERFACE ${WAMR_ROOT_DIR}/core/iwasm/include)
|
||||
target_link_libraries (iwasm_shared INTERFACE ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
|
||||
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
|
||||
target_link_libraries(iwasm_shared INTERFACE boringssl_crypto)
|
||||
endif ()
|
||||
if (WAMR_BUILD_SHARED)
|
||||
add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm)
|
||||
target_include_directories(iwasm_shared INTERFACE ${WAMR_ROOT_DIR}/core/iwasm/include)
|
||||
target_link_libraries (iwasm_shared INTERFACE ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
|
||||
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
|
||||
target_link_libraries(iwasm_shared INTERFACE boringssl_crypto)
|
||||
endif ()
|
||||
|
||||
if (MINGW)
|
||||
target_link_libraries (iwasm_shared INTERFACE -lWs2_32 -lwsock32)
|
||||
endif ()
|
||||
if (MINGW)
|
||||
target_link_libraries (iwasm_shared INTERFACE -lWs2_32 -lwsock32)
|
||||
endif ()
|
||||
|
||||
install (TARGETS iwasm_shared LIBRARY DESTINATION lib)
|
||||
install (TARGETS iwasm_shared LIBRARY DESTINATION lib)
|
||||
endif ()
|
||||
|
||||
# HEADERS
|
||||
install (FILES
|
||||
|
|
|
@ -261,7 +261,7 @@ def main():
|
|||
"xtensa": {
|
||||
"repo": "https://github.com/espressif/llvm-project.git",
|
||||
"repo_ssh": "git@github.com:espressif/llvm-project.git",
|
||||
"branch": "xtensa_release_15.x",
|
||||
"branch": "xtensa_release_17.0.1",
|
||||
},
|
||||
"default": {
|
||||
"repo": "https://github.com/llvm/llvm-project.git",
|
||||
|
|
|
@ -516,7 +516,7 @@ if (WAMR_BUILD_TARGET STREQUAL "X86_64"
|
|||
message (" Write linear memory base addr to x86 GS register enabled")
|
||||
endif ()
|
||||
endif ()
|
||||
if (WAMR_CONFIGUABLE_BOUNDS_CHECKS EQUAL 1)
|
||||
if (WAMR_CONFIGURABLE_BOUNDS_CHECKS EQUAL 1)
|
||||
add_definitions (-DWASM_CONFIGURABLE_BOUNDS_CHECKS=1)
|
||||
message (" Configurable bounds checks enabled")
|
||||
endif ()
|
||||
|
|
|
@ -14,7 +14,7 @@ docker build \
|
|||
--cap-add=SYS_PTRACE \
|
||||
--cpus=".5" \
|
||||
--memory=4G \
|
||||
--mount type=bind,src="${ROOT}",dst=/workspace \
|
||||
--mount type=bind,src="${ROOT}",dst=/workspaces \
|
||||
--name wamr_build_env \
|
||||
--security-opt=seccomp=unconfined \
|
||||
wamr_dev_${VARIANT}:0.1 \
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
import argparse
|
||||
import re
|
||||
import pathlib
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
|
@ -46,18 +46,18 @@ def locate_command(command: str) -> bool:
|
|||
|
||||
|
||||
def is_excluded(path: str) -> bool:
|
||||
path = pathlib.Path(path).resolve()
|
||||
path = Path(path).resolve()
|
||||
for exclude_path in EXCLUDE_PATHS:
|
||||
if path.match(exclude_path):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def pre_flight_check(root: pathlib) -> bool:
|
||||
def pre_flight_check(root: Path) -> bool:
|
||||
def check_aspell(root):
|
||||
return True
|
||||
|
||||
def check_clang_foramt(root: pathlib) -> bool:
|
||||
def check_clang_format(root: Path) -> bool:
|
||||
if not locate_command(CLANG_FORMAT_CMD):
|
||||
return False
|
||||
|
||||
|
@ -74,10 +74,10 @@ def pre_flight_check(root: pathlib) -> bool:
|
|||
def check_git_clang_format() -> bool:
|
||||
return locate_command(GIT_CLANG_FORMAT_CMD)
|
||||
|
||||
return check_aspell(root) and check_clang_foramt(root) and check_git_clang_format()
|
||||
return check_aspell(root) and check_clang_format(root) and check_git_clang_format()
|
||||
|
||||
|
||||
def run_clang_format(file_path: pathlib, root: pathlib) -> bool:
|
||||
def run_clang_format(file_path: Path, root: Path) -> bool:
|
||||
try:
|
||||
subprocess.check_call(
|
||||
shlex.split(
|
||||
|
@ -91,7 +91,7 @@ def run_clang_format(file_path: pathlib, root: pathlib) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def run_clang_format_diff(root: pathlib, commits: str) -> bool:
|
||||
def run_clang_format_diff(root: Path, commits: str) -> bool:
|
||||
"""
|
||||
Use `clang-format-12` or `git-clang-format-12` to check code format of
|
||||
the PR, with a commit range specified. It is required to format the
|
||||
|
@ -155,11 +155,11 @@ def run_clang_format_diff(root: pathlib, commits: str) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def run_aspell(file_path: pathlib, root: pathlib) -> bool:
|
||||
def run_aspell(file_path: Path, root: Path) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def check_dir_name(path: pathlib, root: pathlib) -> bool:
|
||||
def check_dir_name(path: Path, root: Path) -> bool:
|
||||
m = re.search(INVALID_DIR_NAME_SEGMENT, str(path.relative_to(root).parent))
|
||||
if m:
|
||||
print(f"--- found a character '_' in {m.groups()} in {path}")
|
||||
|
@ -167,7 +167,22 @@ def check_dir_name(path: pathlib, root: pathlib) -> bool:
|
|||
return not m
|
||||
|
||||
|
||||
def check_file_name(path: pathlib) -> bool:
|
||||
def check_file_name(path: Path) -> bool:
|
||||
"""
|
||||
file names should not contain any character '-'
|
||||
|
||||
but some names are well known and use '-' as the separator, e.g.:
|
||||
- docker-compose
|
||||
- package-lock
|
||||
- vite-env.d
|
||||
"""
|
||||
if path.stem in [
|
||||
"docker-compose",
|
||||
"package-lock",
|
||||
"vite-env.d",
|
||||
]:
|
||||
return True
|
||||
|
||||
m = re.search(INVALID_FILE_NAME_SEGMENT, path.stem)
|
||||
if m:
|
||||
print(f"--- found a character '-' in {m.groups()} in {path}")
|
||||
|
@ -175,7 +190,7 @@ def check_file_name(path: pathlib) -> bool:
|
|||
return not m
|
||||
|
||||
|
||||
def parse_commits_range(root: pathlib, commits: str) -> list:
|
||||
def parse_commits_range(root: Path, commits: str) -> list:
|
||||
GIT_LOG_CMD = f"git log --pretty='%H' {commits}"
|
||||
try:
|
||||
ret = subprocess.check_output(
|
||||
|
@ -187,7 +202,7 @@ def parse_commits_range(root: pathlib, commits: str) -> list:
|
|||
return []
|
||||
|
||||
|
||||
def analysis_new_item_name(root: pathlib, commit: str) -> bool:
|
||||
def analysis_new_item_name(root: Path, commit: str) -> bool:
|
||||
"""
|
||||
For any file name in the repo, it is required to use '_' to replace '-'.
|
||||
|
||||
|
@ -216,7 +231,7 @@ def analysis_new_item_name(root: pathlib, commit: str) -> bool:
|
|||
continue
|
||||
|
||||
new_item = match.group(1)
|
||||
new_item = pathlib.Path(new_item).resolve()
|
||||
new_item = Path(new_item).resolve()
|
||||
|
||||
if new_item.is_file():
|
||||
if not check_file_name(new_item):
|
||||
|
@ -235,7 +250,7 @@ def analysis_new_item_name(root: pathlib, commit: str) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def process_entire_pr(root: pathlib, commits: str) -> bool:
|
||||
def process_entire_pr(root: Path, commits: str) -> bool:
|
||||
if not commits:
|
||||
print("Please provide a commits range")
|
||||
return False
|
||||
|
@ -268,7 +283,7 @@ def main() -> int:
|
|||
)
|
||||
options = parser.parse_args()
|
||||
|
||||
wamr_root = pathlib.Path(__file__).parent.joinpath("..").resolve()
|
||||
wamr_root = Path(__file__).parent.joinpath("..").resolve()
|
||||
|
||||
if not pre_flight_check(wamr_root):
|
||||
return False
|
||||
|
@ -279,23 +294,23 @@ def main() -> int:
|
|||
# run with python3 -m unitest ci/coding_guidelines_check.py
|
||||
class TestCheck(unittest.TestCase):
|
||||
def test_check_dir_name_failed(self):
|
||||
root = pathlib.Path("/root/Workspace/")
|
||||
root = Path("/root/Workspace/")
|
||||
new_file_path = root.joinpath("core/shared/platform/esp_idf/espid_memmap.c")
|
||||
self.assertFalse(check_dir_name(new_file_path, root))
|
||||
|
||||
def test_check_dir_name_pass(self):
|
||||
root = pathlib.Path("/root/Workspace/")
|
||||
root = Path("/root/Workspace/")
|
||||
new_file_path = root.joinpath("core/shared/platform/esp-idf/espid_memmap.c")
|
||||
self.assertTrue(check_dir_name(new_file_path, root))
|
||||
|
||||
def test_check_file_name_failed(self):
|
||||
new_file_path = pathlib.Path(
|
||||
new_file_path = Path(
|
||||
"/root/Workspace/core/shared/platform/esp-idf/espid-memmap.c"
|
||||
)
|
||||
self.assertFalse(check_file_name(new_file_path))
|
||||
|
||||
def test_check_file_name_pass(self):
|
||||
new_file_path = pathlib.Path(
|
||||
new_file_path = Path(
|
||||
"/root/Workspace/core/shared/platform/esp-idf/espid_memmap.c"
|
||||
)
|
||||
self.assertTrue(check_file_name(new_file_path))
|
||||
|
|
|
@ -304,7 +304,7 @@
|
|||
#define WASM_DISABLE_STACK_HW_BOUND_CHECK 0
|
||||
#endif
|
||||
|
||||
/* Disable SIMD unless it is manualy enabled somewhere */
|
||||
/* Disable SIMD unless it is manually enabled somewhere */
|
||||
#ifndef WASM_ENABLE_SIMD
|
||||
#define WASM_ENABLE_SIMD 0
|
||||
#endif
|
||||
|
@ -368,32 +368,15 @@
|
|||
#define WASM_GLOBAL_HEAP_SIZE (10 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
/* Max app number of all modules */
|
||||
#define MAX_APP_INSTALLATIONS 3
|
||||
|
||||
/* Default timer number in one app */
|
||||
#define DEFAULT_TIMERS_PER_APP 20
|
||||
|
||||
/* Max timer number in one app */
|
||||
#define MAX_TIMERS_PER_APP 30
|
||||
|
||||
/* Max connection number in one app */
|
||||
#define MAX_CONNECTION_PER_APP 20
|
||||
|
||||
/* Max resource registration number in one app */
|
||||
#define RESOURCE_REGISTRATION_NUM_MAX 16
|
||||
|
||||
/* Max length of resource/event url */
|
||||
#define RESOUCE_EVENT_URL_LEN_MAX 256
|
||||
|
||||
/* Default length of queue */
|
||||
#ifndef DEFAULT_QUEUE_LENGTH
|
||||
#define DEFAULT_QUEUE_LENGTH 50
|
||||
|
||||
/* Default watchdog interval in ms */
|
||||
#define DEFAULT_WATCHDOG_INTERVAL (3 * 60 * 1000)
|
||||
#endif
|
||||
|
||||
/* The max percentage of global heap that app memory space can grow */
|
||||
#ifndef APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
|
||||
#define APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT 1 / 3
|
||||
#endif
|
||||
|
||||
/* Default min/max heap size of each app */
|
||||
#ifndef APP_HEAP_SIZE_DEFAULT
|
||||
|
@ -445,7 +428,7 @@
|
|||
#endif
|
||||
|
||||
/* Reserved bytes to the native thread stack boundary, throw native
|
||||
* stack overflow exception if the guard boudary is reached
|
||||
* stack overflow exception if the guard boundary is reached
|
||||
*
|
||||
* WASM_STACK_GUARD_SIZE needs to be large enough for:
|
||||
*
|
||||
|
@ -461,7 +444,7 @@
|
|||
* - aot runtime functions
|
||||
* eg. aot_enlarge_memory.
|
||||
*
|
||||
* - w/o hw bound check, the intepreter loop
|
||||
* - w/o hw bound check, the interpreter loop
|
||||
*
|
||||
* the stack consumption heavily depends on compiler settings,
|
||||
* especially for huge functions like the classic interpreter's
|
||||
|
@ -470,8 +453,23 @@
|
|||
* 200 bytes (release build, macOS/amd64)
|
||||
* 2600 bytes (debug build, macOS/amd64)
|
||||
*
|
||||
* libc snprintf (used by eg. wasm_runtime_set_exception) consumes about
|
||||
* 1600 bytes stack on macOS/amd64, about 2000 bytes on Ubuntu amd64 20.04.
|
||||
* - platform-provided functions (eg. libc)
|
||||
*
|
||||
* the following are examples of the stack consumptions observed for
|
||||
* host APIs.
|
||||
*
|
||||
* snprintf: (used by eg. wasm_runtime_set_exception)
|
||||
* - about 1600 bytes on macOS/amd64
|
||||
* - about 2000 bytes on Ubuntu amd64 20.04
|
||||
*
|
||||
* gethostbyname:
|
||||
* - 3KB-6KB on macOS/amd64
|
||||
* - 10KB on Ubuntu amd64 20.04
|
||||
*
|
||||
* getaddrinfo:
|
||||
* - 4KB-17KB on macOS/amd64
|
||||
* - 12KB on Ubuntu amd64 20.04
|
||||
* - 0.3-1.5KB on NuttX/esp32s3
|
||||
*
|
||||
* - stack check wrapper functions generated by the aot compiler
|
||||
* (--stack-bounds-checks=1)
|
||||
|
@ -480,6 +478,9 @@
|
|||
* "precheck functions themselves consume relatively large amount of stack"
|
||||
* when it detects wrapper functions requiring more than 1KB.
|
||||
*
|
||||
* - the ABI-defined red zone. eg. 128 bytes for SYSV x86-64 ABI.
|
||||
* cf. https://en.wikipedia.org/wiki/Red_zone_(computing)
|
||||
*
|
||||
* Note: on platforms with lazy function binding, don't forget to consider
|
||||
* the symbol resolution overhead on the first call. For example,
|
||||
* on Ubuntu amd64 20.04, it seems to consume about 1500 bytes.
|
||||
|
@ -496,7 +497,7 @@
|
|||
/*
|
||||
* Use a larger default for platforms like macOS/Linux.
|
||||
*
|
||||
* For example, the classic intepreter loop which ended up with a trap
|
||||
* For example, the classic interpreter loop which ended up with a trap
|
||||
* (wasm_runtime_set_exception) would consume about 2KB stack on x86-64
|
||||
* macOS. On Ubuntu amd64 20.04, it seems to consume a bit more.
|
||||
*
|
||||
|
|
|
@ -685,7 +685,7 @@ add_f64xi64_intrinsics(AOTCompContext *comp_ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
add_common_float_integer_convertion(AOTCompContext *comp_ctx)
|
||||
add_common_float_integer_conversion(AOTCompContext *comp_ctx)
|
||||
{
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_TO_F32);
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_U32_TO_F32);
|
||||
|
@ -851,7 +851,7 @@ aot_intrinsic_fill_capability_flags(AOTCompContext *comp_ctx)
|
|||
add_f32_common_intrinsics(comp_ctx);
|
||||
add_f64_common_intrinsics(comp_ctx);
|
||||
add_i64_common_intrinsics(comp_ctx);
|
||||
add_common_float_integer_convertion(comp_ctx);
|
||||
add_common_float_integer_conversion(comp_ctx);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(comp_ctx->target_arch, "riscv", 5)) {
|
||||
|
@ -862,7 +862,7 @@ aot_intrinsic_fill_capability_flags(AOTCompContext *comp_ctx)
|
|||
*/
|
||||
add_f32_common_intrinsics(comp_ctx);
|
||||
add_f64_common_intrinsics(comp_ctx);
|
||||
add_common_float_integer_convertion(comp_ctx);
|
||||
add_common_float_integer_conversion(comp_ctx);
|
||||
if (!strncmp(comp_ctx->target_arch, "riscv32", 7)) {
|
||||
add_i64_common_intrinsics(comp_ctx);
|
||||
}
|
||||
|
@ -876,7 +876,7 @@ aot_intrinsic_fill_capability_flags(AOTCompContext *comp_ctx)
|
|||
add_i32_common_intrinsics(comp_ctx);
|
||||
add_f64_common_intrinsics(comp_ctx);
|
||||
add_i64_common_intrinsics(comp_ctx);
|
||||
add_common_float_integer_convertion(comp_ctx);
|
||||
add_common_float_integer_conversion(comp_ctx);
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F32_CONST);
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F64_CONST);
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_CONST);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "aot_reloc.h"
|
||||
#include "../common/wasm_runtime_common.h"
|
||||
#include "../common/wasm_native.h"
|
||||
#include "../common/wasm_loader_common.h"
|
||||
#include "../compilation/aot.h"
|
||||
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
|
@ -94,7 +95,7 @@ check_buf(const uint8 *buf, const uint8 *buf_end, uint32 length,
|
|||
{
|
||||
if ((uintptr_t)buf + length < (uintptr_t)buf
|
||||
|| (uintptr_t)buf + length > (uintptr_t)buf_end) {
|
||||
set_error_buf(error_buf, error_buf_size, "unexpect end");
|
||||
set_error_buf(error_buf, error_buf_size, "unexpected end");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -323,13 +324,13 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
|||
#endif
|
||||
else if (is_load_from_file_buf) {
|
||||
/* The string is always terminated with '\0', use it directly.
|
||||
* In this case, the file buffer can be reffered to after loading.
|
||||
* In this case, the file buffer can be referred to after loading.
|
||||
*/
|
||||
bh_assert(p[str_len - 1] == '\0');
|
||||
str = (char *)p;
|
||||
}
|
||||
else {
|
||||
/* Load from sections, the file buffer cannot be reffered to
|
||||
/* Load from sections, the file buffer cannot be referred to
|
||||
after loading, we must create another string and insert it
|
||||
into const string set */
|
||||
bh_assert(p[str_len - 1] == '\0');
|
||||
|
@ -1043,6 +1044,12 @@ load_memory_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
|||
|
||||
for (i = 0; i < module->memory_count; i++) {
|
||||
read_uint32(buf, buf_end, module->memories[i].memory_flags);
|
||||
|
||||
if (!wasm_memory_check_flags(module->memories[i].memory_flags,
|
||||
error_buf, error_buf_size, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read_uint32(buf, buf_end, module->memories[i].num_bytes_per_page);
|
||||
read_uint32(buf, buf_end, module->memories[i].mem_init_page_count);
|
||||
read_uint32(buf, buf_end, module->memories[i].mem_max_page_count);
|
||||
|
@ -2042,8 +2049,8 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
|
|||
/* Create each import global */
|
||||
for (i = 0; i < module->import_global_count; i++) {
|
||||
buf = (uint8 *)align_ptr(buf, 2);
|
||||
read_uint8(buf, buf_end, import_globals[i].type);
|
||||
read_uint8(buf, buf_end, import_globals[i].is_mutable);
|
||||
read_uint8(buf, buf_end, import_globals[i].type.val_type);
|
||||
read_uint8(buf, buf_end, import_globals[i].type.is_mutable);
|
||||
read_string(buf, buf_end, import_globals[i].module_name);
|
||||
read_string(buf, buf_end, import_globals[i].global_name);
|
||||
|
||||
|
@ -2051,8 +2058,9 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
|
|||
if (wasm_native_lookup_libc_builtin_global(
|
||||
import_globals[i].module_name, import_globals[i].global_name,
|
||||
&tmp_global)) {
|
||||
if (tmp_global.type != import_globals[i].type
|
||||
|| tmp_global.is_mutable != import_globals[i].is_mutable) {
|
||||
if (tmp_global.type.val_type != import_globals[i].type.val_type
|
||||
|| tmp_global.type.is_mutable
|
||||
!= import_globals[i].type.is_mutable) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"incompatible import type");
|
||||
return false;
|
||||
|
@ -2065,7 +2073,8 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
|
|||
import_globals[i].is_linked = false;
|
||||
#endif
|
||||
|
||||
import_globals[i].size = wasm_value_type_size(import_globals[i].type);
|
||||
import_globals[i].size =
|
||||
wasm_value_type_size(import_globals[i].type.val_type);
|
||||
import_globals[i].data_offset = data_offset;
|
||||
data_offset += import_globals[i].size;
|
||||
module->global_data_size += import_globals[i].size;
|
||||
|
@ -2130,8 +2139,8 @@ load_globals(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
|||
|
||||
/* Create each global */
|
||||
for (i = 0; i < module->global_count; i++) {
|
||||
read_uint8(buf, buf_end, globals[i].type);
|
||||
read_uint8(buf, buf_end, globals[i].is_mutable);
|
||||
read_uint8(buf, buf_end, globals[i].type.val_type);
|
||||
read_uint8(buf, buf_end, globals[i].type.is_mutable);
|
||||
|
||||
buf = align_ptr(buf, 4);
|
||||
|
||||
|
@ -2139,7 +2148,7 @@ load_globals(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
|||
error_buf, error_buf_size))
|
||||
return false;
|
||||
|
||||
globals[i].size = wasm_value_type_size(globals[i].type);
|
||||
globals[i].size = wasm_value_type_size(globals[i].type.val_type);
|
||||
globals[i].data_offset = data_offset;
|
||||
data_offset += globals[i].size;
|
||||
module->global_data_size += globals[i].size;
|
||||
|
@ -2513,26 +2522,15 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
|
|||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 i;
|
||||
uint64 size, text_offset;
|
||||
uint32 func_count = module->func_count;
|
||||
|
||||
#if defined(BUILD_TARGET_XTENSA)
|
||||
/*
|
||||
* For Xtensa XIP, real func_count is doubled, including aot_func and
|
||||
* aot_func_internal, so need to multipy func_count by 2 here.
|
||||
*/
|
||||
if (module->is_indirect_mode) {
|
||||
func_count *= 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
size = sizeof(void *) * (uint64)func_count;
|
||||
size = sizeof(void *) * (uint64)module->func_count;
|
||||
if (size > 0
|
||||
&& !(module->func_ptrs =
|
||||
loader_malloc(size, error_buf, error_buf_size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < func_count; i++) {
|
||||
for (i = 0; i < module->func_count; i++) {
|
||||
if (sizeof(void *) == 8) {
|
||||
read_uint64(p, p_end, text_offset);
|
||||
}
|
||||
|
@ -2567,14 +2565,14 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
|
|||
module->start_function = NULL;
|
||||
}
|
||||
|
||||
size = sizeof(uint32) * (uint64)func_count;
|
||||
size = sizeof(uint32) * (uint64)module->func_count;
|
||||
if (size > 0
|
||||
&& !(module->func_type_indexes =
|
||||
loader_malloc(size, error_buf, error_buf_size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < func_count; i++) {
|
||||
for (i = 0; i < module->func_count; i++) {
|
||||
read_uint32(p, p_end, module->func_type_indexes[i]);
|
||||
if (module->func_type_indexes[i] >= module->type_count) {
|
||||
set_error_buf(error_buf, error_buf_size, "unknown type");
|
||||
|
@ -3632,6 +3630,21 @@ fail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
static bool
|
||||
has_module_memory64(AOTModule *module)
|
||||
{
|
||||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
if (module->import_memory_count > 0)
|
||||
return !!(module->import_memories[0].memory_flags & MEMORY64_FLAG);
|
||||
else if (module->memory_count > 0)
|
||||
return !!(module->memories[0].memory_flags & MEMORY64_FLAG);
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
load_from_sections(AOTModule *module, AOTSection *sections,
|
||||
bool is_load_from_file_buf, char *error_buf,
|
||||
|
@ -3643,6 +3656,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
|||
uint32 i, func_index, func_type_index;
|
||||
AOTFuncType *func_type;
|
||||
AOTExport *exports;
|
||||
uint8 malloc_free_io_type = VALUE_TYPE_I32;
|
||||
|
||||
while (section) {
|
||||
buf = section->section_body;
|
||||
|
@ -3717,7 +3731,10 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
|||
module->malloc_func_index = (uint32)-1;
|
||||
module->free_func_index = (uint32)-1;
|
||||
module->retain_func_index = (uint32)-1;
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (has_module_memory64(module))
|
||||
malloc_free_io_type = VALUE_TYPE_I64;
|
||||
#endif
|
||||
exports = module->exports;
|
||||
for (i = 0; i < module->export_count; i++) {
|
||||
if (exports[i].kind == EXPORT_KIND_FUNC
|
||||
|
@ -3727,8 +3744,8 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
|||
func_type_index = module->func_type_indexes[func_index];
|
||||
func_type = (AOTFuncType *)module->types[func_type_index];
|
||||
if (func_type->param_count == 1 && func_type->result_count == 1
|
||||
&& func_type->types[0] == VALUE_TYPE_I32
|
||||
&& func_type->types[1] == VALUE_TYPE_I32) {
|
||||
&& func_type->types[0] == malloc_free_io_type
|
||||
&& func_type->types[1] == malloc_free_io_type) {
|
||||
bh_assert(module->malloc_func_index == (uint32)-1);
|
||||
module->malloc_func_index = func_index;
|
||||
LOG_VERBOSE("Found malloc function, name: %s, index: %u",
|
||||
|
@ -3740,9 +3757,9 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
|||
func_type_index = module->func_type_indexes[func_index];
|
||||
func_type = (AOTFuncType *)module->types[func_type_index];
|
||||
if (func_type->param_count == 2 && func_type->result_count == 1
|
||||
&& func_type->types[0] == VALUE_TYPE_I32
|
||||
&& func_type->types[0] == malloc_free_io_type
|
||||
&& func_type->types[1] == VALUE_TYPE_I32
|
||||
&& func_type->types[2] == VALUE_TYPE_I32) {
|
||||
&& func_type->types[2] == malloc_free_io_type) {
|
||||
uint32 j;
|
||||
WASMExport *export_tmp;
|
||||
|
||||
|
@ -3766,8 +3783,8 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
|||
(AOTFuncType *)module->types[func_type_index];
|
||||
if (func_type->param_count == 1
|
||||
&& func_type->result_count == 1
|
||||
&& func_type->types[0] == VALUE_TYPE_I32
|
||||
&& func_type->types[1] == VALUE_TYPE_I32) {
|
||||
&& func_type->types[0] == malloc_free_io_type
|
||||
&& func_type->types[1] == malloc_free_io_type) {
|
||||
bh_assert(module->retain_func_index
|
||||
== (uint32)-1);
|
||||
module->retain_func_index = export_tmp->index;
|
||||
|
@ -3793,7 +3810,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
|||
func_type_index = module->func_type_indexes[func_index];
|
||||
func_type = (AOTFuncType *)module->types[func_type_index];
|
||||
if (func_type->param_count == 1 && func_type->result_count == 0
|
||||
&& func_type->types[0] == VALUE_TYPE_I32) {
|
||||
&& func_type->types[0] == malloc_free_io_type) {
|
||||
bh_assert(module->free_func_index == (uint32)-1);
|
||||
module->free_func_index = func_index;
|
||||
LOG_VERBOSE("Found free function, name: %s, index: %u",
|
||||
|
@ -3835,6 +3852,7 @@ create_module(char *name, char *error_buf, uint32 error_buf_size)
|
|||
module->module_type = Wasm_Module_AoT;
|
||||
|
||||
module->name = name;
|
||||
module->is_binary_freeable = false;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
module->import_module_list = &module->import_module_list_head;
|
||||
|
@ -3912,7 +3930,7 @@ resolve_execute_mode(const uint8 *buf, uint32 size, bool *p_mode,
|
|||
p += 8;
|
||||
while (p < p_end) {
|
||||
read_uint32(p, p_end, section_type);
|
||||
if (section_type <= AOT_SECTION_TYPE_SIGANATURE) {
|
||||
if (section_type <= AOT_SECTION_TYPE_SIGNATURE) {
|
||||
read_uint32(p, p_end, section_size);
|
||||
CHECK_BUF(p, p_end, section_size);
|
||||
if (section_type == AOT_SECTION_TYPE_TARGET_INFO) {
|
||||
|
@ -3927,7 +3945,7 @@ resolve_execute_mode(const uint8 *buf, uint32 size, bool *p_mode,
|
|||
break;
|
||||
}
|
||||
}
|
||||
else { /* section_type > AOT_SECTION_TYPE_SIGANATURE */
|
||||
else { /* section_type > AOT_SECTION_TYPE_SIGNATURE */
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"resolve execute mode failed");
|
||||
break;
|
||||
|
@ -3966,7 +3984,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
|
|||
p += 8;
|
||||
while (p < p_end) {
|
||||
read_uint32(p, p_end, section_type);
|
||||
if (section_type < AOT_SECTION_TYPE_SIGANATURE
|
||||
if (section_type < AOT_SECTION_TYPE_SIGNATURE
|
||||
|| section_type == AOT_SECTION_TYPE_CUSTOM) {
|
||||
read_uint32(p, p_end, section_size);
|
||||
CHECK_BUF(p, p_end, section_size);
|
||||
|
@ -4065,8 +4083,8 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
load(const uint8 *buf, uint32 size, AOTModule *module,
|
||||
bool wasm_binary_freeable, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *buf_end = buf + size;
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
|
@ -4090,8 +4108,8 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
|
|||
error_buf_size))
|
||||
return false;
|
||||
|
||||
ret = load_from_sections(module, section_list, true, error_buf,
|
||||
error_buf_size);
|
||||
ret = load_from_sections(module, section_list, !wasm_binary_freeable,
|
||||
error_buf, error_buf_size);
|
||||
if (!ret) {
|
||||
/* If load_from_sections() fails, then aot text is destroyed
|
||||
in destroy_sections() */
|
||||
|
@ -4135,7 +4153,8 @@ aot_load_from_aot_file(const uint8 *buf, uint32 size, const LoadArgs *args,
|
|||
return NULL;
|
||||
|
||||
os_thread_jit_write_protect_np(false); /* Make memory writable */
|
||||
if (!load(buf, size, module, error_buf, error_buf_size)) {
|
||||
if (!load(buf, size, module, args->wasm_binary_freeable, error_buf,
|
||||
error_buf_size)) {
|
||||
aot_unload(module);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,6 @@ check_global_init_expr(const AOTModule *module, uint32 global_index,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_GC == 0
|
||||
/**
|
||||
* Currently, constant expressions occurring as initializers of
|
||||
* globals are further constrained in that contained global.get
|
||||
|
@ -129,24 +128,26 @@ check_global_init_expr(const AOTModule *module, uint32 global_index,
|
|||
* And initializer expression cannot reference a mutable global.
|
||||
*/
|
||||
if (global_index >= module->import_global_count
|
||||
|| module->import_globals->is_mutable) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"constant expression required");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (global_index >= module->import_global_count + module->global_count) {
|
||||
/* make spec test happy */
|
||||
#if WASM_ENABLE_GC != 0
|
||||
+ module->global_count
|
||||
#endif
|
||||
) {
|
||||
set_error_buf_v(error_buf, error_buf_size, "unknown global %u",
|
||||
global_index);
|
||||
return false;
|
||||
}
|
||||
if (global_index < module->import_global_count
|
||||
&& module->import_globals[global_index].is_mutable) {
|
||||
|
||||
if (
|
||||
/* make spec test happy */
|
||||
#if WASM_ENABLE_GC != 0
|
||||
global_index < module->import_global_count &&
|
||||
#endif
|
||||
module->import_globals[global_index].type.is_mutable) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"constant expression required");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -389,7 +390,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
|||
for (i = 0; i < module->import_global_count; i++, import_global++) {
|
||||
bh_assert(import_global->data_offset
|
||||
== (uint32)(p - module_inst->global_data));
|
||||
init_global_data(p, import_global->type,
|
||||
init_global_data(p, import_global->type.val_type,
|
||||
&import_global->global_data_linked);
|
||||
p += import_global->size;
|
||||
}
|
||||
|
@ -410,20 +411,20 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
|||
}
|
||||
#if WASM_ENABLE_GC == 0
|
||||
init_global_data(
|
||||
p, global->type,
|
||||
p, global->type.val_type,
|
||||
&module->import_globals[init_expr->u.global_index]
|
||||
.global_data_linked);
|
||||
#else
|
||||
if (init_expr->u.global_index < module->import_global_count) {
|
||||
init_global_data(
|
||||
p, global->type,
|
||||
p, global->type.val_type,
|
||||
&module->import_globals[init_expr->u.global_index]
|
||||
.global_data_linked);
|
||||
}
|
||||
else {
|
||||
uint32 global_idx =
|
||||
init_expr->u.global_index - module->import_global_count;
|
||||
init_global_data(p, global->type,
|
||||
init_global_data(p, global->type.val_type,
|
||||
&module->globals[global_idx].init_expr.u);
|
||||
}
|
||||
#endif
|
||||
|
@ -581,7 +582,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
|||
#endif /* end of WASM_ENABLE_GC != 0 */
|
||||
default:
|
||||
{
|
||||
init_global_data(p, global->type, &init_expr->u);
|
||||
init_global_data(p, global->type.val_type, &init_expr->u);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -792,16 +793,18 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
uint32 max_page_count =
|
||||
wasm_runtime_get_max_mem(max_memory_pages, memory->mem_init_page_count,
|
||||
memory->mem_max_page_count);
|
||||
uint32 default_max_pages;
|
||||
uint32 inc_page_count, global_idx;
|
||||
uint32 bytes_of_last_page, bytes_to_page_end;
|
||||
uint64 aux_heap_base,
|
||||
heap_offset = (uint64)num_bytes_per_page * init_page_count;
|
||||
uint64 memory_data_size, max_memory_data_size;
|
||||
uint8 *p = NULL, *global_addr;
|
||||
bool is_memory64 = memory->memory_flags & MEMORY64_FLAG;
|
||||
|
||||
bool is_shared_memory = false;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
is_shared_memory = memory->memory_flags & 0x02 ? true : false;
|
||||
is_shared_memory = memory->memory_flags & SHARED_MEMORY_FLAG ? true : false;
|
||||
/* Shared memory */
|
||||
if (is_shared_memory && parent != NULL) {
|
||||
AOTMemoryInstance *shared_memory_instance;
|
||||
|
@ -813,6 +816,16 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64) {
|
||||
default_max_pages = DEFAULT_MEM64_MAX_PAGES;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
default_max_pages = DEFAULT_MAX_PAGES;
|
||||
}
|
||||
|
||||
if (heap_size > 0 && module->malloc_func_index != (uint32)-1
|
||||
&& module->free_func_index != (uint32)-1) {
|
||||
/* Disable app heap, use malloc/free function exported
|
||||
|
@ -893,14 +906,14 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
}
|
||||
init_page_count += inc_page_count;
|
||||
max_page_count += inc_page_count;
|
||||
if (init_page_count > DEFAULT_MAX_PAGES) {
|
||||
if (init_page_count > default_max_pages) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"failed to insert app heap into linear memory, "
|
||||
"try using `--heap-size=0` option");
|
||||
return NULL;
|
||||
}
|
||||
if (max_page_count > DEFAULT_MAX_PAGES)
|
||||
max_page_count = DEFAULT_MAX_PAGES;
|
||||
if (max_page_count > default_max_pages)
|
||||
max_page_count = default_max_pages;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("Memory instantiate:");
|
||||
|
@ -912,11 +925,11 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
heap_size);
|
||||
|
||||
max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
|
||||
bh_assert(max_memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
|
||||
bh_assert(max_memory_data_size <= GET_MAX_LINEAR_MEMORY_SIZE(is_memory64));
|
||||
(void)max_memory_data_size;
|
||||
|
||||
/* TODO: memory64 uses is_memory64 flag */
|
||||
if (wasm_allocate_linear_memory(&p, is_shared_memory, false,
|
||||
if (wasm_allocate_linear_memory(&p, is_shared_memory, is_memory64,
|
||||
num_bytes_per_page, init_page_count,
|
||||
max_page_count, &memory_data_size)
|
||||
!= BHT_OK) {
|
||||
|
@ -930,6 +943,11 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
memory_inst->cur_page_count = init_page_count;
|
||||
memory_inst->max_page_count = max_page_count;
|
||||
memory_inst->memory_data_size = memory_data_size;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64) {
|
||||
memory_inst->is_memory64 = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Init memory info */
|
||||
memory_inst->memory_data = p;
|
||||
|
@ -993,11 +1011,12 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
uint32 max_memory_pages, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
uint32 global_index, global_data_offset, base_offset, length;
|
||||
uint32 global_index, global_data_offset, length;
|
||||
uint32 i, memory_count = module->memory_count;
|
||||
AOTMemoryInstance *memories, *memory_inst;
|
||||
AOTMemInitData *data_seg;
|
||||
uint64 total_size;
|
||||
mem_offset_t base_offset;
|
||||
|
||||
module_inst->memory_count = memory_count;
|
||||
total_size = sizeof(AOTMemoryInstance *) * (uint64)memory_count;
|
||||
|
@ -1036,7 +1055,9 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
initialized */
|
||||
continue;
|
||||
|
||||
bh_assert(data_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
|
||||
bh_assert(data_seg->offset.init_expr_type
|
||||
== (memory_inst->is_memory64 ? INIT_EXPR_TYPE_I64_CONST
|
||||
: INIT_EXPR_TYPE_I32_CONST)
|
||||
|| data_seg->offset.init_expr_type
|
||||
== INIT_EXPR_TYPE_GET_GLOBAL);
|
||||
|
||||
|
@ -1057,11 +1078,28 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
module->globals[global_index - module->import_global_count]
|
||||
.data_offset;
|
||||
|
||||
base_offset =
|
||||
*(uint32 *)(module_inst->global_data + global_data_offset);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (memory_inst->is_memory64) {
|
||||
base_offset =
|
||||
*(uint64 *)(module_inst->global_data + global_data_offset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
base_offset =
|
||||
*(uint32 *)(module_inst->global_data + global_data_offset);
|
||||
}
|
||||
}
|
||||
else {
|
||||
base_offset = (uint32)data_seg->offset.u.i32;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (memory_inst->is_memory64) {
|
||||
base_offset = data_seg->offset.u.i64;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
base_offset = data_seg->offset.u.u32;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy memory data */
|
||||
|
@ -1071,7 +1109,8 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
/* Check memory data */
|
||||
/* check offset since length might negative */
|
||||
if (base_offset > memory_inst->memory_data_size) {
|
||||
LOG_DEBUG("base_offset(%d) > memory_data_size(%" PRIu64 ")",
|
||||
LOG_DEBUG("base_offset(%" PR_MEM_OFFSET
|
||||
") > memory_data_size(%" PRIu64 ")",
|
||||
base_offset, memory_inst->memory_data_size);
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
|
@ -1086,8 +1125,8 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
/* check offset + length(could be zero) */
|
||||
length = data_seg->byte_count;
|
||||
if (base_offset + length > memory_inst->memory_data_size) {
|
||||
LOG_DEBUG("base_offset(%d) + length(%d) > memory_data_size(%" PRIu64
|
||||
")",
|
||||
LOG_DEBUG("base_offset(%" PR_MEM_OFFSET
|
||||
") + length(%d) > memory_data_size(%" PRIu64 ")",
|
||||
base_offset, length, memory_inst->memory_data_size);
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
|
@ -1115,21 +1154,10 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
|
|||
{
|
||||
uint32 i;
|
||||
void **func_ptrs;
|
||||
uint32 func_count = module->func_count;
|
||||
#if defined(BUILD_TARGET_XTENSA)
|
||||
/*
|
||||
* For Xtensa XIP, real func_count is doubled, including aot_func and
|
||||
* aot_func_internal, so need to multipy func_count by 2 here.
|
||||
*/
|
||||
if (module->is_indirect_mode) {
|
||||
func_count *= 2;
|
||||
}
|
||||
#endif
|
||||
uint64 total_size = ((uint64)module->import_func_count + module->func_count)
|
||||
* sizeof(void *);
|
||||
|
||||
uint64 total_size =
|
||||
((uint64)module->import_func_count + func_count) * sizeof(void *);
|
||||
|
||||
if (module->import_func_count + func_count == 0)
|
||||
if (module->import_func_count + module->func_count == 0)
|
||||
return true;
|
||||
|
||||
/* Allocate memory */
|
||||
|
@ -1151,8 +1179,8 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
|
|||
}
|
||||
|
||||
/* Set defined function pointers */
|
||||
bh_memcpy_s(func_ptrs, sizeof(void *) * func_count, module->func_ptrs,
|
||||
sizeof(void *) * func_count);
|
||||
bh_memcpy_s(func_ptrs, sizeof(void *) * module->func_count,
|
||||
module->func_ptrs, sizeof(void *) * module->func_count);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1162,21 +1190,10 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
|
|||
{
|
||||
uint32 i;
|
||||
uint32 *func_type_index;
|
||||
uint32 func_count = module->func_count;
|
||||
#if defined(BUILD_TARGET_XTENSA)
|
||||
/*
|
||||
* For Xtensa XIP, real func_count is doubled, including aot_func and
|
||||
* aot_func_internal, so need to multipy func_count by 2 here.
|
||||
*/
|
||||
if (module->is_indirect_mode) {
|
||||
func_count *= 2;
|
||||
}
|
||||
#endif
|
||||
uint64 total_size = ((uint64)module->import_func_count + module->func_count)
|
||||
* sizeof(uint32);
|
||||
|
||||
uint64 total_size =
|
||||
((uint64)module->import_func_count + func_count) * sizeof(uint32);
|
||||
|
||||
if (module->import_func_count + func_count == 0)
|
||||
if (module->import_func_count + module->func_count == 0)
|
||||
return true;
|
||||
|
||||
/* Allocate memory */
|
||||
|
@ -1190,8 +1207,8 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
|
|||
for (i = 0; i < module->import_func_count; i++, func_type_index++)
|
||||
*func_type_index = module->import_funcs[i].func_type_index;
|
||||
|
||||
bh_memcpy_s(func_type_index, sizeof(uint32) * func_count,
|
||||
module->func_type_indexes, sizeof(uint32) * func_count);
|
||||
bh_memcpy_s(func_type_index, sizeof(uint32) * module->func_count,
|
||||
module->func_type_indexes, sizeof(uint32) * module->func_count);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1394,7 +1411,7 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Execute start function for both main insance and sub instance */
|
||||
/* Execute start function for both main instance and sub instance */
|
||||
if (module->start_function) {
|
||||
AOTFunctionInstance start_func = { 0 };
|
||||
uint32 func_type_idx;
|
||||
|
@ -2221,8 +2238,8 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
|
|||
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0
|
||||
/* Free all frames allocated, note that some frames
|
||||
may be allocated in AOT code and havent' been
|
||||
freed if exception occured */
|
||||
may be allocated in AOT code and haven't been
|
||||
freed if exception occurred */
|
||||
while (exec_env->cur_frame != prev_frame)
|
||||
aot_free_frame(exec_env);
|
||||
#endif
|
||||
|
@ -2291,8 +2308,8 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
|
|||
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0
|
||||
/* Free all frames allocated, note that some frames
|
||||
may be allocated in AOT code and havent' been
|
||||
freed if exception occured */
|
||||
may be allocated in AOT code and haven't been
|
||||
freed if exception occurred */
|
||||
while (exec_env->cur_frame != prev_frame)
|
||||
aot_free_frame(exec_env);
|
||||
#endif
|
||||
|
@ -2334,22 +2351,44 @@ aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf)
|
|||
static bool
|
||||
execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||
AOTFunctionInstance *malloc_func,
|
||||
AOTFunctionInstance *retain_func, uint32 size,
|
||||
uint32 *p_result)
|
||||
AOTFunctionInstance *retain_func, uint64 size,
|
||||
uint64 *p_result)
|
||||
{
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
|
||||
#endif
|
||||
WASMExecEnv *exec_env_created = NULL;
|
||||
WASMModuleInstanceCommon *module_inst_old = NULL;
|
||||
uint32 argv[2], argc;
|
||||
union {
|
||||
uint32 u32[3];
|
||||
uint64 u64;
|
||||
} argv;
|
||||
uint32 argc;
|
||||
bool ret;
|
||||
|
||||
argv[0] = size;
|
||||
argc = 1;
|
||||
if (retain_func) {
|
||||
argv[1] = 0;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
bool is_memory64 = module_inst->memories[0]->is_memory64;
|
||||
if (is_memory64) {
|
||||
argc = 2;
|
||||
PUT_I64_TO_ADDR(&argv.u64, size);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
argc = 1;
|
||||
argv.u32[0] = (uint32)size;
|
||||
}
|
||||
|
||||
/* if __retain is exported, then this module is compiled by
|
||||
assemblyscript, the memory should be managed by as's runtime,
|
||||
in this case we need to call the retain function after malloc
|
||||
the memory */
|
||||
if (retain_func) {
|
||||
/* the malloc function from assemblyscript is:
|
||||
function __new(size: usize, id: u32)
|
||||
id = 0 means this is an ArrayBuffer object */
|
||||
argv.u32[argc] = 0;
|
||||
argc++;
|
||||
}
|
||||
|
||||
if (exec_env) {
|
||||
|
@ -2389,10 +2428,10 @@ execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
}
|
||||
}
|
||||
|
||||
ret = aot_call_function(exec_env, malloc_func, argc, argv);
|
||||
ret = aot_call_function(exec_env, malloc_func, argc, argv.u32);
|
||||
|
||||
if (retain_func && ret)
|
||||
ret = aot_call_function(exec_env, retain_func, 1, argv);
|
||||
ret = aot_call_function(exec_env, retain_func, 1, argv.u32);
|
||||
|
||||
if (module_inst_old)
|
||||
/* Restore the existing exec_env's module inst */
|
||||
|
@ -2401,24 +2440,46 @@ execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
if (exec_env_created)
|
||||
wasm_exec_env_destroy(exec_env_created);
|
||||
|
||||
if (ret)
|
||||
*p_result = argv[0];
|
||||
if (ret) {
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64)
|
||||
*p_result = GET_I64_FROM_ADDR(&argv.u64);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
*p_result = argv.u32[0];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||
AOTFunctionInstance *free_func, uint32 offset)
|
||||
AOTFunctionInstance *free_func, uint64 offset)
|
||||
{
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
|
||||
#endif
|
||||
WASMExecEnv *exec_env_created = NULL;
|
||||
WASMModuleInstanceCommon *module_inst_old = NULL;
|
||||
uint32 argv[2];
|
||||
union {
|
||||
uint32 u32[2];
|
||||
uint64 u64;
|
||||
} argv;
|
||||
uint32 argc;
|
||||
bool ret;
|
||||
|
||||
argv[0] = offset;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (module_inst->memories[0]->is_memory64) {
|
||||
PUT_I64_TO_ADDR(&argv.u64, offset);
|
||||
argc = 2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
argv.u32[0] = (uint32)offset;
|
||||
argc = 1;
|
||||
}
|
||||
|
||||
if (exec_env) {
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
|
@ -2457,7 +2518,7 @@ execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
}
|
||||
}
|
||||
|
||||
ret = aot_call_function(exec_env, free_func, 1, argv);
|
||||
ret = aot_call_function(exec_env, free_func, argc, argv.u32);
|
||||
|
||||
if (module_inst_old)
|
||||
/* Restore the existing exec_env's module inst */
|
||||
|
@ -2477,7 +2538,7 @@ aot_module_malloc_internal(AOTModuleInstance *module_inst,
|
|||
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
|
||||
AOTModule *module = (AOTModule *)module_inst->module;
|
||||
uint8 *addr = NULL;
|
||||
uint32 offset = 0;
|
||||
uint64 offset = 0;
|
||||
|
||||
/* TODO: Memory64 size check based on memory idx type */
|
||||
bh_assert(size <= UINT32_MAX);
|
||||
|
@ -2509,7 +2570,7 @@ aot_module_malloc_internal(AOTModuleInstance *module_inst,
|
|||
|
||||
if (!malloc_func
|
||||
|| !execute_malloc_function(module_inst, exec_env, malloc_func,
|
||||
retain_func, (uint32)size, &offset)) {
|
||||
retain_func, size, &offset)) {
|
||||
return 0;
|
||||
}
|
||||
addr = offset ? (uint8 *)memory_inst->memory_data + offset : NULL;
|
||||
|
@ -2620,8 +2681,7 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
free_func = aot_lookup_function(module_inst, "__unpin");
|
||||
|
||||
if (free_func)
|
||||
execute_free_function(module_inst, exec_env, free_func,
|
||||
(uint32)ptr);
|
||||
execute_free_function(module_inst, exec_env, free_func, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2983,7 +3043,7 @@ aot_sqrtf(float x)
|
|||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bool
|
||||
aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
|
||||
uint32 len, uint32 dst)
|
||||
uint32 len, size_t dst)
|
||||
{
|
||||
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
|
||||
AOTModule *aot_module;
|
||||
|
@ -3016,7 +3076,7 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
|
|||
(WASMModuleInstanceCommon *)module_inst, (uint64)dst);
|
||||
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
bh_memcpy_s(maddr, (uint32)(memory_inst->memory_data_size - dst),
|
||||
bh_memcpy_s(maddr, CLAMP_U64_TO_U32(memory_inst->memory_data_size - dst),
|
||||
data + offset, len);
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return true;
|
||||
|
@ -4296,7 +4356,7 @@ aot_dump_pgo_prof_data_to_buf(AOTModuleInstance *module_inst, char *buf,
|
|||
LLVMProfileData_64 *prof_data_64 = (LLVMProfileData_64 *)buf;
|
||||
|
||||
/* Convert LLVMProfileData to LLVMProfileData_64, the pointer width
|
||||
in the output file is alawys 8 bytes */
|
||||
in the output file is always 8 bytes */
|
||||
prof_data = (LLVMProfileData *)module->data_sections[i].data;
|
||||
prof_data_64->func_md5 = prof_data->func_md5;
|
||||
prof_data_64->func_hash = prof_data->func_hash;
|
||||
|
@ -4549,7 +4609,7 @@ aot_global_traverse_gc_rootset(AOTModuleInstance *module_inst, void *heap)
|
|||
uint32 i;
|
||||
|
||||
for (i = 0; i < module->import_global_count; i++, import_global++) {
|
||||
if (wasm_is_type_reftype(import_global->type)) {
|
||||
if (wasm_is_type_reftype(import_global->type.val_type)) {
|
||||
gc_obj = GET_REF_FROM_ADDR((uint32 *)global_data);
|
||||
if (wasm_obj_is_created_from_heap(gc_obj)) {
|
||||
if (0 != mem_allocator_add_root((mem_allocator_t)heap, gc_obj))
|
||||
|
@ -4560,7 +4620,7 @@ aot_global_traverse_gc_rootset(AOTModuleInstance *module_inst, void *heap)
|
|||
}
|
||||
|
||||
for (i = 0; i < module->global_count; i++, global++) {
|
||||
if (wasm_is_type_reftype(global->type)) {
|
||||
if (wasm_is_type_reftype(global->type.val_type)) {
|
||||
gc_obj = GET_REF_FROM_ADDR((uint32 *)global_data);
|
||||
if (wasm_obj_is_created_from_heap(gc_obj)) {
|
||||
if (0 != mem_allocator_add_root((mem_allocator_t)heap, gc_obj))
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef enum AOTSectionType {
|
|||
AOT_SECTION_TYPE_FUNCTION = 3,
|
||||
AOT_SECTION_TYPE_EXPORT = 4,
|
||||
AOT_SECTION_TYPE_RELOCATION = 5,
|
||||
AOT_SECTION_TYPE_SIGANATURE = 6,
|
||||
AOT_SECTION_TYPE_SIGNATURE = 6,
|
||||
AOT_SECTION_TYPE_CUSTOM = 100,
|
||||
} AOTSectionType;
|
||||
|
||||
|
@ -310,6 +310,9 @@ typedef struct AOTModule {
|
|||
|
||||
/* user defined name */
|
||||
char *name;
|
||||
|
||||
/* Whether the underlying wasm binary buffer can be freed */
|
||||
bool is_binary_freeable;
|
||||
} AOTModule;
|
||||
|
||||
#define AOTMemoryInstance WASMMemoryInstance
|
||||
|
@ -420,7 +423,7 @@ typedef struct LLVMProfileData {
|
|||
uint16 num_value_sites[2];
|
||||
} LLVMProfileData;
|
||||
|
||||
/* The profiling data for writting to the output file, the width of
|
||||
/* The profiling data for writing to the output file, the width of
|
||||
pointer is 8 bytes suppose we always use wamrc and llvm-profdata
|
||||
with 64-bit mode */
|
||||
typedef struct LLVMProfileData_64 {
|
||||
|
@ -627,7 +630,7 @@ aot_sqrtf(float x);
|
|||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bool
|
||||
aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
|
||||
uint32 len, uint32 dst);
|
||||
uint32 len, size_t dst);
|
||||
|
||||
bool
|
||||
aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -56,6 +55,12 @@ typedef struct JITDescriptor {
|
|||
JITCodeEntry *first_entry_;
|
||||
} JITDescriptor;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN32_)
|
||||
#define attribute_noinline __declspec(noinline)
|
||||
#else
|
||||
#define attribute_noinline __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
/* LLVM has already define this */
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
|
||||
/**
|
||||
|
@ -63,9 +68,11 @@ typedef struct JITDescriptor {
|
|||
* To prevent GCC from inlining or removing it we place noinline attribute
|
||||
* and inline assembler statement inside.
|
||||
*/
|
||||
void __attribute__((noinline)) __jit_debug_register_code();
|
||||
void attribute_noinline
|
||||
__jit_debug_register_code();
|
||||
|
||||
void __attribute__((noinline)) __jit_debug_register_code()
|
||||
void attribute_noinline
|
||||
__jit_debug_register_code()
|
||||
{
|
||||
int x;
|
||||
*(char *)&x = '\0';
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
#include "../wasm_runtime_common.h"
|
||||
#include "../wasm_exec_env.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-non-prototype"
|
||||
#endif
|
||||
|
||||
void
|
||||
invokeNative(void (*native_code)(), uint32 argv[], uint32 argc)
|
||||
{
|
||||
|
@ -112,3 +117,7 @@ invokeNative(void (*native_code)(), uint32 argv[], uint32 argc)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
|
|
@ -176,12 +176,6 @@ wasm_defined_type_is_array_type(WASMType *const def_type)
|
|||
return wasm_type_is_array_type(def_type);
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_func_type_get_param_count(WASMFuncType *const func_type)
|
||||
{
|
||||
return func_type->param_count;
|
||||
}
|
||||
|
||||
wasm_ref_type_t
|
||||
wasm_func_type_get_param_type(WASMFuncType *const func_type, uint32 param_idx)
|
||||
{
|
||||
|
@ -202,12 +196,6 @@ wasm_func_type_get_param_type(WASMFuncType *const func_type, uint32 param_idx)
|
|||
return ref_type;
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_func_type_get_result_count(WASMFuncType *const func_type)
|
||||
{
|
||||
return (uint32)func_type->result_count;
|
||||
}
|
||||
|
||||
wasm_ref_type_t
|
||||
wasm_func_type_get_result_type(WASMFuncType *const func_type, uint32 result_idx)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* Object header of a WASM object, as the adddress of allocated memory
|
||||
* Object header of a WASM object, as the address of allocated memory
|
||||
* must be 8-byte aligned, the lowest 3 bits are zero, we use them to
|
||||
* mark the object:
|
||||
* bits[0] is 1: the object is an externref object
|
||||
|
@ -85,7 +85,7 @@ typedef struct WASMArrayObject {
|
|||
/* Must be pointer of WASMRttObject of array type */
|
||||
WASMObjectHeader header;
|
||||
/* (<array length> << 2) | <array element size>,
|
||||
* elem_count = lenght >> 2
|
||||
* elem_count = length >> 2
|
||||
* elem_size = 2 ^ (length & 0x3)
|
||||
*/
|
||||
uint32 length;
|
||||
|
|
|
@ -127,7 +127,7 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
|
|||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
if (ret) {
|
||||
/* On a successful return from the `_start` function,
|
||||
we terminate other threads by mimicing wasi:proc_exit(0).
|
||||
we terminate other threads by mimicking wasi:proc_exit(0).
|
||||
|
||||
Note:
|
||||
- A return from the `main` function is an equivalent of
|
||||
|
@ -516,11 +516,11 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
|||
case VALUE_TYPE_V128:
|
||||
{
|
||||
/* it likes 0x123\0x234 or 123\234 */
|
||||
/* retrive first i64 */
|
||||
/* retrieve first i64 */
|
||||
*(uint64 *)(argv1 + p) = strtoull(argv[i], &endptr, 0);
|
||||
/* skip \ */
|
||||
endptr++;
|
||||
/* retrive second i64 */
|
||||
/* retrieve second i64 */
|
||||
*(uint64 *)(argv1 + p + 2) = strtoull(endptr, &endptr, 0);
|
||||
p += 4;
|
||||
break;
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
typedef struct wasm_module_ex_t {
|
||||
struct WASMModuleCommon *module_comm_rt;
|
||||
wasm_byte_vec_t *binary;
|
||||
/* If true, binary in wasm_module_ex_t contains a copy of the WASM binary */
|
||||
bool is_binary_cloned;
|
||||
korp_mutex lock;
|
||||
uint32 ref_count;
|
||||
#if WASM_ENABLE_WASM_CACHE != 0
|
||||
|
@ -536,7 +538,7 @@ search_thread_local_store_num(Vector *stores_by_tid, korp_tid tid,
|
|||
#endif
|
||||
|
||||
static unsigned
|
||||
retrive_thread_local_store_num(Vector *stores_by_tid, korp_tid tid)
|
||||
retrieve_thread_local_store_num(Vector *stores_by_tid, korp_tid tid)
|
||||
{
|
||||
#ifndef os_thread_local_attribute
|
||||
unsigned i = 0;
|
||||
|
@ -664,8 +666,8 @@ wasm_store_new(wasm_engine_t *engine)
|
|||
if (!engine || singleton_engine != engine)
|
||||
return NULL;
|
||||
|
||||
if (!retrive_thread_local_store_num(&engine->stores_by_tid,
|
||||
os_self_thread())) {
|
||||
if (!retrieve_thread_local_store_num(&engine->stores_by_tid,
|
||||
os_self_thread())) {
|
||||
if (!wasm_runtime_init_thread_env()) {
|
||||
LOG_ERROR("init thread environment failed");
|
||||
return NULL;
|
||||
|
@ -734,8 +736,8 @@ wasm_store_delete(wasm_store_t *store)
|
|||
|
||||
if (decrease_thread_local_store_num(&singleton_engine->stores_by_tid,
|
||||
os_self_thread())) {
|
||||
if (!retrive_thread_local_store_num(&singleton_engine->stores_by_tid,
|
||||
os_self_thread())) {
|
||||
if (!retrieve_thread_local_store_num(&singleton_engine->stores_by_tid,
|
||||
os_self_thread())) {
|
||||
wasm_runtime_destroy_thread_env();
|
||||
}
|
||||
}
|
||||
|
@ -754,11 +756,12 @@ val_type_rt_2_valkind(uint8 val_type_rt)
|
|||
WAMR_VAL_TYPE_2_WASM_VAL_KIND(I64)
|
||||
WAMR_VAL_TYPE_2_WASM_VAL_KIND(F32)
|
||||
WAMR_VAL_TYPE_2_WASM_VAL_KIND(F64)
|
||||
WAMR_VAL_TYPE_2_WASM_VAL_KIND(V128)
|
||||
WAMR_VAL_TYPE_2_WASM_VAL_KIND(FUNCREF)
|
||||
#undef WAMR_VAL_TYPE_2_WASM_VAL_KIND
|
||||
|
||||
default:
|
||||
return WASM_ANYREF;
|
||||
return WASM_EXTERNREF;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,9 +776,9 @@ wasm_valtype_new(wasm_valkind_t kind)
|
|||
{
|
||||
wasm_valtype_t *val_type;
|
||||
|
||||
if (kind > WASM_F64 && WASM_FUNCREF != kind
|
||||
if (kind > WASM_V128 && WASM_FUNCREF != kind
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
&& WASM_ANYREF != kind
|
||||
&& WASM_EXTERNREF != kind
|
||||
#endif
|
||||
) {
|
||||
return NULL;
|
||||
|
@ -807,7 +810,7 @@ wasm_valtype_copy(const wasm_valtype_t *src)
|
|||
wasm_valkind_t
|
||||
wasm_valtype_kind(const wasm_valtype_t *val_type)
|
||||
{
|
||||
return val_type ? val_type->kind : WASM_ANYREF;
|
||||
return val_type ? val_type->kind : WASM_EXTERNREF;
|
||||
}
|
||||
|
||||
static wasm_functype_t *
|
||||
|
@ -974,7 +977,8 @@ cmp_val_kind_with_val_type(wasm_valkind_t v_k, uint8 v_t)
|
|||
|| (v_k == WASM_I64 && v_t == VALUE_TYPE_I64)
|
||||
|| (v_k == WASM_F32 && v_t == VALUE_TYPE_F32)
|
||||
|| (v_k == WASM_F64 && v_t == VALUE_TYPE_F64)
|
||||
|| (v_k == WASM_ANYREF && v_t == VALUE_TYPE_EXTERNREF)
|
||||
|| (v_k == WASM_V128 && v_t == VALUE_TYPE_V128)
|
||||
|| (v_k == WASM_EXTERNREF && v_t == VALUE_TYPE_EXTERNREF)
|
||||
|| (v_k == WASM_FUNCREF && v_t == VALUE_TYPE_FUNCREF);
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1137,7 @@ wasm_tabletype_new(own wasm_valtype_t *val_type, const wasm_limits_t *limits)
|
|||
|
||||
if (wasm_valtype_kind(val_type) != WASM_FUNCREF
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
&& wasm_valtype_kind(val_type) != WASM_ANYREF
|
||||
&& wasm_valtype_kind(val_type) != WASM_EXTERNREF
|
||||
#endif
|
||||
) {
|
||||
return NULL;
|
||||
|
@ -1646,9 +1650,12 @@ rt_val_to_wasm_val(const uint8 *data, uint8 val_type_rt, wasm_val_t *out)
|
|||
out->kind = WASM_F64;
|
||||
out->of.f64 = *((float64 *)data);
|
||||
break;
|
||||
case VALUE_TYPE_V128:
|
||||
bh_assert(0);
|
||||
break;
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
out->kind = WASM_ANYREF;
|
||||
out->kind = WASM_EXTERNREF;
|
||||
if (NULL_REF == *(uint32 *)data) {
|
||||
out->of.ref = NULL;
|
||||
}
|
||||
|
@ -1687,9 +1694,12 @@ wasm_val_to_rt_val(WASMModuleInstanceCommon *inst_comm_rt, uint8 val_type_rt,
|
|||
bh_assert(WASM_F64 == v->kind);
|
||||
*((float64 *)data) = v->of.f64;
|
||||
break;
|
||||
case VALUE_TYPE_V128:
|
||||
bh_assert(0);
|
||||
break;
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
bh_assert(WASM_ANYREF == v->kind);
|
||||
bh_assert(WASM_EXTERNREF == v->kind);
|
||||
ret =
|
||||
wasm_externref_obj2ref(inst_comm_rt, v->of.ref, (uint32 *)data);
|
||||
break;
|
||||
|
@ -2234,8 +2244,7 @@ quit:
|
|||
#endif /* WASM_ENABLE_WASM_CACHE != 0 */
|
||||
|
||||
wasm_module_t *
|
||||
wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
|
||||
const LoadArgs *args)
|
||||
wasm_module_new_ex(wasm_store_t *store, wasm_byte_vec_t *binary, LoadArgs *args)
|
||||
{
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_ex_t *module_ex = NULL;
|
||||
|
@ -2263,7 +2272,7 @@ wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
|
|||
result = result || (pkg_type == Wasm_Module_AoT);
|
||||
#endif
|
||||
if (!result) {
|
||||
LOG_VERBOSE("current building isn't compatiable with the module,"
|
||||
LOG_VERBOSE("current building isn't compatible with the module,"
|
||||
"may need recompile");
|
||||
goto quit;
|
||||
}
|
||||
|
@ -2283,14 +2292,21 @@ wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
|
|||
if (!module_ex)
|
||||
goto quit;
|
||||
|
||||
module_ex->binary = malloc_internal(sizeof(wasm_byte_vec_t));
|
||||
if (!module_ex->binary)
|
||||
goto free_module;
|
||||
module_ex->is_binary_cloned = args->clone_wasm_binary;
|
||||
if (args->clone_wasm_binary) {
|
||||
module_ex->binary = malloc_internal(sizeof(wasm_byte_vec_t));
|
||||
if (!module_ex->binary)
|
||||
goto free_module;
|
||||
|
||||
wasm_byte_vec_copy(module_ex->binary, binary);
|
||||
if (!module_ex->binary->data)
|
||||
goto free_binary;
|
||||
wasm_byte_vec_copy(module_ex->binary, binary);
|
||||
if (!module_ex->binary->data)
|
||||
goto free_binary;
|
||||
}
|
||||
else {
|
||||
module_ex->binary = binary;
|
||||
}
|
||||
|
||||
args->wasm_binary_freeable = !args->clone_wasm_binary;
|
||||
module_ex->module_comm_rt = wasm_runtime_load_ex(
|
||||
(uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size, args,
|
||||
error_buf, (uint32)sizeof(error_buf));
|
||||
|
@ -2328,9 +2344,11 @@ remove_last:
|
|||
unload:
|
||||
wasm_runtime_unload(module_ex->module_comm_rt);
|
||||
free_vec:
|
||||
wasm_byte_vec_delete(module_ex->binary);
|
||||
if (args->clone_wasm_binary)
|
||||
wasm_byte_vec_delete(module_ex->binary);
|
||||
free_binary:
|
||||
wasm_runtime_free(module_ex->binary);
|
||||
if (args->clone_wasm_binary)
|
||||
wasm_runtime_free(module_ex->binary);
|
||||
free_module:
|
||||
wasm_runtime_free(module_ex);
|
||||
quit:
|
||||
|
@ -2343,7 +2361,8 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
|
|||
{
|
||||
LoadArgs args = { 0 };
|
||||
args.name = "";
|
||||
return wasm_module_new_ex(store, binary, &args);
|
||||
args.clone_wasm_binary = true;
|
||||
return wasm_module_new_ex(store, (wasm_byte_vec_t *)binary, &args);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2402,7 +2421,8 @@ wasm_module_delete_internal(wasm_module_t *module)
|
|||
return;
|
||||
}
|
||||
|
||||
DEINIT_VEC(module_ex->binary, wasm_byte_vec_delete);
|
||||
if (module_ex->is_binary_cloned)
|
||||
DEINIT_VEC(module_ex->binary, wasm_byte_vec_delete);
|
||||
|
||||
if (module_ex->module_comm_rt) {
|
||||
wasm_runtime_unload(module_ex->module_comm_rt);
|
||||
|
@ -2521,8 +2541,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
|
|||
+ (i - import_func_count);
|
||||
module_name_rt = import->u.names.module_name;
|
||||
field_name_rt = import->u.names.field_name;
|
||||
val_type_rt = import->u.global.type;
|
||||
mutability_rt = import->u.global.is_mutable;
|
||||
val_type_rt = import->u.global.type.val_type;
|
||||
mutability_rt = import->u.global.type.is_mutable;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2532,8 +2552,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
|
|||
+ (i - import_func_count);
|
||||
module_name_rt = import->module_name;
|
||||
field_name_rt = import->global_name;
|
||||
val_type_rt = import->type;
|
||||
mutability_rt = import->is_mutable;
|
||||
val_type_rt = import->type.val_type;
|
||||
mutability_rt = import->type.is_mutable;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2986,6 +3006,15 @@ wasm_module_get_name(wasm_module_t *module)
|
|||
return wasm_runtime_get_module_name(module_ex->module_comm_rt);
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_module_is_underlying_binary_freeable(const wasm_module_t *module)
|
||||
{
|
||||
if (((wasm_module_ex_t *)module)->is_binary_cloned)
|
||||
return true;
|
||||
|
||||
return wasm_runtime_is_underlying_binary_freeable(*module);
|
||||
}
|
||||
|
||||
static wasm_func_t *
|
||||
wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type,
|
||||
wasm_func_callback_t func_callback)
|
||||
|
@ -3251,8 +3280,11 @@ params_to_argv(const wasm_val_vec_t *params,
|
|||
*(int64 *)argv = param->of.i64;
|
||||
argv += 2;
|
||||
break;
|
||||
case WASM_V128:
|
||||
bh_assert(0);
|
||||
break;
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case WASM_ANYREF:
|
||||
case WASM_EXTERNREF:
|
||||
*(uintptr_t *)argv = (uintptr_t)param->of.ref;
|
||||
argv += sizeof(uintptr_t) / sizeof(uint32);
|
||||
break;
|
||||
|
@ -3293,8 +3325,11 @@ argv_to_results(const uint32 *argv, const wasm_valtype_vec_t *result_defs,
|
|||
result->of.i64 = *(int64 *)argv;
|
||||
argv += 2;
|
||||
break;
|
||||
case WASM_V128:
|
||||
bh_assert(0);
|
||||
break;
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case WASM_ANYREF:
|
||||
case WASM_EXTERNREF:
|
||||
result->of.ref = (struct wasm_ref_t *)(*(uintptr_t *)argv);
|
||||
argv += sizeof(uintptr_t) / sizeof(uint32);
|
||||
break;
|
||||
|
@ -3386,7 +3421,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
|
|||
}
|
||||
}
|
||||
|
||||
/* copy parametes */
|
||||
/* copy parameters */
|
||||
if (param_count
|
||||
&& !params_to_argv(params, wasm_functype_params(func->type), argv,
|
||||
&argc)) {
|
||||
|
@ -3634,7 +3669,7 @@ aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
|
|||
|
||||
if (global_idx_rt < module_aot->import_global_count) {
|
||||
data_offset = module_aot->import_globals[global_idx_rt].data_offset;
|
||||
val_type_rt = module_aot->import_globals[global_idx_rt].type;
|
||||
val_type_rt = module_aot->import_globals[global_idx_rt].type.val_type;
|
||||
}
|
||||
else {
|
||||
data_offset =
|
||||
|
@ -3642,7 +3677,7 @@ aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
|
|||
.data_offset;
|
||||
val_type_rt =
|
||||
module_aot->globals[global_idx_rt - module_aot->import_global_count]
|
||||
.type;
|
||||
.type.val_type;
|
||||
}
|
||||
|
||||
data = (void *)(inst_aot->global_data + data_offset);
|
||||
|
@ -3661,7 +3696,7 @@ aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
|
|||
|
||||
if (global_idx_rt < module_aot->import_global_count) {
|
||||
data_offset = module_aot->import_globals[global_idx_rt].data_offset;
|
||||
val_type_rt = module_aot->import_globals[global_idx_rt].type;
|
||||
val_type_rt = module_aot->import_globals[global_idx_rt].type.val_type;
|
||||
}
|
||||
else {
|
||||
data_offset =
|
||||
|
@ -3669,7 +3704,7 @@ aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
|
|||
.data_offset;
|
||||
val_type_rt =
|
||||
module_aot->globals[global_idx_rt - module_aot->import_global_count]
|
||||
.type;
|
||||
.type.val_type;
|
||||
}
|
||||
|
||||
data = inst_aot->global_data + data_offset;
|
||||
|
@ -3786,15 +3821,15 @@ wasm_global_new_internal(wasm_store_t *store, uint16 global_idx_rt,
|
|||
if (global_idx_rt < module_aot->import_global_count) {
|
||||
AOTImportGlobal *global_import_aot =
|
||||
module_aot->import_globals + global_idx_rt;
|
||||
val_type_rt = global_import_aot->type;
|
||||
is_mutable = global_import_aot->is_mutable;
|
||||
val_type_rt = global_import_aot->type.val_type;
|
||||
is_mutable = global_import_aot->type.is_mutable;
|
||||
}
|
||||
else {
|
||||
AOTGlobal *global_aot =
|
||||
module_aot->globals
|
||||
+ (global_idx_rt - module_aot->import_global_count);
|
||||
val_type_rt = global_aot->type;
|
||||
is_mutable = global_aot->is_mutable;
|
||||
val_type_rt = global_aot->type.val_type;
|
||||
is_mutable = global_aot->type.is_mutable;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -4020,7 +4055,7 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
|
|||
}
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
if (table->type->val_type->kind == WASM_ANYREF) {
|
||||
if (table->type->val_type->kind == WASM_EXTERNREF) {
|
||||
void *externref_obj;
|
||||
if (!wasm_externref_ref2obj(ref_idx, &externref_obj)) {
|
||||
return NULL;
|
||||
|
@ -4050,7 +4085,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
|||
if (ref
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
&& !(WASM_REF_foreign == ref->kind
|
||||
&& WASM_ANYREF == table->type->val_type->kind)
|
||||
&& WASM_EXTERNREF == table->type->val_type->kind)
|
||||
#endif
|
||||
&& !(WASM_REF_func == ref->kind
|
||||
&& WASM_FUNCREF == table->type->val_type->kind)) {
|
||||
|
@ -4097,7 +4132,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
|||
}
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
if (table->type->val_type->kind == WASM_ANYREF) {
|
||||
if (table->type->val_type->kind == WASM_EXTERNREF) {
|
||||
return wasm_externref_obj2ref(table->inst_comm_rt, ref, p_ref_idx);
|
||||
}
|
||||
else
|
||||
|
@ -4511,8 +4546,9 @@ interp_link_global(const WASMModule *module_interp, uint16 global_idx_rt,
|
|||
return true;
|
||||
|
||||
/* type comparison */
|
||||
if (!cmp_val_kind_with_val_type(wasm_valtype_kind(import->type->val_type),
|
||||
imported_global_interp->u.global.type))
|
||||
if (!cmp_val_kind_with_val_type(
|
||||
wasm_valtype_kind(import->type->val_type),
|
||||
imported_global_interp->u.global.type.val_type))
|
||||
return false;
|
||||
|
||||
/* set init value */
|
||||
|
@ -4685,7 +4721,7 @@ aot_link_global(const AOTModule *module_aot, uint16 global_idx_rt,
|
|||
bh_assert(val_type);
|
||||
|
||||
if (!cmp_val_kind_with_val_type(wasm_valtype_kind(val_type),
|
||||
import_aot_global->type))
|
||||
import_aot_global->type.val_type))
|
||||
return false;
|
||||
|
||||
bh_assert(import->init);
|
||||
|
@ -5253,7 +5289,7 @@ wasm_externkind_t
|
|||
wasm_extern_kind(const wasm_extern_t *external)
|
||||
{
|
||||
if (!external) {
|
||||
return WASM_ANYREF;
|
||||
return WASM_EXTERNREF;
|
||||
}
|
||||
|
||||
return external->kind;
|
||||
|
|
|
@ -71,7 +71,7 @@ struct wasm_memorytype_t {
|
|||
|
||||
struct wasm_externtype_t {
|
||||
uint32 extern_kind;
|
||||
/* reservered space */
|
||||
/* reserved space */
|
||||
uint8 data[1];
|
||||
};
|
||||
|
||||
|
@ -205,7 +205,7 @@ struct wasm_extern_t {
|
|||
wasm_name_t *module_name;
|
||||
wasm_name_t *name;
|
||||
wasm_externkind_t kind;
|
||||
/* reservered space */
|
||||
/* reserved space */
|
||||
uint8 data[1];
|
||||
};
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ wasm_exec_env_destroy(WASMExecEnv *exec_env)
|
|||
wasm_cluster_wait_for_all_except_self(cluster, exec_env);
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
/* Must fire exit event after other threads exits, otherwise
|
||||
the stopped thread will be overrided by other threads */
|
||||
the stopped thread will be overriden by other threads */
|
||||
wasm_cluster_thread_exited(exec_env);
|
||||
#endif
|
||||
/* We have waited for other threads, this is the only alive thread, so
|
||||
|
|
58
core/iwasm/common/wasm_loader_common.c
Normal file
58
core/iwasm/common/wasm_loader_common.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
#include "wasm_loader_common.h"
|
||||
#include "bh_log.h"
|
||||
#include "../interpreter/wasm.h"
|
||||
|
||||
static void
|
||||
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string,
|
||||
bool is_aot)
|
||||
{
|
||||
if (error_buf != NULL) {
|
||||
snprintf(error_buf, error_buf_size, "%s module load failed: %s",
|
||||
is_aot ? "AOT" : "WASM", string);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_memory_check_flags(const uint8 mem_flag, char *error_buf,
|
||||
uint32 error_buf_size, bool is_aot)
|
||||
{
|
||||
/* Check whether certain features indicated by mem_flag are enabled in
|
||||
* runtime */
|
||||
if (mem_flag > MAX_PAGE_COUNT_FLAG) {
|
||||
#if WASM_ENABLE_SHARED_MEMORY == 0
|
||||
if (mem_flag & SHARED_MEMORY_FLAG) {
|
||||
LOG_VERBOSE("shared memory flag was found, please enable shared "
|
||||
"memory, lib-pthread or lib-wasi-threads");
|
||||
set_error_buf(error_buf, error_buf_size, "invalid limits flags",
|
||||
is_aot);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_MEMORY64 == 0
|
||||
if (mem_flag & MEMORY64_FLAG) {
|
||||
LOG_VERBOSE("memory64 flag was found, please enable memory64");
|
||||
set_error_buf(error_buf, error_buf_size, "invalid limits flags",
|
||||
is_aot);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mem_flag > MAX_PAGE_COUNT_FLAG + SHARED_MEMORY_FLAG + MEMORY64_FLAG) {
|
||||
set_error_buf(error_buf, error_buf_size, "invalid limits flags",
|
||||
is_aot);
|
||||
return false;
|
||||
}
|
||||
else if ((mem_flag & SHARED_MEMORY_FLAG)
|
||||
&& !(mem_flag & MAX_PAGE_COUNT_FLAG)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"shared memory must have maximum", is_aot);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
23
core/iwasm/common/wasm_loader_common.h
Normal file
23
core/iwasm/common/wasm_loader_common.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _WASM_LOADER_COMMON_H
|
||||
#define _WASM_LOADER_COMMON_H
|
||||
|
||||
#include "platform_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_memory_check_flags(const uint8 mem_flag, char *error_buf,
|
||||
uint32 error_buf_size, bool is_aot);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASM_LOADER_COMMON_H */
|
|
@ -1005,15 +1005,7 @@ wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
|
|||
page_size = os_getpagesize();
|
||||
*memory_data_size = init_page_count * num_bytes_per_page;
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64) {
|
||||
bh_assert(*memory_data_size <= MAX_LINEAR_MEM64_MEMORY_SIZE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
bh_assert(*memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
|
||||
}
|
||||
bh_assert(*memory_data_size <= GET_MAX_LINEAR_MEMORY_SIZE(is_memory64));
|
||||
*memory_data_size = align_as_and_cast(*memory_data_size, page_size);
|
||||
|
||||
if (map_size > 0) {
|
||||
|
|
|
@ -71,7 +71,7 @@ uint32
|
|||
get_lib_rats_export_apis(NativeSymbol **p_lib_rats_apis);
|
||||
|
||||
static bool
|
||||
compare_type_with_signautre(uint8 type, const char signature)
|
||||
compare_type_with_signature(uint8 type, const char signature)
|
||||
{
|
||||
const char num_sig_map[] = { 'F', 'f', 'I', 'i' };
|
||||
|
||||
|
@ -122,10 +122,10 @@ check_symbol_signature(const WASMFuncType *type, const char *signature)
|
|||
sig = *p++;
|
||||
|
||||
/* a f64/f32/i64/i32/externref parameter */
|
||||
if (compare_type_with_signautre(type->types[i], sig))
|
||||
if (compare_type_with_signature(type->types[i], sig))
|
||||
continue;
|
||||
|
||||
/* a pointer/string paramter */
|
||||
/* a pointer/string parameter */
|
||||
if (type->types[i] != VALUE_TYPE_I32)
|
||||
/* pointer and string must be i32 type */
|
||||
return false;
|
||||
|
@ -156,7 +156,7 @@ check_symbol_signature(const WASMFuncType *type, const char *signature)
|
|||
return false;
|
||||
|
||||
/* result types includes: f64,f32,i64,i32,externref */
|
||||
if (!compare_type_with_signautre(type->types[i], *p))
|
||||
if (!compare_type_with_signature(type->types[i], *p))
|
||||
return false;
|
||||
|
||||
p++;
|
||||
|
|
|
@ -91,6 +91,9 @@ wasm_runtime_destroy_registered_module_list();
|
|||
|
||||
#define E_TYPE_XIP 4
|
||||
|
||||
static uint8
|
||||
val_type_to_val_kind(uint8 value_type);
|
||||
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
/* Initialize externref hashmap */
|
||||
static bool
|
||||
|
@ -922,7 +925,7 @@ wasm_runtime_is_xip_file(const uint8 *buf, uint32 size)
|
|||
read_uint16(p, p_end, e_type);
|
||||
return (e_type == E_TYPE_XIP) ? true : false;
|
||||
}
|
||||
else if (section_type >= AOT_SECTION_TYPE_SIGANATURE) {
|
||||
else if (section_type >= AOT_SECTION_TYPE_SIGNATURE) {
|
||||
return false;
|
||||
}
|
||||
p += section_size;
|
||||
|
@ -1034,7 +1037,7 @@ wasm_runtime_register_module_internal(const char *module_name,
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* module has empyt name, reset it */
|
||||
/* module has empty name, reset it */
|
||||
node->module_name = module_name;
|
||||
return true;
|
||||
}
|
||||
|
@ -1350,12 +1353,18 @@ wasm_runtime_load_ex(uint8 *buf, uint32 size, const LoadArgs *args,
|
|||
true,
|
||||
#endif
|
||||
args, error_buf, error_buf_size);
|
||||
if (module_common)
|
||||
((WASMModule *)module_common)->is_binary_freeable =
|
||||
args->wasm_binary_freeable;
|
||||
#endif
|
||||
}
|
||||
else if (get_package_type(buf, size) == Wasm_Module_AoT) {
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
module_common = (WASMModuleCommon *)aot_load_from_aot_file(
|
||||
buf, size, args, error_buf, error_buf_size);
|
||||
if (module_common)
|
||||
((AOTModule *)module_common)->is_binary_freeable =
|
||||
args->wasm_binary_freeable;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
@ -1383,6 +1392,7 @@ wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
|||
{
|
||||
LoadArgs args = { 0 };
|
||||
args.name = "";
|
||||
args.wasm_binary_freeable = false;
|
||||
return wasm_runtime_load_ex(buf, size, &args, error_buf, error_buf_size);
|
||||
}
|
||||
|
||||
|
@ -1400,6 +1410,7 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
|
|||
LOG_DEBUG("WASM module load failed from sections");
|
||||
return NULL;
|
||||
}
|
||||
((WASMModule *)module_common)->is_binary_freeable = true;
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
#endif
|
||||
|
@ -1412,6 +1423,7 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
|
|||
LOG_DEBUG("WASM module load failed from sections");
|
||||
return NULL;
|
||||
}
|
||||
((AOTModule *)module_common)->is_binary_freeable = true;
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
#endif
|
||||
|
@ -1891,6 +1903,67 @@ wasm_runtime_set_module_inst(WASMExecEnv *exec_env,
|
|||
wasm_exec_env_set_module_inst(exec_env, module_inst);
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_get_export_global_inst(WASMModuleInstanceCommon *const module_inst,
|
||||
char const *name,
|
||||
wasm_global_inst_t *global_inst)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
const WASMModuleInstance *wasm_module_inst =
|
||||
(const WASMModuleInstance *)module_inst;
|
||||
const WASMModule *wasm_module = wasm_module_inst->module;
|
||||
uint32 i;
|
||||
for (i = 0; i < wasm_module->export_count; i++) {
|
||||
const WASMExport *wasm_export = &wasm_module->exports[i];
|
||||
if ((wasm_export->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL)
|
||||
&& !strcmp(wasm_export->name, name)) {
|
||||
const WASMModuleInstanceExtra *e =
|
||||
(WASMModuleInstanceExtra *)wasm_module_inst->e;
|
||||
const WASMGlobalInstance *global =
|
||||
&e->globals[wasm_export->index];
|
||||
global_inst->kind = val_type_to_val_kind(global->type);
|
||||
global_inst->is_mutable = global->is_mutable;
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
global_inst->global_data =
|
||||
wasm_module_inst->global_data + global->data_offset;
|
||||
#else
|
||||
global_inst->global_data =
|
||||
global->import_global_inst
|
||||
? global->import_module_inst->global_data
|
||||
+ global->import_global_inst->data_offset
|
||||
: wasm_module_inst->global_data + global->data_offset;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT) {
|
||||
const AOTModuleInstance *aot_module_inst =
|
||||
(AOTModuleInstance *)module_inst;
|
||||
const AOTModule *aot_module = (AOTModule *)aot_module_inst->module;
|
||||
uint32 i;
|
||||
for (i = 0; i < aot_module->export_count; i++) {
|
||||
const AOTExport *aot_export = &aot_module->exports[i];
|
||||
if ((aot_export->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL)
|
||||
&& !strcmp(aot_export->name, name)) {
|
||||
const AOTGlobal *global =
|
||||
&aot_module->globals[aot_export->index];
|
||||
global_inst->kind = val_type_to_val_kind(global->type.val_type);
|
||||
global_inst->is_mutable = global->type.is_mutable;
|
||||
global_inst->global_data =
|
||||
aot_module_inst->global_data + global->data_offset;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_runtime_get_function_attachment(WASMExecEnv *exec_env)
|
||||
{
|
||||
|
@ -1995,10 +2068,12 @@ val_type_to_val_kind(uint8 value_type)
|
|||
return WASM_F32;
|
||||
case VALUE_TYPE_F64:
|
||||
return WASM_F64;
|
||||
case VALUE_TYPE_V128:
|
||||
return WASM_V128;
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
return WASM_FUNCREF;
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
return WASM_ANYREF;
|
||||
return WASM_EXTERNREF;
|
||||
default:
|
||||
bh_assert(0);
|
||||
return 0;
|
||||
|
@ -2150,7 +2225,7 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
|||
bh_assert((argv && ret_argv) || (argc == 0));
|
||||
|
||||
if (argv == ret_argv) {
|
||||
/* no need to transfrom externref results */
|
||||
/* no need to transform externref results */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2301,6 +2376,11 @@ parse_args_to_uint32_array(WASMFuncType *type, wasm_val_t *args,
|
|||
out_argv[p++] = u.parts[1];
|
||||
break;
|
||||
}
|
||||
case WASM_V128:
|
||||
{
|
||||
bh_assert(0);
|
||||
break;
|
||||
}
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
#if WASM_ENABLE_GC == 0
|
||||
case WASM_FUNCREF:
|
||||
|
@ -2311,7 +2391,7 @@ parse_args_to_uint32_array(WASMFuncType *type, wasm_val_t *args,
|
|||
#else
|
||||
case WASM_FUNCREF:
|
||||
#endif
|
||||
case WASM_ANYREF:
|
||||
case WASM_EXTERNREF:
|
||||
{
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
out_argv[p++] = args[i].of.foreign;
|
||||
|
@ -2382,6 +2462,11 @@ parse_uint32_array_to_results(WASMFuncType *type, uint32 *argv,
|
|||
out_results[i].of.f64 = u.val;
|
||||
break;
|
||||
}
|
||||
case VALUE_TYPE_V128:
|
||||
{
|
||||
bh_assert(0);
|
||||
break;
|
||||
}
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
#if WASM_ENABLE_GC == 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
|
@ -2407,7 +2492,7 @@ parse_uint32_array_to_results(WASMFuncType *type, uint32 *argv,
|
|||
#endif /* end of WASM_ENABLE_GC == 0 */
|
||||
{
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
out_results[i].kind = WASM_ANYREF;
|
||||
out_results[i].kind = WASM_EXTERNREF;
|
||||
out_results[i].of.foreign = (uintptr_t)argv[p++];
|
||||
#else
|
||||
union {
|
||||
|
@ -2416,7 +2501,7 @@ parse_uint32_array_to_results(WASMFuncType *type, uint32 *argv,
|
|||
} u;
|
||||
u.parts[0] = argv[p++];
|
||||
u.parts[1] = argv[p++];
|
||||
out_results[i].kind = WASM_ANYREF;
|
||||
out_results[i].kind = WASM_EXTERNREF;
|
||||
out_results[i].of.foreign = u.val;
|
||||
#endif
|
||||
break;
|
||||
|
@ -2558,6 +2643,9 @@ wasm_runtime_call_wasm_v(WASMExecEnv *exec_env,
|
|||
args[i].kind = WASM_F64;
|
||||
args[i].of.f64 = va_arg(vargs, float64);
|
||||
break;
|
||||
case VALUE_TYPE_V128:
|
||||
bh_assert(0);
|
||||
break;
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
{
|
||||
|
@ -2567,7 +2655,7 @@ wasm_runtime_call_wasm_v(WASMExecEnv *exec_env,
|
|||
}
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
{
|
||||
args[i].kind = WASM_ANYREF;
|
||||
args[i].kind = WASM_EXTERNREF;
|
||||
args[i].of.foreign = va_arg(vargs, uintptr_t);
|
||||
break;
|
||||
}
|
||||
|
@ -2823,7 +2911,7 @@ void
|
|||
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
|
||||
bool enable)
|
||||
{
|
||||
/* Alwary disable bounds checks if hw bounds checks enabled */
|
||||
/* Always disable bounds checks if hw bounds checks is enabled */
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
enable = false;
|
||||
#endif
|
||||
|
@ -3756,14 +3844,14 @@ wasm_runtime_get_import_count(WASMModuleCommon *const module)
|
|||
|
||||
void
|
||||
wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
|
||||
wasm_import_type *import_type)
|
||||
wasm_import_t *import_type)
|
||||
{
|
||||
if (!import_type) {
|
||||
bh_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(import_type, 0, sizeof(wasm_import_type));
|
||||
memset(import_type, 0, sizeof(wasm_import_t));
|
||||
|
||||
if (!module) {
|
||||
bh_assert(0);
|
||||
|
@ -3783,6 +3871,7 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
|
|||
import_type->kind = WASM_IMPORT_EXPORT_KIND_FUNC;
|
||||
import_type->linked =
|
||||
aot_import_func->func_ptr_linked ? true : false;
|
||||
import_type->u.func_type = aot_import_func->func_type;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3794,6 +3883,8 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
|
|||
import_type->name = aot_import_global->global_name;
|
||||
import_type->kind = WASM_IMPORT_EXPORT_KIND_GLOBAL;
|
||||
import_type->linked = aot_import_global->is_linked;
|
||||
import_type->u.global_type =
|
||||
(WASMGlobalType *)&aot_import_global->type;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3840,9 +3931,12 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
|
|||
switch (import_type->kind) {
|
||||
case WASM_IMPORT_EXPORT_KIND_FUNC:
|
||||
import_type->linked = wasm_import->u.function.func_ptr_linked;
|
||||
import_type->u.func_type = wasm_import->u.function.func_type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_GLOBAL:
|
||||
import_type->linked = wasm_import->u.global.is_linked;
|
||||
import_type->u.global_type =
|
||||
(WASMGlobalType *)&wasm_import->u.global.type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_TABLE:
|
||||
/* not supported */
|
||||
|
@ -3888,14 +3982,14 @@ wasm_runtime_get_export_count(WASMModuleCommon *const module)
|
|||
|
||||
void
|
||||
wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index,
|
||||
wasm_export_type *export_type)
|
||||
wasm_export_t *export_type)
|
||||
{
|
||||
if (!export_type) {
|
||||
bh_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(export_type, 0, sizeof(wasm_export_type));
|
||||
memset(export_type, 0, sizeof(wasm_export_t));
|
||||
|
||||
if (!module) {
|
||||
bh_assert(0);
|
||||
|
@ -3914,6 +4008,33 @@ wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index,
|
|||
const AOTExport *aot_export = &aot_module->exports[export_index];
|
||||
export_type->name = aot_export->name;
|
||||
export_type->kind = aot_export->kind;
|
||||
switch (export_type->kind) {
|
||||
case WASM_IMPORT_EXPORT_KIND_FUNC:
|
||||
export_type->u.func_type =
|
||||
(AOTFuncType *)aot_module
|
||||
->types[aot_module->func_type_indexes
|
||||
[aot_export->index
|
||||
- aot_module->import_func_count]];
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_GLOBAL:
|
||||
export_type->u.global_type =
|
||||
&aot_module
|
||||
->globals[aot_export->index
|
||||
- aot_module->import_global_count]
|
||||
.type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_TABLE:
|
||||
/* not supported */
|
||||
// export_type->linked = false;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_MEMORY:
|
||||
/* not supported */
|
||||
// export_type->linked = false;
|
||||
break;
|
||||
default:
|
||||
bh_assert(0);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -3929,11 +4050,139 @@ wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index,
|
|||
const WASMExport *wasm_export = &wasm_module->exports[export_index];
|
||||
export_type->name = wasm_export->name;
|
||||
export_type->kind = wasm_export->kind;
|
||||
switch (export_type->kind) {
|
||||
case WASM_IMPORT_EXPORT_KIND_FUNC:
|
||||
export_type->u.func_type =
|
||||
wasm_module
|
||||
->functions[wasm_export->index
|
||||
- wasm_module->import_function_count]
|
||||
->func_type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_GLOBAL:
|
||||
export_type->u.global_type =
|
||||
&wasm_module
|
||||
->globals[wasm_export->index
|
||||
- wasm_module->import_global_count]
|
||||
.type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_TABLE:
|
||||
/* not supported */
|
||||
// export_type->linked = false;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_MEMORY:
|
||||
/* not supported */
|
||||
// export_type->linked = false;
|
||||
break;
|
||||
bh_assert(0);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_func_type_get_param_count(WASMFuncType *const func_type)
|
||||
{
|
||||
bh_assert(func_type);
|
||||
|
||||
return func_type->param_count;
|
||||
}
|
||||
|
||||
wasm_valkind_t
|
||||
wasm_func_type_get_param_valkind(WASMFuncType *const func_type,
|
||||
uint32 param_index)
|
||||
{
|
||||
if (!func_type || (param_index >= func_type->param_count)) {
|
||||
bh_assert(0);
|
||||
return (wasm_valkind_t)-1;
|
||||
}
|
||||
|
||||
switch (func_type->types[param_index]) {
|
||||
case VALUE_TYPE_I32:
|
||||
return WASM_I32;
|
||||
case VALUE_TYPE_I64:
|
||||
return WASM_I64;
|
||||
case VALUE_TYPE_F32:
|
||||
return WASM_F32;
|
||||
case VALUE_TYPE_F64:
|
||||
return WASM_F64;
|
||||
case VALUE_TYPE_V128:
|
||||
return WASM_V128;
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
return WASM_FUNCREF;
|
||||
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
case VALUE_TYPE_VOID:
|
||||
default:
|
||||
{
|
||||
bh_assert(0);
|
||||
return (wasm_valkind_t)-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_func_type_get_result_count(WASMFuncType *const func_type)
|
||||
{
|
||||
bh_assert(func_type);
|
||||
|
||||
return func_type->result_count;
|
||||
}
|
||||
|
||||
wasm_valkind_t
|
||||
wasm_func_type_get_result_valkind(WASMFuncType *const func_type,
|
||||
uint32 result_index)
|
||||
{
|
||||
if (!func_type || (result_index >= func_type->result_count)) {
|
||||
bh_assert(0);
|
||||
return (wasm_valkind_t)-1;
|
||||
}
|
||||
|
||||
switch (func_type->types[func_type->param_count + result_index]) {
|
||||
case VALUE_TYPE_I32:
|
||||
return WASM_I32;
|
||||
case VALUE_TYPE_I64:
|
||||
return WASM_I64;
|
||||
case VALUE_TYPE_F32:
|
||||
return WASM_F32;
|
||||
case VALUE_TYPE_F64:
|
||||
return WASM_F64;
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
return WASM_FUNCREF;
|
||||
|
||||
#if WASM_ENABLE_SIMD != 0
|
||||
case VALUE_TYPE_V128:
|
||||
return WASM_V128;
|
||||
#endif
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
#endif
|
||||
case VALUE_TYPE_VOID:
|
||||
default:
|
||||
{
|
||||
bh_assert(0);
|
||||
return (wasm_valkind_t)-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wasm_valkind_t
|
||||
wasm_global_type_get_valkind(const wasm_global_type_t global_type)
|
||||
{
|
||||
bh_assert(global_type);
|
||||
|
||||
return val_type_to_val_kind(global_type->val_type);
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_global_type_get_mutable(const wasm_global_type_t global_type)
|
||||
{
|
||||
bh_assert(global_type);
|
||||
|
||||
return global_type->is_mutable;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_register_natives(const char *module_name,
|
||||
NativeSymbol *native_symbols,
|
||||
|
@ -5793,7 +6042,7 @@ wasm_externref_ref2obj(uint32 externref_idx, void **p_extern_obj)
|
|||
{
|
||||
ExternRefMapNode *node;
|
||||
|
||||
/* catch a `ref.null` vairable */
|
||||
/* catch a `ref.null` variable */
|
||||
if (externref_idx == NULL_REF) {
|
||||
*p_extern_obj = NULL;
|
||||
return true;
|
||||
|
@ -5892,7 +6141,7 @@ aot_mark_all_externrefs(AOTModuleInstance *module_inst)
|
|||
const AOTTableInstance *table_inst;
|
||||
|
||||
for (i = 0; i < module->global_count; i++, global++) {
|
||||
if (global->type == VALUE_TYPE_EXTERNREF) {
|
||||
if (global->type.val_type == VALUE_TYPE_EXTERNREF) {
|
||||
mark_externref(
|
||||
*(uint32 *)(module_inst->global_data + global->data_offset));
|
||||
}
|
||||
|
@ -6221,14 +6470,14 @@ wasm_runtime_get_export_global_type(const WASMModuleCommon *module_comm,
|
|||
if (export->index < module->import_global_count) {
|
||||
WASMGlobalImport *import_global =
|
||||
&((module->import_globals + export->index)->u.global);
|
||||
*out_val_type = import_global->type;
|
||||
*out_mutability = import_global->is_mutable;
|
||||
*out_val_type = import_global->type.val_type;
|
||||
*out_mutability = import_global->type.is_mutable;
|
||||
}
|
||||
else {
|
||||
WASMGlobal *global =
|
||||
module->globals + (export->index - module->import_global_count);
|
||||
*out_val_type = global->type;
|
||||
*out_mutability = global->is_mutable;
|
||||
*out_val_type = global->type.val_type;
|
||||
*out_mutability = global->type.is_mutable;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -6241,14 +6490,14 @@ wasm_runtime_get_export_global_type(const WASMModuleCommon *module_comm,
|
|||
if (export->index < module->import_global_count) {
|
||||
AOTImportGlobal *import_global =
|
||||
module->import_globals + export->index;
|
||||
*out_val_type = import_global->type;
|
||||
*out_mutability = import_global->is_mutable;
|
||||
*out_val_type = import_global->type.val_type;
|
||||
*out_mutability = import_global->type.is_mutable;
|
||||
}
|
||||
else {
|
||||
AOTGlobal *global =
|
||||
module->globals + (export->index - module->import_global_count);
|
||||
*out_val_type = global->type;
|
||||
*out_mutability = global->is_mutable;
|
||||
*out_val_type = global->type.val_type;
|
||||
*out_mutability = global->type.is_mutable;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -6352,7 +6601,7 @@ argv_to_params(wasm_val_t *out_params, const uint32 *argv,
|
|||
break;
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
param->kind = WASM_ANYREF;
|
||||
param->kind = WASM_EXTERNREF;
|
||||
|
||||
if (!wasm_externref_ref2obj(*argv,
|
||||
(void **)¶m->of.foreign)) {
|
||||
|
@ -6767,7 +7016,7 @@ wasm_runtime_load_depended_module(const WASMModuleCommon *parent_module,
|
|||
goto delete_loading_module;
|
||||
}
|
||||
if (get_package_type(buffer, buffer_size) != parent_module->module_type) {
|
||||
LOG_DEBUG("moudle %s type error", sub_module_name);
|
||||
LOG_DEBUG("module %s type error", sub_module_name);
|
||||
goto destroy_file_buffer;
|
||||
}
|
||||
|
||||
|
@ -7031,7 +7280,7 @@ wasm_runtime_detect_native_stack_overflow(WASMExecEnv *exec_env)
|
|||
uint8 *boundary = exec_env->native_stack_boundary;
|
||||
RECORD_STACK_USAGE(exec_env, (uint8 *)&boundary);
|
||||
if (boundary == NULL) {
|
||||
/* the platfrom doesn't support os_thread_get_stack_boundary */
|
||||
/* the platform doesn't support os_thread_get_stack_boundary */
|
||||
return true;
|
||||
}
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
|
||||
|
@ -7054,7 +7303,7 @@ wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
|
|||
uint8 *boundary = exec_env->native_stack_boundary;
|
||||
RECORD_STACK_USAGE(exec_env, (uint8 *)&boundary);
|
||||
if (boundary == NULL) {
|
||||
/* the platfrom doesn't support os_thread_get_stack_boundary */
|
||||
/* the platform doesn't support os_thread_get_stack_boundary */
|
||||
return true;
|
||||
}
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
|
||||
|
@ -7071,3 +7320,38 @@ wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_is_underlying_binary_freeable(WASMModuleCommon *const module)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode) {
|
||||
#if (WASM_ENABLE_JIT != 0 || WASM_ENABLE_FAST_JIT != 0) \
|
||||
&& (WASM_ENABLE_LAZY_JIT != 0)
|
||||
return false;
|
||||
#elif WASM_ENABLE_FAST_INTERP == 0
|
||||
return false;
|
||||
#else
|
||||
/* Fast interpreter mode */
|
||||
if (!((WASMModule *)module)->is_binary_freeable)
|
||||
return false;
|
||||
#if WASM_ENABLE_GC != 0 && WASM_ENABLE_STRINGREF != 0
|
||||
if (((WASMModule *)module)->string_literal_ptrs)
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif /* WASM_ENABLE_INTERP != 0 */
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT) {
|
||||
if (!((AOTModule *)module)->is_binary_freeable)
|
||||
return false;
|
||||
#if WASM_ENABLE_GC != 0 && WASM_ENABLE_STRINGREF != 0
|
||||
if (((AOTModule *)module)->string_literal_ptrs)
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif /* WASM_ENABLE_AOT != 0 */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -362,6 +362,9 @@ LOAD_I16(void *addr)
|
|||
#define SHARED_MEMORY_UNLOCK(memory) (void)0
|
||||
#endif
|
||||
|
||||
#define CLAMP_U64_TO_U32(value) \
|
||||
((value) > UINT32_MAX ? UINT32_MAX : (uint32)(value))
|
||||
|
||||
typedef struct WASMModuleCommon {
|
||||
/* Module type, for module loaded from WASM bytecode binary,
|
||||
this field is Wasm_Module_Bytecode, and this structure should
|
||||
|
@ -909,7 +912,7 @@ WASMExport *
|
|||
loader_find_export(const WASMModuleCommon *module, const char *module_name,
|
||||
const char *field_name, uint8 export_kind, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
#endif /* WASM_ENALBE_MULTI_MODULE */
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE */
|
||||
|
||||
bool
|
||||
wasm_runtime_is_built_in_module(const char *module_name);
|
||||
|
@ -1196,6 +1199,9 @@ WASM_RUNTIME_API_EXTERN bool
|
|||
wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
|
||||
uint32 requested_size);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_is_underlying_binary_freeable(WASMModuleCommon *const module);
|
||||
|
||||
#if WASM_ENABLE_LINUX_PERF != 0
|
||||
bool
|
||||
wasm_runtime_get_linux_perf(void);
|
||||
|
|
|
@ -333,7 +333,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
|||
|
||||
while (1) {
|
||||
if (timeout < 0) {
|
||||
/* wait forever until it is notified or terminatied
|
||||
/* wait forever until it is notified or terminated
|
||||
here we keep waiting and checking every second */
|
||||
os_cond_reltimedwait(&wait_node->wait_cond, lock,
|
||||
(uint64)timeout_1sec);
|
||||
|
|
|
@ -221,16 +221,16 @@ aot_create_import_globals(const WASMModule *module, bool gc_enabled,
|
|||
WASMGlobalImport *import_global = &module->import_globals[i].u.global;
|
||||
import_globals[i].module_name = import_global->module_name;
|
||||
import_globals[i].global_name = import_global->field_name;
|
||||
import_globals[i].type = import_global->type;
|
||||
import_globals[i].is_mutable = import_global->is_mutable;
|
||||
import_globals[i].type.val_type = import_global->type.val_type;
|
||||
import_globals[i].type.is_mutable = import_global->type.is_mutable;
|
||||
import_globals[i].global_data_linked =
|
||||
import_global->global_data_linked;
|
||||
|
||||
import_globals[i].data_offset_64bit = data_offset_64bit;
|
||||
import_globals[i].data_offset_32bit = data_offset_32bit;
|
||||
|
||||
get_value_type_size(import_global->type, gc_enabled, &value_size_64bit,
|
||||
&value_size_32bit);
|
||||
get_value_type_size(import_global->type.val_type, gc_enabled,
|
||||
&value_size_64bit, &value_size_32bit);
|
||||
|
||||
import_globals[i].size_64bit = value_size_64bit;
|
||||
import_globals[i].size_32bit = value_size_32bit;
|
||||
|
@ -269,16 +269,16 @@ aot_create_globals(const WASMModule *module, bool gc_enabled,
|
|||
/* Create each global */
|
||||
for (i = 0; i < module->global_count; i++) {
|
||||
WASMGlobal *global = &module->globals[i];
|
||||
globals[i].type = global->type;
|
||||
globals[i].is_mutable = global->is_mutable;
|
||||
globals[i].type.val_type = global->type.val_type;
|
||||
globals[i].type.is_mutable = global->type.is_mutable;
|
||||
memcpy(&globals[i].init_expr, &global->init_expr,
|
||||
sizeof(global->init_expr));
|
||||
|
||||
globals[i].data_offset_64bit = data_offset_64bit;
|
||||
globals[i].data_offset_32bit = data_offset_32bit;
|
||||
|
||||
get_value_type_size(global->type, gc_enabled, &value_size_64bit,
|
||||
&value_size_32bit);
|
||||
get_value_type_size(global->type.val_type, gc_enabled,
|
||||
&value_size_64bit, &value_size_32bit);
|
||||
|
||||
globals[i].size_64bit = value_size_64bit;
|
||||
globals[i].size_32bit = value_size_32bit;
|
||||
|
|
|
@ -175,9 +175,7 @@ typedef struct AOTTableInitData {
|
|||
typedef struct AOTImportGlobal {
|
||||
char *module_name;
|
||||
char *global_name;
|
||||
/* VALUE_TYPE_I32/I64/F32/F64 */
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
WASMGlobalType type;
|
||||
uint32 size;
|
||||
/* The data offset of current global in global data */
|
||||
uint32 data_offset;
|
||||
|
@ -203,9 +201,7 @@ typedef struct AOTImportGlobal {
|
|||
* Global variable
|
||||
*/
|
||||
typedef struct AOTGlobal {
|
||||
/* VALUE_TYPE_I32/I64/F32/F64 */
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
WASMGlobalType type;
|
||||
uint32 size;
|
||||
/* The data offset of current global in global data */
|
||||
uint32 data_offset;
|
||||
|
|
|
@ -84,37 +84,46 @@ read_leb(const uint8 *buf, const uint8 *buf_end, uint32 *p_offset,
|
|||
}
|
||||
|
||||
/* NOLINTNEXTLINE */
|
||||
#define read_leb_uint32(p, p_end, res) \
|
||||
do { \
|
||||
uint32 off = 0; \
|
||||
uint64 res64; \
|
||||
if (!read_leb(p, p_end, &off, 32, false, &res64)) \
|
||||
return false; \
|
||||
p += off; \
|
||||
res = (uint32)res64; \
|
||||
#define read_leb_generic(p, p_end, res, res_type, sign) \
|
||||
do { \
|
||||
uint32 off = 0; \
|
||||
uint64 res64; \
|
||||
if (!read_leb(p, p_end, &off, sizeof(res_type) << 3, sign, &res64)) \
|
||||
return false; \
|
||||
p += off; \
|
||||
res = (res_type)res64; \
|
||||
} while (0)
|
||||
|
||||
/* NOLINTNEXTLINE */
|
||||
#define read_leb_int32(p, p_end, res) \
|
||||
do { \
|
||||
uint32 off = 0; \
|
||||
uint64 res64; \
|
||||
if (!read_leb(p, p_end, &off, 32, true, &res64)) \
|
||||
return false; \
|
||||
p += off; \
|
||||
res = (int32)res64; \
|
||||
} while (0)
|
||||
#define read_leb_int32(p, p_end, res) \
|
||||
read_leb_generic(p, p_end, res, int32, true)
|
||||
|
||||
/* NOLINTNEXTLINE */
|
||||
#define read_leb_int64(p, p_end, res) \
|
||||
do { \
|
||||
uint32 off = 0; \
|
||||
uint64 res64; \
|
||||
if (!read_leb(p, p_end, &off, 64, true, &res64)) \
|
||||
return false; \
|
||||
p += off; \
|
||||
res = (int64)res64; \
|
||||
#define read_leb_int64(p, p_end, res) \
|
||||
read_leb_generic(p, p_end, res, int64, true)
|
||||
|
||||
/* NOLINTNEXTLINE */
|
||||
#define read_leb_uint32(p, p_end, res) \
|
||||
read_leb_generic(p, p_end, res, uint32, false)
|
||||
|
||||
/* NOLINTNEXTLINE */
|
||||
#define read_leb_uint64(p, p_end, res) \
|
||||
read_leb_generic(p, p_end, res, uint64, false)
|
||||
|
||||
/* NOLINTNEXTLINE */
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define read_leb_mem_offset(p, p_end, res) \
|
||||
do { \
|
||||
if (IS_MEMORY64) { \
|
||||
read_leb_uint64(p, p_end, res); \
|
||||
} \
|
||||
else { \
|
||||
read_leb_uint32(p, p_end, res); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define read_leb_mem_offset read_leb_uint32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Since wamrc uses a full feature Wasm loader,
|
||||
|
@ -135,6 +144,13 @@ aot_validate_wasm(AOTCompContext *comp_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (comp_ctx->pointer_size < sizeof(uint64) && IS_MEMORY64) {
|
||||
aot_set_last_error("Compiling wasm64 to 32bit platform is not allowed");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -933,7 +949,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
uint16 result_count;
|
||||
uint32 br_depth, *br_depths, br_count;
|
||||
uint32 func_idx, type_idx, mem_idx, local_idx, global_idx, i;
|
||||
uint32 bytes = 4, align, offset;
|
||||
uint32 bytes = 4, align;
|
||||
mem_offset_t offset;
|
||||
uint32 type_index;
|
||||
bool sign = true;
|
||||
int32 i32_const;
|
||||
|
@ -1892,7 +1909,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
sign = (opcode == WASM_OP_I32_LOAD16_S) ? true : false;
|
||||
op_i32_load:
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_op_i32_load(comp_ctx, func_ctx, align, offset,
|
||||
bytes, sign, false))
|
||||
return false;
|
||||
|
@ -1918,7 +1935,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
sign = (opcode == WASM_OP_I64_LOAD32_S) ? true : false;
|
||||
op_i64_load:
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_op_i64_load(comp_ctx, func_ctx, align, offset,
|
||||
bytes, sign, false))
|
||||
return false;
|
||||
|
@ -1926,14 +1943,14 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
|
||||
case WASM_OP_F32_LOAD:
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_op_f32_load(comp_ctx, func_ctx, align, offset))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case WASM_OP_F64_LOAD:
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_op_f64_load(comp_ctx, func_ctx, align, offset))
|
||||
return false;
|
||||
break;
|
||||
|
@ -1948,7 +1965,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
bytes = 2;
|
||||
op_i32_store:
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_op_i32_store(comp_ctx, func_ctx, align, offset,
|
||||
bytes, false))
|
||||
return false;
|
||||
|
@ -1967,7 +1984,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
bytes = 4;
|
||||
op_i64_store:
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_op_i64_store(comp_ctx, func_ctx, align, offset,
|
||||
bytes, false))
|
||||
return false;
|
||||
|
@ -1975,7 +1992,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
|
||||
case WASM_OP_F32_STORE:
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_op_f32_store(comp_ctx, func_ctx, align,
|
||||
offset))
|
||||
return false;
|
||||
|
@ -1983,7 +2000,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
|
||||
case WASM_OP_F64_STORE:
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_op_f64_store(comp_ctx, func_ctx, align,
|
||||
offset))
|
||||
return false;
|
||||
|
@ -2540,7 +2557,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
|
||||
if (opcode != WASM_OP_ATOMIC_FENCE) {
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
}
|
||||
switch (opcode) {
|
||||
case WASM_OP_ATOMIC_WAIT32:
|
||||
|
@ -2705,7 +2722,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case SIMD_v128_load:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_simd_v128_load(comp_ctx, func_ctx,
|
||||
align, offset))
|
||||
return false;
|
||||
|
@ -2720,7 +2737,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case SIMD_v128_load32x2_u:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_simd_load_extend(
|
||||
comp_ctx, func_ctx, opcode, align, offset))
|
||||
return false;
|
||||
|
@ -2733,7 +2750,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case SIMD_v128_load64_splat:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_simd_load_splat(comp_ctx, func_ctx,
|
||||
opcode, align, offset))
|
||||
return false;
|
||||
|
@ -2743,7 +2760,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case SIMD_v128_store:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_simd_v128_store(comp_ctx, func_ctx,
|
||||
align, offset))
|
||||
return false;
|
||||
|
@ -3006,7 +3023,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case SIMD_v128_load64_lane:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_simd_load_lane(comp_ctx, func_ctx,
|
||||
opcode, align, offset,
|
||||
*frame_ip++))
|
||||
|
@ -3020,7 +3037,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case SIMD_v128_store64_lane:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_simd_store_lane(comp_ctx, func_ctx,
|
||||
opcode, align, offset,
|
||||
*frame_ip++))
|
||||
|
@ -3032,7 +3049,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case SIMD_v128_load64_zero:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, align);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
|
||||
if (!aot_compile_simd_load_zero(comp_ctx, func_ctx,
|
||||
opcode, align, offset))
|
||||
return false;
|
||||
|
@ -3966,7 +3983,7 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
|
|||
orc_main_dylib = LLVMOrcLLLazyJITGetMainJITDylib(comp_ctx->orc_jit);
|
||||
if (!orc_main_dylib) {
|
||||
aot_set_last_error(
|
||||
"failed to get orc orc_jit main dynmaic library");
|
||||
"failed to get orc orc_jit main dynamic library");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4191,7 +4208,7 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
|
|||
/*
|
||||
* move the temporary .su file to the specified location.
|
||||
*
|
||||
* Note: the former is automatimally inferred from the output
|
||||
* Note: the former is automatically inferred from the output
|
||||
* filename (file_name here) by clang.
|
||||
*
|
||||
* Note: the latter might be user-specified.
|
||||
|
@ -4247,7 +4264,7 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
|
|||
#endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */
|
||||
|
||||
if (!strncmp(LLVMGetTargetName(target), "arc", 3))
|
||||
/* Emit to assmelby file instead for arc target
|
||||
/* Emit to assembly file instead for arc target
|
||||
as it cannot emit to object file */
|
||||
file_type = LLVMAssemblyFile;
|
||||
|
||||
|
|
|
@ -519,6 +519,15 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
|
|||
wasm_runtime_free(aot_value); \
|
||||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define IS_MEMORY64 \
|
||||
(comp_ctx->comp_data->memories[0].memory_flags & MEMORY64_FLAG)
|
||||
#define MEMORY64_COND_VALUE(VAL_IF_ENABLED, VAL_IF_DISABLED) \
|
||||
(IS_MEMORY64 ? VAL_IF_ENABLED : VAL_IF_DISABLED)
|
||||
#else
|
||||
#define MEMORY64_COND_VALUE(VAL_IF_ENABLED, VAL_IF_DISABLED) (VAL_IF_DISABLED)
|
||||
#endif
|
||||
|
||||
#define POP_I32(v) POP(v, VALUE_TYPE_I32)
|
||||
#define POP_I64(v) POP(v, VALUE_TYPE_I64)
|
||||
#define POP_F32(v) POP(v, VALUE_TYPE_F32)
|
||||
|
@ -527,6 +536,10 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
|
|||
#define POP_FUNCREF(v) POP(v, VALUE_TYPE_FUNCREF)
|
||||
#define POP_EXTERNREF(v) POP(v, VALUE_TYPE_EXTERNREF)
|
||||
#define POP_GC_REF(v) POP(v, VALUE_TYPE_GC_REF)
|
||||
#define POP_MEM_OFFSET(v) \
|
||||
POP(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32))
|
||||
#define POP_PAGE_COUNT(v) \
|
||||
POP(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32))
|
||||
|
||||
#define POP_COND(llvm_value) \
|
||||
do { \
|
||||
|
@ -590,6 +603,8 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
|
|||
#define PUSH_FUNCREF(v) PUSH(v, VALUE_TYPE_FUNCREF)
|
||||
#define PUSH_EXTERNREF(v) PUSH(v, VALUE_TYPE_EXTERNREF)
|
||||
#define PUSH_GC_REF(v) PUSH(v, VALUE_TYPE_GC_REF)
|
||||
#define PUSH_PAGE_COUNT(v) \
|
||||
PUSH(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32))
|
||||
|
||||
#define TO_LLVM_TYPE(wasm_type) \
|
||||
wasm_type_to_llvm_type(comp_ctx, &comp_ctx->basic_types, wasm_type)
|
||||
|
@ -603,6 +618,7 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
|
|||
#define INT8_TYPE comp_ctx->basic_types.int8_type
|
||||
#define INT16_TYPE comp_ctx->basic_types.int16_type
|
||||
#define INTPTR_T_TYPE comp_ctx->basic_types.intptr_t_type
|
||||
#define SIZE_T_TYPE comp_ctx->basic_types.size_t_type
|
||||
#define MD_TYPE comp_ctx->basic_types.meta_data_type
|
||||
#define INT8_PTR_TYPE comp_ctx->basic_types.int8_ptr_type
|
||||
#define INT16_PTR_TYPE comp_ctx->basic_types.int16_ptr_type
|
||||
|
|
|
@ -112,16 +112,6 @@ is_little_endian_binary(const AOTObjectData *obj_data)
|
|||
return obj_data->target_info.bin_type & 1 ? false : true;
|
||||
}
|
||||
|
||||
static bool
|
||||
need_call_wrapped_indirect(const AOTObjectData *obj_data)
|
||||
{
|
||||
const bool need_precheck = obj_data->comp_ctx->enable_stack_bound_check
|
||||
|| obj_data->comp_ctx->enable_stack_estimation;
|
||||
|
||||
return obj_data->comp_ctx->is_indirect_mode && need_precheck
|
||||
&& !strncmp(obj_data->comp_ctx->target_arch, "xtensa", 6);
|
||||
}
|
||||
|
||||
static bool
|
||||
str_starts_with(const char *str, const char *prefix)
|
||||
{
|
||||
|
@ -828,10 +818,6 @@ get_func_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
|||
/* function type indexes */
|
||||
size += (uint32)sizeof(uint32) * comp_data->func_count;
|
||||
|
||||
/* aot_func#xxx + aot_func_internal#xxx in XIP mode for xtensa */
|
||||
if (need_call_wrapped_indirect(obj_data))
|
||||
size *= 2;
|
||||
|
||||
/* max_local_cell_nums */
|
||||
size += (uint32)sizeof(uint32) * comp_data->func_count;
|
||||
|
||||
|
@ -2241,8 +2227,8 @@ aot_emit_import_global_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
|||
|
||||
for (i = 0; i < comp_data->import_global_count; i++, import_global++) {
|
||||
offset = align_uint(offset, 2);
|
||||
EMIT_U8(import_global->type);
|
||||
EMIT_U8(import_global->is_mutable);
|
||||
EMIT_U8(import_global->type.val_type);
|
||||
EMIT_U8(import_global->type.is_mutable);
|
||||
EMIT_STR(import_global->module_name);
|
||||
offset = align_uint(offset, 2);
|
||||
EMIT_STR(import_global->global_name);
|
||||
|
@ -2273,8 +2259,8 @@ aot_emit_global_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
|||
|
||||
for (i = 0; i < comp_data->global_count; i++, global++) {
|
||||
offset = align_uint(offset, 4);
|
||||
EMIT_U8(global->type);
|
||||
EMIT_U8(global->is_mutable);
|
||||
EMIT_U8(global->type.val_type);
|
||||
EMIT_U8(global->type.is_mutable);
|
||||
|
||||
offset = align_uint(offset, 4);
|
||||
if (!aot_emit_init_expr(buf, buf_end, &offset, comp_ctx,
|
||||
|
@ -2590,30 +2576,9 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
|||
EMIT_U64(func->text_offset);
|
||||
}
|
||||
|
||||
if (need_call_wrapped_indirect(obj_data)) {
|
||||
/*
|
||||
* Explicitly emit aot_func_internal#xxx for Xtensa XIP, therefore,
|
||||
* for aot_func#xxx, func_indexes ranged from 0 ~ func_count,
|
||||
* for aot_func_internal#xxxx, from func_count + 1 ~ 2 * func_count.
|
||||
*/
|
||||
for (i = 0, func = obj_data->funcs; i < obj_data->func_count;
|
||||
i++, func++) {
|
||||
if (is_32bit_binary(obj_data))
|
||||
EMIT_U32(func->text_offset_of_aot_func_internal);
|
||||
else
|
||||
EMIT_U64(func->text_offset_of_aot_func_internal);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < comp_data->func_count; i++)
|
||||
EMIT_U32(funcs[i]->func_type_index);
|
||||
|
||||
if (need_call_wrapped_indirect(obj_data)) {
|
||||
/* func_type_index for aot_func_internal#xxxx */
|
||||
for (i = 0; i < comp_data->func_count; i++)
|
||||
EMIT_U32(funcs[i]->func_type_index);
|
||||
}
|
||||
|
||||
for (i = 0; i < comp_data->func_count; i++) {
|
||||
uint32 max_local_cell_num =
|
||||
funcs[i]->param_cell_num + funcs[i]->local_cell_num;
|
||||
|
@ -3090,7 +3055,7 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
|
|||
&& bin_type != LLVMBinaryTypeMachO32B
|
||||
&& bin_type != LLVMBinaryTypeMachO64L
|
||||
&& bin_type != LLVMBinaryTypeMachO64B) {
|
||||
aot_set_last_error("invaid llvm binary bin_type.");
|
||||
aot_set_last_error("invalid llvm binary bin_type.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3166,13 +3131,13 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
|
|||
else if (bin_type == LLVMBinaryTypeMachO32L
|
||||
|| bin_type == LLVMBinaryTypeMachO32B) {
|
||||
/* TODO: parse file type of Mach-O 32 */
|
||||
aot_set_last_error("invaid llvm binary bin_type.");
|
||||
aot_set_last_error("invalid llvm binary bin_type.");
|
||||
return false;
|
||||
}
|
||||
else if (bin_type == LLVMBinaryTypeMachO64L
|
||||
|| bin_type == LLVMBinaryTypeMachO64B) {
|
||||
/* TODO: parse file type of Mach-O 64 */
|
||||
aot_set_last_error("invaid llvm binary bin_type.");
|
||||
aot_set_last_error("invalid llvm binary bin_type.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -2125,7 +2125,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
if (!(table_size_const =
|
||||
LLVMBuildBitCast(comp_ctx->builder, table_size_const,
|
||||
INT32_PTR_TYPE, "cur_siuze_i32p"))) {
|
||||
INT32_PTR_TYPE, "cur_size_i32p"))) {
|
||||
HANDLE_FAILURE("LLVMBuildBitCast");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -569,7 +569,7 @@ aot_compile_op_struct_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
SET_BUILDER_POS(check_struct_obj_succ);
|
||||
|
||||
/* For WASM_OP_STRUCT_NEW, init filed with poped value */
|
||||
/* For WASM_OP_STRUCT_NEW, init field with poped value */
|
||||
if (!init_with_default
|
||||
&& !struct_new_canon_init_fields(comp_ctx, func_ctx, type_index,
|
||||
struct_obj)) {
|
||||
|
|
|
@ -38,6 +38,20 @@
|
|||
|
||||
#define SET_BUILD_POS(block) LLVMPositionBuilderAtEnd(comp_ctx->builder, block)
|
||||
|
||||
static bool
|
||||
zero_extend_u64(AOTCompContext *comp_ctx, LLVMValueRef *value, const char *name)
|
||||
{
|
||||
if (comp_ctx->pointer_size == sizeof(uint64)) {
|
||||
/* zero extend to uint64 if the target is 64-bit */
|
||||
*value = LLVMBuildZExt(comp_ctx->builder, *value, I64_TYPE, name);
|
||||
if (!*value) {
|
||||
aot_set_last_error("llvm build zero extend failed.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static LLVMValueRef
|
||||
get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 bytes)
|
||||
|
@ -82,9 +96,10 @@ get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
|||
|
||||
LLVMValueRef
|
||||
aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 offset, uint32 bytes, bool enable_segue)
|
||||
mem_offset_t offset, uint32 bytes, bool enable_segue)
|
||||
{
|
||||
LLVMValueRef offset_const = I32_CONST(offset);
|
||||
LLVMValueRef offset_const =
|
||||
MEMORY64_COND_VALUE(I64_CONST(offset), I32_CONST(offset));
|
||||
LLVMValueRef addr, maddr, offset1, cmp1, cmp2, cmp;
|
||||
LLVMValueRef mem_base_addr, mem_check_bound;
|
||||
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
|
||||
|
@ -94,17 +109,27 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
bool is_target_64bit, is_local_of_aot_value = false;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
bool is_shared_memory =
|
||||
comp_ctx->comp_data->memories[0].memory_flags & 0x02;
|
||||
comp_ctx->comp_data->memories[0].memory_flags & SHARED_MEMORY_FLAG;
|
||||
#endif
|
||||
|
||||
is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false;
|
||||
|
||||
if (comp_ctx->is_indirect_mode
|
||||
&& aot_intrinsic_check_capability(comp_ctx, "i32.const")) {
|
||||
&& aot_intrinsic_check_capability(
|
||||
comp_ctx, MEMORY64_COND_VALUE("i64.const", "i32.const"))) {
|
||||
WASMValue wasm_value;
|
||||
wasm_value.i32 = offset;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (IS_MEMORY64) {
|
||||
wasm_value.i64 = offset;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
wasm_value.i32 = (int32)offset;
|
||||
}
|
||||
offset_const = aot_load_const_from_table(
|
||||
comp_ctx, func_ctx->native_symbol, &wasm_value, VALUE_TYPE_I32);
|
||||
comp_ctx, func_ctx->native_symbol, &wasm_value,
|
||||
MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32));
|
||||
if (!offset_const) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -139,13 +164,13 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
local_idx_of_aot_value = aot_value_top->local_idx;
|
||||
}
|
||||
|
||||
POP_I32(addr);
|
||||
POP_MEM_OFFSET(addr);
|
||||
|
||||
/*
|
||||
* Note: not throw the integer-overflow-exception here since it must
|
||||
* have been thrown when converting float to integer before
|
||||
*/
|
||||
/* return addres directly if constant offset and inside memory space */
|
||||
/* return address directly if constant offset and inside memory space */
|
||||
if (LLVMIsEfficientConstInt(addr)) {
|
||||
uint64 mem_offset =
|
||||
(uint64)LLVMConstIntGetZExtValue(addr) + (uint64)offset;
|
||||
|
@ -158,7 +183,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (mem_offset + bytes <= mem_data_size) {
|
||||
/* inside memory space */
|
||||
if (comp_ctx->pointer_size == sizeof(uint64))
|
||||
offset1 = I64_CONST((uint32)mem_offset);
|
||||
offset1 = I64_CONST(mem_offset);
|
||||
else
|
||||
offset1 = I32_CONST((uint32)mem_offset);
|
||||
CHECK_LLVM_CONST(offset1);
|
||||
|
@ -206,7 +231,8 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!(mem_size = get_memory_curr_page_count(comp_ctx, func_ctx))) {
|
||||
goto fail;
|
||||
}
|
||||
BUILD_ICMP(LLVMIntEQ, mem_size, I32_ZERO, cmp, "is_zero");
|
||||
BUILD_ICMP(LLVMIntEQ, mem_size,
|
||||
MEMORY64_COND_VALUE(I64_ZERO, I32_ZERO), cmp, "is_zero");
|
||||
ADD_BASIC_BLOCK(check_succ, "check_mem_size_succ");
|
||||
LLVMMoveBasicBlockAfter(check_succ, block_curr);
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx,
|
||||
|
@ -412,8 +438,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes, bool sign,
|
||||
bool atomic)
|
||||
uint32 align, mem_offset_t offset, uint32 bytes,
|
||||
bool sign, bool atomic)
|
||||
{
|
||||
LLVMValueRef maddr, value = NULL;
|
||||
LLVMTypeRef data_type;
|
||||
|
@ -482,8 +508,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes, bool sign,
|
||||
bool atomic)
|
||||
uint32 align, mem_offset_t offset, uint32 bytes,
|
||||
bool sign, bool atomic)
|
||||
{
|
||||
LLVMValueRef maddr, value = NULL;
|
||||
LLVMTypeRef data_type;
|
||||
|
@ -560,7 +586,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_f32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset)
|
||||
uint32 align, mem_offset_t offset)
|
||||
{
|
||||
LLVMValueRef maddr, value;
|
||||
bool enable_segue = comp_ctx->enable_segue_f32_load;
|
||||
|
@ -583,7 +609,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_f64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset)
|
||||
uint32 align, mem_offset_t offset)
|
||||
{
|
||||
LLVMValueRef maddr, value;
|
||||
bool enable_segue = comp_ctx->enable_segue_f64_load;
|
||||
|
@ -606,7 +632,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_i32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes, bool atomic)
|
||||
uint32 align, mem_offset_t offset, uint32 bytes,
|
||||
bool atomic)
|
||||
{
|
||||
LLVMValueRef maddr, value;
|
||||
bool enable_segue = comp_ctx->enable_segue_i32_store;
|
||||
|
@ -656,7 +683,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_i64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes, bool atomic)
|
||||
uint32 align, mem_offset_t offset, uint32 bytes,
|
||||
bool atomic)
|
||||
{
|
||||
LLVMValueRef maddr, value;
|
||||
bool enable_segue = comp_ctx->enable_segue_i64_store;
|
||||
|
@ -713,7 +741,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_f32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset)
|
||||
uint32 align, mem_offset_t offset)
|
||||
{
|
||||
LLVMValueRef maddr, value;
|
||||
bool enable_segue = comp_ctx->enable_segue_f32_store;
|
||||
|
@ -736,7 +764,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_f64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset)
|
||||
uint32 align, mem_offset_t offset)
|
||||
{
|
||||
LLVMValueRef maddr, value;
|
||||
bool enable_segue = comp_ctx->enable_segue_f64_store;
|
||||
|
@ -774,7 +802,8 @@ get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
return mem_size;
|
||||
return LLVMBuildIntCast(comp_ctx->builder, mem_size,
|
||||
MEMORY64_COND_VALUE(I64_TYPE, I32_TYPE), "");
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -785,7 +814,7 @@ aot_compile_op_memory_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
LLVMValueRef mem_size = get_memory_curr_page_count(comp_ctx, func_ctx);
|
||||
|
||||
if (mem_size)
|
||||
PUSH_I32(mem_size);
|
||||
PUSH_PAGE_COUNT(mem_size);
|
||||
return mem_size ? true : false;
|
||||
fail:
|
||||
return false;
|
||||
|
@ -798,11 +827,14 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
LLVMValueRef delta, param_values[2], ret_value, func, value;
|
||||
LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
|
||||
int32 func_index;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
LLVMValueRef u32_max, u32_cmp_result;
|
||||
#endif
|
||||
|
||||
if (!mem_size)
|
||||
return false;
|
||||
|
||||
POP_I32(delta);
|
||||
POP_PAGE_COUNT(delta);
|
||||
|
||||
/* Function type of aot_enlarge_memory() */
|
||||
param_types[0] = INT8_PTR_TYPE;
|
||||
|
@ -854,7 +886,7 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
/* Call function aot_enlarge_memory() */
|
||||
param_values[0] = func_ctx->aot_inst;
|
||||
param_values[1] = delta;
|
||||
param_values[1] = LLVMBuildTrunc(comp_ctx->builder, delta, I32_TYPE, "");
|
||||
if (!(ret_value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
|
||||
param_values, 2, "call"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
|
@ -862,15 +894,26 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
|
||||
BUILD_ICMP(LLVMIntUGT, ret_value, I8_ZERO, ret_value, "mem_grow_ret");
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (IS_MEMORY64) {
|
||||
if (!(u32_max = I64_CONST(UINT32_MAX))) {
|
||||
aot_set_last_error("llvm build const failed");
|
||||
return false;
|
||||
}
|
||||
BUILD_ICMP(LLVMIntULE, delta, u32_max, u32_cmp_result, "page_size_cmp");
|
||||
BUILD_OP(And, ret_value, u32_cmp_result, ret_value, "and");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ret_value = ret_value == true ? delta : pre_page_count */
|
||||
if (!(ret_value = LLVMBuildSelect(comp_ctx->builder, ret_value, mem_size,
|
||||
I32_NEG_ONE, "mem_grow_ret"))) {
|
||||
/* ret_value = ret_value == true ? pre_page_count : -1 */
|
||||
if (!(ret_value = LLVMBuildSelect(
|
||||
comp_ctx->builder, ret_value, mem_size,
|
||||
MEMORY64_COND_VALUE(I64_NEG_ONE, I32_NEG_ONE), "mem_grow_ret"))) {
|
||||
aot_set_last_error("llvm build select failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
PUSH_I32(ret_value);
|
||||
PUSH_PAGE_COUNT(ret_value);
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
|
@ -987,13 +1030,17 @@ aot_compile_op_memory_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
POP_I32(len);
|
||||
POP_I32(offset);
|
||||
POP_I32(dst);
|
||||
POP_MEM_OFFSET(dst);
|
||||
|
||||
if (!zero_extend_u64(comp_ctx, &dst, "dst64")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
param_types[0] = INT8_PTR_TYPE;
|
||||
param_types[1] = I32_TYPE;
|
||||
param_types[2] = I32_TYPE;
|
||||
param_types[3] = I32_TYPE;
|
||||
param_types[4] = I32_TYPE;
|
||||
param_types[4] = SIZE_T_TYPE;
|
||||
ret_type = INT8_TYPE;
|
||||
|
||||
if (comp_ctx->is_jit_mode)
|
||||
|
@ -1080,9 +1127,9 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
LLVMValueRef src, dst, src_addr, dst_addr, len, res;
|
||||
bool call_aot_memmove = false;
|
||||
|
||||
POP_I32(len);
|
||||
POP_I32(src);
|
||||
POP_I32(dst);
|
||||
POP_MEM_OFFSET(len);
|
||||
POP_MEM_OFFSET(src);
|
||||
POP_MEM_OFFSET(dst);
|
||||
|
||||
if (!(src_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, src, len)))
|
||||
return false;
|
||||
|
@ -1090,6 +1137,10 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
|
||||
return false;
|
||||
|
||||
if (!zero_extend_u64(comp_ctx, &len, "len64")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
call_aot_memmove = comp_ctx->is_indirect_mode || comp_ctx->is_jit_mode;
|
||||
if (call_aot_memmove) {
|
||||
LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
|
||||
|
@ -1097,7 +1148,7 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
param_types[0] = INT8_PTR_TYPE;
|
||||
param_types[1] = INT8_PTR_TYPE;
|
||||
param_types[2] = I32_TYPE;
|
||||
param_types[2] = SIZE_T_TYPE;
|
||||
ret_type = INT8_PTR_TYPE;
|
||||
|
||||
if (!(func_type = LLVMFunctionType(ret_type, param_types, 3, false))) {
|
||||
|
@ -1165,16 +1216,20 @@ aot_compile_op_memory_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
|
||||
LLVMValueRef func, params[3];
|
||||
|
||||
POP_I32(len);
|
||||
POP_MEM_OFFSET(len);
|
||||
POP_I32(val);
|
||||
POP_I32(dst);
|
||||
POP_MEM_OFFSET(dst);
|
||||
|
||||
if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
|
||||
return false;
|
||||
|
||||
if (!zero_extend_u64(comp_ctx, &len, "len64")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
param_types[0] = INT8_PTR_TYPE;
|
||||
param_types[1] = I32_TYPE;
|
||||
param_types[2] = I32_TYPE;
|
||||
param_types[2] = SIZE_T_TYPE;
|
||||
ret_type = INT8_PTR_TYPE;
|
||||
|
||||
if (!(func_type = LLVMFunctionType(ret_type, param_types, 3, false))) {
|
||||
|
@ -1233,7 +1288,7 @@ fail:
|
|||
bool
|
||||
aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 atomic_op, uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes)
|
||||
mem_offset_t offset, uint32 bytes)
|
||||
{
|
||||
LLVMValueRef maddr, value, result;
|
||||
bool enable_segue = (op_type == VALUE_TYPE_I32)
|
||||
|
@ -1319,7 +1374,7 @@ fail:
|
|||
bool
|
||||
aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint8 op_type,
|
||||
uint32 align, uint32 offset, uint32 bytes)
|
||||
uint32 align, mem_offset_t offset, uint32 bytes)
|
||||
{
|
||||
LLVMValueRef maddr, value, expect, result;
|
||||
bool enable_segue = (op_type == VALUE_TYPE_I32)
|
||||
|
@ -1392,7 +1447,7 @@ aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
|
|||
LLVMSetVolatile(result, true);
|
||||
|
||||
/* CmpXchg return {i32, i1} structure,
|
||||
we need to extrack the previous_value from the structure */
|
||||
we need to extract the previous_value from the structure */
|
||||
if (!(result = LLVMBuildExtractValue(comp_ctx->builder, result, 0,
|
||||
"previous_value"))) {
|
||||
goto fail;
|
||||
|
@ -1424,7 +1479,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 op_type, uint32 align, uint32 offset,
|
||||
uint8 op_type, uint32 align, mem_offset_t offset,
|
||||
uint32 bytes)
|
||||
{
|
||||
LLVMValueRef maddr, value, timeout, expect, cmp;
|
||||
|
@ -1516,7 +1571,7 @@ fail:
|
|||
bool
|
||||
aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 align,
|
||||
uint32 offset, uint32 bytes)
|
||||
mem_offset_t offset, uint32 bytes)
|
||||
{
|
||||
LLVMValueRef maddr, value, count;
|
||||
LLVMValueRef param_values[3], ret_value, func;
|
||||
|
|
|
@ -17,43 +17,43 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes, bool sign,
|
||||
bool atomic);
|
||||
uint32 align, mem_offset_t offset, uint32 bytes,
|
||||
bool sign, bool atomic);
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes, bool sign,
|
||||
bool atomic);
|
||||
uint32 align, mem_offset_t offset, uint32 bytes,
|
||||
bool sign, bool atomic);
|
||||
|
||||
bool
|
||||
aot_compile_op_f32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset);
|
||||
uint32 align, mem_offset_t offset);
|
||||
|
||||
bool
|
||||
aot_compile_op_f64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset);
|
||||
uint32 align, mem_offset_t offset);
|
||||
|
||||
bool
|
||||
aot_compile_op_i32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes,
|
||||
uint32 align, mem_offset_t offset, uint32 bytes,
|
||||
bool atomic);
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes,
|
||||
uint32 align, mem_offset_t offset, uint32 bytes,
|
||||
bool atomic);
|
||||
|
||||
bool
|
||||
aot_compile_op_f32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset);
|
||||
uint32 align, mem_offset_t offset);
|
||||
|
||||
bool
|
||||
aot_compile_op_f64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset);
|
||||
uint32 align, mem_offset_t offset);
|
||||
|
||||
LLVMValueRef
|
||||
aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 offset, uint32 bytes, bool enable_segue);
|
||||
mem_offset_t offset, uint32 bytes, bool enable_segue);
|
||||
|
||||
bool
|
||||
aot_compile_op_memory_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
@ -89,22 +89,22 @@ aot_compile_op_memory_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
|||
bool
|
||||
aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 atomic_op, uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes);
|
||||
mem_offset_t offset, uint32 bytes);
|
||||
|
||||
bool
|
||||
aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint8 op_type,
|
||||
uint32 align, uint32 offset, uint32 bytes);
|
||||
uint32 align, mem_offset_t offset, uint32 bytes);
|
||||
|
||||
bool
|
||||
aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 op_type, uint32 align, uint32 offset,
|
||||
uint8 op_type, uint32 align, mem_offset_t offset,
|
||||
uint32 bytes);
|
||||
|
||||
bool
|
||||
aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 align,
|
||||
uint32 offset, uint32 bytes);
|
||||
mem_offset_t offset, uint32 bytes);
|
||||
|
||||
bool
|
||||
aot_compiler_op_atomic_fence(AOTCompContext *comp_ctx,
|
||||
|
|
|
@ -228,6 +228,7 @@ compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
bool is_f32, LLVMValueRef left, LLVMValueRef right,
|
||||
bool is_min)
|
||||
{
|
||||
LLVMTypeRef float_param_types[2];
|
||||
LLVMTypeRef param_types[2], ret_type = is_f32 ? F32_TYPE : F64_TYPE,
|
||||
int_type = is_f32 ? I32_TYPE : I64_TYPE;
|
||||
LLVMValueRef cmp, is_eq, is_nan, ret, left_int, right_int, tmp,
|
||||
|
@ -236,7 +237,9 @@ compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
: (is_f32 ? "llvm.maxnum.f32" : "llvm.maxnum.f64");
|
||||
CHECK_LLVM_CONST(nan);
|
||||
|
||||
param_types[0] = param_types[1] = ret_type;
|
||||
/* Note: param_types is used by LLVM_BUILD_OP_OR_INTRINSIC */
|
||||
param_types[0] = param_types[1] = int_type;
|
||||
float_param_types[0] = float_param_types[1] = ret_type;
|
||||
|
||||
if (comp_ctx->disable_llvm_intrinsics
|
||||
&& aot_intrinsic_check_capability(comp_ctx,
|
||||
|
@ -304,7 +307,7 @@ compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (!(cmp = aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, ret_type,
|
||||
param_types, 2, left, right)))
|
||||
float_param_types, 2, left, right)))
|
||||
return NULL;
|
||||
|
||||
/* The result of XIP intrinsic is 0 or 1, should return it directly */
|
||||
|
@ -554,7 +557,7 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* Check divied by zero */
|
||||
/* Check divided by zero */
|
||||
LLVM_BUILD_ICMP(LLVMIntEQ, right, is_i32 ? I32_ZERO : I64_ZERO,
|
||||
cmp_div_zero, "cmp_div_zero");
|
||||
ADD_BASIC_BLOCK(check_div_zero_succ, "check_div_zero_success");
|
||||
|
|
|
@ -147,7 +147,7 @@ aot_check_table_access(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (!(tbl_sz = LLVMBuildBitCast(comp_ctx->builder, tbl_sz, INT32_PTR_TYPE,
|
||||
"cur_siuze_i32p"))) {
|
||||
"cur_size_i32p"))) {
|
||||
HANDLE_FAILURE("LLVMBuildBitCast");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
+ (comp_ctx->pointer_size == sizeof(uint64)
|
||||
? comp_data->import_globals[global_idx].data_offset_64bit
|
||||
: comp_data->import_globals[global_idx].data_offset_32bit);
|
||||
global_type = comp_data->import_globals[global_idx].type;
|
||||
global_type = comp_data->import_globals[global_idx].type.val_type;
|
||||
}
|
||||
else {
|
||||
global_offset =
|
||||
|
@ -185,7 +185,8 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
.data_offset_64bit
|
||||
: comp_data->globals[global_idx - import_global_count]
|
||||
.data_offset_32bit);
|
||||
global_type = comp_data->globals[global_idx - import_global_count].type;
|
||||
global_type =
|
||||
comp_data->globals[global_idx - import_global_count].type.val_type;
|
||||
}
|
||||
|
||||
if (comp_ctx->enable_gc && aot_is_type_gc_reftype(global_type))
|
||||
|
|
|
@ -24,8 +24,6 @@ create_native_stack_bound(const AOTCompContext *comp_ctx,
|
|||
static bool
|
||||
create_native_stack_top_min(const AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx);
|
||||
static bool
|
||||
create_func_ptrs(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
||||
LLVMTypeRef
|
||||
wasm_type_to_llvm_type(const AOTCompContext *comp_ctx,
|
||||
|
@ -539,51 +537,8 @@ aot_build_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
|
|||
if (ret_type == VOID_TYPE) {
|
||||
name = "";
|
||||
}
|
||||
|
||||
LLVMValueRef retval;
|
||||
if (comp_ctx->is_indirect_mode
|
||||
&& !strncmp(comp_ctx->target_arch, "xtensa", 6)) {
|
||||
/* call wrapped_func indirectly */
|
||||
if (!create_func_ptrs(comp_ctx, func_ctx)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
LLVMTypeRef func_ptr_type;
|
||||
LLVMValueRef wrapped_func_indirect;
|
||||
uint32 import_func_count = comp_ctx->comp_data->import_func_count;
|
||||
uint32 func_count = comp_ctx->func_ctx_count;
|
||||
|
||||
/* Check function index */
|
||||
if (func_index >= import_func_count + func_count) {
|
||||
aot_set_last_error("Function index out of range.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Get function type */
|
||||
if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
|
||||
aot_set_last_error("create LLVM function type failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* func_index layout :
|
||||
* aot_func#xxx, range from 0 ~ func_conut - 1;
|
||||
* aot_func#internal#xxx, range from func_conut ~ 2 * func_conut - 1;
|
||||
*/
|
||||
if (!(wrapped_func_indirect = aot_get_func_from_table(
|
||||
comp_ctx, func_ctx->func_ptrs, func_ptr_type,
|
||||
func_index + func_count + import_func_count))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Call the function indirectly */
|
||||
retval = LLVMBuildCall2(b, func_type, wrapped_func_indirect, params,
|
||||
param_count, name);
|
||||
}
|
||||
else
|
||||
retval = LLVMBuildCall2(b, func_type, wrapped_func, params, param_count,
|
||||
name);
|
||||
|
||||
LLVMValueRef retval =
|
||||
LLVMBuildCall2(b, func_type, wrapped_func, params, param_count, name);
|
||||
if (!retval) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -780,9 +735,7 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
|
|||
}
|
||||
|
||||
if (need_precheck) {
|
||||
if (!comp_ctx->is_jit_mode
|
||||
&& !(comp_ctx->is_indirect_mode
|
||||
&& !strncmp(comp_ctx->target_arch, "xtensa", 6)))
|
||||
if (!comp_ctx->is_jit_mode)
|
||||
LLVMSetLinkage(func, LLVMInternalLinkage);
|
||||
unsigned int kind =
|
||||
LLVMGetEnumAttributeKindForName("noinline", strlen("noinline"));
|
||||
|
@ -790,7 +743,16 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
|
|||
LLVMCreateEnumAttribute(comp_ctx->context, kind, 0);
|
||||
LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex,
|
||||
attr_noinline);
|
||||
|
||||
if (!strcmp(comp_ctx->target_arch, "xtensa")) {
|
||||
/* Because "func" is only called by "precheck_func", short-call
|
||||
* should be ok. We prefer short-call because it's smaller
|
||||
* and more importantly doesn't involve relocations.
|
||||
*/
|
||||
LLVMAttributeRef attr_short_call = LLVMCreateStringAttribute(
|
||||
comp_ctx->context, "short-call", strlen("short-call"), "", 0);
|
||||
LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex,
|
||||
attr_short_call);
|
||||
}
|
||||
if (!aot_build_precheck_function(comp_ctx, module, precheck_func,
|
||||
func_index, func_type, func))
|
||||
goto fail;
|
||||
|
@ -1242,7 +1204,7 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
func_ctx->mem_space_unchanged = mem_space_unchanged;
|
||||
|
||||
memory_count = module->memory_count + module->import_memory_count;
|
||||
/* If the module dosen't have memory, reserve
|
||||
/* If the module doesn't have memory, reserve
|
||||
one mem_info space with empty content */
|
||||
if (memory_count == 0)
|
||||
memory_count = 1;
|
||||
|
@ -1973,10 +1935,12 @@ aot_set_llvm_basic_types(AOTLLVMTypes *basic_types, LLVMContextRef context,
|
|||
if (pointer_size == 4) {
|
||||
basic_types->intptr_t_type = basic_types->int32_type;
|
||||
basic_types->intptr_t_ptr_type = basic_types->int32_ptr_type;
|
||||
basic_types->size_t_type = basic_types->int32_type;
|
||||
}
|
||||
else {
|
||||
basic_types->intptr_t_type = basic_types->int64_type;
|
||||
basic_types->intptr_t_ptr_type = basic_types->int64_ptr_type;
|
||||
basic_types->size_t_type = basic_types->int64_type;
|
||||
}
|
||||
|
||||
basic_types->gc_ref_type = basic_types->int8_ptr_type;
|
||||
|
@ -2416,7 +2380,7 @@ orc_jit_create(AOTCompContext *comp_ctx)
|
|||
}
|
||||
|
||||
if (comp_ctx->enable_stack_bound_check || comp_ctx->enable_stack_estimation)
|
||||
LLVMOrcLLJITBuilderSetCompileFuncitonCreatorWithStackSizesCallback(
|
||||
LLVMOrcLLJITBuilderSetCompileFunctionCreatorWithStackSizesCallback(
|
||||
builder, jit_stack_size_callback, comp_ctx);
|
||||
|
||||
err = LLVMOrcJITTargetMachineBuilderDetectHost(&jtmb);
|
||||
|
|
|
@ -262,6 +262,7 @@ typedef struct AOTLLVMTypes {
|
|||
LLVMTypeRef int32_type;
|
||||
LLVMTypeRef int64_type;
|
||||
LLVMTypeRef intptr_t_type;
|
||||
LLVMTypeRef size_t_type;
|
||||
LLVMTypeRef float32_type;
|
||||
LLVMTypeRef float64_type;
|
||||
LLVMTypeRef void_type;
|
||||
|
@ -373,7 +374,7 @@ typedef struct AOTCompContext {
|
|||
char target_arch[16];
|
||||
unsigned pointer_size;
|
||||
|
||||
/* Hardware intrinsic compability flags */
|
||||
/* Hardware intrinsic compatibility flags */
|
||||
uint64 flags[8];
|
||||
|
||||
/* required by JIT */
|
||||
|
@ -440,7 +441,7 @@ typedef struct AOTCompContext {
|
|||
/* Use profile file collected by LLVM PGO */
|
||||
char *use_prof_file;
|
||||
|
||||
/* Enable to use segument register as the base addr
|
||||
/* Enable to use segment register as the base addr
|
||||
of linear memory for load/store operations */
|
||||
bool enable_segue_i32_load;
|
||||
bool enable_segue_i64_load;
|
||||
|
@ -610,12 +611,6 @@ aot_load_const_from_table(AOTCompContext *comp_ctx, LLVMValueRef base,
|
|||
bool
|
||||
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
|
||||
|
||||
void
|
||||
aot_add_expand_memory_op_pass(LLVMPassManagerRef pass);
|
||||
|
||||
void
|
||||
aot_add_simple_loop_unswitch_pass(LLVMPassManagerRef pass);
|
||||
|
||||
void
|
||||
aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module);
|
||||
|
||||
|
|
|
@ -76,12 +76,6 @@ LLVM_C_EXTERN_C_BEGIN
|
|||
bool
|
||||
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
|
||||
|
||||
void
|
||||
aot_add_expand_memory_op_pass(LLVMPassManagerRef pass);
|
||||
|
||||
void
|
||||
aot_add_simple_loop_unswitch_pass(LLVMPassManagerRef pass);
|
||||
|
||||
void
|
||||
aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module);
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ PartitionFunction(GlobalValueSet Requested)
|
|||
* if the jit wrapper (which has "_wrapper" suffix in
|
||||
* the name) is requested, compile others in the group too.
|
||||
* otherwise, only compile the requested one.
|
||||
* (and possibly the correspondig wrapped function,
|
||||
* (and possibly the corresponding wrapped function,
|
||||
* which has AOT_FUNC_INTERNAL_PREFIX.)
|
||||
*/
|
||||
wrapper = strstr(gvname + prefix_len, "_wrapper");
|
||||
|
|
|
@ -72,7 +72,7 @@ LLVMOrcObjectTransformLayerRef
|
|||
LLVMOrcLLLazyJITGetObjTransformLayer(LLVMOrcLLLazyJITRef J);
|
||||
|
||||
void
|
||||
LLVMOrcLLJITBuilderSetCompileFuncitonCreatorWithStackSizesCallback(
|
||||
LLVMOrcLLJITBuilderSetCompileFunctionCreatorWithStackSizesCallback(
|
||||
LLVMOrcLLLazyJITBuilderRef Builder,
|
||||
void (*cb)(void *, const char *, size_t, size_t), void *cb_data);
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::orc::LLLazyJITBuilder,
|
|||
LLVMOrcLLLazyJITBuilderRef)
|
||||
|
||||
void
|
||||
LLVMOrcLLJITBuilderSetCompileFuncitonCreatorWithStackSizesCallback(
|
||||
LLVMOrcLLJITBuilderSetCompileFunctionCreatorWithStackSizesCallback(
|
||||
LLVMOrcLLLazyJITBuilderRef Builder,
|
||||
void (*cb)(void *, const char *, size_t, size_t), void *cb_data)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ typedef struct dwarf_extractor {
|
|||
|
||||
#define TO_HANDLE(extractor) (dwarf_extractor_handle_t)(extractor)
|
||||
|
||||
#define TO_EXTACTOR(handle) (dwarf_extractor *)(handle)
|
||||
#define TO_EXTRACTOR(handle) (dwarf_extractor *)(handle)
|
||||
|
||||
static bool is_debugger_initialized;
|
||||
|
||||
|
@ -103,7 +103,7 @@ fail3:
|
|||
void
|
||||
destroy_dwarf_extractor(dwarf_extractor_handle_t handle)
|
||||
{
|
||||
dwarf_extractor *extractor = TO_EXTACTOR(handle);
|
||||
dwarf_extractor *extractor = TO_EXTRACTOR(handle);
|
||||
if (!extractor)
|
||||
return;
|
||||
extractor->debugger.DeleteTarget(extractor->target);
|
||||
|
@ -122,7 +122,7 @@ dwarf_gen_file_info(const AOTCompContext *comp_ctx)
|
|||
const char *file_name;
|
||||
const char *dir_name;
|
||||
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
if (!(extractor = TO_EXTRACTOR(comp_ctx->comp_data->extractor)))
|
||||
return NULL;
|
||||
|
||||
units_number = extractor->module.GetNumCompileUnits();
|
||||
|
@ -198,7 +198,7 @@ dwarf_gen_comp_unit_info(const AOTCompContext *comp_ctx)
|
|||
int units_number;
|
||||
LLVMMetadataRef comp_unit = NULL;
|
||||
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
if (!(extractor = TO_EXTRACTOR(comp_ctx->comp_data->extractor)))
|
||||
return NULL;
|
||||
|
||||
units_number = extractor->module.GetNumCompileUnits();
|
||||
|
@ -312,12 +312,12 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
|
|||
case eLanguageTypeC17:
|
||||
break;
|
||||
default:
|
||||
LOG_WARNING("func %s has unsuppoted language_type 0x%x",
|
||||
LOG_WARNING("func %s has unsupported language_type 0x%x",
|
||||
function_name, (int)language_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
if (!(extractor = TO_EXTRACTOR(comp_ctx->comp_data->extractor)))
|
||||
return NULL;
|
||||
|
||||
LLVMDIBuilderRef DIB = comp_ctx->debug_builder;
|
||||
|
@ -389,7 +389,7 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
|
|||
function.GetBlock().GetVariables(extractor->target, true, false, false);
|
||||
if (num_function_args != variable_list.GetSize()) {
|
||||
LOG_ERROR(
|
||||
"function args number dismatch!:value number=%d, function args=%d",
|
||||
"function args number mismatch!:value number=%d, function args=%d",
|
||||
variable_list.GetSize(), num_function_args);
|
||||
}
|
||||
|
||||
|
@ -399,13 +399,13 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
|
|||
// TODO:change to void * or WasmExenv * ?
|
||||
LLVMMetadataRef voidtype =
|
||||
LLVMDIBuilderCreateBasicType(DIB, "void", 4, 0, 0, LLVMDIFlagZero);
|
||||
LLVMMetadataRef voidpionter =
|
||||
LLVMMetadataRef voidpointer =
|
||||
LLVMDIBuilderCreatePointerType(DIB, voidtype, 64, 0, 0, "void *", 6);
|
||||
|
||||
LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable(
|
||||
DIB, FunctionMetadata, "exenv", 5, 1,
|
||||
File, // starts form 1, and 1 is exenv,
|
||||
line_entry.GetLine(), voidpionter, true, LLVMDIFlagZero);
|
||||
line_entry.GetLine(), voidpointer, true, LLVMDIFlagZero);
|
||||
LLVMValueRef Param = LLVMGetParam(func_ctx->func, 0);
|
||||
LLVMBasicBlockRef block_curr = LLVMGetEntryBasicBlock(func_ctx->func);
|
||||
LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar, ParamExpression,
|
||||
|
@ -447,13 +447,13 @@ dwarf_gen_func_info(const AOTCompContext *comp_ctx,
|
|||
uint64_t vm_offset;
|
||||
AOTFunc *func = func_ctx->aot_func;
|
||||
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
if (!(extractor = TO_EXTRACTOR(comp_ctx->comp_data->extractor)))
|
||||
return NULL;
|
||||
|
||||
// A code address in DWARF for WebAssembly is the offset of an
|
||||
// instruction relative within the Code section of the WebAssembly file.
|
||||
// For this reason Section::GetFileAddress() must return zero for the
|
||||
// Code section. (refert to ObjectFileWasm.cpp)
|
||||
// Code section. (refer to ObjectFileWasm.cpp)
|
||||
vm_offset = func->code - comp_ctx->comp_data->wasm_module->buf_code;
|
||||
|
||||
auto sbaddr = extractor->target.ResolveFileAddress(vm_offset);
|
||||
|
@ -479,13 +479,13 @@ dwarf_get_func_name(const AOTCompContext *comp_ctx,
|
|||
|
||||
name[0] = '\0';
|
||||
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
if (!(extractor = TO_EXTRACTOR(comp_ctx->comp_data->extractor)))
|
||||
return;
|
||||
|
||||
// A code address in DWARF for WebAssembly is the offset of an
|
||||
// instruction relative within the Code section of the WebAssembly file.
|
||||
// For this reason Section::GetFileAddress() must return zero for the
|
||||
// Code section. (refert to ObjectFileWasm.cpp)
|
||||
// Code section. (refer to ObjectFileWasm.cpp)
|
||||
vm_offset = func->code - comp_ctx->comp_data->wasm_module->buf_code;
|
||||
|
||||
auto sbaddr = extractor->target.ResolveFileAddress(vm_offset);
|
||||
|
@ -509,7 +509,7 @@ dwarf_gen_location(const AOTCompContext *comp_ctx,
|
|||
|
||||
if (func_ctx->debug_func == NULL)
|
||||
return NULL;
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
if (!(extractor = TO_EXTRACTOR(comp_ctx->comp_data->extractor)))
|
||||
return NULL;
|
||||
|
||||
auto sbaddr = extractor->target.ResolveFileAddress(vm_offset);
|
||||
|
@ -550,13 +550,13 @@ dwarf_gen_func_ret_location(const AOTCompContext *comp_ctx,
|
|||
AOTFunc *func = func_ctx->aot_func;
|
||||
LLVMMetadataRef location_info = NULL;
|
||||
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
if (!(extractor = TO_EXTRACTOR(comp_ctx->comp_data->extractor)))
|
||||
return NULL;
|
||||
|
||||
// A code address in DWARF for WebAssembly is the offset of an
|
||||
// instruction relative within the Code section of the WebAssembly file.
|
||||
// For this reason Section::GetFileAddress() must return zero for the
|
||||
// Code section. (refert to ObjectFileWasm.cpp)
|
||||
// Code section. (refer to ObjectFileWasm.cpp)
|
||||
vm_offset = (func->code + func->code_size - 1)
|
||||
- comp_ctx->comp_data->wasm_module->buf_code;
|
||||
location_info = dwarf_gen_location(comp_ctx, func_ctx, vm_offset);
|
||||
|
|
|
@ -85,7 +85,7 @@ aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
if (!(condition = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, mask,
|
||||
max_lanes, "compare_with_16"))) {
|
||||
HANDLE_FAILURE("LLVMBuldICmp");
|
||||
HANDLE_FAILURE("LLVMBuildICmp");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ aot_compile_simd_replace(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "reesult");
|
||||
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result");
|
||||
|
||||
fail:
|
||||
return false;
|
||||
|
|
|
@ -45,7 +45,7 @@ simd_build_bitmask(const AOTCompContext *comp_ctx,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
/* fill every bit in a lange with its sign bit */
|
||||
/* fill every bit in a lane with its sign bit */
|
||||
if (!(ashr_distance = simd_build_splat_const_integer_vector(
|
||||
comp_ctx, element_type[itype], lane_bits[itype] - 1,
|
||||
lanes[itype]))) {
|
||||
|
|
|
@ -86,8 +86,8 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
interger_vector_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntCond cond, LLVMTypeRef vector_type)
|
||||
integer_vector_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntCond cond, LLVMTypeRef vector_type)
|
||||
{
|
||||
LLVMValueRef vec1, vec2, result;
|
||||
LLVMIntPredicate int_pred;
|
||||
|
@ -138,28 +138,28 @@ bool
|
|||
aot_compile_simd_i8x16_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, IntCond cond)
|
||||
{
|
||||
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i8x16_TYPE);
|
||||
return integer_vector_compare(comp_ctx, func_ctx, cond, V128_i8x16_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, IntCond cond)
|
||||
{
|
||||
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i16x8_TYPE);
|
||||
return integer_vector_compare(comp_ctx, func_ctx, cond, V128_i16x8_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, IntCond cond)
|
||||
{
|
||||
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i32x4_TYPE);
|
||||
return integer_vector_compare(comp_ctx, func_ctx, cond, V128_i32x4_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, IntCond cond)
|
||||
{
|
||||
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i64x2_TYPE);
|
||||
return integer_vector_compare(comp_ctx, func_ctx, cond, V128_i64x2_TYPE);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
static bool
|
||||
simd_integer_narrow_x86(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef in_vector_type, LLVMTypeRef out_vector_type,
|
||||
const char *instrinsic)
|
||||
const char *intrinsic)
|
||||
{
|
||||
LLVMValueRef vector1, vector2, result;
|
||||
LLVMTypeRef param_types[2] = { in_vector_type, in_vector_type };
|
||||
|
@ -24,7 +24,7 @@ simd_integer_narrow_x86(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(result = aot_call_llvm_intrinsic(comp_ctx, func_ctx, instrinsic,
|
||||
if (!(result = aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic,
|
||||
out_vector_type, param_types, 2,
|
||||
vector1, vector2))) {
|
||||
HANDLE_FAILURE("LLVMBuildCall");
|
||||
|
@ -261,7 +261,7 @@ simd_integer_extension(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* retrive the low or high half */
|
||||
/* retrieve the low or high half */
|
||||
if (!(sub_vector = LLVMBuildShuffleVector(comp_ctx->builder, vector,
|
||||
undef[itype], mask, "half"))) {
|
||||
HANDLE_FAILURE("LLVMBuildShuffleVector");
|
||||
|
@ -659,7 +659,7 @@ aot_compile_simd_i16x8_q15mulr_sat(AOTCompContext *comp_ctx,
|
|||
|
||||
if (!(result = LLVMBuildTrunc(comp_ctx->builder, result, V128_i16x8_TYPE,
|
||||
"down_to_v8i16"))) {
|
||||
HANDLE_FAILURE("LLVMBuidlTrunc");
|
||||
HANDLE_FAILURE("LLVMBuildTrunc");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
/* data_length in bytes */
|
||||
static LLVMValueRef
|
||||
simd_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
|
||||
uint32 offset, uint32 data_length, LLVMTypeRef ptr_type,
|
||||
mem_offset_t offset, uint32 data_length, LLVMTypeRef ptr_type,
|
||||
LLVMTypeRef data_type, bool enable_segue)
|
||||
{
|
||||
LLVMValueRef maddr, data;
|
||||
|
@ -42,7 +42,7 @@ simd_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
|
|||
|
||||
bool
|
||||
aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset)
|
||||
uint32 align, mem_offset_t offset)
|
||||
{
|
||||
bool enable_segue = comp_ctx->enable_segue_v128_load;
|
||||
LLVMTypeRef v128_ptr_type = enable_segue ? V128_PTR_TYPE_GS : V128_PTR_TYPE;
|
||||
|
@ -62,7 +62,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset)
|
||||
uint8 opcode, uint32 align, mem_offset_t offset)
|
||||
{
|
||||
LLVMValueRef sub_vector, result;
|
||||
uint32 opcode_index = opcode - SIMD_v128_load8x8_s;
|
||||
|
@ -117,7 +117,7 @@ aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset)
|
||||
uint8 opcode, uint32 align, mem_offset_t offset)
|
||||
{
|
||||
uint32 opcode_index = opcode - SIMD_v128_load8_splat;
|
||||
LLVMValueRef element, result;
|
||||
|
@ -173,7 +173,7 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset,
|
||||
uint8 opcode, uint32 align, mem_offset_t offset,
|
||||
uint8 lane_id)
|
||||
{
|
||||
LLVMValueRef element, vector;
|
||||
|
@ -218,7 +218,7 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset)
|
||||
uint8 opcode, uint32 align, mem_offset_t offset)
|
||||
{
|
||||
LLVMValueRef element, result, mask;
|
||||
uint32 opcode_index = opcode - SIMD_v128_load32_zero;
|
||||
|
@ -308,7 +308,7 @@ simd_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
|
|||
|
||||
bool
|
||||
aot_compile_simd_v128_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset)
|
||||
uint32 align, mem_offset_t offset)
|
||||
{
|
||||
bool enable_segue = comp_ctx->enable_segue_v128_store;
|
||||
LLVMTypeRef v128_ptr_type = enable_segue ? V128_PTR_TYPE_GS : V128_PTR_TYPE;
|
||||
|
@ -324,7 +324,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset,
|
||||
uint8 opcode, uint32 align, mem_offset_t offset,
|
||||
uint8 lane_id)
|
||||
{
|
||||
LLVMValueRef element, vector;
|
||||
|
|
|
@ -14,32 +14,32 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset);
|
||||
uint32 align, mem_offset_t offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset);
|
||||
uint8 opcode, uint32 align, mem_offset_t offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset);
|
||||
uint8 opcode, uint32 align, mem_offset_t offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset,
|
||||
uint8 opcode, uint32 align, mem_offset_t offset,
|
||||
uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset);
|
||||
uint8 opcode, uint32 align, mem_offset_t offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_v128_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset);
|
||||
uint32 align, mem_offset_t offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset,
|
||||
uint8 opcode, uint32 align, mem_offset_t offset,
|
||||
uint8 lane_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
# Wasm Function
|
||||
# Wasm Function
|
||||
|
||||
## Internal data structure
|
||||
|
||||

|
||||
|
||||
## Module level data (function)
|
||||
**WASMModule**: Data structure created for loading a module.
|
||||
**WASMModule**: Data structure created for loading a module.
|
||||
- `WASMImport *import_functions`: initialized from the Wasm file function section
|
||||
- `WASMImport *import_functions`: initialized from the Wasm file import section. The runtime will try to solve the imports from the native API registration, refer to [Export native API to WASM application](../../../doc/export_native_api.md).
|
||||
- `WASMImport *import_functions`: initialized from the Wasm file import section. The runtime will try to solve the imports from the native API registration, refer to [Export native API to WASM application](../../../doc/export_native_api.md).
|
||||
|
||||
**WASMFunction**: represent a Wasm function located in Wasm file code section. Track the links to the compiled function body.
|
||||
**WASMFunction**: represent a Wasm function located in Wasm file code section. Track the links to the compiled function body.
|
||||
**WASMImport**: represent a imported Wasm function which can be a solved as a native function or another Wasm module exported function.
|
||||
|
||||
## Instance level data (function)
|
||||
**WASMModuleInstance**: Data structure created for instantiating a module
|
||||
- `WASMModuleInstanceExtra::functions`: combined the imported and internal functions into single array of structure `WASMFunctionInstance`
|
||||
- `WASMModuleInstance::import_func_ptrs`: pointer array for solved function imports. This array is referred during calling imported native function. Note it is initialzed with the module level solved imports, but may points to different native function later due to c-api calls.
|
||||
|
||||
- `WASMModuleInstance::import_func_ptrs`: pointer array for solved function imports. This array is referred during calling imported native function. Note it is initialized with the module level solved imports, but may points to different native function later due to c-api calls.
|
||||
|
||||
## Execution paths
|
||||
**Interpreter**:
|
||||
- Execute internal bytecode function:
|
||||
```
|
||||
WASMModuleInstance::e
|
||||
-> WASMModuleInstanceExtra::functions[..]
|
||||
-> WASMFunctionInstance::func
|
||||
WASMModuleInstance::e
|
||||
-> WASMModuleInstanceExtra::functions[..]
|
||||
-> WASMFunctionInstance::func
|
||||
-> WASMFunction::code
|
||||
```
|
||||
|
||||
- Execute imported function from other module:
|
||||
```
|
||||
WASMModuleInstance::e
|
||||
-> WASMModuleInstanceExtra::functions[..]
|
||||
WASMModuleInstance::e
|
||||
-> WASMModuleInstanceExtra::functions[..]
|
||||
(WASMFunctionInstance flag indicates an import)
|
||||
-> WASMFunctionInstance::import_func_inst
|
||||
-> WASMModuleInstance(second)::func
|
||||
|
@ -39,9 +39,9 @@
|
|||
|
||||
- Execute imported native function:
|
||||
```
|
||||
WASMModuleInstance::e
|
||||
-> WASMModuleInstanceExtra::functions[..]
|
||||
WASMModuleInstance::e
|
||||
-> WASMModuleInstanceExtra::functions[..]
|
||||
(flag indicates imported native)
|
||||
WASMModuleInstance::import_func_ptrs[..]
|
||||
-> native function
|
||||
```
|
||||
```
|
||||
|
|
|
@ -168,12 +168,12 @@ get_global_type(const WASMModule *module, uint32 global_idx)
|
|||
if (global_idx < module->import_global_count) {
|
||||
const WASMGlobalImport *import_global =
|
||||
&((module->import_globals + global_idx)->u.global);
|
||||
return import_global->type;
|
||||
return import_global->type.val_type;
|
||||
}
|
||||
else {
|
||||
const WASMGlobal *global =
|
||||
module->globals + (global_idx - module->import_global_count);
|
||||
return global->type;
|
||||
return global->type.val_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1243,6 +1243,21 @@ init_func_translation(JitCompContext *cc)
|
|||
NEW_CONST(I32, local_off));
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
|
||||
/* externref/funcref should be NULL_REF rather than 0 */
|
||||
local_off = (uint32)offsetof(WASMInterpFrame, lp)
|
||||
+ cur_wasm_func->param_cell_num * 4;
|
||||
for (i = 0; i < cur_wasm_func->local_count; i++) {
|
||||
if (cur_wasm_func->local_types[i] == VALUE_TYPE_EXTERNREF
|
||||
|| cur_wasm_func->local_types[i] == VALUE_TYPE_FUNCREF) {
|
||||
GEN_INSN(STI32, NEW_CONST(I32, NULL_REF), cc->fp_reg,
|
||||
NEW_CONST(I32, local_off));
|
||||
}
|
||||
local_off +=
|
||||
4 * wasm_value_type_cell_num(cur_wasm_func->local_types[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return jit_frame;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ typedef struct WASMObject *wasm_obj_t;
|
|||
typedef union V128 {
|
||||
int8_t i8x16[16];
|
||||
int16_t i16x8[8];
|
||||
int32_t i32x8[4];
|
||||
int32_t i32x4[4];
|
||||
int64_t i64x2[2];
|
||||
float f32x4[4];
|
||||
double f64x2[2];
|
||||
|
@ -230,16 +230,6 @@ wasm_defined_type_is_struct_type(const wasm_defined_type_t def_type);
|
|||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_defined_type_is_array_type(const wasm_defined_type_t def_type);
|
||||
|
||||
/**
|
||||
* Get parameter count of a function type
|
||||
*
|
||||
* @param func_type the specified function type
|
||||
*
|
||||
* @return the param count of the specified function type
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint32_t
|
||||
wasm_func_type_get_param_count(const wasm_func_type_t func_type);
|
||||
|
||||
/**
|
||||
* Get type of a specified parameter of a function type
|
||||
*
|
||||
|
@ -253,16 +243,6 @@ WASM_RUNTIME_API_EXTERN wasm_ref_type_t
|
|||
wasm_func_type_get_param_type(const wasm_func_type_t func_type,
|
||||
uint32_t param_idx);
|
||||
|
||||
/**
|
||||
* Get result count of a function type
|
||||
*
|
||||
* @param func_type the specified function type
|
||||
*
|
||||
* @return the result count of the specified function type
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint32_t
|
||||
wasm_func_type_get_result_count(const wasm_func_type_t func_type);
|
||||
|
||||
/**
|
||||
* Get type of a specified result of a function type
|
||||
*
|
||||
|
@ -727,7 +707,7 @@ wasm_externref_obj_to_internal_obj(const wasm_externref_obj_t externref_obj);
|
|||
* @param exec_env the execution environment
|
||||
* @param internal_obj the internal object
|
||||
*
|
||||
* @return wasm_externref_obj_t if create success, NULL othersise
|
||||
* @return wasm_externref_obj_t if create success, NULL otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_externref_obj_t
|
||||
wasm_internal_obj_to_externref_obj(wasm_exec_env_t exec_env,
|
||||
|
@ -777,7 +757,7 @@ WASM_RUNTIME_API_EXTERN bool
|
|||
wasm_runtime_unpin_object(wasm_exec_env_t exec_env, wasm_obj_t obj);
|
||||
|
||||
/**
|
||||
* Check whether an object is a struct objectc
|
||||
* Check whether an object is a struct object
|
||||
*
|
||||
* @param obj the object to check
|
||||
*
|
||||
|
|
|
@ -96,7 +96,7 @@ typedef double float64_t;
|
|||
// Vectors
|
||||
// size: capacity
|
||||
// num_elems: current number of elements
|
||||
// size_of_elem: size of one elemen
|
||||
// size_of_elem: size of one element
|
||||
#define WASM_DECLARE_VEC(name, ptr_or_none) \
|
||||
typedef struct wasm_##name##_vec_t { \
|
||||
size_t size; \
|
||||
|
@ -183,7 +183,7 @@ typedef union MemAllocOption {
|
|||
} MemAllocOption;
|
||||
#endif /* MEM_ALLOC_OPTION_DEFINED */
|
||||
|
||||
/* Runtime configration */
|
||||
/* Runtime configuration */
|
||||
struct wasm_config_t {
|
||||
mem_alloc_type_t mem_alloc_type;
|
||||
MemAllocOption mem_alloc_option;
|
||||
|
@ -297,7 +297,8 @@ enum wasm_valkind_enum {
|
|||
WASM_I64,
|
||||
WASM_F32,
|
||||
WASM_F64,
|
||||
WASM_ANYREF = 128,
|
||||
WASM_V128,
|
||||
WASM_EXTERNREF = 128,
|
||||
WASM_FUNCREF,
|
||||
};
|
||||
#endif
|
||||
|
@ -307,10 +308,10 @@ WASM_API_EXTERN own wasm_valtype_t* wasm_valtype_new(wasm_valkind_t);
|
|||
WASM_API_EXTERN wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*);
|
||||
|
||||
static inline bool wasm_valkind_is_num(wasm_valkind_t k) {
|
||||
return k < WASM_ANYREF;
|
||||
return k < WASM_EXTERNREF;
|
||||
}
|
||||
static inline bool wasm_valkind_is_ref(wasm_valkind_t k) {
|
||||
return k >= WASM_ANYREF;
|
||||
return k >= WASM_EXTERNREF;
|
||||
}
|
||||
|
||||
static inline bool wasm_valtype_is_num(const wasm_valtype_t* t) {
|
||||
|
@ -433,7 +434,7 @@ struct wasm_ref_t;
|
|||
|
||||
typedef struct wasm_val_t {
|
||||
wasm_valkind_t kind;
|
||||
uint8_t __paddings[7];
|
||||
uint8_t _paddings[7];
|
||||
union {
|
||||
int32_t i32;
|
||||
int64_t i64;
|
||||
|
@ -527,6 +528,12 @@ typedef struct WASMModuleCommon *wasm_module_t;
|
|||
#define LOAD_ARGS_OPTION_DEFINED
|
||||
typedef struct LoadArgs {
|
||||
char *name;
|
||||
/* True by default, used by wasm-c-api only.
|
||||
If false, the wasm input buffer (wasm_byte_vec_t) is referenced by the
|
||||
module instead of being cloned. Hence, it can be freed after module loading. */
|
||||
bool clone_wasm_binary;
|
||||
/* This option is only used by the AOT/wasm loader (see wasm_export.h) */
|
||||
bool wasm_binary_freeable;
|
||||
/* TODO: more fields? */
|
||||
} LoadArgs;
|
||||
#endif /* LOAD_ARGS_OPTION_DEFINED */
|
||||
|
@ -536,7 +543,7 @@ WASM_API_EXTERN own wasm_module_t* wasm_module_new(
|
|||
|
||||
// please refer to wasm_runtime_load_ex(...) in core/iwasm/include/wasm_export.h
|
||||
WASM_API_EXTERN own wasm_module_t* wasm_module_new_ex(
|
||||
wasm_store_t*, const wasm_byte_vec_t* binary, const LoadArgs *args);
|
||||
wasm_store_t*, wasm_byte_vec_t* binary, LoadArgs *args);
|
||||
|
||||
WASM_API_EXTERN void wasm_module_delete(own wasm_module_t*);
|
||||
|
||||
|
@ -556,6 +563,8 @@ WASM_API_EXTERN void wasm_shared_module_delete(own wasm_shared_module_t*);
|
|||
WASM_API_EXTERN bool wasm_module_set_name(wasm_module_t*, const char* name);
|
||||
WASM_API_EXTERN const char *wasm_module_get_name(wasm_module_t*);
|
||||
|
||||
WASM_API_EXTERN bool wasm_module_is_underlying_binary_freeable(const wasm_module_t *module);
|
||||
|
||||
|
||||
// Function Instances
|
||||
|
||||
|
@ -706,9 +715,12 @@ static inline own wasm_valtype_t* wasm_valtype_new_f32(void) {
|
|||
static inline own wasm_valtype_t* wasm_valtype_new_f64(void) {
|
||||
return wasm_valtype_new(WASM_F64);
|
||||
}
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_v128(void) {
|
||||
return wasm_valtype_new(WASM_V128);
|
||||
}
|
||||
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_anyref(void) {
|
||||
return wasm_valtype_new(WASM_ANYREF);
|
||||
return wasm_valtype_new(WASM_EXTERNREF);
|
||||
}
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_funcref(void) {
|
||||
return wasm_valtype_new(WASM_FUNCREF);
|
||||
|
@ -864,12 +876,12 @@ static inline void* wasm_val_ptr(const wasm_val_t* val) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#define WASM_I32_VAL(i) {.kind = WASM_I32, .__paddings = {0}, .of = {.i32 = i}}
|
||||
#define WASM_I64_VAL(i) {.kind = WASM_I64, .__paddings = {0}, .of = {.i64 = i}}
|
||||
#define WASM_F32_VAL(z) {.kind = WASM_F32, .__paddings = {0}, .of = {.f32 = z}}
|
||||
#define WASM_F64_VAL(z) {.kind = WASM_F64, .__paddings = {0}, .of = {.f64 = z}}
|
||||
#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .__paddings = {0}, .of = {.ref = r}}
|
||||
#define WASM_INIT_VAL {.kind = WASM_ANYREF, .__paddings = {0}, .of = {.ref = NULL}}
|
||||
#define WASM_I32_VAL(i) {.kind = WASM_I32, ._paddings = {0}, .of = {.i32 = i}}
|
||||
#define WASM_I64_VAL(i) {.kind = WASM_I64, ._paddings = {0}, .of = {.i64 = i}}
|
||||
#define WASM_F32_VAL(z) {.kind = WASM_F32, ._paddings = {0}, .of = {.f32 = z}}
|
||||
#define WASM_F64_VAL(z) {.kind = WASM_F64, ._paddings = {0}, .of = {.f64 = z}}
|
||||
#define WASM_REF_VAL(r) {.kind = WASM_EXTERNREF, ._paddings = {0}, .of = {.ref = r}}
|
||||
#define WASM_INIT_VAL {.kind = WASM_EXTERNREF, ._paddings = {0}, .of = {.ref = NULL}}
|
||||
|
||||
#define KILOBYTE(n) ((n) * 1024)
|
||||
|
||||
|
|
|
@ -72,17 +72,31 @@ typedef enum {
|
|||
WASM_IMPORT_EXPORT_KIND_GLOBAL
|
||||
} wasm_import_export_kind_t;
|
||||
|
||||
typedef struct wasm_import_type {
|
||||
struct WASMFuncType;
|
||||
typedef struct WASMFuncType *wasm_func_type_t;
|
||||
|
||||
struct WASMGlobalType;
|
||||
typedef struct WASMGlobalType *wasm_global_type_t;
|
||||
|
||||
typedef struct wasm_import_t {
|
||||
const char *module_name;
|
||||
const char *name;
|
||||
wasm_import_export_kind_t kind;
|
||||
bool linked;
|
||||
} wasm_import_type;
|
||||
union {
|
||||
wasm_func_type_t func_type;
|
||||
wasm_global_type_t global_type;
|
||||
} u;
|
||||
} wasm_import_t;
|
||||
|
||||
typedef struct wasm_export_type {
|
||||
typedef struct wasm_export_t {
|
||||
const char *name;
|
||||
wasm_import_export_kind_t kind;
|
||||
} wasm_export_type;
|
||||
union {
|
||||
wasm_func_type_t func_type;
|
||||
wasm_global_type_t global_type;
|
||||
} u;
|
||||
} wasm_export_t;
|
||||
|
||||
/* Instantiated WASM module */
|
||||
struct WASMModuleInstanceCommon;
|
||||
|
@ -213,6 +227,13 @@ typedef struct RuntimeInitArgs {
|
|||
#define LOAD_ARGS_OPTION_DEFINED
|
||||
typedef struct LoadArgs {
|
||||
char *name;
|
||||
/* This option is only used by the Wasm C API (see wasm_c_api.h) */
|
||||
bool clone_wasm_binary;
|
||||
/* False by default, used by AOT/wasm loader only.
|
||||
If true, the AOT/wasm loader creates a copy of some module fields (e.g.
|
||||
const strings), making it possible to free the wasm binary buffer after
|
||||
loading. */
|
||||
bool wasm_binary_freeable;
|
||||
/* TODO: more fields? */
|
||||
} LoadArgs;
|
||||
#endif /* LOAD_ARGS_OPTION_DEFINED */
|
||||
|
@ -235,7 +256,8 @@ enum wasm_valkind_enum {
|
|||
WASM_I64,
|
||||
WASM_F32,
|
||||
WASM_F64,
|
||||
WASM_ANYREF = 128,
|
||||
WASM_V128,
|
||||
WASM_EXTERNREF = 128,
|
||||
WASM_FUNCREF,
|
||||
};
|
||||
#endif
|
||||
|
@ -246,7 +268,7 @@ struct wasm_ref_t;
|
|||
|
||||
typedef struct wasm_val_t {
|
||||
wasm_valkind_t kind;
|
||||
uint8_t __paddings[7];
|
||||
uint8_t _paddings[7];
|
||||
union {
|
||||
/* also represent a function index */
|
||||
int32_t i32;
|
||||
|
@ -260,6 +282,13 @@ typedef struct wasm_val_t {
|
|||
} wasm_val_t;
|
||||
#endif
|
||||
|
||||
/* Global instance*/
|
||||
typedef struct wasm_global_inst_t {
|
||||
wasm_valkind_t kind;
|
||||
bool is_mutable;
|
||||
void *global_data;
|
||||
} wasm_global_inst_t;
|
||||
|
||||
typedef enum {
|
||||
WASM_LOG_LEVEL_FATAL = 0,
|
||||
WASM_LOG_LEVEL_ERROR = 1,
|
||||
|
@ -419,7 +448,7 @@ wasm_runtime_register_module(const char *module_name, wasm_module_t module,
|
|||
|
||||
/**
|
||||
* Check if there is already a loaded module named module_name in the
|
||||
* runtime. Repeately loading a module with the same name is not allowed.
|
||||
* runtime. Repeatedly loading a module with the same name is not allowed.
|
||||
*
|
||||
* @param module_name indicate a name
|
||||
*
|
||||
|
@ -442,7 +471,7 @@ wasm_runtime_find_module_registered(const char *module_name);
|
|||
* @param buf the byte buffer which contains the WASM/AOT binary data,
|
||||
* note that the byte buffer must be writable since runtime may
|
||||
* change its content for footprint and performance purpose, and
|
||||
* it must be referencable until wasm_runtime_unload is called
|
||||
* it must be referenceable until wasm_runtime_unload is called
|
||||
* @param size the size of the buffer
|
||||
* @param error_buf output of the exception info
|
||||
* @param error_buf_size the size of the exception string
|
||||
|
@ -912,7 +941,7 @@ wasm_runtime_call_wasm_v(wasm_exec_env_t exec_env,
|
|||
* @param exec_env the execution environment to call the function
|
||||
* which must be created from wasm_create_exec_env()
|
||||
* @param element_index the function reference index, usually
|
||||
* prvovided by the caller of a registed native function
|
||||
* provided by the caller of a registered native function
|
||||
* @param argc the number of arguments
|
||||
* @param argv the arguments. If the function method has return value,
|
||||
* the first (or first two in case 64-bit return value) element of
|
||||
|
@ -1160,7 +1189,7 @@ wasm_runtime_validate_native_addr(wasm_module_inst_t module_inst,
|
|||
* stable.)
|
||||
*
|
||||
* @param module_inst the WASM module instance
|
||||
* @param app_offset the app adress
|
||||
* @param app_offset the app address
|
||||
*
|
||||
* @return the native address converted
|
||||
*/
|
||||
|
@ -1234,7 +1263,7 @@ wasm_runtime_get_import_count(const wasm_module_t module);
|
|||
*/
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_get_import_type(const wasm_module_t module, int32_t import_index,
|
||||
wasm_import_type *import_type);
|
||||
wasm_import_t *import_type);
|
||||
|
||||
/**
|
||||
* Get the number of export items for a WASM module
|
||||
|
@ -1255,7 +1284,71 @@ wasm_runtime_get_export_count(const wasm_module_t module);
|
|||
*/
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_get_export_type(const wasm_module_t module, int32_t export_index,
|
||||
wasm_export_type *export_type);
|
||||
wasm_export_t *export_type);
|
||||
|
||||
/**
|
||||
* Get the number of parameters for a function type
|
||||
*
|
||||
* @param func_type the function type
|
||||
*
|
||||
* @return the number of parameters for the function type
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint32_t
|
||||
wasm_func_type_get_param_count(wasm_func_type_t const func_type);
|
||||
|
||||
/**
|
||||
* Get the kind of a parameter for a function type
|
||||
*
|
||||
* @param func_type the function type
|
||||
* @param param_index the index of the parameter to get
|
||||
*
|
||||
* @return the kind of the parameter if successful, -1 otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_valkind_t
|
||||
wasm_func_type_get_param_valkind(wasm_func_type_t const func_type,
|
||||
uint32_t param_index);
|
||||
|
||||
/**
|
||||
* Get the number of results for a function type
|
||||
*
|
||||
* @param func_type the function type
|
||||
*
|
||||
* @return the number of results for the function type
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint32_t
|
||||
wasm_func_type_get_result_count(wasm_func_type_t const func_type);
|
||||
|
||||
/**
|
||||
* Get the kind of a result for a function type
|
||||
*
|
||||
* @param func_type the function type
|
||||
* @param result_index the index of the result to get
|
||||
*
|
||||
* @return the kind of the result if successful, -1 otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_valkind_t
|
||||
wasm_func_type_get_result_valkind(wasm_func_type_t const func_type,
|
||||
uint32_t result_index);
|
||||
|
||||
/**
|
||||
* Get the kind for a global type
|
||||
*
|
||||
* @param global_type the global type
|
||||
*
|
||||
* @return the kind of the global
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_valkind_t
|
||||
wasm_global_type_get_valkind(const wasm_global_type_t global_type);
|
||||
|
||||
/**
|
||||
* Get the mutability for a global type
|
||||
*
|
||||
* @param global_type the global type
|
||||
*
|
||||
* @return true if mutable, false otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_global_type_get_mutable(const wasm_global_type_t global_type);
|
||||
|
||||
/**
|
||||
* Register native functions with same module name
|
||||
|
@ -1328,6 +1421,21 @@ WASM_RUNTIME_API_EXTERN bool
|
|||
wasm_runtime_unregister_natives(const char *module_name,
|
||||
NativeSymbol *native_symbols);
|
||||
|
||||
/**
|
||||
* Get an export global instance
|
||||
*
|
||||
* @param module_inst the module instance
|
||||
* @param name the export global name
|
||||
* @param global_inst location to store the global instance
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_get_export_global_inst(const wasm_module_inst_t module_inst,
|
||||
const char *name,
|
||||
wasm_global_inst_t *global_inst);
|
||||
|
||||
/**
|
||||
* Get attachment of native function from execution environment
|
||||
*
|
||||
|
@ -1386,7 +1494,7 @@ WASM_RUNTIME_API_EXTERN double
|
|||
wasm_runtime_sum_wasm_exec_time(wasm_module_inst_t module_inst);
|
||||
|
||||
/**
|
||||
* Return execution time in ms of a given wasm funciton with
|
||||
* Return execution time in ms of a given wasm function with
|
||||
* func_name. If the function is not found, return 0.
|
||||
*
|
||||
* @param module_inst the WASM module instance to profile
|
||||
|
@ -1602,7 +1710,7 @@ wasm_runtime_get_version(uint32_t *major, uint32_t *minor, uint32_t *patch);
|
|||
|
||||
/**
|
||||
* Check whether an import func `(import <module_name> <func_name> (func ...))`
|
||||
* is linked or not with runtime registered natvie functions
|
||||
* is linked or not with runtime registered native functions
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_is_import_func_linked(const char *module_name,
|
||||
|
@ -1610,7 +1718,7 @@ wasm_runtime_is_import_func_linked(const char *module_name,
|
|||
|
||||
/**
|
||||
* Check whether an import global `(import <module_name> <global_name>
|
||||
* (global ...))` is linked or not with runtime registered natvie globals
|
||||
* (global ...))` is linked or not with runtime registered native globals
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_is_import_global_linked(const char *module_name,
|
||||
|
@ -1653,7 +1761,7 @@ wasm_runtime_set_enlarge_mem_error_callback(
|
|||
* to all threads in the cluster.
|
||||
* It's an undefined behavior if multiple threads in a cluster call
|
||||
* wasm_runtime_set_context_spread on the same key
|
||||
* simultaneously. It's a caller's resposibility to perform necessary
|
||||
* simultaneously. It's a caller's responsibility to perform necessary
|
||||
* serialization if necessary. For example:
|
||||
*
|
||||
* if (wasm_runtime_get_context(inst, key) == NULL) {
|
||||
|
@ -1673,7 +1781,7 @@ wasm_runtime_set_enlarge_mem_error_callback(
|
|||
*
|
||||
* Note: dynamic key create/destroy while instances are live is not
|
||||
* implemented as of writing this.
|
||||
* it's caller's resposibility to ensure destorying all module instances
|
||||
* it's caller's responsibility to ensure destroying all module instances
|
||||
* before calling wasm_runtime_create_context_key or
|
||||
* wasm_runtime_destroy_context_key.
|
||||
* otherwise, it's an undefined behavior.
|
||||
|
@ -1734,7 +1842,7 @@ wasm_runtime_get_context(wasm_module_inst_t inst, void *key);
|
|||
*
|
||||
* The actual wake up mechanism used by `os_wakeup_blocking_op` is
|
||||
* platform-dependent. It might impose some platform-dependent restrictions
|
||||
* on the implementation of the blocking opearation.
|
||||
* on the implementation of the blocking operation.
|
||||
*
|
||||
* For example, on POSIX-like platforms, a signal (by default SIGUSR1) is
|
||||
* used. The signal delivery configurations (eg. signal handler, signal mask,
|
||||
|
@ -1807,6 +1915,15 @@ WASM_RUNTIME_API_EXTERN bool
|
|||
wasm_runtime_detect_native_stack_overflow_size(wasm_exec_env_t exec_env,
|
||||
uint32_t required_size);
|
||||
|
||||
/**
|
||||
* Query whether the wasm binary buffer used to create the module can be freed
|
||||
*
|
||||
* @param module the target module
|
||||
* @return true if the wasm binary buffer can be freed
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_is_underlying_binary_freeable(const wasm_module_t module);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -85,8 +85,8 @@ extern "C" {
|
|||
/**
|
||||
* Used by wamr compiler to represent object ref types,
|
||||
* including func object ref, externref object ref,
|
||||
* internal object ref, eq obect ref, i31 object ref,
|
||||
* struct object ref, array obect ref
|
||||
* internal object ref, eq object ref, i31 object ref,
|
||||
* struct object ref, array object ref
|
||||
*/
|
||||
#define VALUE_TYPE_GC_REF 0x43
|
||||
|
||||
|
@ -213,10 +213,11 @@ typedef struct WASMTag WASMTag;
|
|||
|
||||
#ifndef WASM_VALUE_DEFINED
|
||||
#define WASM_VALUE_DEFINED
|
||||
|
||||
typedef union V128 {
|
||||
int8 i8x16[16];
|
||||
int16 i16x8[8];
|
||||
int32 i32x8[4];
|
||||
int32 i32x4[4];
|
||||
int64 i64x2[2];
|
||||
float32 f32x4[4];
|
||||
float64 f64x2[2];
|
||||
|
@ -249,13 +250,13 @@ typedef union WASMValue {
|
|||
#endif /* end of WASM_VALUE_DEFINED */
|
||||
|
||||
typedef struct WASMStructNewInitValues {
|
||||
uint8 type_idx;
|
||||
uint32 type_idx;
|
||||
uint32 count;
|
||||
WASMValue fields[1];
|
||||
} WASMStructNewInitValues;
|
||||
|
||||
typedef struct WASMArrayNewInitValues {
|
||||
uint8 type_idx;
|
||||
uint32 type_idx;
|
||||
uint32 length;
|
||||
WASMValue elem_data[1];
|
||||
} WASMArrayNewInitValues;
|
||||
|
@ -500,8 +501,10 @@ typedef struct WASMTable {
|
|||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
typedef uint64 mem_offset_t;
|
||||
#define PR_MEM_OFFSET PRIu64
|
||||
#else
|
||||
typedef uint32 mem_offset_t;
|
||||
#define PR_MEM_OFFSET PRIu32
|
||||
#endif
|
||||
|
||||
typedef struct WASMMemory {
|
||||
|
@ -572,7 +575,7 @@ typedef struct WASMTagImport {
|
|||
char *field_name;
|
||||
uint8 attribute; /* the type of the tag (numerical) */
|
||||
uint32 type; /* the type of the catch function (numerical)*/
|
||||
WASMType *tag_type;
|
||||
WASMFuncType *tag_type;
|
||||
void *tag_ptr_linked;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
|
@ -584,11 +587,15 @@ typedef struct WASMTagImport {
|
|||
} WASMTagImport;
|
||||
#endif
|
||||
|
||||
typedef struct WASMGlobalType {
|
||||
uint8 val_type;
|
||||
bool is_mutable;
|
||||
} WASMGlobalType;
|
||||
|
||||
typedef struct WASMGlobalImport {
|
||||
char *module_name;
|
||||
char *field_name;
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
WASMGlobalType type;
|
||||
bool is_linked;
|
||||
/* global data after linked */
|
||||
WASMValue global_data_linked;
|
||||
|
@ -700,13 +707,12 @@ struct WASMFunction {
|
|||
struct WASMTag {
|
||||
uint8 attribute; /* the attribute property of the tag (expected to be 0) */
|
||||
uint32 type; /* the type of the tag (expected valid inden in type table) */
|
||||
WASMType *tag_type;
|
||||
WASMFuncType *tag_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct WASMGlobal {
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
WASMGlobalType type;
|
||||
#if WASM_ENABLE_GC != 0
|
||||
WASMRefType *ref_type;
|
||||
#endif
|
||||
|
@ -746,6 +752,7 @@ typedef struct WASMDataSeg {
|
|||
bool is_passive;
|
||||
#endif
|
||||
uint8 *data;
|
||||
bool is_data_cloned;
|
||||
} WASMDataSeg;
|
||||
|
||||
typedef struct BlockAddr {
|
||||
|
@ -762,7 +769,7 @@ typedef struct WASIArguments {
|
|||
uint32 map_dir_count;
|
||||
const char **env;
|
||||
uint32 env_count;
|
||||
/* in CIDR noation */
|
||||
/* in CIDR notation */
|
||||
const char **addr_pool;
|
||||
uint32 addr_count;
|
||||
const char **ns_lookup_pool;
|
||||
|
@ -1021,7 +1028,7 @@ struct WASMModule {
|
|||
/**
|
||||
* func pointers of LLVM JITed (un-imported) functions
|
||||
* for non Multi-Tier JIT mode:
|
||||
* each pointer is set to the lookuped llvm jit func ptr, note that it
|
||||
* each pointer is set to the looked up llvm jit func ptr, note that it
|
||||
* is a stub and will trigger the actual compilation when it is called
|
||||
* for Multi-Tier JIT mode:
|
||||
* each pointer is inited as call_to_fast_jit code block, when the llvm
|
||||
|
@ -1071,6 +1078,9 @@ struct WASMModule {
|
|||
|
||||
/* user defined name */
|
||||
char *name;
|
||||
|
||||
/* Whether the underlying wasm binary buffer can be freed */
|
||||
bool is_binary_freeable;
|
||||
};
|
||||
|
||||
typedef struct BlockType {
|
||||
|
|
|
@ -1584,7 +1584,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
|
||||
uint32 *tgtframe_sp = tgtframe->frame_sp;
|
||||
|
||||
/* frame sp of tgtframe points to catched exception */
|
||||
/* frame sp of tgtframe points to caught exception */
|
||||
exception_tag_index = *((uint32 *)tgtframe_sp);
|
||||
tgtframe_sp++;
|
||||
|
||||
|
@ -1612,7 +1612,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
/* landing pad for the rethrow ? */
|
||||
find_a_catch_handler:
|
||||
{
|
||||
WASMType *tag_type = NULL;
|
||||
WASMFuncType *tag_type = NULL;
|
||||
uint32 cell_num_to_copy = 0;
|
||||
if (IS_INVALID_TAGINDEX(exception_tag_index)) {
|
||||
/*
|
||||
|
@ -1655,7 +1655,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
* BLOCK, IF and LOOP do not contain handlers and
|
||||
* cannot catch exceptions.
|
||||
* blocks marked as CATCH or
|
||||
* CATCH_ALL did already caugth an exception and can
|
||||
* CATCH_ALL did already caught an exception and can
|
||||
* only be a target for RETHROW, but cannot catch an
|
||||
* exception again
|
||||
*/
|
||||
|
@ -1787,7 +1787,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
}
|
||||
handler_number++;
|
||||
}
|
||||
/* exception not catched in this frame */
|
||||
/* exception not caught in this frame */
|
||||
break;
|
||||
}
|
||||
case LABEL_TYPE_FUNCTION:
|
||||
|
@ -6411,7 +6411,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
}
|
||||
}
|
||||
/*
|
||||
* excange the thrown exception (index valid in submodule)
|
||||
* exchange the thrown exception (index valid in submodule)
|
||||
* with the imported exception index (valid in this module)
|
||||
* if the module did not import the exception,
|
||||
* that results in a "INVALID_TAGINDEX", that triggers
|
||||
|
@ -6468,7 +6468,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
goto find_a_catch_handler;
|
||||
}
|
||||
|
||||
/* when throw hits the end of a function it signalles with a
|
||||
/* when throw hits the end of a function it signals with a
|
||||
* "uncaught wasm exception" trap */
|
||||
if (has_exception
|
||||
&& strstr(uncaught_exception, "uncaught wasm exception")) {
|
||||
|
@ -6487,6 +6487,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
WASMFuncType *func_type = cur_wasm_func->func_type;
|
||||
uint32 max_stack_cell_num = cur_wasm_func->max_stack_cell_num;
|
||||
uint32 cell_num_of_local_stack;
|
||||
#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
|
||||
uint32 local_cell_idx;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_EXCE_HANDLING != 0
|
||||
/* account for exception handlers, bundle them here */
|
||||
|
@ -6546,6 +6549,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
memset(frame_lp + cur_func->param_cell_num, 0,
|
||||
(uint32)(cur_func->local_cell_num * 4));
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
|
||||
/* externref/funcref should be NULL_REF rather than 0 */
|
||||
local_cell_idx = cur_func->param_cell_num;
|
||||
for (i = 0; i < cur_wasm_func->local_count; i++) {
|
||||
if (cur_wasm_func->local_types[i] == VALUE_TYPE_EXTERNREF
|
||||
|| cur_wasm_func->local_types[i] == VALUE_TYPE_FUNCREF) {
|
||||
*(frame_lp + local_cell_idx) = NULL_REF;
|
||||
}
|
||||
local_cell_idx +=
|
||||
wasm_value_type_cell_num(cur_wasm_func->local_types[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Push function block as first block */
|
||||
cell_num = func_type->ret_cell_num;
|
||||
PUSH_CSP(LABEL_TYPE_FUNCTION, 0, cell_num, frame_ip_end - 1);
|
||||
|
|
|
@ -973,9 +973,9 @@ fail:
|
|||
} \
|
||||
} \
|
||||
else if (cells[0] == 2) { \
|
||||
frame_lp[dst_offsets[0]] = frame_lp[src_offsets[0]]; \
|
||||
frame_lp[dst_offsets[0] + 1] = \
|
||||
frame_lp[src_offsets[0] + 1]; \
|
||||
PUT_I64_TO_ADDR( \
|
||||
frame_lp + dst_offsets[0], \
|
||||
GET_I64_FROM_ADDR(frame_lp + src_offsets[0])); \
|
||||
/* Ignore constants because they are not reference */ \
|
||||
if (src_offsets[0] >= 0) { \
|
||||
CLEAR_FRAME_REF((unsigned)src_offsets[0]); \
|
||||
|
@ -1020,9 +1020,9 @@ fail:
|
|||
if (cells[0] == 1) \
|
||||
frame_lp[dst_offsets[0]] = frame_lp[src_offsets[0]]; \
|
||||
else if (cells[0] == 2) { \
|
||||
frame_lp[dst_offsets[0]] = frame_lp[src_offsets[0]]; \
|
||||
frame_lp[dst_offsets[0] + 1] = \
|
||||
frame_lp[src_offsets[0] + 1]; \
|
||||
PUT_I64_TO_ADDR( \
|
||||
frame_lp + dst_offsets[0], \
|
||||
GET_I64_FROM_ADDR(frame_lp + src_offsets[0])); \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
|
@ -4868,8 +4868,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
GET_LOCAL_INDEX_TYPE_AND_OFFSET();
|
||||
addr1 = GET_OFFSET();
|
||||
|
||||
if (local_type == VALUE_TYPE_I32
|
||||
|| local_type == VALUE_TYPE_F32) {
|
||||
if (local_type == VALUE_TYPE_I32 || local_type == VALUE_TYPE_F32
|
||||
#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
|
||||
|| local_type == VALUE_TYPE_FUNCREF
|
||||
|| local_type == VALUE_TYPE_EXTERNREF
|
||||
#endif
|
||||
) {
|
||||
*(int32 *)(frame_lp + local_offset) = frame_lp[addr1];
|
||||
}
|
||||
else if (local_type == VALUE_TYPE_I64
|
||||
|
@ -5905,6 +5909,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
else {
|
||||
WASMFunction *cur_wasm_func = cur_func->u.func;
|
||||
uint32 cell_num_of_local_stack;
|
||||
#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
|
||||
uint32 i, local_cell_idx;
|
||||
#endif
|
||||
|
||||
cell_num_of_local_stack = cur_func->param_cell_num
|
||||
+ cur_func->local_cell_num
|
||||
|
@ -5947,6 +5954,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
memset(frame_lp + cur_func->param_cell_num, 0,
|
||||
(uint32)(cur_func->local_cell_num * 4));
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
|
||||
/* externref/funcref should be NULL_REF rather than 0 */
|
||||
local_cell_idx = cur_func->param_cell_num;
|
||||
for (i = 0; i < cur_wasm_func->local_count; i++) {
|
||||
if (cur_wasm_func->local_types[i] == VALUE_TYPE_EXTERNREF
|
||||
|| cur_wasm_func->local_types[i] == VALUE_TYPE_FUNCREF) {
|
||||
*(frame_lp + local_cell_idx) = NULL_REF;
|
||||
}
|
||||
local_cell_idx +=
|
||||
wasm_value_type_cell_num(cur_wasm_func->local_types[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
/* frame->ip is used during GC root set enumeration, so we must
|
||||
* initialized this field here */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@
|
|||
#include "wasm_runtime.h"
|
||||
#include "../common/wasm_native.h"
|
||||
#include "../common/wasm_memory.h"
|
||||
#include "wasm_loader_common.h"
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
#include "../fast-jit/jit_compiler.h"
|
||||
#include "../fast-jit/jit_codecache.h"
|
||||
|
@ -474,18 +475,18 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
|||
global_idx = cur_value.global_index;
|
||||
|
||||
bh_assert(global_idx < module->import_global_count);
|
||||
bh_assert(
|
||||
!module->import_globals[global_idx].u.global.is_mutable);
|
||||
bh_assert(!module->import_globals[global_idx]
|
||||
.u.global.type.is_mutable);
|
||||
|
||||
if (global_idx < module->import_global_count) {
|
||||
global_type =
|
||||
module->import_globals[global_idx].u.global.type;
|
||||
global_type = module->import_globals[global_idx]
|
||||
.u.global.type.val_type;
|
||||
}
|
||||
else {
|
||||
global_type =
|
||||
module
|
||||
->globals[global_idx - module->import_global_count]
|
||||
.type;
|
||||
.type.val_type;
|
||||
}
|
||||
|
||||
if (!push_const_expr_stack(&const_expr_ctx, flag, global_type,
|
||||
|
@ -714,38 +715,6 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_memory_flag(const uint8 mem_flag)
|
||||
{
|
||||
/* Check whether certain features indicated by mem_flag are enabled in
|
||||
* runtime */
|
||||
if (mem_flag > MAX_PAGE_COUNT_FLAG) {
|
||||
#if WASM_ENABLE_SHARED_MEMORY == 0
|
||||
if (mem_flag & SHARED_MEMORY_FLAG) {
|
||||
LOG_VERBOSE("shared memory flag was found, please enable shared "
|
||||
"memory, lib-pthread or lib-wasi-threads");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_MEMORY64 == 0
|
||||
if (mem_flag & MEMORY64_FLAG) {
|
||||
LOG_VERBOSE("memory64 flag was found, please enable memory64");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mem_flag > MAX_PAGE_COUNT_FLAG + SHARED_MEMORY_FLAG + MEMORY64_FLAG) {
|
||||
return false;
|
||||
}
|
||||
else if ((mem_flag & SHARED_MEMORY_FLAG)
|
||||
&& !(mem_flag & MAX_PAGE_COUNT_FLAG)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMModule *parent_module, const char *sub_module_name,
|
||||
|
@ -766,7 +735,9 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
uint32 declare_max_page_count = 0;
|
||||
|
||||
read_leb_uint32(p, p_end, mem_flag);
|
||||
bh_assert(check_memory_flag(mem_flag));
|
||||
if (!wasm_memory_check_flags(mem_flag, error_buf, error_buf_size, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_APP_FRAMEWORK == 0
|
||||
is_memory64 = mem_flag & MEMORY64_FLAG;
|
||||
|
@ -796,7 +767,6 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
memory->num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
|
||||
*p_buf = p;
|
||||
(void)check_memory_flag;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -826,16 +796,16 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
ret = wasm_native_lookup_libc_builtin_global(sub_module_name, global_name,
|
||||
global);
|
||||
if (ret) {
|
||||
bh_assert(global->type == declare_type
|
||||
&& global->is_mutable != declare_mutable);
|
||||
bh_assert(global->type.val_type == declare_type
|
||||
&& global->type.is_mutable != declare_mutable);
|
||||
}
|
||||
#endif /* WASM_ENABLE_LIBC_BUILTIN */
|
||||
|
||||
global->is_linked = ret;
|
||||
global->module_name = sub_module_name;
|
||||
global->field_name = global_name;
|
||||
global->type = declare_type;
|
||||
global->is_mutable = is_mutable;
|
||||
global->type.val_type = declare_type;
|
||||
global->type.is_mutable = is_mutable;
|
||||
(void)p_end;
|
||||
return true;
|
||||
}
|
||||
|
@ -891,7 +861,10 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
|
|||
read_leb_uint32(p, p_end, memory->flags);
|
||||
bh_assert(p - p_org <= 1);
|
||||
(void)p_org;
|
||||
bh_assert(check_memory_flag(memory->flags));
|
||||
if (!wasm_memory_check_flags(memory->flags, error_buf, error_buf_size,
|
||||
false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_APP_FRAMEWORK == 0
|
||||
is_memory64 = memory->flags & MEMORY64_FLAG;
|
||||
|
@ -916,7 +889,6 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
|
|||
memory->num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
|
||||
*p_buf = p;
|
||||
(void)check_memory_flag;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1373,14 +1345,15 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
|
||||
for (i = 0; i < global_count; i++, global++) {
|
||||
CHECK_BUF(p, p_end, 2);
|
||||
global->type = read_uint8(p);
|
||||
global->type.val_type = read_uint8(p);
|
||||
mutable = read_uint8(p);
|
||||
bh_assert(mutable < 2);
|
||||
global->is_mutable = mutable ? true : false;
|
||||
global->type.is_mutable = mutable ? true : false;
|
||||
|
||||
/* initialize expression */
|
||||
if (!load_init_expr(module, &p, p_end, &(global->init_expr),
|
||||
global->type, error_buf, error_buf_size))
|
||||
global->type.val_type, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
|
||||
if (INIT_EXPR_TYPE_GET_GLOBAL == global->init_expr.init_expr_type) {
|
||||
|
@ -1767,8 +1740,8 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
|
||||
static bool
|
||||
load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
WASMModule *module, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
WASMModule *module, bool clone_data_seg,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 data_seg_count, i, mem_index, data_seg_len;
|
||||
|
@ -1878,7 +1851,19 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
|
||||
dataseg->data_length = data_seg_len;
|
||||
CHECK_BUF(p, p_end, data_seg_len);
|
||||
dataseg->data = (uint8 *)p;
|
||||
if (clone_data_seg) {
|
||||
if (!(dataseg->data = loader_malloc(
|
||||
dataseg->data_length, error_buf, error_buf_size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bh_memcpy_s(dataseg->data, dataseg->data_length, p,
|
||||
data_seg_len);
|
||||
}
|
||||
else {
|
||||
dataseg->data = (uint8 *)p;
|
||||
}
|
||||
dataseg->is_data_cloned = clone_data_seg;
|
||||
p += data_seg_len;
|
||||
}
|
||||
}
|
||||
|
@ -2065,7 +2050,7 @@ calculate_global_data_offset(WASMModule *module)
|
|||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
import_global->data_offset = data_offset;
|
||||
#endif
|
||||
data_offset += wasm_value_type_size(import_global->type);
|
||||
data_offset += wasm_value_type_size(import_global->type.val_type);
|
||||
}
|
||||
|
||||
for (i = 0; i < module->global_count; i++) {
|
||||
|
@ -2073,7 +2058,7 @@ calculate_global_data_offset(WASMModule *module)
|
|||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
global->data_offset = data_offset;
|
||||
#endif
|
||||
data_offset += wasm_value_type_size(global->type);
|
||||
data_offset += wasm_value_type_size(global->type.val_type);
|
||||
}
|
||||
|
||||
module->global_data_size = data_offset;
|
||||
|
@ -2311,7 +2296,7 @@ orcjit_thread_callback(void *arg)
|
|||
uint32 i;
|
||||
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
/* Compile fast jit funcitons of this group */
|
||||
/* Compile fast jit functions of this group */
|
||||
for (i = group_idx; i < func_count; i += group_stride) {
|
||||
if (!jit_compiler_compile(module, i + module->import_function_count)) {
|
||||
LOG_ERROR("failed to compile fast jit function %u\n", i);
|
||||
|
@ -2576,8 +2561,8 @@ static void **handle_table;
|
|||
|
||||
static bool
|
||||
load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
bool is_load_from_file_buf, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
bool is_load_from_file_buf, bool wasm_binary_freeable,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMExport *export;
|
||||
WASMSection *section = sections;
|
||||
|
@ -2592,6 +2577,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
uint32 aux_heap_base_global_index = (uint32)-1;
|
||||
WASMFuncType *func_type;
|
||||
uint8 malloc_free_io_type = VALUE_TYPE_I32;
|
||||
bool reuse_const_strings = is_load_from_file_buf && !wasm_binary_freeable;
|
||||
bool clone_data_seg = is_load_from_file_buf && wasm_binary_freeable;
|
||||
|
||||
/* Find code and function sections if have */
|
||||
while (section) {
|
||||
|
@ -2615,7 +2602,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
case SECTION_TYPE_USER:
|
||||
/* unsupported user section, ignore it. */
|
||||
if (!load_user_section(buf, buf_end, module,
|
||||
is_load_from_file_buf, error_buf,
|
||||
reuse_const_strings, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
break;
|
||||
|
@ -2626,7 +2613,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
break;
|
||||
case SECTION_TYPE_IMPORT:
|
||||
if (!load_import_section(buf, buf_end, module,
|
||||
is_load_from_file_buf, error_buf,
|
||||
reuse_const_strings, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
break;
|
||||
|
@ -2652,7 +2639,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
break;
|
||||
case SECTION_TYPE_EXPORT:
|
||||
if (!load_export_section(buf, buf_end, module,
|
||||
is_load_from_file_buf, error_buf,
|
||||
reuse_const_strings, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
break;
|
||||
|
@ -2672,7 +2659,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
return false;
|
||||
break;
|
||||
case SECTION_TYPE_DATA:
|
||||
if (!load_data_segment_section(buf, buf_end, module, error_buf,
|
||||
if (!load_data_segment_section(buf, buf_end, module,
|
||||
clone_data_seg, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
break;
|
||||
|
@ -2702,7 +2690,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
if (!strcmp(export->name, "__heap_base")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32 && !global->is_mutable
|
||||
if (global->type.val_type == VALUE_TYPE_I32
|
||||
&& !global->type.is_mutable
|
||||
&& global->init_expr.init_expr_type
|
||||
== INIT_EXPR_TYPE_I32_CONST) {
|
||||
aux_heap_base_global = global;
|
||||
|
@ -2715,7 +2704,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
else if (!strcmp(export->name, "__data_end")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32 && !global->is_mutable
|
||||
if (global->type.val_type == VALUE_TYPE_I32
|
||||
&& !global->type.is_mutable
|
||||
&& global->init_expr.init_expr_type
|
||||
== INIT_EXPR_TYPE_I32_CONST) {
|
||||
aux_data_end_global = global;
|
||||
|
@ -2754,9 +2744,9 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
for (global_index = 0; global_index < module->global_count;
|
||||
global_index++) {
|
||||
global = module->globals + global_index;
|
||||
if (global->is_mutable /* heap_base and data_end is
|
||||
not mutable */
|
||||
&& global->type == VALUE_TYPE_I32
|
||||
if (global->type.is_mutable /* heap_base and data_end is
|
||||
not mutable */
|
||||
&& global->type.val_type == VALUE_TYPE_I32
|
||||
&& global->init_expr.init_expr_type
|
||||
== INIT_EXPR_TYPE_I32_CONST
|
||||
&& (uint64)(uint32)global->init_expr.u.i32
|
||||
|
@ -3033,6 +3023,7 @@ create_module(char *name, char *error_buf, uint32 error_buf_size)
|
|||
module->start_function = (uint32)-1;
|
||||
|
||||
module->name = name;
|
||||
module->is_binary_freeable = false;
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
module->br_table_cache_list = &module->br_table_cache_list_head;
|
||||
|
@ -3062,7 +3053,7 @@ wasm_loader_load_from_sections(WASMSection *section_list, char *error_buf,
|
|||
if (!module)
|
||||
return NULL;
|
||||
|
||||
if (!load_from_sections(module, section_list, false, error_buf,
|
||||
if (!load_from_sections(module, section_list, false, true, error_buf,
|
||||
error_buf_size)) {
|
||||
wasm_loader_unload(module);
|
||||
return NULL;
|
||||
|
@ -3191,8 +3182,8 @@ static union {
|
|||
#define is_little_endian() (__ue.b == 1)
|
||||
|
||||
static bool
|
||||
load(const uint8 *buf, uint32 size, WASMModule *module, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
load(const uint8 *buf, uint32 size, WASMModule *module,
|
||||
bool wasm_binary_freeable, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *buf_end = buf + size;
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
|
@ -3217,8 +3208,8 @@ load(const uint8 *buf, uint32 size, WASMModule *module, char *error_buf,
|
|||
}
|
||||
|
||||
if (!create_sections(buf, size, §ion_list, error_buf, error_buf_size)
|
||||
|| !load_from_sections(module, section_list, true, error_buf,
|
||||
error_buf_size)) {
|
||||
|| !load_from_sections(module, section_list, true, wasm_binary_freeable,
|
||||
error_buf, error_buf_size)) {
|
||||
destroy_sections(section_list);
|
||||
return false;
|
||||
}
|
||||
|
@ -3243,7 +3234,8 @@ wasm_loader_load(uint8 *buf, uint32 size, const LoadArgs *args, char *error_buf,
|
|||
module->load_size = size;
|
||||
#endif
|
||||
|
||||
if (!load(buf, size, module, error_buf, error_buf_size)) {
|
||||
if (!load(buf, size, module, args->wasm_binary_freeable, error_buf,
|
||||
error_buf_size)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -3355,8 +3347,11 @@ wasm_loader_unload(WASMModule *module)
|
|||
|
||||
if (module->data_segments) {
|
||||
for (i = 0; i < module->data_seg_count; i++) {
|
||||
if (module->data_segments[i])
|
||||
if (module->data_segments[i]) {
|
||||
if (module->data_segments[i]->is_data_cloned)
|
||||
wasm_runtime_free(module->data_segments[i]->data);
|
||||
wasm_runtime_free(module->data_segments[i]);
|
||||
}
|
||||
}
|
||||
wasm_runtime_free(module->data_segments);
|
||||
}
|
||||
|
@ -4240,7 +4235,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
|
|||
ctx->frame_ref--;
|
||||
ctx->stack_cell_num--;
|
||||
|
||||
if (is_32bit_type(type))
|
||||
if (is_32bit_type(type) || *ctx->frame_ref == VALUE_TYPE_ANY)
|
||||
return true;
|
||||
|
||||
ctx->frame_ref--;
|
||||
|
@ -6213,6 +6208,7 @@ re_scan:
|
|||
}
|
||||
|
||||
case WASM_OP_ELSE:
|
||||
handle_op_else:
|
||||
{
|
||||
BranchBlock *block = NULL;
|
||||
BlockType block_type = (loader_ctx->frame_csp - 1)->block_type;
|
||||
|
@ -6272,26 +6268,21 @@ re_scan:
|
|||
error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* if no else branch, and return types do not match param types,
|
||||
* fail */
|
||||
/* if there is no else branch, make a virtual else opcode for
|
||||
easier integrity check and to copy the correct results to
|
||||
the block return address for fast-interp mode:
|
||||
change if block from `if ... end` to `if ... else end` */
|
||||
if (cur_block->label_type == LABEL_TYPE_IF
|
||||
&& !cur_block->else_addr) {
|
||||
uint32 block_param_count = 0, block_ret_count = 0;
|
||||
uint8 *block_param_types = NULL, *block_ret_types = NULL;
|
||||
BlockType *cur_block_type = &cur_block->block_type;
|
||||
|
||||
block_param_count = block_type_get_param_types(
|
||||
cur_block_type, &block_param_types);
|
||||
block_ret_count = block_type_get_result_types(
|
||||
cur_block_type, &block_ret_types);
|
||||
bh_assert(block_param_count == block_ret_count
|
||||
&& (!block_param_count
|
||||
|| !memcmp(block_param_types, block_ret_types,
|
||||
block_param_count)));
|
||||
(void)block_ret_types;
|
||||
(void)block_ret_count;
|
||||
(void)block_param_types;
|
||||
(void)block_param_count;
|
||||
opcode = WASM_OP_ELSE;
|
||||
p--;
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
p_org = p;
|
||||
skip_label();
|
||||
disable_emit = false;
|
||||
emit_label(opcode);
|
||||
#endif
|
||||
goto handle_op_else;
|
||||
}
|
||||
|
||||
POP_CSP();
|
||||
|
@ -6696,6 +6687,7 @@ re_scan:
|
|||
switch (*(loader_ctx->frame_ref - 1)) {
|
||||
case REF_I32:
|
||||
case REF_F32:
|
||||
case REF_ANY:
|
||||
break;
|
||||
case REF_I64_2:
|
||||
case REF_F64_2:
|
||||
|
@ -7152,13 +7144,13 @@ re_scan:
|
|||
read_leb_uint32(p, p_end, global_idx);
|
||||
bh_assert(global_idx < global_count);
|
||||
|
||||
global_type =
|
||||
global_idx < module->import_global_count
|
||||
? module->import_globals[global_idx].u.global.type
|
||||
: module
|
||||
->globals[global_idx
|
||||
- module->import_global_count]
|
||||
.type;
|
||||
global_type = global_idx < module->import_global_count
|
||||
? module->import_globals[global_idx]
|
||||
.u.global.type.val_type
|
||||
: module
|
||||
->globals[global_idx
|
||||
- module->import_global_count]
|
||||
.type.val_type;
|
||||
|
||||
PUSH_TYPE(global_type);
|
||||
|
||||
|
@ -7186,22 +7178,22 @@ re_scan:
|
|||
read_leb_uint32(p, p_end, global_idx);
|
||||
bh_assert(global_idx < global_count);
|
||||
|
||||
is_mutable =
|
||||
global_idx < module->import_global_count
|
||||
? module->import_globals[global_idx].u.global.is_mutable
|
||||
: module
|
||||
->globals[global_idx
|
||||
- module->import_global_count]
|
||||
.is_mutable;
|
||||
is_mutable = global_idx < module->import_global_count
|
||||
? module->import_globals[global_idx]
|
||||
.u.global.type.is_mutable
|
||||
: module
|
||||
->globals[global_idx
|
||||
- module->import_global_count]
|
||||
.type.is_mutable;
|
||||
bh_assert(is_mutable);
|
||||
|
||||
global_type =
|
||||
global_idx < module->import_global_count
|
||||
? module->import_globals[global_idx].u.global.type
|
||||
: module
|
||||
->globals[global_idx
|
||||
- module->import_global_count]
|
||||
.type;
|
||||
global_type = global_idx < module->import_global_count
|
||||
? module->import_globals[global_idx]
|
||||
.u.global.type.val_type
|
||||
: module
|
||||
->globals[global_idx
|
||||
- module->import_global_count]
|
||||
.type.val_type;
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
if (is_64bit_type(global_type)) {
|
||||
|
|
|
@ -86,7 +86,7 @@ typedef enum WASMOpcode {
|
|||
WASM_OP_I32_STORE8 = 0x3a, /* i32.store8 */
|
||||
WASM_OP_I32_STORE16 = 0x3b, /* i32.store16 */
|
||||
WASM_OP_I64_STORE8 = 0x3c, /* i64.store8 */
|
||||
WASM_OP_I64_STORE16 = 0x3d, /* i64.sotre16 */
|
||||
WASM_OP_I64_STORE16 = 0x3d, /* i64.store16 */
|
||||
WASM_OP_I64_STORE32 = 0x3e, /* i64.store32 */
|
||||
WASM_OP_MEMORY_SIZE = 0x3f, /* memory.size */
|
||||
WASM_OP_MEMORY_GROW = 0x40, /* memory.grow */
|
||||
|
@ -325,7 +325,7 @@ typedef enum WASMGCEXTOpcode {
|
|||
WASM_OP_I31_GET_S = 0x1D, /* i31.get_s */
|
||||
WASM_OP_I31_GET_U = 0x1E, /* i31.get_u */
|
||||
|
||||
/* stringref related opcoded */
|
||||
/* stringref related opcodes */
|
||||
WASM_OP_STRING_NEW_UTF8 = 0x80, /* string.new_utf8 */
|
||||
WASM_OP_STRING_NEW_WTF16 = 0x81, /* string.new_wtf16 */
|
||||
WASM_OP_STRING_CONST = 0x82, /* string.const */
|
||||
|
|
|
@ -856,7 +856,7 @@ check_global_init_expr(const WASMModule *module, uint32 global_index,
|
|||
* And initializer expression cannot reference a mutable global.
|
||||
*/
|
||||
if (global_index >= module->import_global_count
|
||||
|| (module->import_globals + global_index)->u.global.is_mutable) {
|
||||
|| (module->import_globals + global_index)->u.global.type.is_mutable) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"constant expression required");
|
||||
return false;
|
||||
|
@ -866,6 +866,174 @@ check_global_init_expr(const WASMModule *module, uint32 global_index,
|
|||
return true;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
/* Instantiate struct global variable recursively */
|
||||
static WASMStructObjectRef
|
||||
instantiate_struct_global_recursive(WASMModule *module,
|
||||
WASMModuleInstance *module_inst,
|
||||
uint32 type_idx, uint8 flag,
|
||||
WASMStructNewInitValues *init_values,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMRttType *rtt_type;
|
||||
WASMStructObjectRef struct_obj;
|
||||
WASMStructType *struct_type;
|
||||
|
||||
struct_type = (WASMStructType *)module->types[type_idx];
|
||||
|
||||
if (!(rtt_type = wasm_rtt_type_new((WASMType *)struct_type, type_idx,
|
||||
module->rtt_types, module->type_count,
|
||||
&module->rtt_type_lock))) {
|
||||
set_error_buf(error_buf, error_buf_size, "create rtt object failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(struct_obj = wasm_struct_obj_new_internal(
|
||||
module_inst->e->common.gc_heap_handle, rtt_type))) {
|
||||
set_error_buf(error_buf, error_buf_size, "create struct object failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
|
||||
uint32 field_idx;
|
||||
WASMRefTypeMap *ref_type_map = struct_type->ref_type_maps;
|
||||
|
||||
bh_assert(init_values->count == struct_type->field_count);
|
||||
|
||||
for (field_idx = 0; field_idx < init_values->count; field_idx++) {
|
||||
uint8 field_type = struct_type->fields[field_idx].field_type;
|
||||
WASMRefType *field_ref_type = NULL;
|
||||
if (wasm_is_type_multi_byte_type(field_type)) {
|
||||
field_ref_type = ref_type_map->ref_type;
|
||||
}
|
||||
|
||||
if (wasm_reftype_is_subtype_of(field_type, field_ref_type,
|
||||
REF_TYPE_STRUCTREF, NULL,
|
||||
module->types, module->type_count)
|
||||
|| wasm_reftype_is_subtype_of(field_type, field_ref_type,
|
||||
REF_TYPE_ARRAYREF, NULL,
|
||||
module->types, module->type_count)
|
||||
|| wasm_reftype_is_subtype_of(
|
||||
field_type, field_ref_type, REF_TYPE_FUNCREF, NULL,
|
||||
module->types, module->type_count)) {
|
||||
WASMType *wasm_type;
|
||||
int32 heap_type =
|
||||
ref_type_map->ref_type->ref_ht_common.heap_type;
|
||||
WASMValue *wasm_value = &init_values->fields[field_idx];
|
||||
WASMValue field_value = { 0 };
|
||||
|
||||
bh_assert(heap_type >= 0);
|
||||
wasm_type = module->types[heap_type];
|
||||
|
||||
bh_assert(wasm_type->type_flag == WASM_TYPE_STRUCT
|
||||
|| wasm_type->type_flag == WASM_TYPE_ARRAY
|
||||
|| wasm_type->type_flag == WASM_TYPE_FUNC);
|
||||
|
||||
if (wasm_type->type_flag == WASM_TYPE_STRUCT) {
|
||||
WASMStructNewInitValues *init_values1 =
|
||||
(WASMStructNewInitValues *)wasm_value->data;
|
||||
WASMStructObjectRef field =
|
||||
instantiate_struct_global_recursive(
|
||||
module, module_inst, heap_type,
|
||||
init_values1 ? INIT_EXPR_TYPE_STRUCT_NEW
|
||||
: INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT,
|
||||
init_values1, error_buf, error_buf_size);
|
||||
field_value.gc_obj = (WASMObjectRef)field;
|
||||
wasm_struct_obj_set_field(struct_obj, field_idx,
|
||||
&field_value);
|
||||
}
|
||||
else if (wasm_type->type_flag == WASM_TYPE_ARRAY) {
|
||||
/* struct object's field is an array obj */
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"array as a field in struct object is "
|
||||
"not supported in constant init expr");
|
||||
return NULL;
|
||||
}
|
||||
else if (wasm_type->type_flag == WASM_TYPE_FUNC) {
|
||||
WASMFuncObjectRef func_obj = NULL;
|
||||
/* UINT32_MAX indicates that it is a null reference */
|
||||
if (wasm_value->u32 != UINT32_MAX) {
|
||||
if (!(func_obj = wasm_create_func_obj(
|
||||
module_inst, wasm_value->u32, false,
|
||||
error_buf, error_buf_size))) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
field_value.gc_obj = (WASMObjectRef)func_obj;
|
||||
wasm_struct_obj_set_field(struct_obj, field_idx,
|
||||
&field_value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wasm_struct_obj_set_field(struct_obj, field_idx,
|
||||
&init_values->fields[field_idx]);
|
||||
}
|
||||
if (wasm_is_type_multi_byte_type(field_type)) {
|
||||
ref_type_map++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return struct_obj;
|
||||
}
|
||||
|
||||
static WASMArrayObjectRef
|
||||
instantiate_array_global_recursive(WASMModule *module,
|
||||
WASMModuleInstance *module_inst,
|
||||
uint32 type_idx, uint8 flag, uint32 len,
|
||||
WASMValue *array_init_value,
|
||||
WASMArrayNewInitValues *init_values,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMRttType *rtt_type;
|
||||
WASMArrayObjectRef array_obj;
|
||||
WASMArrayType *array_type;
|
||||
|
||||
array_type = (WASMArrayType *)module->types[type_idx];
|
||||
|
||||
if (!(rtt_type = wasm_rtt_type_new((WASMType *)array_type, type_idx,
|
||||
module->rtt_types, module->type_count,
|
||||
&module->rtt_type_lock))) {
|
||||
set_error_buf(error_buf, error_buf_size, "create rtt object failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(array_obj =
|
||||
wasm_array_obj_new_internal(module_inst->e->common.gc_heap_handle,
|
||||
rtt_type, len, array_init_value))) {
|
||||
set_error_buf(error_buf, error_buf_size, "create array object failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
|
||||
uint32 elem_idx;
|
||||
uint8 elem_type = array_type->elem_type;
|
||||
WASMRefType *elem_ref_type = array_type->elem_ref_type;
|
||||
|
||||
bh_assert(init_values);
|
||||
|
||||
if (wasm_reftype_is_subtype_of(elem_type, elem_ref_type,
|
||||
REF_TYPE_STRUCTREF, NULL, module->types,
|
||||
module->type_count)
|
||||
|| wasm_reftype_is_subtype_of(elem_type, elem_ref_type,
|
||||
REF_TYPE_ARRAYREF, NULL,
|
||||
module->types, module->type_count)
|
||||
|| wasm_reftype_is_subtype_of(elem_type, elem_ref_type,
|
||||
REF_TYPE_FUNCREF, NULL, module->types,
|
||||
module->type_count)) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
for (elem_idx = 0; elem_idx < len; elem_idx++) {
|
||||
wasm_array_obj_set_elem(array_obj, elem_idx,
|
||||
&init_values->elem_data[elem_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
return array_obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Instantiate globals in a module.
|
||||
*/
|
||||
|
@ -888,8 +1056,8 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|||
import = module->import_globals;
|
||||
for (i = 0; i < module->import_global_count; i++, import++) {
|
||||
WASMGlobalImport *global_import = &import->u.global;
|
||||
global->type = global_import->type;
|
||||
global->is_mutable = global_import->is_mutable;
|
||||
global->type = global_import->type.val_type;
|
||||
global->is_mutable = global_import->type.is_mutable;
|
||||
#if WASM_ENABLE_GC != 0
|
||||
global->ref_type = global_import->ref_type;
|
||||
#endif
|
||||
|
@ -935,8 +1103,8 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|||
InitializerExpression *init_expr = &(module->globals[i].init_expr);
|
||||
uint8 flag = init_expr->init_expr_type;
|
||||
|
||||
global->type = module->globals[i].type;
|
||||
global->is_mutable = module->globals[i].is_mutable;
|
||||
global->type = module->globals[i].type.val_type;
|
||||
global->is_mutable = module->globals[i].type.is_mutable;
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
bh_assert(global_data_offset == module->globals[i].data_offset);
|
||||
#endif
|
||||
|
@ -964,9 +1132,7 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|||
case INIT_EXPR_TYPE_STRUCT_NEW:
|
||||
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
|
||||
{
|
||||
WASMRttType *rtt_type;
|
||||
WASMStructObjectRef struct_obj;
|
||||
WASMStructType *struct_type;
|
||||
WASMStructNewInitValues *init_values = NULL;
|
||||
uint32 type_idx;
|
||||
|
||||
|
@ -978,36 +1144,13 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|||
type_idx = init_expr->u.type_index;
|
||||
}
|
||||
|
||||
struct_type = (WASMStructType *)module->types[type_idx];
|
||||
|
||||
if (!(rtt_type = wasm_rtt_type_new(
|
||||
(WASMType *)struct_type, type_idx, module->rtt_types,
|
||||
module->type_count, &module->rtt_type_lock))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"create rtt object failed");
|
||||
struct_obj = instantiate_struct_global_recursive(
|
||||
module, module_inst, type_idx, flag, init_values, error_buf,
|
||||
error_buf_size);
|
||||
if (!struct_obj) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(struct_obj = wasm_struct_obj_new_internal(
|
||||
module_inst->e->common.gc_heap_handle, rtt_type))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"create struct object failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
|
||||
uint32 field_idx;
|
||||
|
||||
bh_assert(init_values->count == struct_type->field_count);
|
||||
|
||||
for (field_idx = 0; field_idx < init_values->count;
|
||||
field_idx++) {
|
||||
wasm_struct_obj_set_field(
|
||||
struct_obj, field_idx,
|
||||
&init_values->fields[field_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
global->initial_value.gc_obj = (void *)struct_obj;
|
||||
break;
|
||||
}
|
||||
|
@ -1015,17 +1158,15 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|||
case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
|
||||
case INIT_EXPR_TYPE_ARRAY_NEW_FIXED:
|
||||
{
|
||||
WASMRttType *rtt_type;
|
||||
WASMArrayObjectRef array_obj;
|
||||
WASMArrayType *array_type;
|
||||
WASMArrayNewInitValues *init_values = NULL;
|
||||
WASMValue *arr_init_val = NULL, empty_val = { 0 };
|
||||
WASMValue *array_init_value = NULL, empty_value = { 0 };
|
||||
uint32 type_idx, len;
|
||||
|
||||
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
|
||||
type_idx = init_expr->u.array_new_default.type_index;
|
||||
len = init_expr->u.array_new_default.length;
|
||||
arr_init_val = &empty_val;
|
||||
array_init_value = &empty_value;
|
||||
}
|
||||
else {
|
||||
init_values = (WASMArrayNewInitValues *)init_expr->u.data;
|
||||
|
@ -1033,42 +1174,15 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|||
len = init_values->length;
|
||||
|
||||
if (flag == INIT_EXPR_TYPE_ARRAY_NEW) {
|
||||
arr_init_val = init_values->elem_data;
|
||||
array_init_value = init_values->elem_data;
|
||||
}
|
||||
}
|
||||
|
||||
array_type = (WASMArrayType *)module->types[type_idx];
|
||||
|
||||
if (!(rtt_type = wasm_rtt_type_new(
|
||||
(WASMType *)array_type, type_idx, module->rtt_types,
|
||||
module->type_count, &module->rtt_type_lock))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"create rtt object failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(array_obj = wasm_array_obj_new_internal(
|
||||
module_inst->e->common.gc_heap_handle, rtt_type, len,
|
||||
arr_init_val))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"create array object failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
|
||||
uint32 elem_idx;
|
||||
|
||||
bh_assert(init_values);
|
||||
|
||||
for (elem_idx = 0; elem_idx < len; elem_idx++) {
|
||||
wasm_array_obj_set_elem(
|
||||
array_obj, elem_idx,
|
||||
&init_values->elem_data[elem_idx]);
|
||||
}
|
||||
}
|
||||
array_obj = instantiate_array_global_recursive(
|
||||
module, module_inst, type_idx, flag, len, array_init_value,
|
||||
init_values, error_buf, error_buf_size);
|
||||
|
||||
global->initial_value.gc_obj = (void *)array_obj;
|
||||
|
||||
break;
|
||||
}
|
||||
case INIT_EXPR_TYPE_I31_NEW:
|
||||
|
@ -1355,7 +1469,7 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
|
|||
}
|
||||
}
|
||||
|
||||
/* Execute start function for both main insance and sub instance */
|
||||
/* Execute start function for both main instance and sub instance */
|
||||
if (start_func && !wasm_call_function(exec_env, start_func, 0, NULL)) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1408,19 +1522,23 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
#endif
|
||||
WASMExecEnv *exec_env_created = NULL;
|
||||
WASMModuleInstanceCommon *module_inst_old = NULL;
|
||||
uint32 argv[3], argc;
|
||||
union {
|
||||
uint32 u32[3];
|
||||
uint64 u64;
|
||||
} argv;
|
||||
uint32 argc;
|
||||
bool ret;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
bool is_memory64 = module_inst->memories[0]->is_memory64;
|
||||
if (is_memory64) {
|
||||
argc = 2;
|
||||
PUT_I64_TO_ADDR(&argv[0], size);
|
||||
PUT_I64_TO_ADDR(&argv.u64, size);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
argc = 1;
|
||||
argv[0] = size;
|
||||
argv.u32[0] = (uint32)size;
|
||||
}
|
||||
|
||||
/* if __retain is exported, then this module is compiled by
|
||||
|
@ -1431,7 +1549,7 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
/* the malloc function from assemblyscript is:
|
||||
function __new(size: usize, id: u32)
|
||||
id = 0 means this is an ArrayBuffer object */
|
||||
argv[argc] = 0;
|
||||
argv.u32[argc] = 0;
|
||||
argc++;
|
||||
}
|
||||
|
||||
|
@ -1472,10 +1590,10 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
}
|
||||
}
|
||||
|
||||
ret = wasm_call_function(exec_env, malloc_func, argc, argv);
|
||||
ret = wasm_call_function(exec_env, malloc_func, argc, argv.u32);
|
||||
|
||||
if (retain_func && ret)
|
||||
ret = wasm_call_function(exec_env, retain_func, 1, argv);
|
||||
ret = wasm_call_function(exec_env, retain_func, 1, argv.u32);
|
||||
|
||||
if (module_inst_old)
|
||||
/* Restore the existing exec_env's module inst */
|
||||
|
@ -1487,11 +1605,11 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
if (ret) {
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64)
|
||||
*p_result = GET_I64_FROM_ADDR(&argv[0]);
|
||||
*p_result = GET_I64_FROM_ADDR(&argv.u64);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
*p_result = argv[0];
|
||||
*p_result = argv.u32[0];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -1506,18 +1624,22 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
#endif
|
||||
WASMExecEnv *exec_env_created = NULL;
|
||||
WASMModuleInstanceCommon *module_inst_old = NULL;
|
||||
uint32 argv[2], argc;
|
||||
union {
|
||||
uint32 u32[2];
|
||||
uint64 u64;
|
||||
} argv;
|
||||
uint32 argc;
|
||||
bool ret;
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (module_inst->memories[0]->is_memory64) {
|
||||
PUT_I64_TO_ADDR(&argv[0], offset);
|
||||
PUT_I64_TO_ADDR(&argv.u64, offset);
|
||||
argc = 2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
argv[0] = (uint32)offset;
|
||||
argv.u32[0] = (uint32)offset;
|
||||
argc = 1;
|
||||
}
|
||||
|
||||
|
@ -1558,7 +1680,7 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
}
|
||||
}
|
||||
|
||||
ret = wasm_call_function(exec_env, free_func, argc, argv);
|
||||
ret = wasm_call_function(exec_env, free_func, argc, argv.u32);
|
||||
|
||||
if (module_inst_old)
|
||||
/* Restore the existing exec_env's module inst */
|
||||
|
@ -1696,7 +1818,6 @@ wasm_create_func_obj(WASMModuleInstance *module_inst, uint32 func_idx,
|
|||
WASMModule *module = module_inst->module;
|
||||
WASMRttTypeRef rtt_type;
|
||||
WASMFuncObjectRef func_obj;
|
||||
WASMFunctionInstance *func_inst;
|
||||
WASMFuncType *func_type;
|
||||
uint32 type_idx;
|
||||
|
||||
|
@ -1705,17 +1826,22 @@ wasm_create_func_obj(WASMModuleInstance *module_inst, uint32 func_idx,
|
|||
error_buf_size = sizeof(module_inst->cur_exception);
|
||||
}
|
||||
|
||||
if (func_idx >= module_inst->e->function_count) {
|
||||
if (func_idx >= module->import_function_count + module->function_count) {
|
||||
set_error_buf_v(error_buf, error_buf_size, "unknown function %d",
|
||||
func_idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
func_inst = &module_inst->e->functions[func_idx];
|
||||
func_type = func_inst->is_import_func ? func_inst->u.func_import->func_type
|
||||
: func_inst->u.func->func_type;
|
||||
type_idx = func_inst->is_import_func ? func_inst->u.func_import->type_idx
|
||||
: func_inst->u.func->type_idx;
|
||||
if (func_idx < module->import_function_count) {
|
||||
func_type = module->import_functions[func_idx].u.function.func_type;
|
||||
type_idx = module->import_functions[func_idx].u.function.type_idx;
|
||||
}
|
||||
else {
|
||||
func_type = module->functions[func_idx - module->import_function_count]
|
||||
->func_type;
|
||||
type_idx = module->functions[func_idx - module->import_function_count]
|
||||
->type_idx;
|
||||
}
|
||||
|
||||
if (!(rtt_type = wasm_rtt_type_new((WASMType *)func_type, type_idx,
|
||||
module->rtt_types, module->type_count,
|
||||
|
@ -2022,7 +2148,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
* (module->import_memory_count + module->memory_count);
|
||||
|
||||
#if WASM_ENABLE_JIT != 0
|
||||
/* If the module dosen't have memory, reserve one mem_info space
|
||||
/* If the module doesn't have memory, reserve one mem_info space
|
||||
with empty content to align with llvm jit compiler */
|
||||
if (module_inst_mem_inst_size == 0)
|
||||
module_inst_mem_inst_size = (uint64)sizeof(WASMMemoryInstance);
|
||||
|
@ -2356,12 +2482,11 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
(uint64)memory->num_bytes_per_page * memory->cur_page_count;
|
||||
bh_assert(memory_data || memory_size == 0);
|
||||
|
||||
bh_assert(
|
||||
data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
|
||||
|| (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
|
||||
&& !memory->is_memory64)
|
||||
|| (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I64_CONST
|
||||
&& memory->is_memory64));
|
||||
bh_assert(data_seg->base_offset.init_expr_type
|
||||
== INIT_EXPR_TYPE_GET_GLOBAL
|
||||
|| data_seg->base_offset.init_expr_type
|
||||
== (memory->is_memory64 ? INIT_EXPR_TYPE_I64_CONST
|
||||
: INIT_EXPR_TYPE_I32_CONST));
|
||||
|
||||
if (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
|
||||
if (!check_global_init_expr(module,
|
||||
|
@ -3791,13 +3916,13 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst,
|
|||
mem_conspn->app_heap_size += memory->heap_data_end - memory->heap_data;
|
||||
/* size of app heap structure */
|
||||
mem_conspn->memories_size += mem_allocator_get_heap_struct_size();
|
||||
/* Module instance structures have been appened into the end of
|
||||
/* Module instance structures have been appended into the end of
|
||||
module instance */
|
||||
}
|
||||
|
||||
mem_conspn->tables_size =
|
||||
sizeof(WASMTableInstance *) * module_inst->table_count;
|
||||
/* Table instance structures and table elements have been appened into
|
||||
/* Table instance structures and table elements have been appended into
|
||||
the end of module instance */
|
||||
|
||||
mem_conspn->functions_size =
|
||||
|
@ -3805,7 +3930,7 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst,
|
|||
|
||||
mem_conspn->globals_size =
|
||||
sizeof(WASMGlobalInstance) * module_inst->e->global_count;
|
||||
/* Global data has been appened into the end of module instance */
|
||||
/* Global data has been appended into the end of module instance */
|
||||
|
||||
mem_conspn->exports_size =
|
||||
sizeof(WASMExportFuncInstance) * module_inst->export_func_count;
|
||||
|
@ -4176,7 +4301,7 @@ fail:
|
|||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bool
|
||||
llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
|
||||
uint32 offset, uint32 len, uint32 dst)
|
||||
uint32 offset, uint32 len, size_t dst)
|
||||
{
|
||||
WASMMemoryInstance *memory_inst;
|
||||
WASMModule *module;
|
||||
|
@ -4211,7 +4336,7 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
|
|||
(WASMModuleInstanceCommon *)module_inst, (uint64)dst);
|
||||
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
bh_memcpy_s(maddr, (uint32)(memory_inst->memory_data_size - dst),
|
||||
bh_memcpy_s(maddr, CLAMP_U64_TO_U32(memory_inst->memory_data_size - dst),
|
||||
data + offset, len);
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return true;
|
||||
|
|
|
@ -112,7 +112,7 @@ struct WASMMemoryInstance {
|
|||
|
||||
/* Four-byte paddings to ensure the layout of WASMMemoryInstance is the same
|
||||
* in both 64-bit and 32-bit */
|
||||
uint8 __paddings[4];
|
||||
uint8 _paddings[4];
|
||||
|
||||
/* Number bytes per page */
|
||||
uint32 num_bytes_per_page;
|
||||
|
@ -760,7 +760,7 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
|
|||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bool
|
||||
llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
|
||||
uint32 offset, uint32 len, uint32 dst);
|
||||
uint32 offset, uint32 len, size_t dst);
|
||||
|
||||
bool
|
||||
llvm_jit_data_drop(WASMModuleInstance *module_inst, uint32 seg_index);
|
||||
|
|
|
@ -321,10 +321,22 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifndef BUILTIN_LIBC_BUFFERED_PRINTF
|
||||
#define BUILTIN_LIBC_BUFFERED_PRINTF 0
|
||||
#endif
|
||||
|
||||
#ifndef BUILTIN_LIBC_BUFFERED_PRINT_SIZE
|
||||
#define BUILTIN_LIBC_BUFFERED_PRINT_SIZE 128
|
||||
#endif
|
||||
|
||||
struct str_context {
|
||||
char *str;
|
||||
uint32 max;
|
||||
uint32 count;
|
||||
#if BUILTIN_LIBC_BUFFERED_PRINTF != 0
|
||||
char print_buf[BUILTIN_LIBC_BUFFERED_PRINT_SIZE];
|
||||
uint32 print_buf_size;
|
||||
#endif
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -345,41 +357,23 @@ sprintf_out(int c, struct str_context *ctx)
|
|||
return c;
|
||||
}
|
||||
|
||||
#ifndef BUILTIN_LIBC_BUFFERED_PRINTF
|
||||
#define BUILTIN_LIBC_BUFFERED_PRINTF 0
|
||||
#endif
|
||||
|
||||
#ifndef BUILTIN_LIBC_BUFFERED_PRINT_SIZE
|
||||
#define BUILTIN_LIBC_BUFFERED_PRINT_SIZE 128
|
||||
#endif
|
||||
#ifndef BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
|
||||
#define BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
|
||||
#endif
|
||||
|
||||
#if BUILTIN_LIBC_BUFFERED_PRINTF != 0
|
||||
|
||||
BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
|
||||
static char print_buf[BUILTIN_LIBC_BUFFERED_PRINT_SIZE] = { 0 };
|
||||
|
||||
BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
|
||||
static int print_buf_size = 0;
|
||||
|
||||
static int
|
||||
printf_out(int c, struct str_context *ctx)
|
||||
{
|
||||
if (c == '\n') {
|
||||
print_buf[print_buf_size] = '\0';
|
||||
os_printf("%s\n", print_buf);
|
||||
print_buf_size = 0;
|
||||
ctx->print_buf[ctx->print_buf_size] = '\0';
|
||||
os_printf("%s\n", ctx->print_buf);
|
||||
ctx->print_buf_size = 0;
|
||||
}
|
||||
else if (print_buf_size >= sizeof(print_buf) - 2) {
|
||||
print_buf[print_buf_size++] = (char)c;
|
||||
print_buf[print_buf_size] = '\0';
|
||||
os_printf("%s\n", print_buf);
|
||||
print_buf_size = 0;
|
||||
else if (ctx->print_buf_size >= sizeof(ctx->print_buf) - 2) {
|
||||
ctx->print_buf[ctx->print_buf_size++] = (char)c;
|
||||
ctx->print_buf[ctx->print_buf_size] = '\0';
|
||||
os_printf("%s\n", ctx->print_buf);
|
||||
ctx->print_buf_size = 0;
|
||||
}
|
||||
else {
|
||||
print_buf[print_buf_size++] = (char)c;
|
||||
ctx->print_buf[ctx->print_buf_size++] = (char)c;
|
||||
}
|
||||
ctx->count++;
|
||||
return c;
|
||||
|
@ -398,7 +392,9 @@ static int
|
|||
printf_wrapper(wasm_exec_env_t exec_env, const char *format, _va_list va_args)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
struct str_context ctx = { NULL, 0, 0 };
|
||||
struct str_context ctx = { 0 };
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
||||
/* format has been checked by runtime */
|
||||
if (!validate_native_addr(va_args, (uint64)sizeof(int32)))
|
||||
|
@ -408,6 +404,11 @@ printf_wrapper(wasm_exec_env_t exec_env, const char *format, _va_list va_args)
|
|||
module_inst))
|
||||
return 0;
|
||||
|
||||
#if BUILTIN_LIBC_BUFFERED_PRINTF != 0
|
||||
if (ctx.print_buf_size > 0)
|
||||
os_printf("%s", ctx.print_buf);
|
||||
#endif
|
||||
|
||||
return (int)ctx.count;
|
||||
}
|
||||
|
||||
|
@ -1001,6 +1002,12 @@ print_i32_wrapper(wasm_exec_env_t exec_env, int32 i32)
|
|||
os_printf("in specttest.print_i32(%" PRId32 ")\n", i32);
|
||||
}
|
||||
|
||||
static void
|
||||
print_i64_wrapper(wasm_exec_env_t exec_env, int64 i64)
|
||||
{
|
||||
os_printf("in specttest.print_i64(%" PRId32 ")\n", i64);
|
||||
}
|
||||
|
||||
static void
|
||||
print_i32_f32_wrapper(wasm_exec_env_t exec_env, int32 i32, float f32)
|
||||
{
|
||||
|
@ -1091,6 +1098,7 @@ static NativeSymbol native_symbols_libc_builtin[] = {
|
|||
static NativeSymbol native_symbols_spectest[] = {
|
||||
REG_NATIVE_FUNC(print, "()"),
|
||||
REG_NATIVE_FUNC(print_i32, "(i)"),
|
||||
REG_NATIVE_FUNC(print_i64, "(I)"),
|
||||
REG_NATIVE_FUNC(print_i32_f32, "(if)"),
|
||||
REG_NATIVE_FUNC(print_f64_f64, "(FF)"),
|
||||
REG_NATIVE_FUNC(print_f32, "(f)"),
|
||||
|
@ -1136,6 +1144,7 @@ static WASMNativeGlobalDef native_global_defs[] = {
|
|||
{ "test", "global-f32", VALUE_TYPE_F32, false, .value.f32 = 0 },
|
||||
{ "test", "global-mut-i32", VALUE_TYPE_I32, true, .value.i32 = 0 },
|
||||
{ "test", "global-mut-i64", VALUE_TYPE_I64, true, .value.i64 = 0 },
|
||||
{ "test", "g", VALUE_TYPE_I32, true, .value.i32 = 0 },
|
||||
#if WASM_ENABLE_GC != 0
|
||||
{ "G", "g", VALUE_TYPE_I32, false, .value.i32 = 4 },
|
||||
{ "M", "g", REF_TYPE_HT_NON_NULLABLE, false, .value.gc_obj = 0 },
|
||||
|
@ -1161,8 +1170,8 @@ wasm_native_lookup_libc_builtin_global(const char *module_name,
|
|||
while (global_def < global_def_end) {
|
||||
if (!strcmp(global_def->module_name, module_name)
|
||||
&& !strcmp(global_def->global_name, global_name)) {
|
||||
global->type = global_def->type;
|
||||
global->is_mutable = global_def->is_mutable;
|
||||
global->type.val_type = global_def->type;
|
||||
global->type.is_mutable = global_def->is_mutable;
|
||||
global->global_data_linked = global_def->value;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -650,8 +650,10 @@ fd_table_insert(wasm_exec_env_t exec_env, struct fd_table *ft,
|
|||
|
||||
__wasi_errno_t error = fd_table_unused(ft, out);
|
||||
|
||||
if (error != __WASI_ESUCCESS)
|
||||
if (error != __WASI_ESUCCESS) {
|
||||
rwlock_unlock(&ft->lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
fd_table_attach(ft, *out, fo, rights_base, rights_inheriting);
|
||||
rwlock_unlock(&ft->lock);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "gnuc.h"
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) \
|
||||
|| (defined(ANDROID) && __ANDROID_API__ < 28)
|
||||
|| ((defined(ANDROID) || defined(__ANDROID__)) && (__ANDROID_API__ < 28))
|
||||
#define CONFIG_HAS_ARC4RANDOM_BUF 1
|
||||
#else
|
||||
#define CONFIG_HAS_ARC4RANDOM_BUF 0
|
||||
|
@ -26,9 +26,17 @@
|
|||
|
||||
// On Linux, prefer to use getrandom, though it isn't available in
|
||||
// GLIBC before 2.25.
|
||||
#if (defined(__linux__) || defined(ESP_PLATFORM) || defined(__COSMOPOLITAN__)) \
|
||||
&& (!defined(__GLIBC__) || __GLIBC__ > 2 \
|
||||
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
|
||||
//
|
||||
// NuttX has arc4random_buf, getrandom, and /dev/urandom.
|
||||
// We prefer getrandom here because it has the best chance to be usable.
|
||||
// - Our /dev/urandom usage (keep the open descriptor in a global variable)
|
||||
// is not compatible with NuttX flat memory model.
|
||||
// - arc4random_buf is only available with CONFIG_CRYPTO_RANDOM_POOL=y.
|
||||
#if defined(__NuttX__) \
|
||||
|| ((defined(__linux__) || defined(ESP_PLATFORM) \
|
||||
|| defined(__COSMOPOLITAN__)) \
|
||||
&& (!defined(__GLIBC__) || __GLIBC__ > 2 \
|
||||
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))
|
||||
#define CONFIG_HAS_GETRANDOM 1
|
||||
#else
|
||||
#define CONFIG_HAS_GETRANDOM 0
|
||||
|
|
|
@ -1194,7 +1194,7 @@ wait_for_thread_visitor(void *node, void *user_data)
|
|||
}
|
||||
|
||||
void
|
||||
wams_cluster_wait_for_all(WASMCluster *cluster)
|
||||
wasm_cluster_wait_for_all(WASMCluster *cluster)
|
||||
{
|
||||
os_mutex_lock(&cluster->lock);
|
||||
cluster->processing = true;
|
||||
|
|
|
@ -45,7 +45,7 @@ struct WASMCluster {
|
|||
* requests. This is a short-lived state, must be cleared immediately once
|
||||
* the processing finished.
|
||||
* This is used to avoid dead lock when one thread waiting another thread
|
||||
* with lock, see wams_cluster_wait_for_all and wasm_cluster_terminate_all
|
||||
* with lock, see wasm_cluster_wait_for_all and wasm_cluster_terminate_all
|
||||
*/
|
||||
bool processing;
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
|
@ -135,7 +135,7 @@ wasm_cluster_terminate_all_except_self(WASMCluster *cluster,
|
|||
WASMExecEnv *exec_env);
|
||||
|
||||
void
|
||||
wams_cluster_wait_for_all(WASMCluster *cluster);
|
||||
wasm_cluster_wait_for_all(WASMCluster *cluster);
|
||||
|
||||
void
|
||||
wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
|
||||
|
|
|
@ -70,7 +70,10 @@ typedef enum {
|
|||
GC_STAT_MAX
|
||||
} GC_STAT_INDEX;
|
||||
|
||||
#ifndef GC_FINALIZER_T_DEFINED
|
||||
#define GC_FINALIZER_T_DEFINED
|
||||
typedef void (*gc_finalizer_t)(void *obj, void *data);
|
||||
#endif
|
||||
|
||||
#ifndef EXTRA_INFO_NORMAL_NODE_CNT
|
||||
#define EXTRA_INFO_NORMAL_NODE_CNT 32
|
||||
|
|
|
@ -17,7 +17,10 @@ extern "C" {
|
|||
|
||||
typedef void *mem_allocator_t;
|
||||
|
||||
#ifndef GC_FINALIZER_T_DEFINED
|
||||
#define GC_FINALIZER_T_DEFINED
|
||||
typedef void (*gc_finalizer_t)(void *obj, void *data);
|
||||
#endif
|
||||
|
||||
mem_allocator_t
|
||||
mem_allocator_create(void *mem, uint32_t size);
|
||||
|
|
|
@ -10,46 +10,6 @@
|
|||
#include <nuttx/arch.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_CHIP_ESP32S3)
|
||||
/*
|
||||
* TODO: Move these methods below the operating system level
|
||||
*/
|
||||
#define MEM_DUAL_BUS_OFFSET (0x42000000 - 0x3C000000)
|
||||
#define IRAM0_CACHE_ADDRESS_LOW 0x42000000
|
||||
#define IRAM0_CACHE_ADDRESS_HIGH 0x44000000
|
||||
#define IRAM_ATTR locate_data(".iram1")
|
||||
|
||||
#define in_ibus_ext(addr) \
|
||||
(((uint32)addr >= IRAM0_CACHE_ADDRESS_LOW) \
|
||||
&& ((uint32)addr < IRAM0_CACHE_ADDRESS_HIGH))
|
||||
void IRAM_ATTR
|
||||
bus_sync(void)
|
||||
{
|
||||
extern void cache_writeback_all(void);
|
||||
extern uint32_t Cache_Disable_ICache(void);
|
||||
extern void Cache_Enable_ICache(uint32_t autoload);
|
||||
|
||||
irqstate_t flags;
|
||||
uint32_t preload;
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
cache_writeback_all();
|
||||
preload = Cache_Disable_ICache();
|
||||
Cache_Enable_ICache(preload);
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
#else
|
||||
#define MEM_DUAL_BUS_OFFSET (0)
|
||||
#define IRAM0_CACHE_ADDRESS_LOW (0)
|
||||
#define IRAM0_CACHE_ADDRESS_HIGH (0)
|
||||
#define in_ibus_ext(addr) (0)
|
||||
static void
|
||||
bus_sync(void)
|
||||
{}
|
||||
#endif
|
||||
|
||||
int
|
||||
bh_platform_init()
|
||||
{
|
||||
|
@ -88,15 +48,18 @@ void *
|
|||
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||
{
|
||||
void *p;
|
||||
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
||||
void *i_addr, *d_addr;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
||||
if ((prot & MMAP_PROT_EXEC) != 0) {
|
||||
p = up_textheap_memalign(sizeof(void *), size);
|
||||
if (p) {
|
||||
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
||||
void *dp = os_get_dbus_mirror(p);
|
||||
memset(dp, 0, size);
|
||||
os_dcache_flush();
|
||||
#else
|
||||
memset(p, 0, size);
|
||||
#endif
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
@ -105,20 +68,6 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
|||
if ((uint64)size >= UINT32_MAX)
|
||||
return NULL;
|
||||
|
||||
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
||||
if ((prot & MMAP_PROT_EXEC) != 0) {
|
||||
d_addr = malloc((uint32)size);
|
||||
if (d_addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
i_addr = (void *)((uint8 *)d_addr + MEM_DUAL_BUS_OFFSET);
|
||||
p = in_ibus_ext(i_addr) ? i_addr : d_addr;
|
||||
if (p) {
|
||||
memset(p, 0, size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
/* Note: aot_loader.c assumes that os_mmap provides large enough
|
||||
* alignment for any data sections. Some sections like rodata.cst32
|
||||
* actually require alignment larger than the natural alignment
|
||||
|
@ -150,12 +99,6 @@ os_munmap(void *addr, size_t size)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
||||
if (in_ibus_ext(addr)) {
|
||||
free((void *)((uint8 *)addr - MEM_DUAL_BUS_OFFSET));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
free(addr);
|
||||
}
|
||||
|
||||
|
@ -168,7 +111,10 @@ os_mprotect(void *addr, size_t size, int prot)
|
|||
void
|
||||
os_dcache_flush()
|
||||
{
|
||||
bus_sync();
|
||||
#if defined(CONFIG_ARCH_USE_TEXT_HEAP) \
|
||||
&& defined(CONFIG_ARCH_HAVE_TEXT_HEAP_SEPARATE_DATA_ADDRESS)
|
||||
up_textheap_data_sync();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -179,12 +125,12 @@ os_icache_flush(void *start, size_t len)
|
|||
void *
|
||||
os_get_dbus_mirror(void *ibus)
|
||||
{
|
||||
if (in_ibus_ext(ibus)) {
|
||||
return (void *)((uint8 *)ibus - MEM_DUAL_BUS_OFFSET);
|
||||
}
|
||||
else {
|
||||
return ibus;
|
||||
}
|
||||
#if defined(CONFIG_ARCH_USE_TEXT_HEAP) \
|
||||
&& defined(CONFIG_ARCH_HAVE_TEXT_HEAP_SEPARATE_DATA_ADDRESS)
|
||||
return up_textheap_data_address(ibus);
|
||||
#else
|
||||
return ibus;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
/**
|
||||
* The verbose level of the log system. Only those verbose logs whose
|
||||
* levels are less than or equal to this value are outputed.
|
||||
* levels are less than or equal to this value are output.
|
||||
*/
|
||||
static uint32 log_verbose_level = BH_LOG_LEVEL_WARNING;
|
||||
|
||||
|
@ -38,7 +38,7 @@ bh_log(LogLevel log_level, const char *file, int line, const char *fmt, ...)
|
|||
t = t % (60 * 60);
|
||||
m = t / 60;
|
||||
s = t % 60;
|
||||
mills = (uint32)(usec % 1000);
|
||||
mills = (uint32)((usec % 1000000) / 1000);
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ":%03" PRIu32, h, m, s,
|
||||
|
|
|
@ -79,7 +79,7 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
|
|||
#### **Enable memory64 feature**
|
||||
- **WAMR_BUILD_MEMORY64**=1/0, default to disable if not set
|
||||
|
||||
> Note: Currently, the memory64 feature is only supported in classic interpreter running mode.
|
||||
> Note: Currently, the memory64 feature is only supported in classic interpreter running mode and AOT mode.
|
||||
|
||||
#### **Enable thread manager**
|
||||
- **WAMR_BUILD_THREAD_MGR**=1/0, default to disable if not set
|
||||
|
@ -137,7 +137,7 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
|
|||
#### **Enable Exception Handling**
|
||||
- **WAMR_BUILD_EXCE_HANDLING**=1/0, default to disable if not set
|
||||
|
||||
> Note: Currently, the exception handling feature is only supported in classic interpreter running mode.
|
||||
> Note: Currently, the exception handling feature is only supported in classic interpreter running mode.
|
||||
|
||||
#### **Enable Garbage Collection**
|
||||
- **WAMR_BUILD_GC**=1/0, default to disable if not set
|
||||
|
@ -210,7 +210,7 @@ Currently we only profile the memory consumption of module, module_instance and
|
|||
> }
|
||||
> ```
|
||||
>
|
||||
> and then use `cmake -DWAMR_BH_VPRINTF=my_vprintf ..` to pass the callback function, or add `BH_VPRINTF=my_vprintf` macro for the compiler, e.g. add line `add_defintions(-DBH_VPRINTF=my_vprintf)` in CMakeListst.txt. See [basic sample](../samples/basic/src/main.c) for a usage example.
|
||||
> and then use `cmake -DWAMR_BH_VPRINTF=my_vprintf ..` to pass the callback function, or add `BH_VPRINTF=my_vprintf` macro for the compiler, e.g. add line `add_definitions(-DBH_VPRINTF=my_vprintf)` in CMakeLists.txt. See [basic sample](../samples/basic/src/main.c) for a usage example.
|
||||
|
||||
#### **WAMR_BH_LOG**=<log_callback>, default to disable if not set
|
||||
> Note: if the log_callback function is provided by the developer, WAMR logs are redirected to such callback. For example:
|
||||
|
@ -285,8 +285,8 @@ Currently we only profile the memory consumption of module, module_instance and
|
|||
- **WAMR_BUILD_AOT_INTRINSICS**=1/0, enable the AOT intrinsic functions, default to enable if not set. These functions can be called from the AOT code when `--disable-llvm-intrinsics` flag or `--enable-builtin-intrinsics=<intr1,intr2,...>` flag is used by wamrc to generate the AOT file.
|
||||
> Note: See [Tuning the XIP intrinsic functions](./xip.md#tuning-the-xip-intrinsic-functions) for more details.
|
||||
|
||||
#### **Configurale memory access boundary check**
|
||||
- **WAMR_CONFIGUABLE_BOUNDS_CHECKS**=1/0, default to disable if not set
|
||||
#### **Configurable memory access boundary check**
|
||||
- **WAMR_CONFIGURABLE_BOUNDS_CHECKS**=1/0, default to disable if not set
|
||||
> Note: If it is enabled, allow to run `iwasm --disable-bounds-checks` to disable the memory access boundary checks for interpreter mode.
|
||||
|
||||
#### **Module instance context APIs**
|
||||
|
|
|
@ -207,7 +207,7 @@ There are two runtime APIs available for this purpose.
|
|||
/**
|
||||
* malloc a buffer from instance's private memory space.
|
||||
*
|
||||
* return: the buffer address in instance's memory space (pass to the WASM funciton)
|
||||
* return: the buffer address in instance's memory space (pass to the WASM function)
|
||||
* p_native_addr: return the native address of allocated memory
|
||||
* size: the buffer size to allocate
|
||||
*/
|
||||
|
@ -219,7 +219,7 @@ wasm_runtime_module_malloc(wasm_module_inst_t module_inst,
|
|||
* malloc a buffer from instance's private memory space,
|
||||
* and copy the data from another native buffer to it.
|
||||
*
|
||||
* return: the buffer address in instance's memory space (pass to the WASM funciton)
|
||||
* return: the buffer address in instance's memory space (pass to the WASM function)
|
||||
* src: the native buffer address
|
||||
* size: the size of buffer to be allocated and copy data
|
||||
*/
|
||||
|
|
|
@ -36,7 +36,7 @@ void foo2(wasm_exec_env_t exec_env, char * msg, uint8 * buffer, int buf_len)
|
|||
}
|
||||
```
|
||||
|
||||
The first parameter exec_env must be defined using type **wasm_exec_env_t** which is the calling convention by WAMR.
|
||||
The first parameter exec_env must be defined using type **wasm_exec_env_t** which is the calling convention by WAMR.
|
||||
|
||||
The rest parameters should be in the same types as the parameters of WASM function foo(), but there are a few special cases that are explained in section "Buffer address conversion and boundary check". Regarding the parameter names, they don't have to be the same, but we would suggest using the same names for easy maintenance.
|
||||
|
||||
|
@ -47,10 +47,10 @@ The rest parameters should be in the same types as the parameters of WASM functi
|
|||
Register the native APIs in the runtime, then everything is fine. It is ready to build the runtime software.
|
||||
|
||||
``` C
|
||||
// Define an array of NativeSymbol for the APIs to be exported.
|
||||
// Define an array of NativeSymbol for the APIs to be exported.
|
||||
// Note: the array must be static defined since runtime
|
||||
// will keep it after registration
|
||||
static NativeSymbol native_symbols[] =
|
||||
static NativeSymbol native_symbols[] =
|
||||
{
|
||||
{
|
||||
"foo", // the name of WASM function name
|
||||
|
@ -61,7 +61,7 @@ static NativeSymbol native_symbols[] =
|
|||
"foo2", // the name of WASM function name
|
||||
foo2, // the native function pointer
|
||||
"($*~)" // the function prototype signature
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// initialize the runtime before registering the native functions
|
||||
|
@ -69,12 +69,12 @@ wasm_runtime_init();
|
|||
|
||||
int n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol);
|
||||
if (!wasm_runtime_register_natives("env",
|
||||
native_symbols,
|
||||
native_symbols,
|
||||
n_native_symbols)) {
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
// natives registeration must be done before loading WASM modules
|
||||
// natives registration must be done before loading WASM modules
|
||||
module = wasm_runtime_load(buffer, size, error_buf, sizeof(error_buf));
|
||||
|
||||
```
|
||||
|
@ -86,7 +86,7 @@ The function signature field in **NativeSymbol** structure is a string for descr
|
|||
Each letter in the "()" represents a parameter type, and the one following after ")" represents the return value type. The meaning of each letter:
|
||||
|
||||
- '**i**': i32
|
||||
- '**I**': i64
|
||||
- '**I**': i64
|
||||
- '**f**': f32
|
||||
- '**F**': f64
|
||||
- '**r**': externref (has to be the value of a `uintptr_t` variable), or all kinds of GC reference types when GC feature is enabled
|
||||
|
@ -101,13 +101,13 @@ The signature can defined as NULL, then all function parameters are assumed as i
|
|||
The `NativeSymbol` element for `foo2 ` above can be also defined with macro EXPORT_WASM_API_WITH_SIG. This macro can be used when the native function name is the same as the WASM symbol name.
|
||||
|
||||
```c
|
||||
static NativeSymbol native_symbols[] =
|
||||
static NativeSymbol native_symbols[] =
|
||||
{
|
||||
EXPORT_WASM_API_WITH_SIG(foo2, "($*~)") // wasm symbol name will be "foo2"
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Call exported API in WASM application
|
||||
|
||||
|
@ -124,7 +124,7 @@ int main(int argc, char **argv)
|
|||
|
||||
int c = foo(a, b); // call into native foo_native()
|
||||
foo2(msg, buffer, sizeof(buffer)); // call into native foo2()
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
@ -157,9 +157,9 @@ As function parameters are always passed in 32 bits numbers, you can also use 'i
|
|||
// for buffer address or string parameters, here
|
||||
// is how to do address conversion and boundary check manually
|
||||
//
|
||||
void foo2(wasm_exec_env_t exec_env,
|
||||
uint32 msg_offset,
|
||||
uint32 buffer_offset,
|
||||
void foo2(wasm_exec_env_t exec_env,
|
||||
uint32 msg_offset,
|
||||
uint32 buffer_offset,
|
||||
int32 buf_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
|
@ -169,7 +169,7 @@ void foo2(wasm_exec_env_t exec_env,
|
|||
// do boundary check
|
||||
if (!wasm_runtime_validate_app_str_add(msg_offset))
|
||||
return 0;
|
||||
|
||||
|
||||
if (!wasm_runtime_validate_app_addr((uint64)buffer_offset, (uint64)buf_len))
|
||||
return;
|
||||
|
||||
|
@ -187,7 +187,7 @@ void foo2(wasm_exec_env_t exec_env,
|
|||
|
||||
## Sandbox security attention
|
||||
|
||||
The runtime builder should ensure not broking the memory sandbox when exporting the native function to WASM.
|
||||
The runtime builder should ensure not broking the memory sandbox when exporting the native function to WASM.
|
||||
|
||||
A ground rule:
|
||||
|
||||
|
@ -196,7 +196,7 @@ A ground rule:
|
|||
A few recommendations:
|
||||
|
||||
- Never pass any structure/class object pointer to native (do data serialization instead)
|
||||
- Never pass a function pointer to the native
|
||||
- Never pass a function pointer to the native
|
||||
|
||||
Note: while not recommended here, nothing prevents you from passing
|
||||
structure/function pointers as far as the native API is aware of
|
||||
|
|
|
@ -30,3 +30,5 @@ Normally there are some methods to tune the memory usage:
|
|||
- set the app heap size with `wasm_runtime_instantiate`
|
||||
- use `nostdlib` mode, add `-Wl,--strip-all`: refer to [How to reduce the footprint](./build_wasm_app.md#2-how-to-reduce-the-footprint) of building wasm app for more details
|
||||
- use XIP mode, refer to [WAMR XIP (Execution In Place) feature introduction](./xip.md) for more details
|
||||
- when using the Wasm C API in fast interpreter or AOT mode, set `clone_wasm_binary=false` in `LoadArgs` and free the wasm binary buffer (with `wasm_byte_vec_delete`) after module loading; `wasm_module_is_underlying_binary_freeable` can be queried to check if the wasm binary buffer can be safely freed (see [the example](../samples/basic/src/free_buffer_early.c)); after the buffer is freed, `wasm_runtime_get_custom_section` cannot be called anymore
|
||||
- when using the wasm/AOT loader in fast interpreter or AOT mode, set `wasm_binary_freeable=true` in `LoadArgs` and free the wasm binary buffer (with `wasm_byte_vec_delete`) after module loading; `wasm_runtime_is_underlying_binary_freeable` can be queried to check if the wasm binary buffer can be safely freed; after the buffer is freed, `wasm_runtime_get_custom_section` cannot be called anymore
|
||||
|
|
|
@ -48,7 +48,7 @@ A WASM linear memory is either shared or non-shared.
|
|||
A WASM linear memory has `min` and `max` sizes.
|
||||
(They correspond to `wasm-ld`'s `--init-memory` and `--max-memory` options.)
|
||||
They are in the number of WASM pages, each of which is of 65536 bytes.
|
||||
The `max` is optional for non-shared memory. When omitted, it effectivily
|
||||
The `max` is optional for non-shared memory. When omitted, it effectively
|
||||
means unlimited.
|
||||
|
||||
The linear memory is allocated via `os_mmap` and `os_mem_commit`/`os_mprotect`.
|
||||
|
|
|
@ -84,7 +84,7 @@ Developer can refer to the `test_pgo.sh` files under each benchmark folder for m
|
|||
|
||||
Please notice that this method is not a general solution since it may lead to security issues. And only boost the performance for some platforms in AOT mode and don't support hardware trap for memory boundary check.
|
||||
|
||||
1. Build WAMR with `-DWAMR_CONFIGUABLE_BOUNDS_CHECKS=1` option.
|
||||
1. Build WAMR with `-DWAMR_CONFIGURABLE_BOUNDS_CHECKS=1` option.
|
||||
|
||||
2. Compile AOT module by wamrc with `--bounds-check=0` option.
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ make
|
|||
```
|
||||
|
||||
|
||||
## Aux stack seperation
|
||||
## Aux stack separation
|
||||
The compiler may use some spaces in the linear memory as an auxiliary stack. When pthread is enabled, every thread should have its own aux stack space, so the total aux stack space reserved by the compiler will be divided into N + 1 parts, where N is the maximum number of threads that can be created by the user code.
|
||||
|
||||
The default value of N is 4, which means you can create 4 threads at most. This value can be changed by an option if you are using product-mini:
|
||||
|
|
|
@ -13,7 +13,7 @@ There are three parts in the new version string:
|
|||
|
||||
## Legacy versions
|
||||
|
||||
All legacy versions(tags) will keep their current status. No existed releasings names
|
||||
All legacy versions(tags) will keep their current status. No existing release names
|
||||
and links will be changed.
|
||||
|
||||
## Reference
|
||||
|
|
|
@ -13,8 +13,8 @@ llvm-dwarfdump-12 test.wasm
|
|||
|
||||
## Debugging with interpreter
|
||||
|
||||
See [Debuggging with interpreter](source_debugging_interpreter.md).
|
||||
See [Debugging with interpreter](source_debugging_interpreter.md).
|
||||
|
||||
## Debugging with AOT
|
||||
|
||||
See [Debuggging with AOT](source_debugging_aot.md).
|
||||
See [Debugging with AOT](source_debugging_aot.md).
|
||||
|
|
|
@ -31,7 +31,7 @@ are helpful.
|
|||
- call `wasm_engine_new` or `wasm_engine_delete` multiple times in
|
||||
different threads
|
||||
|
||||
## unspported list
|
||||
## unsupported list
|
||||
|
||||
Currently WAMR supports most of the APIs, the unsupported APIs are listed as below:
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ func (self *Instance) CallFuncV(funcName string,
|
|||
case int32:
|
||||
if (param_types[i] != C.WASM_I32 &&
|
||||
param_types[i] != C.WASM_FUNCREF &&
|
||||
param_types[i] != C.WASM_ANYREF) {
|
||||
param_types[i] != C.WASM_EXTERNREF) {
|
||||
str := "CallFunc error: invalid param type %d, " +
|
||||
"expect i32 but got other"
|
||||
return fmt.Errorf(str, param_types[i])
|
||||
|
@ -273,7 +273,7 @@ func (self *Instance) CallFuncV(funcName string,
|
|||
fallthrough
|
||||
case C.WASM_FUNCREF:
|
||||
fallthrough
|
||||
case C.WASM_ANYREF:
|
||||
case C.WASM_EXTERNREF:
|
||||
i32 := (int32)(argv[argc])
|
||||
results[i] = i32
|
||||
argc++
|
||||
|
|
|
@ -213,7 +213,7 @@ WASM_I32 = 0
|
|||
WASM_I64 = 1
|
||||
WASM_F32 = 2
|
||||
WASM_F64 = 3
|
||||
WASM_ANYREF = 128
|
||||
WASM_EXTERNREF = 128
|
||||
WASM_FUNCREF = 129
|
||||
|
||||
def wasm_valtype_new(arg0):
|
||||
|
|
|
@ -180,7 +180,7 @@ def __repr_wasm_valtype_t(self):
|
|||
elif WASM_FUNCREF == val_kind:
|
||||
return "funcref"
|
||||
else:
|
||||
return "anyref"
|
||||
return "externref"
|
||||
|
||||
|
||||
wasm_valtype_t.__eq__ = __compare_wasm_valtype_t
|
||||
|
@ -406,7 +406,7 @@ def __compare_wasm_val_t(self, other):
|
|||
return self.of.f32 == other.of.f32
|
||||
elif WASM_F64 == self.kind:
|
||||
return self.of.f64 == other.of.f63
|
||||
elif WASM_ANYREF == self.kind:
|
||||
elif WASM_EXTERNREF == self.kind:
|
||||
raise RuntimeError("FIXME")
|
||||
else:
|
||||
raise RuntimeError("not a valid val kind")
|
||||
|
@ -421,8 +421,8 @@ def __repr_wasm_val_t(self):
|
|||
return f"f32 {self.of.f32}"
|
||||
elif WASM_F64 == self.kind:
|
||||
return f"f64 {self.of.f64}"
|
||||
elif WASM_ANYREF == self.kind:
|
||||
return f"anyref {self.of.ref}"
|
||||
elif WASM_EXTERNREF == self.kind:
|
||||
return f"externref {self.of.ref}"
|
||||
else:
|
||||
raise RuntimeError("not a valid val kind")
|
||||
|
||||
|
|
|
@ -70,11 +70,11 @@ Create a corresponding concept for every native structured data type includes
|
|||
|
||||
#### Enum types
|
||||
|
||||
For example, if there is a `enum wams_mutability_enum` in native.
|
||||
For example, if there is a `enum wasm_mutability_enum` in native.
|
||||
|
||||
```c
|
||||
typedef uint8_t wams_mutability_t;
|
||||
enum wams_mutability_enum {
|
||||
typedef uint8_t wasm_mutability_t;
|
||||
enum wasm_mutability_enum {
|
||||
WASM_CONST,
|
||||
WASM_VAR
|
||||
};
|
||||
|
@ -83,7 +83,7 @@ enum wams_mutability_enum {
|
|||
Use `ctypes.int`(or any integer types in ctypes) to represents its value directly.
|
||||
|
||||
```python
|
||||
# represents enum wams_mutability_enum
|
||||
# represents enum wasm_mutability_enum
|
||||
wasm_mutability_t = c_uint8
|
||||
|
||||
WASM_CONST = 0
|
||||
|
|
|
@ -61,7 +61,7 @@ class BasicTestSuite(unittest.TestCase):
|
|||
|
||||
def test_wasm_valkind(self):
|
||||
self.assertEqual(
|
||||
[WASM_I32, WASM_I64, WASM_F32, WASM_F64, WASM_ANYREF, WASM_FUNCREF],
|
||||
[WASM_I32, WASM_I64, WASM_F32, WASM_F64, WASM_EXTERNREF, WASM_FUNCREF],
|
||||
[0, 1, 2, 3, 128, 129],
|
||||
)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
iwasm is the executable binary built with WAMR VMcore supports WASI and command line interface. Refer to [**how to build wamr vmcore**](../doc/build_wamr.md) for all the supported CMAKE compilation variables.
|
||||
|
||||
If you are building for ARM architecture on a X86 development machine, you can use the `CMAKE_TOOLCHAIN_FILE` to set the toolchain file for cross compling.
|
||||
If you are building for ARM architecture on a X86 development machine, you can use the `CMAKE_TOOLCHAIN_FILE` to set the toolchain file for cross compiling.
|
||||
|
||||
```
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=$TOOL_CHAIN_FILE \
|
||||
|
|
|
@ -111,6 +111,7 @@ $(NAME)_SOURCES := ${SHARED_ROOT}/platform/alios/alios_platform.c \
|
|||
${IWASM_ROOT}/common/wasm_runtime_common.c \
|
||||
${IWASM_ROOT}/common/wasm_native.c \
|
||||
${IWASM_ROOT}/common/wasm_exec_env.c \
|
||||
${IWASM_ROOT}/common/wasm_loader_common.c \
|
||||
${IWASM_ROOT}/common/wasm_memory.c \
|
||||
${IWASM_ROOT}/common/wasm_c_api.c \
|
||||
${IWASM_ROOT}/common/arch/${INVOKE_NATIVE} \
|
||||
|
|
|
@ -157,7 +157,7 @@ align_ptr(const uint8 *p, uint32 b)
|
|||
}
|
||||
|
||||
#define AOT_SECTION_TYPE_TARGET_INFO 0
|
||||
#define AOT_SECTION_TYPE_SIGANATURE 6
|
||||
#define AOT_SECTION_TYPE_SIGNATURE 6
|
||||
#define E_TYPE_XIP 4
|
||||
|
||||
#define CHECK_BUF(buf, buf_end, length) \
|
||||
|
@ -205,7 +205,7 @@ is_xip_file(const uint8 *buf, uint32 size)
|
|||
read_uint16(p, p_end, e_type);
|
||||
return (e_type == E_TYPE_XIP) ? true : false;
|
||||
}
|
||||
else if (section_type >= AOT_SECTION_TYPE_SIGANATURE) {
|
||||
else if (section_type >= AOT_SECTION_TYPE_SIGNATURE) {
|
||||
return false;
|
||||
}
|
||||
p += section_size;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user