Merge pull request #2600 from bytecodealliance/main

Merge branch main into dev/exce_handling
This commit is contained in:
Wenyong Huang 2023-09-27 16:05:19 +08:00 committed by GitHub
commit 95b19a587e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
204 changed files with 8879 additions and 3463 deletions

View File

@ -1,20 +1,21 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.195.0/containers/cpp/.devcontainer/base.Dockerfile # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/cpp/.devcontainer/base.Dockerfile
# [Choice] Debian / Ubuntu version (use Debian 11/9, Ubuntu 18.04/21.04 on local arm64/Apple Silicon): debian-11, debian-10, debian-9, ubuntu-21.04, ubuntu-20.04, ubuntu-18.04 # [Choice] Debian / Ubuntu version (use Debian 12/11/9, Ubuntu 18.04/21.04 on local arm64/Apple Silicon): debian-12, debian-11, debian-10, debian-9, ubuntu-21.04, ubuntu-20.04, ubuntu-18.04
ARG VARIANT=ubuntu-20.04 ARG VARIANT=debian-12
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT} FROM mcr.microsoft.com/vscode/devcontainers/cpp:${VARIANT}
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asian/Shanghai ENV TZ=Asian/Shanghai
# hadolint ignore=DL3008 # hadolint ignore=DL3008
RUN apt-get update \ RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y apt-transport-https apt-utils build-essential \ && apt-get install -y apt-transport-https apt-utils build-essential \
ca-certificates ccache curl g++-multilib git gnupg \ ca-certificates ccache cmake curl g++-multilib git gnupg \
libgcc-9-dev lib32gcc-9-dev lsb-release \ libgcc-12-dev lib32gcc-12-dev lsb-release \
ninja-build ocaml ocamlbuild python2.7 \ ninja-build ocaml ocamlbuild \
software-properties-common tree tzdata \ software-properties-common tree tzdata \
unzip valgrind vim wget zip --no-install-recommends \ unzip valgrind vim wget zip --no-install-recommends \
&& apt-get clean -y \ && apt-get clean -y \
@ -22,32 +23,32 @@ RUN apt-get update \
# #
# binaryen # binaryen
ARG BINARYEN_VER=111 ARG BINARYEN_VER=114
WORKDIR /opt WORKDIR /opt
RUN wget -c --progress=dot:giga https://github.com/WebAssembly/binaryen/releases/download/version_${BINARYEN_VER}/binaryen-version_${BINARYEN_VER}-x86_64-linux.tar.gz \ RUN wget -c --progress=dot:giga https://github.com/WebAssembly/binaryen/releases/download/version_${BINARYEN_VER}/binaryen-version_${BINARYEN_VER}-x86_64-linux.tar.gz \
&& tar xf binaryen-version_${BINARYEN_VER}-x86_64-linux.tar.gz \ && tar xf binaryen-version_${BINARYEN_VER}-x86_64-linux.tar.gz \
&& ln -sf /opt/binaryen-version_111 /opt/binaryen \ && ln -sf /opt/binaryen-version_${BINARYEN_VER} /opt/binaryen \
&& rm binaryen-version_${BINARYEN_VER}-x86_64-linux.tar.gz && rm binaryen-version_${BINARYEN_VER}-x86_64-linux.tar.gz
# #
# CMAKE (https://apt.kitware.com/) # CMAKE (https://apt.kitware.com/)
SHELL ["/bin/bash", "-o", "pipefail", "-c"] SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# hadolint ignore=DL3008 # hadolint ignore=DL3008
RUN wget --progress=dot:giga -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null \ ARG CMAKE_VER=3.27.0
&& echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ bionic main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null \ RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \
&& apt-get update \ -q -O /tmp/cmake-install.sh \
&& rm /usr/share/keyrings/kitware-archive-keyring.gpg \ && chmod u+x /tmp/cmake-install.sh \
&& apt-get install -y kitware-archive-keyring --no-install-recommends \ && mkdir /opt/cmake-${CMAKE_VER} \
&& apt-get install -y cmake --no-install-recommends \ && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \
&& apt-get clean -y \ && rm /tmp/cmake-install.sh \
&& rm -rf /var/lib/apt/lists/* && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin
# #
# install emsdk # install emsdk
WORKDIR /opt WORKDIR /opt
RUN git clone https://github.com/emscripten-core/emsdk.git RUN git clone https://github.com/emscripten-core/emsdk.git
ARG EMSDK_VER=3.0.0 ARG EMSDK_VER=3.1.43
WORKDIR /opt/emsdk WORKDIR /opt/emsdk
RUN git pull \ RUN git pull \
&& ./emsdk install ${EMSDK_VER} \ && ./emsdk install ${EMSDK_VER} \
@ -56,7 +57,7 @@ RUN git pull \
# #
# install wasi-sdk # install wasi-sdk
ARG WASI_SDK_VER=19 ARG WASI_SDK_VER=20
RUN wget -c --progress=dot:giga https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VER}/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -P /opt \ RUN wget -c --progress=dot:giga https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VER}/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -P /opt \
&& tar xf /opt/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -C /opt \ && tar xf /opt/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -C /opt \
&& ln -sf /opt/wasi-sdk-${WASI_SDK_VER}.0 /opt/wasi-sdk \ && ln -sf /opt/wasi-sdk-${WASI_SDK_VER}.0 /opt/wasi-sdk \
@ -64,7 +65,7 @@ RUN wget -c --progress=dot:giga https://github.com/WebAssembly/wasi-sdk/releases
# #
#install wabt #install wabt
ARG WABT_VER=1.0.29 ARG WABT_VER=1.0.33
RUN wget -c --progress=dot:giga https://github.com/WebAssembly/wabt/releases/download/${WABT_VER}/wabt-${WABT_VER}-ubuntu.tar.gz -P /opt \ RUN wget -c --progress=dot:giga https://github.com/WebAssembly/wabt/releases/download/${WABT_VER}/wabt-${WABT_VER}-ubuntu.tar.gz -P /opt \
&& tar xf /opt/wabt-${WABT_VER}-ubuntu.tar.gz -C /opt \ && tar xf /opt/wabt-${WABT_VER}-ubuntu.tar.gz -C /opt \
&& ln -sf /opt/wabt-${WABT_VER} /opt/wabt \ && ln -sf /opt/wabt-${WABT_VER} /opt/wabt \
@ -72,7 +73,7 @@ RUN wget -c --progress=dot:giga https://github.com/WebAssembly/wabt/releases/dow
# #
# install bazelisk # install bazelisk
ARG BAZELISK_VER=1.12.0 ARG BAZELISK_VER=1.17.0
RUN mkdir /opt/bazelisk \ RUN mkdir /opt/bazelisk \
&& wget -c --progress=dot:giga https://github.com/bazelbuild/bazelisk/releases/download/v${BAZELISK_VER}/bazelisk-linux-amd64 -P /opt/bazelisk \ && wget -c --progress=dot:giga https://github.com/bazelbuild/bazelisk/releases/download/v${BAZELISK_VER}/bazelisk-linux-amd64 -P /opt/bazelisk \
&& chmod a+x /opt/bazelisk/bazelisk-linux-amd64 \ && chmod a+x /opt/bazelisk/bazelisk-linux-amd64 \
@ -80,16 +81,30 @@ RUN mkdir /opt/bazelisk \
# #
# install clang+llvm # install clang+llvm
ARG LLVM_VER=14 ARG LLVM_VER=16
RUN apt-get purge -y clang-10 llvm-10 && apt-get autoremove -y RUN apt-get purge -y clang-14 llvm-14 && apt-get autoremove -y
WORKDIR /etc/apt/apt.conf.d WORKDIR /etc/apt/apt.conf.d
RUN touch 99verfiy-peer.conf \ RUN touch 99verfiy-peer.conf \
&& echo "Acquire { https::Verify-Peer false }" > 99verfiy-peer.conf && echo "Acquire { https::Verify-Peer false }" > 99verfiy-peer.conf
WORKDIR /tmp WORKDIR /tmp
RUN wget --progress=dot:giga https://apt.llvm.org/llvm.sh \ #RUN wget --progress=dot:giga https://apt.llvm.org/llvm.sh \
&& chmod a+x ./llvm.sh \ # && chmod a+x ./llvm.sh \
&& ./llvm.sh ${LLVM_VER} all # && ./llvm.sh ${LLVM_VER} all
# Workaround due to https://github.com/llvm/llvm-project/issues/62475
# hadolint ignore=DL3008
RUN set -ex \
&& echo "deb http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm-${LLVM_VER} main" > /etc/apt/sources.list.d/apt.llvm.org.list \
&& wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc \
&& apt-get update \
&& apt-get install -y \
clang-${LLVM_VER} lldb-${LLVM_VER} lld-${LLVM_VER} clangd-${LLVM_VER} clang-tidy-${LLVM_VER} clang-format-${LLVM_VER} clang-tools-${LLVM_VER} \
llvm-${LLVM_VER}-dev lld-${LLVM_VER} lldb-${LLVM_VER} llvm-${LLVM_VER}-tools libomp-${LLVM_VER}-dev libc++-${LLVM_VER}-dev libc++abi-${LLVM_VER}-dev \
libclang-common-${LLVM_VER}-dev libclang-${LLVM_VER}-dev libclang-cpp${LLVM_VER}-dev libunwind-${LLVM_VER}-dev \
libclang-rt-${LLVM_VER}-dev libpolly-${LLVM_VER}-dev --no-install-recommends \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
# #
# [Optional] # [Optional]
@ -105,18 +120,19 @@ RUN apt-get update \
# #
# Install required python packages # Install required python packages
# hadolint ignore=DL3013 # hadolint ignore=DL3013
RUN python3 -m pip install --no-cache-dir --upgrade pip \ RUN python3 -m pip install --no-cache-dir --break-system-packages --upgrade pip \
&& pip3 install --no-cache-dir black nose pycparser pylint && pip3 install --no-cache-dir --break-system-packages black nose pycparser pylint
# #
# Install github-cli. It doens't work as a feature of devcontainer.json # Install github-cli. It doens't work as a feature of devcontainer.json
ARG GH_CLI_VER=2.32.0
WORKDIR /tmp WORKDIR /tmp
RUN wget -q https://github.com/cli/cli/releases/download/v2.20.2/gh_2.20.2_linux_amd64.deb \ RUN wget -q https://github.com/cli/cli/releases/download/v${GH_CLI_VER}/gh_${GH_CLI_VER}_linux_amd64.deb \
&& dpkg -i gh_2.20.2_linux_amd64.deb && dpkg -i gh_${GH_CLI_VER}_linux_amd64.deb
# #
# Install NodeJS # Install NodeJS
RUN wget -qO- https://deb.nodesource.com/setup_19.x | bash - RUN wget -qO- https://deb.nodesource.com/setup_20.x | bash -
# hadolint ignore=DL3008 # hadolint ignore=DL3008
RUN apt-get install -y nodejs --no-install-recommends RUN apt-get install -y nodejs --no-install-recommends

View File

@ -1,20 +1,23 @@
// Copyright (C) 2019 Intel Corporation. All rights reserved. // Copyright (C) 2019 Intel Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at: // For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.195.0/containers/cpp // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/cpp
{ {
"name": "WAMR-Dev", "name": "WAMR-Dev",
"build": { "build": {
"dockerfile": "Dockerfile", "dockerfile": "Dockerfile",
// Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-11, debian-10, debian-9, ubuntu-21.04, ubuntu-20.04, ubuntu-18.04 // Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-12, debian-11, debian-10, debian-9, ubuntu-21.04, ubuntu-20.04, ubuntu-18.04
// Use Debian 11, Debian 9, Ubuntu 18.04 or Ubuntu 21.04 on local arm64/Apple Silicon // Use Debian 12, Debian 11, Debian 9, Ubuntu 18.04 or Ubuntu 21.04 on local arm64/Apple Silicon
"args": { "args": {
"BINARYEN_VER": "111", "BINARYEN_VER": "114",
"EMSDK_VER": "3.0.0", "BAZELISK_VER": "1.17.0",
"LLVM_VER": "15", "CMAKE_VER": "3.27.0",
"VARIANT": "ubuntu-20.04", "EMSDK_VER": "3.1.43",
"WASI_SDK_VER": "19", "GH_CLI_VER": "2.32.0",
"WABT_VER": "1.0.31" "LLVM_VER": "16",
"VARIANT": "debian-12",
"WASI_SDK_VER": "20",
"WABT_VER": "1.0.33"
} }
}, },
"runArgs": [ "runArgs": [
@ -34,7 +37,7 @@
"llvm-vs-code-extensions.vscode-clangd", "llvm-vs-code-extensions.vscode-clangd",
"ms-python.python", "ms-python.python",
"ms-python.vscode-pylance", "ms-python.vscode-pylance",
"ms-vscode.cmake-tools", "ms-vscode.cmake-tools"
] ]
} }
}, },

View File

@ -22,6 +22,11 @@ on:
description: a semantic version number description: a semantic version number
type: string type: string
required: true required: true
wasi_sdk_url:
description: download WASI_SDK from this URL
type: string
required: false
default: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz"
jobs: jobs:
try_reuse: try_reuse:
@ -29,7 +34,7 @@ jobs:
with: with:
binary_name_stem: "wamr-lldb-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}" binary_name_stem: "wamr-lldb-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}"
last_commit: "ea63ba4bd010c2285623ad4acc0262a4d63bcfea" last_commit: "ea63ba4bd010c2285623ad4acc0262a4d63bcfea"
the_path: "./build-scripts/lldb-wasm.patch" the_path: "./build-scripts/lldb_wasm.patch"
upload_url: ${{ inputs.upload_url }} upload_url: ${{ inputs.upload_url }}
build: build:
@ -44,6 +49,15 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: download and install wasi-sdk
run: |
cd /opt
basename=$(basename ${{ inputs.wasi_sdk_url }})
sudo wget --progress=dot:giga ${{ inputs.wasi_sdk_url }}
sudo tar -xzf ${basename}
sudo rm ${basename}
sudo mv wasi-sdk-* wasi-sdk
- name: Cache build - name: Cache build
id: lldb_build_cache id: lldb_build_cache
uses: actions/cache@v3 uses: actions/cache@v3
@ -69,8 +83,8 @@ jobs:
if: steps.lldb_build_cache.outputs.cache-hit != 'true' && contains(inputs.runner, 'macos') if: steps.lldb_build_cache.outputs.cache-hit != 'true' && contains(inputs.runner, 'macos')
run: | run: |
brew remove swig brew remove swig
brew install swig@3 cmake ninja libedit brew install swig@4.1 cmake ninja libedit
brew link --overwrite swig@3 brew link --overwrite swig@4.1
sudo rm -rf /Library/Developer/CommandLineTools sudo rm -rf /Library/Developer/CommandLineTools
- name: install utils ubuntu - name: install utils ubuntu
@ -92,7 +106,7 @@ jobs:
git init git init
git config user.email "action@github.com" git config user.email "action@github.com"
git config user.name "github action" git config user.name "github action"
git apply ../../../build-scripts/lldb-wasm.patch git apply ../../../build-scripts/lldb_wasm.patch
working-directory: core/deps/llvm-project working-directory: core/deps/llvm-project
- name: get stand-alone python ubuntu - name: get stand-alone python ubuntu
@ -141,6 +155,17 @@ jobs:
cmake --build build --target lldb install --parallel $(nproc) cmake --build build --target lldb install --parallel $(nproc)
working-directory: core/deps/llvm-project working-directory: core/deps/llvm-project
- name: validate lldb ubuntu
if: steps.lldb_build_cache.outputs.cache-hit != 'true' && contains(inputs.runner, 'ubuntu')
run: |
echo "start to validate lldb..."
mkdir -p wamr-debug
cmake -S product-mini/platforms/linux -B wamr-debug -DWAMR_BUILD_DEBUG_INTERP=1
cmake --build wamr-debug --parallel $(nproc)
export LD_LIBRARY_PATH=$(pwd)/core/deps/python/lib:${LD_LIBRARY_PATH}
python3 ci/validate_lldb.py --port 1239 --lldb core/deps/wamr-lldb/bin/lldb --wamr wamr-debug/iwasm --verbose
working-directory: .
- name: build lldb macos - name: build lldb macos
if: steps.lldb_build_cache.outputs.cache-hit != 'true' && contains(inputs.runner, 'macos') if: steps.lldb_build_cache.outputs.cache-hit != 'true' && contains(inputs.runner, 'macos')
run: | run: |
@ -180,7 +205,7 @@ jobs:
mkdir -p wamr-lldb/lib mkdir -p wamr-lldb/lib
cp build/bin/lldb* wamr-lldb/bin cp build/bin/lldb* wamr-lldb/bin
cp lldb/tools/lldb-vscode/package.json wamr-lldb cp lldb/tools/lldb-vscode/package.json wamr-lldb
cp -r lldb/tools/lldb-vscode/syntaxes/ wamr-lldb cp -r lldb/tools/lldb-vscode/syntaxes/ wamr-lldb
working-directory: core/deps/llvm-project working-directory: core/deps/llvm-project
- name: pack ubuntu specific libraries - name: pack ubuntu specific libraries
@ -201,7 +226,7 @@ jobs:
cp -R ../python/lib/python* wamr-lldb/lib cp -R ../python/lib/python* wamr-lldb/lib
cp ../python/lib/libpython*.dylib wamr-lldb/lib cp ../python/lib/libpython*.dylib wamr-lldb/lib
install_name_tool -change /install/lib/libpython${{ env.PYTHON_VERSION }}.dylib @rpath/libpython${{ env.PYTHON_VERSION }}.dylib wamr-lldb/lib/liblldb.*.dylib install_name_tool -change /install/lib/libpython${{ env.PYTHON_VERSION }}.dylib @rpath/libpython${{ env.PYTHON_VERSION }}.dylib wamr-lldb/lib/liblldb.*.dylib
# Patch path of python library -> https://github.com/indygreg/python-build-standalone/blob/85923ca3911784e6978b85d56e06e9ae75cb2dc4/docs/quirks.rst?plain=1#L412-L446 # Patch path of python library -> https://github.com/indygreg/python-build-standalone/blob/85923ca3911784e6978b85d56e06e9ae75cb2dc4/docs/quirks.rst?plain=1#L412-L446
working-directory: core/deps/llvm-project working-directory: core/deps/llvm-project
- name: compress the binary - name: compress the binary

View File

@ -72,7 +72,7 @@ jobs:
with: with:
os: "ubuntu-22.04" os: "ubuntu-22.04"
arch: "X86" arch: "X86"
build_wamrc: build_wamrc:
needs: needs:
[build_llvm_libraries_on_ubuntu_2204] [build_llvm_libraries_on_ubuntu_2204]
@ -241,6 +241,14 @@ jobs:
cmake --build . --config Release --parallel 4 cmake --build . --config Release --parallel 4
working-directory: product-mini/platforms/${{ matrix.platform }} working-directory: product-mini/platforms/${{ matrix.platform }}
- name: Build and run unit tests
run: |
mkdir build-unittests && cd build-unittests
cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }}
cmake --build . --config Release --parallel 4
ctest
working-directory: tests/unit
build_samples_wasm_c_api: build_samples_wasm_c_api:
needs: needs:
[ [
@ -483,6 +491,16 @@ jobs:
sudo tar -xzf wasi-sdk-*.tar.gz sudo tar -xzf wasi-sdk-*.tar.gz
sudo mv wasi-sdk-20.0 wasi-sdk sudo mv wasi-sdk-20.0 wasi-sdk
# It is a temporary solution until new wasi-sdk that includes bug fixes is released
- name: build wasi-libc from source
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: |
git clone https://github.com/WebAssembly/wasi-libc
cd wasi-libc
make -j AR=/opt/wasi-sdk/bin/llvm-ar NM=/opt/wasi-sdk/bin/llvm-nm CC=/opt/wasi-sdk/bin/clang THREAD_MODEL=posix
echo "SYSROOT_PATH=$PWD/sysroot" >> $GITHUB_ENV
- name: set env variable(if llvm are used) - name: set env variable(if llvm are used)
if: matrix.running_mode == 'aot' || matrix.running_mode == 'jit' || matrix.running_mode == 'multi-tier-jit' if: matrix.running_mode == 'aot' || matrix.running_mode == 'jit' || matrix.running_mode == 'multi-tier-jit'
run: echo "USE_LLVM=true" >> $GITHUB_ENV run: echo "USE_LLVM=true" >> $GITHUB_ENV
@ -518,7 +536,7 @@ jobs:
- name: Build WASI thread tests - name: Build WASI thread tests
if: matrix.test_option == '$WASI_TEST_OPTIONS' if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: bash build.sh run: bash build.sh --sysroot "$SYSROOT_PATH"
working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/ working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/
- name: build socket api tests - name: build socket api tests
@ -527,7 +545,7 @@ jobs:
working-directory: ./core/iwasm/libraries/lib-socket/test/ working-directory: ./core/iwasm/libraries/lib-socket/test/
- name: run tests - name: run tests
timeout-minutes: 10 timeout-minutes: 30
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites working-directory: ./tests/wamr-test-suites
@ -543,7 +561,7 @@ jobs:
sudo apt install -y g++-multilib lib32gcc-9-dev sudo apt install -y g++-multilib lib32gcc-9-dev
- name: run tests x86_32 - name: run tests x86_32
timeout-minutes: 10 timeout-minutes: 30
if: env.TEST_ON_X86_32 == 'true' if: env.TEST_ON_X86_32 == 'true'
run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }} run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites working-directory: ./tests/wamr-test-suites
@ -584,7 +602,7 @@ jobs:
cache-name: cache-lldb-vscode cache-name: cache-lldb-vscode
with: with:
path: test-tools/wamr-ide/VSCode-Extension/resource/debug/linux path: test-tools/wamr-ide/VSCode-Extension/resource/debug/linux
key: ${{ env.cache-name }}-${{ hashFiles('build-scripts/lldb-wasm.patch') }}-${{ env.PYTHON_UBUNTU_STANDALONE_BUILD }} key: ${{ env.cache-name }}-${{ hashFiles('build-scripts/lldb_wasm.patch') }}-${{ env.PYTHON_UBUNTU_STANDALONE_BUILD }}
- if: ${{ steps.cache-lldb.outputs.cache-hit != 'true' }} - if: ${{ steps.cache-lldb.outputs.cache-hit != 'true' }}
name: get stand-alone python ubuntu name: get stand-alone python ubuntu
@ -607,7 +625,7 @@ jobs:
git init git init
git config user.email "action@github.com" git config user.email "action@github.com"
git config user.name "github action" git config user.name "github action"
git apply ../../../build-scripts/lldb-wasm.patch git apply ../../../build-scripts/lldb_wasm.patch
working-directory: core/deps/llvm-project working-directory: core/deps/llvm-project
- if: ${{ steps.cache-lldb.outputs.cache-hit != 'true' }} - if: ${{ steps.cache-lldb.outputs.cache-hit != 'true' }}

View File

@ -0,0 +1,47 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
name: hadolint dockerfiles
on:
# will be triggered on PR events
pull_request:
types:
- opened
- synchronize
paths:
- "**/Dockerfile*"
- ".github/workflows/hadolint_dockerfiles.yml"
push:
branches:
- main
- "dev/**"
paths:
- "**/Dockerfile*"
- ".github/workflows/hadolint_dockerfiles.yml"
# allow to be triggered manually
workflow_dispatch:
# Cancel any in-flight jobs for the same PR/branch so there's only one active
# at a time
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
run-hadolint-on-dockerfiles:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v3
# on default, hadolint will fail on warnings and errors
- name: Run hadolint on dockerfiles
run: |
docker pull hadolint/hadolint:latest-debian
find . -name "*Dockerfile*" | while read dockerfile; do
echo "run hadolint on $dockerfile:"
docker run --rm -i hadolint/hadolint:latest-debian hadolint - <"$dockerfile"
echo "successful"
done

View File

@ -548,6 +548,16 @@ jobs:
sudo wget ${{ matrix.wasi_sdk_release }} sudo wget ${{ matrix.wasi_sdk_release }}
sudo tar -xzf wasi-sdk-*.tar.gz sudo tar -xzf wasi-sdk-*.tar.gz
sudo mv wasi-sdk-20.0 wasi-sdk sudo mv wasi-sdk-20.0 wasi-sdk
# It is a temporary solution until new wasi-sdk that includes bug fixes is released
- name: build wasi-libc from source
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: |
git clone https://github.com/WebAssembly/wasi-libc
cd wasi-libc
make -j AR=/opt/wasi-sdk/bin/llvm-ar NM=/opt/wasi-sdk/bin/llvm-nm CC=/opt/wasi-sdk/bin/clang THREAD_MODEL=posix
echo "SYSROOT_PATH=$PWD/sysroot" >> $GITHUB_ENV
- name: set env variable(if llvm are used) - name: set env variable(if llvm are used)
if: matrix.running_mode == 'aot' || matrix.running_mode == 'jit' || matrix.running_mode == 'multi-tier-jit' if: matrix.running_mode == 'aot' || matrix.running_mode == 'jit' || matrix.running_mode == 'multi-tier-jit'
run: echo "USE_LLVM=true" >> $GITHUB_ENV run: echo "USE_LLVM=true" >> $GITHUB_ENV
@ -586,16 +596,21 @@ jobs:
- name: Build WASI thread tests - name: Build WASI thread tests
if: matrix.test_option == '$WASI_TEST_OPTIONS' if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: bash build.sh run: bash build.sh --sysroot "$SYSROOT_PATH"
working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/ working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/
- name: Build WASI thread stress tests
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: bash build.sh --sysroot "$SYSROOT_PATH"
working-directory: ./core/iwasm/libraries/lib-wasi-threads/stress-test/
- name: build socket api tests - name: build socket api tests
if: matrix.test_option == '$WASI_TEST_OPTIONS' if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: bash build.sh run: bash build.sh
working-directory: ./core/iwasm/libraries/lib-socket/test/ working-directory: ./core/iwasm/libraries/lib-socket/test/
- name: run tests - name: run tests
timeout-minutes: 10 timeout-minutes: 40
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites working-directory: ./tests/wamr-test-suites
@ -611,7 +626,7 @@ jobs:
sudo apt install -y g++-multilib lib32gcc-9-dev sudo apt install -y g++-multilib lib32gcc-9-dev
- name: run tests x86_32 - name: run tests x86_32
timeout-minutes: 10 timeout-minutes: 40
if: env.TEST_ON_X86_32 == 'true' if: env.TEST_ON_X86_32 == 'true'
run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }} run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites working-directory: ./tests/wamr-test-suites

View File

@ -22,7 +22,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
| third party components | version number | latest release | vendor pages | CVE details | | third party components | version number | latest release | vendor pages | CVE details |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| cjson | 1.7.10 | 1.7.14 | https://github.com/DaveGamble/cJSON | https://www.cvedetails.com/vendor/19164/Cjson-Project.html | | cjson | 1.7.16 | 1.7.16 | https://github.com/DaveGamble/cJSON | https://www.cvedetails.com/vendor/19164/Cjson-Project.html |
| contiki-ng (er-coap) | unspecified | 3.0 | https://github.com/contiki-os/contiki | https://www.cvedetails.com/vendor/16528/Contiki-os.html | | contiki-ng (er-coap) | unspecified | 3.0 | https://github.com/contiki-os/contiki | https://www.cvedetails.com/vendor/16528/Contiki-os.html |
| freebsd libm | unspecified | 13.0 | https://www.freebsd.org/ | https://www.cvedetails.com/vendor/6/Freebsd.html | | freebsd libm | unspecified | 13.0 | https://www.freebsd.org/ | https://www.cvedetails.com/vendor/6/Freebsd.html |
| LVGL | 6.0.1 | 7.11.0 | https://lvgl.io/ | | | LVGL | 6.0.1 | 7.11.0 | https://lvgl.io/ | |
@ -31,7 +31,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
| wasmtime | unspecified | v0.26.0 | https://github.com/bytecodealliance/wasmtime | | | wasmtime | unspecified | v0.26.0 | https://github.com/bytecodealliance/wasmtime | |
| zephyr | unspecified | v2.5.0 | https://www.zephyrproject.org/ | https://www.cvedetails.com/vendor/19255/Zephyrproject.html | | zephyr | unspecified | v2.5.0 | https://www.zephyrproject.org/ | https://www.cvedetails.com/vendor/19255/Zephyrproject.html |
| WebAssembly debugging patch for LLDB | unspecified | unspecified | https://reviews.llvm.org/D78801 | | | WebAssembly debugging patch for LLDB | unspecified | unspecified | https://reviews.llvm.org/D78801 | |
| libuv | v1.42.0 | v1.44.1 | https://github.com/libuv/libuv | https://www.cvedetails.com/vendor/15402/Libuv-Project.html | | libuv | v1.46.0 | v1.46.0 | https://github.com/libuv/libuv | https://www.cvedetails.com/vendor/15402/Libuv-Project.html |
| uvwasi | unspecified | v0.0.12 | https://github.com/nodejs/uvwasi | | | uvwasi | unspecified | v0.0.12 | https://github.com/nodejs/uvwasi | |
| asmjit | unspecified | unspecified | https://github.com/asmjit/asmjit | | | asmjit | unspecified | unspecified | https://github.com/asmjit/asmjit | |
| zydis | unspecified | e14a07895136182a5b53e181eec3b1c6e0b434de | https://github.com/zyantific/zydis | | | zydis | unspecified | e14a07895136182a5b53e181eec3b1c6e0b434de | https://github.com/zyantific/zydis | |

View File

@ -107,6 +107,11 @@ endif ()
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
# Set the strip command based on the system (GNU or Clang)
if (CMAKE_STRIP)
set (CMAKE_STRIP_FLAGS "--strip-all")
endif ()
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security -Wshadow -Wno-unused-parameter") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security -Wshadow -Wno-unused-parameter")
@ -141,6 +146,15 @@ endif ()
install (TARGETS iwasm_static ARCHIVE DESTINATION lib) install (TARGETS iwasm_static ARCHIVE DESTINATION lib)
# If it's a Release build, strip the static library
if (CMAKE_STRIP AND CMAKE_BUILD_TYPE STREQUAL "Release")
# Strip static library
message (STATUS "Stripping static library after build!")
add_custom_command (TARGET iwasm_static POST_BUILD
COMMAND ${CMAKE_STRIP} ${CMAKE_STRIP_FLAGS} $<TARGET_FILE:iwasm_static>
)
endif ()
# SHARED LIBRARY # SHARED LIBRARY
add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE}) add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE})
set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm) set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm)
@ -162,3 +176,12 @@ install (FILES
${WAMR_ROOT_DIR}/core/iwasm/include/wasm_export.h ${WAMR_ROOT_DIR}/core/iwasm/include/wasm_export.h
${WAMR_ROOT_DIR}/core/iwasm/include/lib_export.h ${WAMR_ROOT_DIR}/core/iwasm/include/lib_export.h
DESTINATION include) DESTINATION include)
# If it's a Release build, strip the shared library
if (CMAKE_STRIP AND CMAKE_BUILD_TYPE STREQUAL "Release")
# Strip shared library
message (STATUS "Stripping shared library after build!")
add_custom_command (TARGET iwasm_shared POST_BUILD
COMMAND ${CMAKE_STRIP} ${CMAKE_STRIP_FLAGS} $<TARGET_FILE:iwasm_shared>
)
endif ()

View File

@ -1,3 +1,139 @@
## WAMR-1.2.3
### Breaking Changes
- Increase default native stack size (#2332)
### New Features
- Implement the segue optimization for LLVM AOT/JIT (#2230)
- Implement AOT static PGO (#2243)
- Enable static PGO for Linux SGX (#2270)
- Add Rust Formatters to Debugger (Vector, Map etc.) (#2219)
### Bug Fixes
- The Python language-binding needs python>=3.9 (#2228)
- aot_compile_op_call: Remove a wrong optimization (#2233)
- Fix typo in samples/ref-types (#2236)
- Update thread proposal ignore cases (#2246)
- Disable writting GS register on linux-sgx platform (#2255)
- Fix compile error of wamrc with llvm-13/llvm-14 (#2261)
- aot/jit: Set module layout (#2260)
- Fix build error with LLVM 16 (#2259)
- spec-test-script: Disable conversions.wast on i386 (#2269)
- Fix a heap corruption bug in ems realloc (#2279)
- Fix fast-interp issue of LAST_OP_OUTPUT_I32/64 check (#2295)
- Fix wamrc build issues with LLVM 13 and LLVM 16 (#2313)
- aot: Move stack_sizes table to a dedicated section (#2317)
- product-mini/platforms/linux: Mark vmlib POSITION_INDEPENDENT_CODE (#2323)
- aot: Avoid possible relocations around "stack_sizes" for XIP mode (#2322)
- Avoid switch lowering to lookup tables for XIP (#2339)
- Fix typo in zephyr's Dockerfile.old (#2354)
- Fix typo (dwarf) in the codebase (#2367)
- Implement suspend flags as atomic variable (#2361)
- Fix llvm jit failed to lookup aot_stack_sizes symbol issue (#2384)
- Fix some check issues on table operations (#2392)
- Fix ExpandMemoryOpPass doesn't work properly (#2399)
- Fix non-builtin BH_ATOMIC_32_FETCH_OR and BH_ATOMIC_32_FETCH_AND (#2400)
- Fix wasi-sockets tests (#2389)
- Fix result arity check on select_t opcode (#2406)
- Re-organize intrinsics in aot_reloc_riscv.c to fix some FPU issues (#2414)
- Fix lib-pthread issues (#2410)
- Fix typo in test_wamr.sh (#2421)
- Fix memory sharing (#2415)
- wasm_export.h: Fix struct wasm_val_t (#2435)
- Fix typos in wamrc print_help() (#2442)
- iwasm: Fix native lib cleanup after error occurs (#2443)
- Correct --heap-size option in messages (#2458)
- wasm_instantiate: Fix a potential integer overflow issue (#2459)
- Fix windows link error and clear windows warnings (#2463)
- aot: Disable musttail for mips (#2457)
- Fix opcode overwrite issue in fast interp (#2476)
- wamrc: Fix windows relocation to `aot_func_internal#n` (#2474)
- Fix windows AOT hw bound check (#2475)
- Fix typo in aot_emit_aot_file.c (#2478)
### Enhancements
- A few changes related to WAMRC_LLC_COMPILER (#2218)
- Enhance linux-sgx CI (#2102)
- Add asan and ubsan to WAMR CI (#2161)
- Update doc on WAMR_DISABLE_HW_BOUND_CHECK 32-bit (#2262)
- wamrc: Add an incompatibility note in the help message (#2276)
- Add cmake variable to disable writing gs register (#2284)
- Make hmu_tree_node 4 byte aligned to reduce compiler warning (#2268)
- Appease unused warning on min_uint64 (#2277)
- Fix format warning by PRIu32 in [wasm|aot] dump call stack (#2251)
- Fix a compile warning due to missing include (#2293)
- Fix dockerfile linter warnings (#2291)
- Enable windows x86-32 AOT relocations (#2285)
- wamr-ide: Add vscode extension tests (#2292)
- AOT/JIT native stack bound check improvement (#2244)
- Add retries to flaky step in nightly run CI (#2306)
- Use system libuv if available (#1861)
- wasi-nn: Simplify cmake and headers' location (#2308)
- wasi-nn: Improve tests paths for local dev (#2309)
- aot: Implement a few more relocation types for riscv (#2318)
- wasi-nn: Add support of wasi-nn as shared lib (#2310)
- Add a few more assertions on structures to which aot abi is sensitive (#2326)
- Fix sanitizer errors in posix socket (#2331)
- Add "--xip" option for wamrc (#2336)
- Add "--enable-llvm-passes=<passes>" option to wamrc (#2335)
- Make memory access boundary check behavior configurable (#2289)
- Migrate ExpandMemoryOpPass to llvm new pass manager (#2334)
- Allow defining hints without exact socket type or address family (#2337)
- wamrc: Warn on text relocations for XIP (#2340)
- Add scripts to validate lldb source debugger (#2150)
- Add docker file to fix Zephy ESP32 linking issue (#2314)
- Add "--native-lib=<lib>" option to wamrc (#2342)
- Fix unused warnings on disable_bounds_checks (#2347)
- Add "--enable-builtin-intrinsics=<flags>" option to wamrc (#2341)
- nuttx: Add a kconfig for wasi-threads (#2343)
- iwasm: Disable app heap by default if wasi is enabled (#2346)
- Fix some static scan issues (#2362)
- Bring up WAMR on esp32-s3 device (#2348)
- ESP-IDF platform supports to load AOT to PSRAM and run it (#2385)
- Add hadolint CI for Dockerfile linting (#2387)
- Move generic parts of wasm_suspend_flags.h to bh_atomic.h (#2393)
- bh_atomic.h: Add comments (#2398)
- bh_atomic.h: Add BH_ATOMIC_32_FETCH_ADD/BH_ATOMIC_32_FETCH_SUB (#2408)
- Update libuv version to v1.46.0 (#2405)
- Remove a few unused functions (#2409)
- Add initial stress test (#2364)
- Move wasm_runtime_destroy_wasi and wasi_nn_destroy calls together (#2418)
- embed_wamr.md: Improvements about threads (#2420)
- Add runtime inited checks in Enclave command handlings to improve security (#2416)
- Add some relocation symbols for xtensa target (#2422)
- Remove unnecessary and extra zero length check in mem functions' macro (#2428)
- Introduce WASMModuleInstanceExtraCommon (#2429)
- Strip static and shared libraries of iwasm to reduce the binary size (#2431)
- Auto-check wrgsbase in cmake script (#2437)
- iwasm: call native lib init/deinit if exists (#2439)
- wasi-nn: Support uint8 quantized networks (#2433)
- Implement `wasm_externref_objdel` and `wasm_externref_set_cleanup` (#2455)
- wasi-nn: Improve TPU support (#2447)
- wamr-python: Enable debugging WASM and grant dir access (#2449)
- Build wasi-libc from source in WAMR CI (#2465)
- wamrc: More friendly to print help info (#2451)
- Add another wamr test (#2411)
- Fix issues reported by Coverity and clear windows warnings (#2467)
- Clone the input binary during wasm_module_validate (#2483)
### Others
- Nuttx CI: Ignore the expired certificate for riscv gcc toolchain (#2222)
- core/iwasm/compilation: constify a bit (#2223)
- Bump requests from 2.28.2 to 2.31.0 in /build-scripts (#2229)
- dwarf_extractor: Constify a bit (#2278)
- AOTFuncContext: Remove a stale comment (#2283)
- Add performance tunning document (#2286)
- Reduce CI jobs number (#2296)
- CI: Update used node version to 16 (#2303)
- Update Docker image for latest version of external libraries & tools (#2374)
- Upgrade cJSON version to v1.7.16 (#2404)
- Upgrade XNNPACK workload (#2394)
- Build more benchmarks in workload XNNPACK (#2417)
- Upgrade SGX-RA integration for 0.1.2 and Ubuntu 20.04 (#2454)
- Add sample pre-commit hook (#2470)
---
## WAMR-1.2.2 ## WAMR-1.2.2
### Breaking Changes ### Breaking Changes

View File

@ -273,6 +273,13 @@ else ()
add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=0) add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=0)
endif () endif ()
endif () endif ()
if (WAMR_DISABLE_WAKEUP_BLOCKING_OP EQUAL 1)
add_definitions (-DWASM_DISABLE_WAKEUP_BLOCKING_OP=1)
message (" Wakeup of blocking operations disabled")
else ()
add_definitions (-DWASM_DISABLE_WAKEUP_BLOCKING_OP=0)
message (" Wakeup of blocking operations enabled")
endif ()
if (WAMR_BUILD_SIMD EQUAL 1) if (WAMR_BUILD_SIMD EQUAL 1)
if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*") if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")
add_definitions (-DWASM_ENABLE_SIMD=1) add_definitions (-DWASM_ENABLE_SIMD=1)
@ -363,16 +370,16 @@ endif ()
if (WAMR_BUILD_WASI_NN EQUAL 1) if (WAMR_BUILD_WASI_NN EQUAL 1)
message (" WASI-NN enabled") message (" WASI-NN enabled")
add_definitions (-DWASM_ENABLE_WASI_NN=1) add_definitions (-DWASM_ENABLE_WASI_NN=1)
if (WASI_NN_ENABLE_GPU EQUAL 1) if (WAMR_BUILD_WASI_NN_ENABLE_GPU EQUAL 1)
message (" WASI-NN: GPU enabled") message (" WASI-NN: GPU enabled")
add_definitions (-DWASI_NN_ENABLE_GPU=1) add_definitions (-DWASM_ENABLE_WASI_NN_GPU=1)
endif () endif ()
if (WAMR_BUILD_WASI_NN_ENABLE_EXT EQUAL 1) if (WAMR_BUILD_WASI_NN_ENABLE_EXTERNAL_DELEGATE EQUAL 1)
message (" WASI-NN: External Delegation enabled") message (" WASI-NN: External Delegation enabled")
add_definitions (-DWASI_NN_ENABLE_EXTERNAL_DELEGATE=1) add_definitions (-DWASM_ENABLE_WASI_NN_EXTERNAL_DELEGATE=1)
endif () endif ()
if (DEFINED WASI_NN_EXT_DELEGATE_PATH) if (DEFINED WAMR_BUILD_WASI_NN_EXTERNAL_DELEGATE_PATH)
add_definitions (-DWASI_NN_EXT_DELEGATE_PATH="${WASI_NN_EXT_DELEGATE_PATH}") add_definitions (-DWASM_WASI_NN_EXTERNAL_DELEGATE_PATH="${WAMR_BUILD_WASI_NN_EXTERNAL_DELEGATE_PATH}")
endif () endif ()
endif () endif ()
if (WAMR_BUILD_ALLOC_WITH_USER_DATA EQUAL 1) if (WAMR_BUILD_ALLOC_WITH_USER_DATA EQUAL 1)
@ -382,6 +389,10 @@ if (WAMR_BUILD_WASM_CACHE EQUAL 1)
add_definitions (-DWASM_ENABLE_WASM_CACHE=1) add_definitions (-DWASM_ENABLE_WASM_CACHE=1)
message (" Wasm files cache enabled") message (" Wasm files cache enabled")
endif () endif ()
if (WAMR_BUILD_MODULE_INST_CONTEXT EQUAL 1)
add_definitions (-DWASM_ENABLE_MODULE_INST_CONTEXT=1)
message (" Module instance context enabled")
endif ()
if (WAMR_BUILD_GC_HEAP_VERIFY EQUAL 1) if (WAMR_BUILD_GC_HEAP_VERIFY EQUAL 1)
add_definitions (-DWASM_ENABLE_GC_VERIFY=1) add_definitions (-DWASM_ENABLE_GC_VERIFY=1)
message (" GC heap verification enabled") message (" GC heap verification enabled")
@ -399,4 +410,32 @@ endif ()
if (WAMR_DISABLE_WRITE_GS_BASE EQUAL 1) if (WAMR_DISABLE_WRITE_GS_BASE EQUAL 1)
add_definitions (-DWASM_DISABLE_WRITE_GS_BASE=1) add_definitions (-DWASM_DISABLE_WRITE_GS_BASE=1)
message (" Write linear memory base addr to x86 GS register disabled") message (" Write linear memory base addr to x86 GS register disabled")
elseif (WAMR_BUILD_TARGET STREQUAL "X86_64"
AND WAMR_BUILD_PLATFORM STREQUAL "linux")
set (TEST_WRGSBASE_SOURCE "${CMAKE_BINARY_DIR}/test_wrgsbase.c")
file (WRITE "${TEST_WRGSBASE_SOURCE}" "
#include <stdio.h>
#include <stdint.h>
int main() {
uint64_t value;
asm volatile (\"wrgsbase %0\" : : \"r\"(value));
printf(\"WRGSBASE instruction is available.\\n\");
return 0;
}")
# Try to compile and run the test program
try_run (TEST_WRGSBASE_RESULT
TEST_WRGSBASE_COMPILED
${CMAKE_BINARY_DIR}/test_wrgsbase
SOURCES ${TEST_WRGSBASE_SOURCE}
CMAKE_FLAGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
)
#message("${TEST_WRGSBASE_COMPILED}, ${TEST_WRGSBASE_RESULT}")
if (NOT TEST_WRGSBASE_RESULT EQUAL 0)
add_definitions (-DWASM_DISABLE_WRITE_GS_BASE=1)
message (" Write linear memory base addr to x86 GS register disabled")
endif ()
endif ()
if (WAMR_CONFIGUABLE_BOUNDS_CHECKS EQUAL 1)
add_definitions (-DWASM_CONFIGURABLE_BOUNDS_CHECKS=1)
message (" Configurable bounds checks enabled")
endif () endif ()

View File

@ -1,5 +1,44 @@
diff --git a/lldb/bindings/CMakeLists.txt b/lldb/bindings/CMakeLists.txt
index 9759b069fdc4..25b427f8bcf2 100644
--- a/lldb/bindings/CMakeLists.txt
+++ b/lldb/bindings/CMakeLists.txt
@@ -26,8 +26,6 @@ set(SWIG_COMMON_FLAGS
-features autodoc
-I${LLDB_SOURCE_DIR}/include
-I${CMAKE_CURRENT_SOURCE_DIR}
- -D__STDC_LIMIT_MACROS
- -D__STDC_CONSTANT_MACROS
${DARWIN_EXTRAS}
)
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index c9a6d0f06056..021c7683d170 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -1,8 +1,5 @@
/* Various liblldb typedefs that SWIG needs to know about. */
#define __extension__ /* Undefine GCC keyword to make Swig happy when processing glibc's stdint.h. */
-/* The ISO C99 standard specifies that in C++ implementations limit macros such
- as INT32_MAX should only be defined if __STDC_LIMIT_MACROS is. */
-#define __STDC_LIMIT_MACROS
%include "stdint.i"
%include "lldb/lldb-defines.h"
diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig
index b1ace4ff3b1e..5f8f4aa678c4 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -439,7 +439,7 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
%typemap(out) lldb::FileSP {
$result = nullptr;
- lldb::FileSP &sp = $1;
+ const lldb::FileSP &sp = $1;
if (sp) {
PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp));
if (!pyfile.IsValid())
diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h
index f2e2a0d22..426d1129b 100644 index f2e2a0d22784..426d1129bd10 100644
--- a/lldb/include/lldb/Breakpoint/Breakpoint.h --- a/lldb/include/lldb/Breakpoint/Breakpoint.h
+++ b/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/lldb/include/lldb/Breakpoint/Breakpoint.h
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
@ -11,7 +50,7 @@ index f2e2a0d22..426d1129b 100644
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index dd7100c46..97d70daad 100644 index dd7100c4616c..97d70daadbdc 100644
--- a/lldb/include/lldb/Core/Module.h --- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h +++ b/lldb/include/lldb/Core/Module.h
@@ -41,6 +41,7 @@ @@ -41,6 +41,7 @@
@ -41,7 +80,7 @@ index dd7100c46..97d70daad 100644
/// ///
/// Tries to resolve \a vm_addr as a file address (if \a /// Tries to resolve \a vm_addr as a file address (if \a
diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h
index be91929c6..8d876fc1f 100644 index be91929c62e1..8d876fc1fa2f 100644
--- a/lldb/include/lldb/Core/PluginManager.h --- a/lldb/include/lldb/Core/PluginManager.h
+++ b/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h
@@ -508,6 +508,17 @@ public: @@ -508,6 +508,17 @@ public:
@ -64,7 +103,7 @@ index be91929c6..8d876fc1f 100644
} // namespace lldb_private } // namespace lldb_private
diff --git a/lldb/include/lldb/Expression/DWARFEvaluator.h b/lldb/include/lldb/Expression/DWARFEvaluator.h diff --git a/lldb/include/lldb/Expression/DWARFEvaluator.h b/lldb/include/lldb/Expression/DWARFEvaluator.h
new file mode 100644 new file mode 100644
index 000000000..6811cbeae index 000000000000..6811cbeae3d3
--- /dev/null --- /dev/null
+++ b/lldb/include/lldb/Expression/DWARFEvaluator.h +++ b/lldb/include/lldb/Expression/DWARFEvaluator.h
@@ -0,0 +1,110 @@ @@ -0,0 +1,110 @@
@ -180,7 +219,7 @@ index 000000000..6811cbeae
+#endif // LLDB_EXPRESSION_DWARFEVALUATOR_H +#endif // LLDB_EXPRESSION_DWARFEVALUATOR_H
diff --git a/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h b/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h diff --git a/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h b/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h
new file mode 100644 new file mode 100644
index 000000000..f3b496c58 index 000000000000..f3b496c580e4
--- /dev/null --- /dev/null
+++ b/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h +++ b/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h
@@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
@ -241,7 +280,7 @@ index 000000000..f3b496c58
+ +
+#endif // LLDB_EXPRESSION_DWARFEVALUATORFACTORY_H +#endif // LLDB_EXPRESSION_DWARFEVALUATORFACTORY_H
diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index 1490ac2d6..35c741d4e 100644 index 1490ac2d614a..35c741d4e6ba 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h --- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -120,6 +120,10 @@ public: @@ -120,6 +120,10 @@ public:
@ -275,7 +314,7 @@ index 1490ac2d6..35c741d4e 100644
GetLocationExpression(lldb::addr_t load_function_start, GetLocationExpression(lldb::addr_t load_function_start,
lldb::addr_t addr) const; lldb::addr_t addr) const;
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index aaa2470d2..c15f2db52 100644 index aaa2470d2931..c15f2db52fbc 100644
--- a/lldb/include/lldb/Target/Process.h --- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h
@@ -1434,7 +1434,7 @@ public: @@ -1434,7 +1434,7 @@ public:
@ -288,7 +327,7 @@ index aaa2470d2..c15f2db52 100644
/// Read of memory from a process. /// Read of memory from a process.
/// ///
diff --git a/lldb/include/lldb/Target/ProcessTrace.h b/lldb/include/lldb/Target/ProcessTrace.h diff --git a/lldb/include/lldb/Target/ProcessTrace.h b/lldb/include/lldb/Target/ProcessTrace.h
index 7b9d6b13d..9525fc975 100644 index 7b9d6b13dd6f..9525fc9750fd 100644
--- a/lldb/include/lldb/Target/ProcessTrace.h --- a/lldb/include/lldb/Target/ProcessTrace.h
+++ b/lldb/include/lldb/Target/ProcessTrace.h +++ b/lldb/include/lldb/Target/ProcessTrace.h
@@ -59,7 +59,7 @@ public: @@ -59,7 +59,7 @@ public:
@ -301,7 +340,7 @@ index 7b9d6b13d..9525fc975 100644
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
Status &error) override; Status &error) override;
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index ad5298151..5a3c0b27a 100644 index ad5298151e4a..5a3c0b27a738 100644
--- a/lldb/include/lldb/lldb-forward.h --- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h
@@ -74,6 +74,7 @@ class Disassembler; @@ -74,6 +74,7 @@ class Disassembler;
@ -313,7 +352,7 @@ index ad5298151..5a3c0b27a 100644
class EmulateInstruction; class EmulateInstruction;
class Environment; class Environment;
diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h
index 2ed083ec8..f4d500d19 100644 index 2ed083ec8ae9..f4d500d198e8 100644
--- a/lldb/include/lldb/lldb-private-interfaces.h --- a/lldb/include/lldb/lldb-private-interfaces.h
+++ b/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h
@@ -113,6 +113,8 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error, @@ -113,6 +113,8 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error,
@ -326,7 +365,7 @@ index 2ed083ec8..f4d500d19 100644
/// \{ /// \{
typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForSessionFile)( typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForSessionFile)(
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 19c97be15..1647f93ec 100644 index 19c97be15066..1647f93ec4f3 100644
--- a/lldb/source/Core/Module.cpp --- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
@ -348,7 +387,7 @@ index 19c97be15..1647f93ec 100644
+ return m_dwarf_evaluator_factory.get(); + return m_dwarf_evaluator_factory.get();
+} +}
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index fcaa868b0..59a404d4a 100644 index fcaa868b083e..59a404d4a7e1 100644
--- a/lldb/source/Core/PluginManager.cpp --- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp
@@ -1597,3 +1597,32 @@ bool PluginManager::CreateSettingForStructuredDataPlugin( @@ -1597,3 +1597,32 @@ bool PluginManager::CreateSettingForStructuredDataPlugin(
@ -385,7 +424,7 @@ index fcaa868b0..59a404d4a 100644
+ return GetDWARFEvaluatorFactoryInstances().GetCallbackAtIndex(idx); + return GetDWARFEvaluatorFactoryInstances().GetCallbackAtIndex(idx);
+} +}
diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
index fb57c0fed..f92d6a54d 100644 index fb57c0fedf04..f92d6a54de94 100644
--- a/lldb/source/Core/Value.cpp --- a/lldb/source/Core/Value.cpp
+++ b/lldb/source/Core/Value.cpp +++ b/lldb/source/Core/Value.cpp
@@ -538,7 +538,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, @@ -538,7 +538,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
@ -398,7 +437,7 @@ index fb57c0fed..f92d6a54d 100644
error.SetErrorStringWithFormat( error.SetErrorStringWithFormat(
"read memory from 0x%" PRIx64 " failed (%u of %u bytes read)", "read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 9c1ba99da..b15b214b2 100644 index 9c1ba99da1d0..b15b214b2a2f 100644
--- a/lldb/source/Core/ValueObject.cpp --- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp
@@ -735,7 +735,7 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx, @@ -735,7 +735,7 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
@ -411,7 +450,7 @@ index 9c1ba99da..b15b214b2 100644
data.SetData(data_sp); data.SetData(data_sp);
return bytes_read; return bytes_read;
diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt
index bf94361dd..4e76d547a 100644 index bf94361dd6c1..4e76d547aeaf 100644
--- a/lldb/source/Expression/CMakeLists.txt --- a/lldb/source/Expression/CMakeLists.txt
+++ b/lldb/source/Expression/CMakeLists.txt +++ b/lldb/source/Expression/CMakeLists.txt
@@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
@ -424,7 +463,7 @@ index bf94361dd..4e76d547a 100644
ExpressionVariable.cpp ExpressionVariable.cpp
diff --git a/lldb/source/Expression/DWARFEvaluator.cpp b/lldb/source/Expression/DWARFEvaluator.cpp diff --git a/lldb/source/Expression/DWARFEvaluator.cpp b/lldb/source/Expression/DWARFEvaluator.cpp
new file mode 100644 new file mode 100644
index 000000000..06107e136 index 000000000000..06107e136197
--- /dev/null --- /dev/null
+++ b/lldb/source/Expression/DWARFEvaluator.cpp +++ b/lldb/source/Expression/DWARFEvaluator.cpp
@@ -0,0 +1,1952 @@ @@ -0,0 +1,1952 @@
@ -2382,7 +2421,7 @@ index 000000000..06107e136
+} +}
diff --git a/lldb/source/Expression/DWARFEvaluatorFactory.cpp b/lldb/source/Expression/DWARFEvaluatorFactory.cpp diff --git a/lldb/source/Expression/DWARFEvaluatorFactory.cpp b/lldb/source/Expression/DWARFEvaluatorFactory.cpp
new file mode 100644 new file mode 100644
index 000000000..c06126412 index 000000000000..c0612641204a
--- /dev/null --- /dev/null
+++ b/lldb/source/Expression/DWARFEvaluatorFactory.cpp +++ b/lldb/source/Expression/DWARFEvaluatorFactory.cpp
@@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
@ -2444,7 +2483,7 @@ index 000000000..c06126412
+ object_address_ptr); + object_address_ptr);
+} +}
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index a10546c1d..4d13e4642 100644 index a10546c1deae..4d13e4642af3 100644
--- a/lldb/source/Expression/DWARFExpression.cpp --- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
@ -4261,7 +4300,7 @@ index a10546c1d..4d13e4642 100644
static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc, static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc,
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index 00e9ccb76..2137a1ac8 100644 index 00e9ccb762c3..2137a1ac8324 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp --- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -759,6 +759,24 @@ void CommandInterpreter::LoadCommandDictionary() { @@ -759,6 +759,24 @@ void CommandInterpreter::LoadCommandDictionary() {
@ -4290,7 +4329,7 @@ index 00e9ccb76..2137a1ac8 100644
new CommandObjectRegexCommand( new CommandObjectRegexCommand(
*this, "kdp-remote", *this, "kdp-remote",
diff --git a/lldb/source/Plugins/CMakeLists.txt b/lldb/source/Plugins/CMakeLists.txt diff --git a/lldb/source/Plugins/CMakeLists.txt b/lldb/source/Plugins/CMakeLists.txt
index 9181a4e47..2be6ec365 100644 index 9181a4e47675..2be6ec3657c0 100644
--- a/lldb/source/Plugins/CMakeLists.txt --- a/lldb/source/Plugins/CMakeLists.txt
+++ b/lldb/source/Plugins/CMakeLists.txt +++ b/lldb/source/Plugins/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory(ABI) @@ -2,6 +2,7 @@ add_subdirectory(ABI)
@ -4320,14 +4359,14 @@ index 9181a4e47..2be6ec365 100644
endif() endif()
diff --git a/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt b/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt diff --git a/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt b/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt
new file mode 100644 new file mode 100644
index 000000000..73fad41e1 index 000000000000..73fad41e1a72
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt +++ b/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt
@@ -0,0 +1 @@ @@ -0,0 +1 @@
+add_subdirectory(wasm) +add_subdirectory(wasm)
diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt b/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt b/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt
new file mode 100644 new file mode 100644
index 000000000..e50b1bef7 index 000000000000..e50b1bef7e69
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt
@@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
@ -4343,7 +4382,7 @@ index 000000000..e50b1bef7
+ ) + )
diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp
new file mode 100644 new file mode 100644
index 000000000..fdda1991d index 000000000000..fdda1991d19f
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp
@@ -0,0 +1,126 @@ @@ -0,0 +1,126 @@
@ -4475,7 +4514,7 @@ index 000000000..fdda1991d
+} +}
diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h
new file mode 100644 new file mode 100644
index 000000000..a01159064 index 000000000000..a01159064a39
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h
@@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
@ -4528,7 +4567,7 @@ index 000000000..a01159064
+#endif // LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATOR_H +#endif // LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATOR_H
diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp
new file mode 100644 new file mode 100644
index 000000000..d43e96a34 index 000000000000..d43e96a34d37
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp
@@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
@ -4598,7 +4637,7 @@ index 000000000..d43e96a34
+} +}
diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h
new file mode 100644 new file mode 100644
index 000000000..8a946592a index 000000000000..8a946592a09a
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h
@@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
@ -4658,7 +4697,7 @@ index 000000000..8a946592a
+ +
+#endif // LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATORFACTORY_H +#endif // LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATORFACTORY_H
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
index ae7e011ea..24ea75d19 100644 index ae7e011eaa52..24ea75d1971c 100644
--- a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp --- a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
@@ -62,6 +62,15 @@ void DynamicLoaderWasmDYLD::DidAttach() { @@ -62,6 +62,15 @@ void DynamicLoaderWasmDYLD::DidAttach() {
@ -4678,7 +4717,7 @@ index ae7e011ea..24ea75d19 100644
ThreadPlanSP DynamicLoaderWasmDYLD::GetStepThroughTrampolinePlan(Thread &thread, ThreadPlanSP DynamicLoaderWasmDYLD::GetStepThroughTrampolinePlan(Thread &thread,
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 5272da9ab..abc5523bf 100644 index 5272da9ab33a..abc5523bfd70 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp --- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp +++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
@ -4718,7 +4757,7 @@ index 5272da9ab..abc5523bf 100644
} }
} }
diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt
index 5f284e517..6084cbc93 100644 index 5f284e517dca..6084cbc9378d 100644
--- a/lldb/source/Plugins/Platform/CMakeLists.txt --- a/lldb/source/Plugins/Platform/CMakeLists.txt
+++ b/lldb/source/Plugins/Platform/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/CMakeLists.txt
@@ -15,3 +15,4 @@ @@ -15,3 +15,4 @@
@ -4728,7 +4767,7 @@ index 5f284e517..6084cbc93 100644
+add_subdirectory(wasm-remote) +add_subdirectory(wasm-remote)
diff --git a/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt b/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt diff --git a/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt b/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt
new file mode 100644 new file mode 100644
index 000000000..4a65765a5 index 000000000000..4a65765a5659
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt
@@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
@ -4744,7 +4783,7 @@ index 000000000..4a65765a5
+ ) + )
diff --git a/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp diff --git a/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp
new file mode 100644 new file mode 100644
index 000000000..f26d11f00 index 000000000000..f26d11f00e5c
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp +++ b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp
@@ -0,0 +1,139 @@ @@ -0,0 +1,139 @@
@ -4890,7 +4929,7 @@ index 000000000..f26d11f00
\ No newline at end of file \ No newline at end of file
diff --git a/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h diff --git a/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h
new file mode 100644 new file mode 100644
index 000000000..f306a79d3 index 000000000000..f306a79d3f4f
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h +++ b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h
@@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
@ -4933,7 +4972,7 @@ index 000000000..f306a79d3
+#endif +#endif
\ No newline at end of file \ No newline at end of file
diff --git a/lldb/source/Plugins/Plugins.def.in b/lldb/source/Plugins/Plugins.def.in diff --git a/lldb/source/Plugins/Plugins.def.in b/lldb/source/Plugins/Plugins.def.in
index bf54598fb..b0bd7b996 100644 index bf54598fb2f3..b0bd7b9965fe 100644
--- a/lldb/source/Plugins/Plugins.def.in --- a/lldb/source/Plugins/Plugins.def.in
+++ b/lldb/source/Plugins/Plugins.def.in +++ b/lldb/source/Plugins/Plugins.def.in
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
@ -4945,7 +4984,7 @@ index bf54598fb..b0bd7b996 100644
#undef LLDB_PLUGIN #undef LLDB_PLUGIN
diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt
index bea5bac9e..7a0855e02 100644 index bea5bac9eb21..7a0855e02ca2 100644
--- a/lldb/source/Plugins/Process/CMakeLists.txt --- a/lldb/source/Plugins/Process/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/CMakeLists.txt +++ b/lldb/source/Plugins/Process/CMakeLists.txt
@@ -18,3 +18,4 @@ add_subdirectory(Utility) @@ -18,3 +18,4 @@ add_subdirectory(Utility)
@ -4954,7 +4993,7 @@ index bea5bac9e..7a0855e02 100644
add_subdirectory(minidump) add_subdirectory(minidump)
+add_subdirectory(wasm) +add_subdirectory(wasm)
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 12bc7390c..707ab85e5 100644 index 12bc7390c729..707ab85e5615 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -285,7 +285,7 @@ bool ProcessElfCore::IsAlive() { return true; } @@ -285,7 +285,7 @@ bool ProcessElfCore::IsAlive() { return true; }
@ -4967,7 +5006,7 @@ index 12bc7390c..707ab85e5 100644
// in core files we have it all cached our our core file anyway. // in core files we have it all cached our our core file anyway.
return DoReadMemory(addr, buf, size, error); return DoReadMemory(addr, buf, size, error);
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index d8e3cc9ae..f0bf9c4d3 100644 index d8e3cc9ae3e1..f0bf9c4d3b00 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -84,7 +84,8 @@ public: @@ -84,7 +84,8 @@ public:
@ -4981,7 +5020,7 @@ index d8e3cc9ae..f0bf9c4d3 100644
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Status &error) override; lldb_private::Status &error) override;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 6914b3734..bb8a05604 100644 index 6914b37348ea..bb8a056049f3 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -334,6 +334,11 @@ ConstString ProcessGDBRemote::GetPluginName() { return GetPluginNameStatic(); } @@ -334,6 +334,11 @@ ConstString ProcessGDBRemote::GetPluginName() { return GetPluginNameStatic(); }
@ -5015,7 +5054,7 @@ index 6914b3734..bb8a05604 100644
} }
} }
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index fe04cdddd..e4a14c645 100644 index fe04cdddd0f5..e4a14c64579a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -237,6 +237,8 @@ protected: @@ -237,6 +237,8 @@ protected:
@ -5028,7 +5067,7 @@ index fe04cdddd..e4a14c645 100644
enum { enum {
eBroadcastBitAsyncContinue = (1 << 0), eBroadcastBitAsyncContinue = (1 << 0),
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 84548edb5..0ae6f7e4a 100644 index 84548edb5caa..0ae6f7e4a177 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -596,7 +596,7 @@ bool ProcessMachCore::WarnBeforeDetach() const { return false; } @@ -596,7 +596,7 @@ bool ProcessMachCore::WarnBeforeDetach() const { return false; }
@ -5041,7 +5080,7 @@ index 84548edb5..0ae6f7e4a 100644
// in core files we have it all cached our our core file anyway. // in core files we have it all cached our our core file anyway.
return DoReadMemory(addr, buf, size, error); return DoReadMemory(addr, buf, size, error);
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
index db77e96f1..1c930896c 100644 index db77e96f1072..1c930896c743 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -65,7 +65,8 @@ public: @@ -65,7 +65,8 @@ public:
@ -5055,7 +5094,7 @@ index db77e96f1..1c930896c 100644
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Status &error) override; lldb_private::Status &error) override;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 385557422..d8bb21581 100644 index 385557422758..d8bb21581086 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -374,7 +374,7 @@ bool ProcessMinidump::IsAlive() { return true; } @@ -374,7 +374,7 @@ bool ProcessMinidump::IsAlive() { return true; }
@ -5068,7 +5107,7 @@ index 385557422..d8bb21581 100644
// we have it all cached in our dump file anyway. // we have it all cached in our dump file anyway.
return DoReadMemory(addr, buf, size, error); return DoReadMemory(addr, buf, size, error);
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 27b0da004..e94ecab43 100644 index 27b0da0047a5..e94ecab430c1 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -69,8 +69,8 @@ public: @@ -69,8 +69,8 @@ public:
@ -5084,7 +5123,7 @@ index 27b0da004..e94ecab43 100644
Status &error) override; Status &error) override;
diff --git a/lldb/source/Plugins/Process/wasm/CMakeLists.txt b/lldb/source/Plugins/Process/wasm/CMakeLists.txt diff --git a/lldb/source/Plugins/Process/wasm/CMakeLists.txt b/lldb/source/Plugins/Process/wasm/CMakeLists.txt
new file mode 100644 new file mode 100644
index 000000000..61efb933f index 000000000000..61efb933fa62
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/CMakeLists.txt +++ b/lldb/source/Plugins/Process/wasm/CMakeLists.txt
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
@ -5102,7 +5141,7 @@ index 000000000..61efb933f
+ ) + )
diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
new file mode 100644 new file mode 100644
index 000000000..9c0fc7b7f index 000000000000..9c0fc7b7f270
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
@@ -0,0 +1,261 @@ @@ -0,0 +1,261 @@
@ -5369,7 +5408,7 @@ index 000000000..9c0fc7b7f
+} +}
diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.h b/lldb/source/Plugins/Process/wasm/ProcessWasm.h diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.h b/lldb/source/Plugins/Process/wasm/ProcessWasm.h
new file mode 100644 new file mode 100644
index 000000000..d3aece7a6 index 000000000000..d3aece7a6554
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.h +++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.h
@@ -0,0 +1,128 @@ @@ -0,0 +1,128 @@
@ -5503,7 +5542,7 @@ index 000000000..d3aece7a6
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_WASM_PROCESSWASM_H +#endif // LLDB_SOURCE_PLUGINS_PROCESS_WASM_PROCESSWASM_H
diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp
new file mode 100644 new file mode 100644
index 000000000..fa02073e7 index 000000000000..fa02073e7a52
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
@ -5544,7 +5583,7 @@ index 000000000..fa02073e7
+} +}
diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.h b/lldb/source/Plugins/Process/wasm/ThreadWasm.h diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.h b/lldb/source/Plugins/Process/wasm/ThreadWasm.h
new file mode 100644 new file mode 100644
index 000000000..0a33c07de index 000000000000..0a33c07de994
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.h +++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.h
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
@ -5591,7 +5630,7 @@ index 000000000..0a33c07de
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_WASM_THREADWASM_H +#endif // LLDB_SOURCE_PLUGINS_PROCESS_WASM_THREADWASM_H
diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
new file mode 100644 new file mode 100644
index 000000000..1a195cb93 index 000000000000..1a195cb9361a
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
@@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
@ -5672,7 +5711,7 @@ index 000000000..1a195cb93
\ No newline at end of file \ No newline at end of file
diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.h b/lldb/source/Plugins/Process/wasm/UnwindWasm.h diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.h b/lldb/source/Plugins/Process/wasm/UnwindWasm.h
new file mode 100644 new file mode 100644
index 000000000..9bd1dac9a index 000000000000..9bd1dac9a98a
--- /dev/null --- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.h +++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.h
@@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
@ -5732,7 +5771,7 @@ index 000000000..9bd1dac9a
+ +
+#endif // lldb_UnwindWasm_h_ +#endif // lldb_UnwindWasm_h_
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ccaf31317..c3ef5aebd 100644 index ccaf31317d75..c3ef5aebd46d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3212,8 +3212,13 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, @@ -3212,8 +3212,13 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
@ -5751,7 +5790,7 @@ index ccaf31317..c3ef5aebd 100644
// DWARF doesn't specify if a DW_TAG_variable is a local, global // DWARF doesn't specify if a DW_TAG_variable is a local, global
// or static variable, so we have to do a little digging: // or static variable, so we have to do a little digging:
diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp
index b660c310e..cd76421ce 100644 index b660c310ef31..cd76421cec18 100644
--- a/lldb/source/Target/PathMappingList.cpp --- a/lldb/source/Target/PathMappingList.cpp
+++ b/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp
@@ -218,7 +218,12 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co @@ -218,7 +218,12 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co
@ -5769,7 +5808,7 @@ index b660c310e..cd76421ce 100644
return {}; return {};
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index a77ecddfb..e257f9350 100644 index a77ecddfbab6..e257f93508f6 100644
--- a/lldb/source/Target/Platform.cpp --- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp
@@ -1970,6 +1970,12 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, @@ -1970,6 +1970,12 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
@ -5786,7 +5825,7 @@ index a77ecddfb..e257f9350 100644
return 0; return 0;
} }
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 8ecc66b59..f14898791 100644 index 8ecc66b592ea..f148987915de 100644
--- a/lldb/source/Target/Process.cpp --- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp
@@ -1892,7 +1892,8 @@ Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) { @@ -1892,7 +1892,8 @@ Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) {
@ -5800,7 +5839,7 @@ index 8ecc66b59..f14898791 100644
if (!GetDisableMemoryCache()) { if (!GetDisableMemoryCache()) {
#if defined(VERIFY_MEMORY_READS) #if defined(VERIFY_MEMORY_READS)
diff --git a/lldb/source/Target/ProcessTrace.cpp b/lldb/source/Target/ProcessTrace.cpp diff --git a/lldb/source/Target/ProcessTrace.cpp b/lldb/source/Target/ProcessTrace.cpp
index c878a2ac4..ad5945b0a 100644 index c878a2ac4eb9..ad5945b0ad1f 100644
--- a/lldb/source/Target/ProcessTrace.cpp --- a/lldb/source/Target/ProcessTrace.cpp
+++ b/lldb/source/Target/ProcessTrace.cpp +++ b/lldb/source/Target/ProcessTrace.cpp
@@ -88,7 +88,7 @@ void ProcessTrace::RefreshStateAfterStop() {} @@ -88,7 +88,7 @@ void ProcessTrace::RefreshStateAfterStop() {}
@ -5813,7 +5852,7 @@ index c878a2ac4..ad5945b0a 100644
// we have it all cached in the trace files. // we have it all cached in the trace files.
return DoReadMemory(addr, buf, size, error); return DoReadMemory(addr, buf, size, error);
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp
index 896e647bb..f76307016 100644 index 896e647bbb52..f76307016102 100644
--- a/lldb/source/Target/ThreadPlanStepRange.cpp --- a/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -334,7 +334,10 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { @@ -334,7 +334,10 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
@ -5829,7 +5868,7 @@ index 896e647bb..f76307016 100644
instructions->GetInstructionAtIndex(last_index); instructions->GetInstructionAtIndex(last_index);
size_t last_inst_size = last_inst->GetOpcode().GetByteSize(); size_t last_inst_size = last_inst->GetOpcode().GetByteSize();
diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp
index 4ec2e25c7..24c88fe9a 100644 index 4ec2e25c7e3b..24c88fe9ae4f 100644
--- a/lldb/source/Target/UnixSignals.cpp --- a/lldb/source/Target/UnixSignals.cpp
+++ b/lldb/source/Target/UnixSignals.cpp +++ b/lldb/source/Target/UnixSignals.cpp
@@ -46,6 +46,8 @@ lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) { @@ -46,6 +46,8 @@ lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) {
@ -5842,7 +5881,7 @@ index 4ec2e25c7..24c88fe9a 100644
return std::make_shared<UnixSignals>(); return std::make_shared<UnixSignals>();
} }
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h
index 4310ba9ce..297b33879 100644 index 4310ba9ce9e0..297b3387999d 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h --- a/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
@ -5854,7 +5893,7 @@ index 4310ba9ce..297b33879 100644
#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h" #include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h" #include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index 753b1998c..27370c62d 100644 index 753b1998c40c..27370c62dd6e 100644
--- a/llvm/include/llvm/Support/MathExtras.h --- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@

View File

@ -91,8 +91,10 @@ endif ()
if (WAMR_BUILD_LIBC_UVWASI EQUAL 1) if (WAMR_BUILD_LIBC_UVWASI EQUAL 1)
include (${IWASM_DIR}/libraries/libc-uvwasi/libc_uvwasi.cmake) include (${IWASM_DIR}/libraries/libc-uvwasi/libc_uvwasi.cmake)
set (WAMR_BUILD_MODULE_INST_CONTEXT 1)
elseif (WAMR_BUILD_LIBC_WASI EQUAL 1) elseif (WAMR_BUILD_LIBC_WASI EQUAL 1)
include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake) include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake)
set (WAMR_BUILD_MODULE_INST_CONTEXT 1)
endif () endif ()
if (WAMR_BUILD_LIB_PTHREAD_SEMAPHORE EQUAL 1) if (WAMR_BUILD_LIB_PTHREAD_SEMAPHORE EQUAL 1)

32
ci/pre_commit_hook_sample Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
# Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# This is a sample of pre-commit hook that can be used to make your code fit the WAMR CI code style requirements.
# You need to have clang-format-12 installed to use this hook.
# To add this pre-commit hook, copy it to <path_to_wamr>/.git/hooks/pre-commit
# (you don't need any extensions here)
# Function to check if a file has a C or C++ extension
is_c_or_cpp_file() {
file="$1"
if [[ "$filename" =~ \.(h|c|cpp)$ ]]; then
return 0
else
return 1
fi
}
# Loop through staged files and apply command "abc" to C and C++ files
for staged_file in $(git diff --cached --name-only); do
if is_c_or_cpp_file "$staged_file"; then
clang-format-12 -Werror --style file --dry-run "$staged_file" 2>/dev/null
if [ $? -ne 0 ]; then
echo "Issues are found in $staged_file. Applying the fix"
clang-format-12 --style file -i "$staged_file"
fi
git add "$staged_file" # Add the modified file back to staging
fi
done

15
ci/setup.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
# Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# This script executes some commands to make your onboarding with WAMR easier.
# For example, setting pre-commit hook that will make your code complaint with the
# code style requirements checked in WAMR CI
echo "Copy the pre-commit hook to your hooks folder"
cp pre_commit_hook_sample ../.git/hooks/pre-commit
# Feel free to propose your commands to this script to make developing WAMR easier
echo "Setup is done"

128
ci/validate_lldb.py Executable file
View File

@ -0,0 +1,128 @@
#!/usr/bin/env python3
#
# Copyright (C) 2023 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
import argparse
import time
from pathlib import Path
import subprocess, shlex
SCRIPT_DIR = Path(__file__).parent.resolve()
REPO_ROOT_DIR = SCRIPT_DIR.parent
SAMPLE_CODE_FILE = REPO_ROOT_DIR / 'product-mini/app-samples/hello-world/main.c'
WASM_OUT_FILE = SCRIPT_DIR / 'out.wasm'
parser = argparse.ArgumentParser(
description="Validate the customized lldb with sample code"
)
parser.add_argument(
"-l", "--lldb", dest='lldb', default='lldb', help="path to lldb executable"
)
parser.add_argument(
"-w", "--wamr", dest='wamr', default='iwasm', help="path to iwasm executable"
)
parser.add_argument(
"-p", "--port", dest='port', default='1234', help="debug server listen port"
)
parser.add_argument(
"-v", "--verbose", dest='verbose', action='store_true', default=False, help="display lldb stdout"
)
options = parser.parse_args()
lldb_command_epilogue = '-o q'
test_cases = {
'run_to_exit': '-o c',
'func_breakpoint': '-o "b main" -o c -o c',
'line_breakpoint': '-o "b main.c:12" -o c -o c',
'break_on_unknown_func': '-o "b not_a_func" -o c',
'watch_point': '-o "b main" -o c -o "watchpoint set variable buf" -o c -o "fr v buf" -o c',
}
# Step1: Build wasm module with debug information
build_cmd = f'/opt/wasi-sdk/bin/clang -g -O0 -o {WASM_OUT_FILE} {SAMPLE_CODE_FILE}'
try:
print(f'building wasm module ...', end='', flush=True)
subprocess.check_call(shlex.split(build_cmd))
print(f'\t OK')
except subprocess.CalledProcessError:
print("Failed to build wasm module with debug information")
exit(1)
def print_process_output(p):
try:
outs, errs = p.communicate(timeout=2)
print("stdout:")
print(outs)
print("stderr:")
print(errs)
except subprocess.TimeoutExpired:
print("Failed to get process output")
# Step2: Launch WAMR in debug mode and validate lldb commands
iteration = 0
for case, cmd in test_cases.items():
lldb_command_prologue = f'{options.lldb} -o "process connect -p wasm connect://127.0.0.1:{int(options.port) + iteration}"'
wamr_cmd = f'{options.wamr} -g=127.0.0.1:{int(options.port) + iteration} {WASM_OUT_FILE}'
iteration += 1
has_error = False
print(f'validating case [{case}] ...', end='', flush=True)
lldb_cmd = f'{lldb_command_prologue} {cmd} {lldb_command_epilogue}'
wamr_process = subprocess.Popen(shlex.split(
wamr_cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
time.sleep(0.1)
if (wamr_process.poll() != None):
print("\nWAMR doesn't wait for lldb connection")
print_process_output(wamr_process)
exit(1)
lldb_process = subprocess.Popen(shlex.split(
lldb_cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
if (options.verbose):
while (lldb_process.poll() is None):
print(lldb_process.stdout.read(), end='', flush=True)
try:
if (lldb_process.wait(5) != 0):
print(f"\nFailed to validate case [{case}]")
print_process_output(lldb_process)
has_error = True
if wamr_process.wait(2) != 0:
print("\nWAMR process doesn't exit normally")
print_process_output(wamr_process)
has_error = True
except subprocess.TimeoutExpired:
print(f"\nFailed to validate case [{case}]")
print("wamr output:")
print_process_output(wamr_process)
print("lldb output:")
print_process_output(lldb_process)
has_error = True
finally:
if (lldb_process.poll() == None):
print(f'\nterminating lldb process [{lldb_process.pid}]')
lldb_process.kill()
if (wamr_process.poll() == None):
print(f'terminating wamr process [{wamr_process.pid}]')
wamr_process.kill()
if (has_error):
exit(1)
print(f'\t OK')
# wait 100ms to ensure the socket is closed
time.sleep(0.1)
print('Validate lldb success')
exit(0)

View File

@ -144,6 +144,14 @@
#define WASM_ENABLE_WASI_NN 0 #define WASM_ENABLE_WASI_NN 0
#endif #endif
#ifndef WASM_ENABLE_WASI_NN_GPU
#define WASM_ENABLE_WASI_NN_GPU 0
#endif
#ifndef WASM_ENABLE_WASI_NN_EXTERNAL_DELEGATE
#define WASM_ENABLE_WASI_NN_EXTERNAL_DELEGATE 0
#endif
/* Default disable libc emcc */ /* Default disable libc emcc */
#ifndef WASM_ENABLE_LIBC_EMCC #ifndef WASM_ENABLE_LIBC_EMCC
#define WASM_ENABLE_LIBC_EMCC 0 #define WASM_ENABLE_LIBC_EMCC 0
@ -384,7 +392,7 @@
#define APP_THREAD_STACK_SIZE_DEFAULT (64 * 1024) #define APP_THREAD_STACK_SIZE_DEFAULT (64 * 1024)
#define APP_THREAD_STACK_SIZE_MIN (48 * 1024) #define APP_THREAD_STACK_SIZE_MIN (48 * 1024)
#else #else
#define APP_THREAD_STACK_SIZE_DEFAULT (32 * 1024) #define APP_THREAD_STACK_SIZE_DEFAULT (64 * 1024)
#define APP_THREAD_STACK_SIZE_MIN (24 * 1024) #define APP_THREAD_STACK_SIZE_MIN (24 * 1024)
#endif #endif
#endif /* end of !(defined(APP_THREAD_STACK_SIZE_DEFAULT) \ #endif /* end of !(defined(APP_THREAD_STACK_SIZE_DEFAULT) \
@ -460,4 +468,25 @@
#define WASM_DISABLE_WRITE_GS_BASE 0 #define WASM_DISABLE_WRITE_GS_BASE 0
#endif #endif
/* Configurable bounds checks */
#ifndef WASM_CONFIGURABLE_BOUNDS_CHECKS
#define WASM_CONFIGURABLE_BOUNDS_CHECKS 0
#endif
/* Some chip cannot support external ram with rwx attr at the same time,
it has to map it into 2 spaces of idbus and dbus, code in dbus can be
read/written and read/executed in ibus. so there are 2 steps to execute
the code, first, copy&do relocaiton in dbus space, and second execute
it in ibus space, since in the 2 spaces the contents are the same,
so we call it bus mirror.
*/
#ifndef WASM_MEM_DUAL_BUS_MIRROR
#define WASM_MEM_DUAL_BUS_MIRROR 0
#endif
/* The max number of module instance contexts. */
#ifndef WASM_MAX_INSTANCE_CONTEXTS
#define WASM_MAX_INSTANCE_CONTEXTS 8
#endif
#endif /* end of _CONFIG_H_ */ #endif /* end of _CONFIG_H_ */

View File

@ -648,6 +648,42 @@ add_f64_common_intrinsics(AOTCompContext *comp_ctx)
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F64_CMP); add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F64_CMP);
} }
static void
add_f32xi32_intrinsics(AOTCompContext *comp_ctx)
{
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F32_TO_I32);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F32_TO_U32);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_TO_F32);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_U32_TO_F32);
}
static void
add_f64xi32_intrinsics(AOTCompContext *comp_ctx)
{
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F64_TO_I32);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F64_TO_U32);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_TO_F64);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_U32_TO_F64);
}
static void
add_f32xi64_intrinsics(AOTCompContext *comp_ctx)
{
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F32_TO_I64);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F32_TO_U64);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_TO_F32);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_U64_TO_F32);
}
static void
add_f64xi64_intrinsics(AOTCompContext *comp_ctx)
{
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F64_TO_I64);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F64_TO_U64);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_TO_F64);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_U64_TO_F64);
}
static void static void
add_common_float_integer_convertion(AOTCompContext *comp_ctx) add_common_float_integer_convertion(AOTCompContext *comp_ctx)
{ {
@ -705,8 +741,101 @@ aot_intrinsic_check_capability(const AOTCompContext *comp_ctx,
void void
aot_intrinsic_fill_capability_flags(AOTCompContext *comp_ctx) aot_intrinsic_fill_capability_flags(AOTCompContext *comp_ctx)
{ {
uint32 i;
memset(comp_ctx->flags, 0, sizeof(comp_ctx->flags)); memset(comp_ctx->flags, 0, sizeof(comp_ctx->flags));
/* Intrinsics from command line have highest priority */
if (comp_ctx->builtin_intrinsics) {
/* Handle 'all' group */
if (strstr(comp_ctx->builtin_intrinsics, "all")) {
for (i = 0; i < g_intrinsic_count; i++) {
add_intrinsic_capability(comp_ctx, g_intrinsic_mapping[i].flag);
}
return;
}
/* Handle 'i32.common' group */
if (strstr(comp_ctx->builtin_intrinsics, "i32.common")) {
add_i32_common_intrinsics(comp_ctx);
}
/* Handle 'i64.common' group */
if (strstr(comp_ctx->builtin_intrinsics, "i64.common")) {
add_i64_common_intrinsics(comp_ctx);
}
/* Handle 'fp.common' group */
if (strstr(comp_ctx->builtin_intrinsics, "fp.common")) {
add_f32_common_intrinsics(comp_ctx);
add_f64_common_intrinsics(comp_ctx);
}
/* Handle 'f32.common' group */
if (strstr(comp_ctx->builtin_intrinsics, "f32.common")) {
add_f32_common_intrinsics(comp_ctx);
}
/* Handle 'f64.common' group */
if (strstr(comp_ctx->builtin_intrinsics, "f64.common")) {
add_f64_common_intrinsics(comp_ctx);
}
/* Handle 'f32xi32' group */
if (strstr(comp_ctx->builtin_intrinsics, "f32xi32")) {
add_f32xi32_intrinsics(comp_ctx);
}
/* Handle 'f64xi32' group */
if (strstr(comp_ctx->builtin_intrinsics, "f64xi32")) {
add_f64xi32_intrinsics(comp_ctx);
}
/* Handle 'f32xi64' group */
if (strstr(comp_ctx->builtin_intrinsics, "f32xi64")) {
add_f32xi64_intrinsics(comp_ctx);
}
/* Handle 'f64xi64' group */
if (strstr(comp_ctx->builtin_intrinsics, "f64xi64")) {
add_f64xi64_intrinsics(comp_ctx);
}
/* Handle 'fpxint' group */
if (strstr(comp_ctx->builtin_intrinsics, "fpxint")) {
add_f32xi32_intrinsics(comp_ctx);
add_f64xi32_intrinsics(comp_ctx);
add_f32xi64_intrinsics(comp_ctx);
add_f64xi64_intrinsics(comp_ctx);
}
/* Handle 'constop' group */
if (strstr(comp_ctx->builtin_intrinsics, "constop")) {
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_CONST);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_CONST);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F32_CONST);
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_F64_CONST);
}
/* Handle 'fp.common' group */
if (strstr(comp_ctx->builtin_intrinsics, "fp.common")) {
add_f32_common_intrinsics(comp_ctx);
add_f64_common_intrinsics(comp_ctx);
}
/* Handle other single items */
for (i = 0; i < g_intrinsic_count; i++) {
if (strstr(comp_ctx->builtin_intrinsics,
g_intrinsic_mapping[i].llvm_intrinsic)) {
add_intrinsic_capability(comp_ctx, g_intrinsic_mapping[i].flag);
}
}
return;
}
if (!comp_ctx->target_cpu) if (!comp_ctx->target_cpu)
return; return;

View File

@ -1644,27 +1644,6 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
const uint8 *p = buf, *p_end = buf_end; const uint8 *p = buf, *p_end = buf_end;
uint32 i; uint32 i;
uint64 size, text_offset; uint64 size, text_offset;
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
RUNTIME_FUNCTION *rtl_func_table;
AOTUnwindInfo *unwind_info;
uint32 unwind_info_offset = module->code_size - sizeof(AOTUnwindInfo);
uint32 unwind_code_offset = unwind_info_offset - PLT_ITEM_SIZE;
#endif
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
unwind_info = (AOTUnwindInfo *)((uint8 *)module->code + module->code_size
- sizeof(AOTUnwindInfo));
unwind_info->Version = 1;
unwind_info->Flags = UNW_FLAG_NHANDLER;
*(uint32 *)&unwind_info->UnwindCode[0] = unwind_code_offset;
size = sizeof(RUNTIME_FUNCTION) * (uint64)module->func_count;
if (size > 0
&& !(rtl_func_table = module->rtl_func_table =
loader_malloc(size, error_buf, error_buf_size))) {
return false;
}
#endif
size = sizeof(void *) * (uint64)module->func_count; size = sizeof(void *) * (uint64)module->func_count;
if (size > 0 if (size > 0
@ -1691,33 +1670,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
#if defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP) #if defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP)
/* bits[0] of thumb function address must be 1 */ /* bits[0] of thumb function address must be 1 */
module->func_ptrs[i] = (void *)((uintptr_t)module->func_ptrs[i] | 1); module->func_ptrs[i] = (void *)((uintptr_t)module->func_ptrs[i] | 1);
#endif
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
rtl_func_table[i].BeginAddress = (DWORD)text_offset;
if (i > 0) {
rtl_func_table[i - 1].EndAddress = rtl_func_table[i].BeginAddress;
}
rtl_func_table[i].UnwindInfoAddress = (DWORD)unwind_info_offset;
#endif #endif
} }
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
if (module->func_count > 0) {
uint32 plt_table_size =
module->is_indirect_mode ? 0 : get_plt_table_size();
rtl_func_table[module->func_count - 1].EndAddress =
(DWORD)(module->code_size - plt_table_size);
if (!RtlAddFunctionTable(rtl_func_table, module->func_count,
(DWORD64)(uintptr_t)module->code)) {
set_error_buf(error_buf, error_buf_size,
"add dynamic function table failed");
return false;
}
module->rtl_func_table_registered = true;
}
#endif
/* Set start function when function pointers are resolved */ /* Set start function when function pointers are resolved */
if (module->start_func_index != (uint32)-1) { if (module->start_func_index != (uint32)-1) {
if (module->start_func_index >= module->import_func_count) if (module->start_func_index >= module->import_func_count)
@ -3013,6 +2968,9 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
uint32 section_size; uint32 section_size;
uint64 total_size; uint64 total_size;
uint8 *aot_text; uint8 *aot_text;
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
uint8 *mirrored_text;
#endif
if (!resolve_execute_mode(buf, size, &is_indirect_mode, error_buf, if (!resolve_execute_mode(buf, size, &is_indirect_mode, error_buf,
error_buf_size)) { error_buf_size)) {
@ -3071,8 +3029,17 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
bh_assert((uintptr_t)aot_text < INT32_MAX); bh_assert((uintptr_t)aot_text < INT32_MAX);
#endif #endif
#endif #endif
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
mirrored_text = os_get_dbus_mirror(aot_text);
bh_assert(mirrored_text != NULL);
bh_memcpy_s(mirrored_text, (uint32)total_size,
section->section_body, (uint32)section_size);
os_dcache_flush();
#else
bh_memcpy_s(aot_text, (uint32)total_size, bh_memcpy_s(aot_text, (uint32)total_size,
section->section_body, (uint32)section_size); section->section_body, (uint32)section_size);
#endif
section->section_body = aot_text; section->section_body = aot_text;
destroy_aot_text = true; destroy_aot_text = true;
@ -3249,14 +3216,6 @@ aot_unload(AOTModule *module)
} }
#endif #endif
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
if (module->rtl_func_table) {
if (module->rtl_func_table_registered)
RtlDeleteFunctionTable(module->rtl_func_table);
wasm_runtime_free(module->rtl_func_table);
}
#endif
#if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \ #if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
&& !defined(BH_PLATFORM_WINDOWS) && !defined(BH_PLATFORM_WINDOWS)
{ {

View File

@ -42,6 +42,9 @@ bh_static_assert(offsetof(AOTModuleInstance, cur_exception)
bh_static_assert(offsetof(AOTModuleInstance, global_table_data) bh_static_assert(offsetof(AOTModuleInstance, global_table_data)
== 13 * sizeof(uint64) + 128 + 11 * sizeof(uint64)); == 13 * sizeof(uint64) + 128 + 11 * sizeof(uint64));
bh_static_assert(sizeof(AOTMemoryInstance) == 104);
bh_static_assert(offsetof(AOTTableInstance, elems) == 8);
bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0); bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0);
static void static void
@ -336,11 +339,8 @@ memories_deinstantiate(AOTModuleInstance *module_inst)
memory_inst = module_inst->memories[i]; memory_inst = module_inst->memories[i];
if (memory_inst) { if (memory_inst) {
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (memory_inst->is_shared) { if (shared_memory_is_shared(memory_inst)) {
int32 ref_count = shared_memory_dec_reference( uint32 ref_count = shared_memory_dec_reference(memory_inst);
(WASMModuleCommon *)module_inst->module);
bh_assert(ref_count >= 0);
/* if the reference count is not zero, /* if the reference count is not zero,
don't free the memory */ don't free the memory */
if (ref_count > 0) if (ref_count > 0)
@ -370,9 +370,10 @@ memories_deinstantiate(AOTModuleInstance *module_inst)
} }
static AOTMemoryInstance * static AOTMemoryInstance *
memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module, memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
AOTMemoryInstance *memory_inst, AOTMemory *memory, AOTModule *module, AOTMemoryInstance *memory_inst,
uint32 heap_size, char *error_buf, uint32 error_buf_size) AOTMemory *memory, uint32 memory_idx, uint32 heap_size,
char *error_buf, uint32 error_buf_size)
{ {
void *heap_handle; void *heap_handle;
uint32 num_bytes_per_page = memory->num_bytes_per_page; uint32 num_bytes_per_page = memory->num_bytes_per_page;
@ -393,23 +394,13 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
bool is_shared_memory = memory->memory_flags & 0x02 ? true : false; bool is_shared_memory = memory->memory_flags & 0x02 ? true : false;
/* Shared memory */ /* Shared memory */
if (is_shared_memory) { if (is_shared_memory && parent != NULL) {
AOTMemoryInstance *shared_memory_instance; AOTMemoryInstance *shared_memory_instance;
WASMSharedMemNode *node = bh_assert(memory_idx == 0);
wasm_module_get_shared_memory((WASMModuleCommon *)module); bh_assert(parent->memory_count > memory_idx);
/* If the memory of this module has been instantiated, shared_memory_instance = parent->memories[memory_idx];
return the memory instance directly */ shared_memory_inc_reference(shared_memory_instance);
if (node) { return shared_memory_instance;
uint32 ref_count;
ref_count = shared_memory_inc_reference((WASMModuleCommon *)module);
bh_assert(ref_count > 0);
shared_memory_instance =
(AOTMemoryInstance *)shared_memory_get_memory_inst(node);
bh_assert(shared_memory_instance);
(void)ref_count;
return shared_memory_instance;
}
} }
#endif #endif
@ -429,7 +420,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
if (num_bytes_per_page < heap_size) { if (num_bytes_per_page < heap_size) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, " "failed to insert app heap into linear memory, "
"try using `--heap_size=0` option"); "try using `--heap-size=0` option");
return NULL; return NULL;
} }
} }
@ -487,7 +478,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
if (init_page_count > DEFAULT_MAX_PAGES) { if (init_page_count > DEFAULT_MAX_PAGES) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, " "failed to insert app heap into linear memory, "
"try using `--heap_size=0` option"); "try using `--heap-size=0` option");
return NULL; return NULL;
} }
else if (init_page_count == DEFAULT_MAX_PAGES) { else if (init_page_count == DEFAULT_MAX_PAGES) {
@ -606,23 +597,12 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (is_shared_memory) { if (is_shared_memory) {
memory_inst->is_shared = true; memory_inst->ref_count = 1;
if (!shared_memory_set_memory_inst(
(WASMModuleCommon *)module,
(WASMMemoryInstanceCommon *)memory_inst)) {
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
goto fail3;
}
} }
#endif #endif
return memory_inst; return memory_inst;
#if WASM_ENABLE_SHARED_MEMORY != 0
fail3:
if (heap_size > 0)
mem_allocator_destroy(memory_inst->heap_handle);
#endif
fail2: fail2:
if (heap_size > 0) if (heap_size > 0)
wasm_runtime_free(memory_inst->heap_handle); wasm_runtime_free(memory_inst->heap_handle);
@ -651,8 +631,9 @@ aot_get_default_memory(AOTModuleInstance *module_inst)
} }
static bool static bool
memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module, memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
uint32 heap_size, char *error_buf, uint32 error_buf_size) AOTModule *module, uint32 heap_size, char *error_buf,
uint32 error_buf_size)
{ {
uint32 global_index, global_data_offset, base_offset, length; uint32 global_index, global_data_offset, base_offset, length;
uint32 i, memory_count = module->memory_count; uint32 i, memory_count = module->memory_count;
@ -669,8 +650,8 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
memories = module_inst->global_table_data.memory_instances; memories = module_inst->global_table_data.memory_instances;
for (i = 0; i < memory_count; i++, memories++) { for (i = 0; i < memory_count; i++, memories++) {
memory_inst = memory_instantiate(module_inst, module, memories, memory_inst = memory_instantiate(module_inst, parent, module, memories,
&module->memories[i], heap_size, &module->memories[i], i, heap_size,
error_buf, error_buf_size); error_buf, error_buf_size);
if (!memory_inst) { if (!memory_inst) {
return false; return false;
@ -1097,9 +1078,9 @@ check_linked_symbol(AOTModule *module, char *error_buf, uint32 error_buf_size)
} }
AOTModuleInstance * AOTModuleInstance *
aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main, aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
uint32 stack_size, uint32 heap_size, char *error_buf, WASMExecEnv *exec_env_main, uint32 stack_size, uint32 heap_size,
uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
AOTModuleInstance *module_inst; AOTModuleInstance *module_inst;
const uint32 module_inst_struct_size = const uint32 module_inst_struct_size =
@ -1109,6 +1090,7 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main,
uint64 total_size, table_size = 0; uint64 total_size, table_size = 0;
uint8 *p; uint8 *p;
uint32 i, extra_info_offset; uint32 i, extra_info_offset;
const bool is_sub_inst = parent != NULL;
/* Check heap size */ /* Check heap size */
heap_size = align_uint(heap_size, 8); heap_size = align_uint(heap_size, 8);
@ -1168,7 +1150,7 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main,
goto fail; goto fail;
/* Initialize memory space */ /* Initialize memory space */
if (!memories_instantiate(module_inst, module, heap_size, error_buf, if (!memories_instantiate(module_inst, parent, module, heap_size, error_buf,
error_buf_size)) error_buf_size))
goto fail; goto fail;
@ -1261,16 +1243,6 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
wasm_exec_env_destroy((WASMExecEnv *)module_inst->exec_env_singleton); wasm_exec_env_destroy((WASMExecEnv *)module_inst->exec_env_singleton);
} }
#if WASM_ENABLE_LIBC_WASI != 0
/* Destroy wasi resource before freeing app heap, since some fields of
wasi contex are allocated from app heap, and if app heap is freed,
these fields will be set to NULL, we cannot free their internal data
which may allocated from global heap. */
/* Only destroy wasi ctx in the main module instance */
if (!is_sub_inst)
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst);
#endif
#if WASM_ENABLE_PERF_PROFILING != 0 #if WASM_ENABLE_PERF_PROFILING != 0
if (module_inst->func_perf_profilings) if (module_inst->func_perf_profilings)
wasm_runtime_free(module_inst->func_perf_profilings); wasm_runtime_free(module_inst->func_perf_profilings);
@ -1299,14 +1271,16 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
if (module_inst->func_type_indexes) if (module_inst->func_type_indexes)
wasm_runtime_free(module_inst->func_type_indexes); wasm_runtime_free(module_inst->func_type_indexes);
if (((AOTModuleInstanceExtra *)module_inst->e)->c_api_func_imports) if (((AOTModuleInstanceExtra *)module_inst->e)->common.c_api_func_imports)
wasm_runtime_free( wasm_runtime_free(((AOTModuleInstanceExtra *)module_inst->e)
((AOTModuleInstanceExtra *)module_inst->e)->c_api_func_imports); ->common.c_api_func_imports);
if (!is_sub_inst) {
#if WASM_ENABLE_WASI_NN != 0 #if WASM_ENABLE_WASI_NN != 0
if (!is_sub_inst)
wasi_nn_destroy(module_inst); wasi_nn_destroy(module_inst);
#endif #endif
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
}
wasm_runtime_free(module_inst); wasm_runtime_free(module_inst);
} }
@ -1467,6 +1441,9 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
/* set thread handle and stack boundary */ /* set thread handle and stack boundary */
wasm_exec_env_set_thread_info(exec_env); wasm_exec_env_set_thread_info(exec_env);
/* set exec env so it can be later retrieved from instance */
((AOTModuleInstanceExtra *)module_inst->e)->common.cur_exec_env = exec_env;
if (ext_ret_count > 0) { if (ext_ret_count > 0) {
uint32 cell_num = 0, i; uint32 cell_num = 0, i;
uint8 *ext_ret_types = func_type->types + func_type->param_count + 1; uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
@ -1949,8 +1926,8 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
AOTModuleInstanceExtra *module_inst_extra = AOTModuleInstanceExtra *module_inst_extra =
(AOTModuleInstanceExtra *)module_inst->e; (AOTModuleInstanceExtra *)module_inst->e;
CApiFuncImport *c_api_func_import = CApiFuncImport *c_api_func_import =
module_inst_extra->c_api_func_imports module_inst_extra->common.c_api_func_imports
? module_inst_extra->c_api_func_imports + func_idx ? module_inst_extra->common.c_api_func_imports + func_idx
: NULL; : NULL;
uint32 *func_type_indexes = module_inst->func_type_indexes; uint32 *func_type_indexes = module_inst->func_type_indexes;
uint32 func_type_idx = func_type_indexes[func_idx]; uint32 func_type_idx = func_type_indexes[func_idx];
@ -2486,13 +2463,13 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
tbl_seg = module->table_init_data_list[tbl_seg_idx]; tbl_seg = module->table_init_data_list[tbl_seg_idx];
bh_assert(tbl_seg); bh_assert(tbl_seg);
if (!length) { if (offset_len_out_of_bounds(src_offset, length, tbl_seg->func_index_count)
|| offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
return; return;
} }
if (length + src_offset > tbl_seg->func_index_count if (!length) {
|| dst_offset + length > tbl_inst->cur_size) {
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
return; return;
} }
@ -2525,8 +2502,9 @@ aot_table_copy(AOTModuleInstance *module_inst, uint32 src_tbl_idx,
dst_tbl_inst = module_inst->tables[dst_tbl_idx]; dst_tbl_inst = module_inst->tables[dst_tbl_idx];
bh_assert(dst_tbl_inst); bh_assert(dst_tbl_inst);
if ((uint64)dst_offset + length > dst_tbl_inst->cur_size if (offset_len_out_of_bounds(dst_offset, length, dst_tbl_inst->cur_size)
|| (uint64)src_offset + length > src_tbl_inst->cur_size) { || offset_len_out_of_bounds(src_offset, length,
src_tbl_inst->cur_size)) {
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
return; return;
} }
@ -2551,7 +2529,7 @@ aot_table_fill(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 length,
tbl_inst = module_inst->tables[tbl_idx]; tbl_inst = module_inst->tables[tbl_idx];
bh_assert(tbl_inst); bh_assert(tbl_inst);
if (data_offset + length > tbl_inst->cur_size) { if (offset_len_out_of_bounds(data_offset, length, tbl_inst->cur_size)) {
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
return; return;
} }

View File

@ -89,33 +89,9 @@ typedef struct AOTFunctionInstance {
typedef struct AOTModuleInstanceExtra { typedef struct AOTModuleInstanceExtra {
DefPointer(const uint32 *, stack_sizes); DefPointer(const uint32 *, stack_sizes);
CApiFuncImport *c_api_func_imports; WASMModuleInstanceExtraCommon common;
} AOTModuleInstanceExtra; } AOTModuleInstanceExtra;
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
/* clang-format off */
typedef struct AOTUnwindInfo {
uint8 Version : 3;
uint8 Flags : 5;
uint8 SizeOfProlog;
uint8 CountOfCodes;
uint8 FrameRegister : 4;
uint8 FrameOffset : 4;
struct {
struct {
uint8 CodeOffset;
uint8 UnwindOp : 4;
uint8 OpInfo : 4;
};
uint16 FrameOffset;
} UnwindCode[1];
} AOTUnwindInfo;
/* clang-format on */
/* size of mov instruction and jmp instruction */
#define PLT_ITEM_SIZE 12
#endif
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
typedef struct GOTItem { typedef struct GOTItem {
uint32 func_idx; uint32 func_idx;
@ -211,14 +187,6 @@ typedef struct AOTModule {
uint32 float_plt_count; uint32 float_plt_count;
#endif #endif
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
/* dynamic function table to be added by RtlAddFunctionTable(),
used to unwind the call stack and register exception handler
for AOT functions */
RUNTIME_FUNCTION *rtl_func_table;
bool rtl_func_table_registered;
#endif
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
uint32 got_item_count; uint32 got_item_count;
GOTItemList got_item_list; GOTItemList got_item_list;
@ -402,7 +370,7 @@ aot_unload(AOTModule *module);
* Instantiate a AOT module. * Instantiate a AOT module.
* *
* @param module the AOT module to instantiate * @param module the AOT module to instantiate
* @param is_sub_inst the flag of sub instance * @param parent the parent module instance
* @param heap_size the default heap size of the module instance, a heap will * @param heap_size the default heap size of the module instance, a heap will
* be created besides the app memory space. Both wasm app and native * be created besides the app memory space. Both wasm app and native
* function can allocate memory from the heap. If heap_size is 0, the * function can allocate memory from the heap. If heap_size is 0, the
@ -413,9 +381,9 @@ aot_unload(AOTModule *module);
* @return return the instantiated AOT module instance, NULL if failed * @return return the instantiated AOT module instance, NULL if failed
*/ */
AOTModuleInstance * AOTModuleInstance *
aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main, aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
uint32 stack_size, uint32 heap_size, char *error_buf, WASMExecEnv *exec_env_main, uint32 stack_size, uint32 heap_size,
uint32 error_buf_size); char *error_buf, uint32 error_buf_size);
/** /**
* Deinstantiate a AOT module instance, destroy the resources. * Deinstantiate a AOT module instance, destroy the resources.

View File

@ -40,6 +40,7 @@ void __aeabi_ldivmod();
void __aeabi_memcpy(); void __aeabi_memcpy();
void __aeabi_memmove(); void __aeabi_memmove();
void __aeabi_memset(); void __aeabi_memset();
void __aeabi_memclr();
void __aeabi_uidiv(); void __aeabi_uidiv();
void __aeabi_uidivmod(); void __aeabi_uidivmod();
void __aeabi_ul2d(); void __aeabi_ul2d();
@ -126,6 +127,7 @@ static SymbolMap target_sym_map[] = {
REG_SYM(__aeabi_memcpy), REG_SYM(__aeabi_memcpy),
REG_SYM(__aeabi_memmove), REG_SYM(__aeabi_memmove),
REG_SYM(__aeabi_memset), REG_SYM(__aeabi_memset),
REG_SYM(__aeabi_memclr),
REG_SYM(__aeabi_uidiv), REG_SYM(__aeabi_uidiv),
REG_SYM(__aeabi_uidivmod), REG_SYM(__aeabi_uidivmod),
REG_SYM(__aeabi_ul2d), REG_SYM(__aeabi_ul2d),

View File

@ -78,6 +78,13 @@ static SymbolMap target_sym_map[] = {
REG_SYM(__addsf3), REG_SYM(__addsf3),
REG_SYM(__divdf3), REG_SYM(__divdf3),
REG_SYM(__divsf3), REG_SYM(__divsf3),
REG_SYM(__eqdf2),
REG_SYM(__eqsf2),
REG_SYM(__extendsfdf2),
REG_SYM(__fixunsdfdi),
REG_SYM(__fixunsdfsi),
REG_SYM(__fixunssfdi),
REG_SYM(__fixunssfsi),
REG_SYM(__gedf2), REG_SYM(__gedf2),
REG_SYM(__gesf2), REG_SYM(__gesf2),
REG_SYM(__gtdf2), REG_SYM(__gtdf2),
@ -89,44 +96,33 @@ static SymbolMap target_sym_map[] = {
REG_SYM(__muldf3), REG_SYM(__muldf3),
REG_SYM(__nedf2), REG_SYM(__nedf2),
REG_SYM(__nesf2), REG_SYM(__nesf2),
REG_SYM(__eqsf2),
REG_SYM(__eqdf2),
REG_SYM(__extendsfdf2),
REG_SYM(__fixunsdfdi),
REG_SYM(__fixunsdfsi),
REG_SYM(__fixunssfsi),
REG_SYM(__subdf3), REG_SYM(__subdf3),
REG_SYM(__subsf3), REG_SYM(__subsf3),
REG_SYM(__truncdfsf2), REG_SYM(__truncdfsf2),
REG_SYM(__unorddf2), REG_SYM(__unorddf2),
REG_SYM(__unordsf2), REG_SYM(__unordsf2),
#endif
REG_SYM(__divdi3),
REG_SYM(__divsi3),
#if __riscv_xlen == 32 #if __riscv_xlen == 32
REG_SYM(__fixdfdi), REG_SYM(__fixdfdi),
REG_SYM(__fixdfsi), REG_SYM(__fixdfsi),
REG_SYM(__fixsfdi), REG_SYM(__fixsfdi),
REG_SYM(__fixsfsi), REG_SYM(__fixsfsi),
#endif
REG_SYM(__fixunssfdi),
#if __riscv_xlen == 32
REG_SYM(__floatdidf), REG_SYM(__floatdidf),
REG_SYM(__floatdisf), REG_SYM(__floatdisf),
REG_SYM(__floatsisf),
REG_SYM(__floatsidf), REG_SYM(__floatsidf),
REG_SYM(__floatsisf),
REG_SYM(__floatundidf), REG_SYM(__floatundidf),
REG_SYM(__floatundisf), REG_SYM(__floatundisf),
REG_SYM(__floatunsisf),
REG_SYM(__floatunsidf), REG_SYM(__floatunsidf),
#endif REG_SYM(__floatunsisf),
REG_SYM(__moddi3),
REG_SYM(__modsi3),
REG_SYM(__muldi3),
#if __riscv_xlen == 32
REG_SYM(__mulsf3), REG_SYM(__mulsf3),
REG_SYM(__mulsi3), REG_SYM(__mulsi3),
#endif #endif
#endif
REG_SYM(__divdi3),
REG_SYM(__divsi3),
REG_SYM(__moddi3),
REG_SYM(__modsi3),
REG_SYM(__muldi3),
REG_SYM(__udivdi3), REG_SYM(__udivdi3),
REG_SYM(__udivsi3), REG_SYM(__udivsi3),
REG_SYM(__umoddi3), REG_SYM(__umoddi3),

View File

@ -164,6 +164,9 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
(uint32)((uintptr_t)symbol_addr + (intptr_t)reloc_addend (uint32)((uintptr_t)symbol_addr + (intptr_t)reloc_addend
- (uintptr_t)(target_section_addr - (uintptr_t)(target_section_addr
+ (uint32)reloc_offset) + (uint32)reloc_offset)
#if defined(BH_PLATFORM_WINDOWS)
- sizeof(int32)
#endif
+ value); /* S + A - P */ + value); /* S + A - P */
break; break;
} }

View File

@ -69,9 +69,6 @@ get_plt_table_size()
{ {
uint32 size = uint32 size =
get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap)); get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
size += get_plt_item_size() + sizeof(AOTUnwindInfo);
#endif
return size; return size;
} }
@ -93,18 +90,6 @@ init_plt_table(uint8 *plt)
*p++ = 0xE0; *p++ = 0xE0;
plt += get_plt_item_size(); plt += get_plt_item_size();
} }
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
p = plt;
/* mov exception_handler, rax */
*p++ = 0x48;
*p++ = 0xB8;
*(uint64 *)p = 0; /*(uint64)(uintptr_t)aot_exception_handler;*/
p += sizeof(uint64);
/* jmp rax */
*p++ = 0xFF;
*p++ = 0xE0;
#endif
} }
static bool static bool
@ -242,7 +227,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
- (uintptr_t)(target_section_addr + reloc_offset)); - (uintptr_t)(target_section_addr + reloc_offset));
} }
else { else {
target_addr = (intptr_t) /* L + A - P */ target_addr = (intptr_t) /* S + A - P */
((uintptr_t)symbol_addr + reloc_addend ((uintptr_t)symbol_addr + reloc_addend
- (uintptr_t)(target_section_addr + reloc_offset)); - (uintptr_t)(target_section_addr + reloc_offset));
} }

View File

@ -43,6 +43,11 @@ void __floatdidf();
void __divsf3(); void __divsf3();
void __fixdfdi(); void __fixdfdi();
void __floatundidf(); void __floatundidf();
void __fixsfdi();
void __fixunssfdi();
void __fixunsdfdi();
void __floatdisf();
void __floatundisf();
static SymbolMap target_sym_map[] = { static SymbolMap target_sym_map[] = {
@ -85,6 +90,11 @@ static SymbolMap target_sym_map[] = {
REG_SYM(__divsf3), REG_SYM(__divsf3),
REG_SYM(__fixdfdi), REG_SYM(__fixdfdi),
REG_SYM(__floatundidf), REG_SYM(__floatundidf),
REG_SYM(__fixsfdi),
REG_SYM(__fixunssfdi),
REG_SYM(__fixunsdfdi),
REG_SYM(__floatdisf),
REG_SYM(__floatundisf),
}; };
/* clang-format on */ /* clang-format on */
@ -207,6 +217,10 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
case R_XTENSA_32: case R_XTENSA_32:
{ {
uint8 *insn_addr = target_section_addr + reloc_offset; uint8 *insn_addr = target_section_addr + reloc_offset;
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
insn_addr = os_get_dbus_mirror((void *)insn_addr);
bh_assert(insn_addr != NULL);
#endif
int32 initial_addend; int32 initial_addend;
/* (S + A) */ /* (S + A) */
if ((intptr_t)insn_addr & 3) { if ((intptr_t)insn_addr & 3) {
@ -265,6 +279,11 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
return false; return false;
} }
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
insn_addr = os_get_dbus_mirror((void *)insn_addr);
bh_assert(insn_addr != NULL);
l32r_insn = (l32r_insn_t *)insn_addr;
#endif
imm16 = (int16)(relative_offset >> 2); imm16 = (int16)(relative_offset >> 2);
/* write back the imm16 to the l32r instruction */ /* write back the imm16 to the l32r instruction */
@ -285,7 +304,6 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
#if __GNUC__ >= 9 #if __GNUC__ >= 9
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
break; break;
} }

View File

@ -36,5 +36,49 @@ if (WAMR_BUILD_DEBUG_AOT EQUAL 1)
file(GLOB debug_source ${IWASM_AOT_DIR}/debug/*.c) file(GLOB debug_source ${IWASM_AOT_DIR}/debug/*.c)
endif() endif()
set (IWASM_AOT_SOURCE ${c_source_all} ${arch_source} ${debug_source}) if ((WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
AND (WAMR_BUILD_PLATFORM STREQUAL "windows")
AND (NOT WAMR_DISABLE_HW_BOUND_CHECK EQUAL 1))
include(FetchContent)
FetchContent_Declare(
zycore
GIT_REPOSITORY https://github.com/zyantific/zycore-c.git
)
FetchContent_GetProperties(zycore)
if (NOT zycore_POPULATED)
message ("-- Fetching zycore ..")
FetchContent_Populate(zycore)
include_directories("${zycore_SOURCE_DIR}/include")
include_directories("${zycore_BINARY_DIR}")
add_definitions(-DZYCORE_STATIC_BUILD=1)
add_subdirectory(${zycore_SOURCE_DIR} ${zycore_BINARY_DIR} EXCLUDE_FROM_ALL)
file (GLOB_RECURSE c_source_zycore ${zycore_SOURCE_DIR}/src/*.c)
endif ()
FetchContent_Declare(
zydis
GIT_REPOSITORY https://github.com/zyantific/zydis.git
GIT_TAG e14a07895136182a5b53e181eec3b1c6e0b434de
)
FetchContent_GetProperties(zydis)
if (NOT zydis_POPULATED)
message ("-- Fetching zydis ..")
FetchContent_Populate(zydis)
option(ZYDIS_FEATURE_ENCODER "" OFF)
option(ZYDIS_BUILD_TOOLS "" OFF)
option(ZYDIS_BUILD_EXAMPLES "" OFF)
option(ZYDIS_BUILD_MAN "" OFF)
option(ZYDIS_BUILD_DOXYGEN "" OFF)
include_directories("${zydis_BINARY_DIR}")
include_directories("${zydis_SOURCE_DIR}/include")
include_directories("${zydis_SOURCE_DIR}/src")
add_definitions(-DZYDIS_STATIC_BUILD=1)
add_subdirectory(${zydis_SOURCE_DIR} ${zydis_BINARY_DIR} EXCLUDE_FROM_ALL)
file (GLOB_RECURSE c_source_zydis ${zydis_SOURCE_DIR}/src/*.c)
endif ()
endif ()
set (IWASM_AOT_SOURCE ${c_source_all} ${arch_source} ${debug_source}
${c_source_zycore} ${c_source_zydis})

View File

@ -107,7 +107,34 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
the actual main function. Directly calling main function the actual main function. Directly calling main function
may cause exception thrown. */ may cause exception thrown. */
if ((func = wasm_runtime_lookup_wasi_start_function(module_inst))) { if ((func = wasm_runtime_lookup_wasi_start_function(module_inst))) {
return wasm_runtime_call_wasm(exec_env, func, 0, NULL); const char *wasi_proc_exit_exception = "wasi proc exit";
ret = wasm_runtime_call_wasm(exec_env, func, 0, NULL);
#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).
Note:
- A return from the `main` function is an equivalent of
exit(). (C standard)
- When exit code is 0, wasi-libc's `_start` function just
returns w/o calling `proc_exit`.
- A process termination should terminate threads in
the process. */
wasm_runtime_set_exception(module_inst, wasi_proc_exit_exception);
/* exit_code is zero-initialized */
ret = false;
}
#endif
/* report wasm proc exit as a success */
WASMModuleInstance *inst = (WASMModuleInstance *)module_inst;
if (!ret && strstr(inst->cur_exception, wasi_proc_exit_exception)) {
inst->cur_exception[0] = 0;
ret = true;
}
return ret;
} }
#endif /* end of WASM_ENABLE_LIBC_WASI */ #endif /* end of WASM_ENABLE_LIBC_WASI */

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "wasm_runtime_common.h"
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_assert.h"
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
#define LOCK(env) WASM_SUSPEND_FLAGS_LOCK((env)->wait_lock)
#define UNLOCK(env) WASM_SUSPEND_FLAGS_UNLOCK((env)->wait_lock)
#define ISSET(env, bit) \
((WASM_SUSPEND_FLAGS_GET((env)->suspend_flags) & WASM_SUSPEND_FLAG_##bit) \
!= 0)
#define SET(env, bit) \
WASM_SUSPEND_FLAGS_FETCH_OR((env)->suspend_flags, WASM_SUSPEND_FLAG_##bit)
#define CLR(env, bit) \
WASM_SUSPEND_FLAGS_FETCH_AND((env)->suspend_flags, ~WASM_SUSPEND_FLAG_##bit)
bool
wasm_runtime_begin_blocking_op(wasm_exec_env_t env)
{
LOCK(env);
bh_assert(!ISSET(env, BLOCKING));
SET(env, BLOCKING);
if (ISSET(env, TERMINATE)) {
CLR(env, BLOCKING);
UNLOCK(env);
return false;
}
UNLOCK(env);
os_begin_blocking_op();
return true;
}
void
wasm_runtime_end_blocking_op(wasm_exec_env_t env)
{
int saved_errno = errno;
LOCK(env);
bh_assert(ISSET(env, BLOCKING));
CLR(env, BLOCKING);
UNLOCK(env);
os_end_blocking_op();
errno = saved_errno;
}
void
wasm_runtime_interrupt_blocking_op(wasm_exec_env_t env)
{
/*
* ISSET(BLOCKING) here means that the target thread
* is in somewhere between wasm_begin_blocking_op and
* wasm_end_blocking_op.
* keep waking it up until it reaches wasm_end_blocking_op,
* which clears the BLOCKING bit.
*
* this dumb loop is necessary because posix doesn't provide
* a way to unmask signal and block atomically.
*/
LOCK(env);
SET(env, TERMINATE);
while (ISSET(env, BLOCKING)) {
UNLOCK(env);
os_wakeup_blocking_op(env->handle);
/* relax a bit */
os_usleep(50 * 1000);
LOCK(env);
}
UNLOCK(env);
}
#else /* WASM_ENABLE_THREAD_MGR && OS_ENABLE_WAKEUP_BLOCKING_OP */
bool
wasm_runtime_begin_blocking_op(wasm_exec_env_t env)
{
return true;
}
void
wasm_runtime_end_blocking_op(wasm_exec_env_t env)
{}
#endif /* WASM_ENABLE_THREAD_MGR && OS_ENABLE_WAKEUP_BLOCKING_OP */

View File

@ -2290,8 +2290,10 @@ quit:
bool bool
wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary) wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary)
{ {
wasm_byte_vec_t local_binary = { 0 };
struct WASMModuleCommon *module_rt; struct WASMModuleCommon *module_rt;
char error_buf[128] = { 0 }; char error_buf[128] = { 0 };
bool ret;
bh_assert(singleton_engine); bh_assert(singleton_engine);
@ -2300,15 +2302,25 @@ wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary)
return false; return false;
} }
if ((module_rt = wasm_runtime_load((uint8 *)binary->data, /* make a copy of binary */
(uint32)binary->size, error_buf, 128))) { wasm_byte_vec_copy(&local_binary, binary);
if (binary->size && !local_binary.data)
return false;
module_rt = wasm_runtime_load((uint8 *)local_binary.data,
(uint32)local_binary.size, error_buf, 128);
wasm_byte_vec_delete(&local_binary);
if (module_rt) {
wasm_runtime_unload(module_rt); wasm_runtime_unload(module_rt);
return true; ret = true;
} }
else { else {
ret = false;
LOG_VERBOSE(error_buf); LOG_VERBOSE(error_buf);
return false;
} }
return ret;
} }
static void static void
@ -4858,7 +4870,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
if (instance->inst_comm_rt->module_type == Wasm_Module_Bytecode) { if (instance->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
WASMModuleInstanceExtra *e = WASMModuleInstanceExtra *e =
((WASMModuleInstance *)instance->inst_comm_rt)->e; ((WASMModuleInstance *)instance->inst_comm_rt)->e;
p_func_imports = &(e->c_api_func_imports); p_func_imports = &(e->common.c_api_func_imports);
import_func_count = MODULE_INTERP(module)->import_function_count; import_func_count = MODULE_INTERP(module)->import_function_count;
} }
#endif #endif
@ -4868,7 +4880,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
(AOTModuleInstanceExtra *)((AOTModuleInstance *) (AOTModuleInstanceExtra *)((AOTModuleInstance *)
instance->inst_comm_rt) instance->inst_comm_rt)
->e; ->e;
p_func_imports = &(e->c_api_func_imports); p_func_imports = &(e->common.c_api_func_imports);
import_func_count = MODULE_AOT(module)->import_func_count; import_func_count = MODULE_AOT(module)->import_func_count;
} }
#endif #endif

View File

@ -7,6 +7,7 @@
#define _WASM_EXEC_ENV_H #define _WASM_EXEC_ENV_H
#include "bh_assert.h" #include "bh_assert.h"
#include "wasm_suspend_flags.h"
#if WASM_ENABLE_INTERP != 0 #if WASM_ENABLE_INTERP != 0
#include "../interpreter/wasm.h" #include "../interpreter/wasm.h"
#endif #endif
@ -57,15 +58,8 @@ typedef struct WASMExecEnv {
exception. */ exception. */
uint8 *native_stack_boundary; uint8 *native_stack_boundary;
/* Used to terminate or suspend current thread /* Used to terminate or suspend current thread */
bit 0: need to terminate WASMSuspendFlags suspend_flags;
bit 1: need to suspend
bit 2: need to go into breakpoint
bit 3: return from pthread_exit */
union {
uint32 flags;
uintptr_t __padding__;
} suspend_flags;
/* Auxiliary stack boundary */ /* Auxiliary stack boundary */
union { union {

View File

@ -5,8 +5,10 @@
#include "wasm_runtime_common.h" #include "wasm_runtime_common.h"
#include "../interpreter/wasm_runtime.h" #include "../interpreter/wasm_runtime.h"
#include "../aot/aot_runtime.h"
#include "bh_platform.h" #include "bh_platform.h"
#include "mem_alloc.h" #include "mem_alloc.h"
#include "wasm_memory.h"
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
#include "../common/wasm_shared_memory.h" #include "../common/wasm_shared_memory.h"
@ -23,6 +25,9 @@ static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN;
static mem_allocator_t pool_allocator = NULL; static mem_allocator_t pool_allocator = NULL;
static enlarge_memory_error_callback_t enlarge_memory_error_cb;
static void *enlarge_memory_error_user_data;
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
static void *allocator_user_data = NULL; static void *allocator_user_data = NULL;
static void *(*malloc_func)(void *user_data, unsigned int size) = NULL; static void *(*malloc_func)(void *user_data, unsigned int size) = NULL;
@ -87,6 +92,16 @@ wasm_memory_init_with_allocator(void *_malloc_func, void *_realloc_func,
} }
#endif #endif
static inline bool
is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
{
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
return wasm_runtime_is_bounds_checks_enabled(module_inst);
#else
return true;
#endif
}
bool bool
wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type, wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
const MemAllocOption *alloc_option) const MemAllocOption *alloc_option)
@ -269,6 +284,10 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT); || module_inst_comm->module_type == Wasm_Module_AoT);
if (!is_bounds_checks_enabled(module_inst_comm)) {
return true;
}
memory_inst = wasm_get_default_memory(module_inst); memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) { if (!memory_inst) {
goto fail; goto fail;
@ -299,6 +318,10 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT); || module_inst_comm->module_type == Wasm_Module_AoT);
if (!is_bounds_checks_enabled(module_inst_comm)) {
return true;
}
if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset, NULL, if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset, NULL,
&app_end_offset)) &app_end_offset))
goto fail; goto fail;
@ -327,6 +350,10 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT); || module_inst_comm->module_type == Wasm_Module_AoT);
if (!is_bounds_checks_enabled(module_inst_comm)) {
return true;
}
memory_inst = wasm_get_default_memory(module_inst); memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) { if (!memory_inst) {
goto fail; goto fail;
@ -354,10 +381,13 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst; WASMMemoryInstance *memory_inst;
uint8 *addr; uint8 *addr;
bool bounds_checks;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT); || module_inst_comm->module_type == Wasm_Module_AoT);
bounds_checks = is_bounds_checks_enabled(module_inst_comm);
memory_inst = wasm_get_default_memory(module_inst); memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) { if (!memory_inst) {
return NULL; return NULL;
@ -365,8 +395,17 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
addr = memory_inst->memory_data + app_offset; addr = memory_inst->memory_data + app_offset;
if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end) if (bounds_checks) {
if (memory_inst->memory_data <= addr
&& addr < memory_inst->memory_data_end) {
return addr;
}
}
/* If bounds checks is disabled, return the address directly */
else if (app_offset != 0) {
return addr; return addr;
}
return NULL; return NULL;
} }
@ -378,17 +417,27 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst; WASMMemoryInstance *memory_inst;
uint8 *addr = (uint8 *)native_ptr; uint8 *addr = (uint8 *)native_ptr;
bool bounds_checks;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT); || module_inst_comm->module_type == Wasm_Module_AoT);
bounds_checks = is_bounds_checks_enabled(module_inst_comm);
memory_inst = wasm_get_default_memory(module_inst); memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) { if (!memory_inst) {
return 0; return 0;
} }
if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end) if (bounds_checks) {
if (memory_inst->memory_data <= addr
&& addr < memory_inst->memory_data_end)
return (uint32)(addr - memory_inst->memory_data);
}
/* If bounds checks is disabled, return the offset directly */
else if (addr != NULL) {
return (uint32)(addr - memory_inst->memory_data); return (uint32)(addr - memory_inst->memory_data);
}
return 0; return 0;
} }
@ -460,6 +509,7 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
{ {
WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst); WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
uint8 *native_addr; uint8 *native_addr;
bool bounds_checks;
if (!memory_inst) { if (!memory_inst) {
goto fail; goto fail;
@ -467,6 +517,15 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
native_addr = memory_inst->memory_data + app_buf_addr; native_addr = memory_inst->memory_data + app_buf_addr;
bounds_checks = is_bounds_checks_enabled((wasm_module_inst_t)module_inst);
if (!bounds_checks) {
if (app_buf_addr == 0) {
native_addr = NULL;
}
goto success;
}
/* No need to check the app_offset and buf_size if memory access /* No need to check the app_offset and buf_size if memory access
boundary check with hardware trap is enabled */ boundary check with hardware trap is enabled */
#ifndef OS_ENABLE_HW_BOUND_CHECK #ifndef OS_ENABLE_HW_BOUND_CHECK
@ -492,6 +551,7 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
} }
#endif #endif
success:
*p_native_addr = (void *)native_addr; *p_native_addr = (void *)native_addr;
return true; return true;
fail: fail:
@ -514,13 +574,16 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
{ {
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
uint8 *memory_data_old, *memory_data_new, *heap_data_old; uint8 *memory_data_old, *memory_data_new, *heap_data_old;
uint32 num_bytes_per_page, heap_size, total_size_old; uint32 num_bytes_per_page, heap_size, total_size_old = 0;
uint32 cur_page_count, max_page_count, total_page_count; uint32 cur_page_count, max_page_count, total_page_count;
uint64 total_size_new; uint64 total_size_new;
bool ret = true; bool ret = true;
enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR;
if (!memory) if (!memory) {
return false; ret = false;
goto return_func;
}
heap_data_old = memory->heap_data; heap_data_old = memory->heap_data;
heap_size = (uint32)(memory->heap_data_end - memory->heap_data); heap_size = (uint32)(memory->heap_data_end - memory->heap_data);
@ -538,9 +601,15 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
/* No need to enlarge memory */ /* No need to enlarge memory */
return true; return true;
if (total_page_count < cur_page_count /* integer overflow */ if (total_page_count < cur_page_count) { /* integer overflow */
|| total_page_count > max_page_count) { ret = false;
return false; goto return_func;
}
if (total_page_count > max_page_count) {
failure_reason = MAX_SIZE_REACHED;
ret = false;
goto return_func;
} }
bh_assert(total_size_new <= 4 * (uint64)BH_GB); bh_assert(total_size_new <= 4 * (uint64)BH_GB);
@ -552,7 +621,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
} }
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (memory->is_shared) { if (shared_memory_is_shared(memory)) {
memory->num_bytes_per_page = num_bytes_per_page; memory->num_bytes_per_page = num_bytes_per_page;
memory->cur_page_count = total_page_count; memory->cur_page_count = total_page_count;
memory->max_page_count = max_page_count; memory->max_page_count = max_page_count;
@ -566,14 +635,16 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
if (heap_size > 0) { if (heap_size > 0) {
if (mem_allocator_is_heap_corrupted(memory->heap_handle)) { if (mem_allocator_is_heap_corrupted(memory->heap_handle)) {
wasm_runtime_show_app_heap_corrupted_prompt(); wasm_runtime_show_app_heap_corrupted_prompt();
return false; ret = false;
goto return_func;
} }
} }
if (!(memory_data_new = if (!(memory_data_new =
wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) { wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) { if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
return false; ret = false;
goto return_func;
} }
if (memory_data_old) { if (memory_data_old) {
bh_memcpy_s(memory_data_new, (uint32)total_size_new, bh_memcpy_s(memory_data_new, (uint32)total_size_new,
@ -629,6 +700,27 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
os_writegsbase(memory_data_new); os_writegsbase(memory_data_new);
#endif #endif
return_func:
if (!ret && enlarge_memory_error_cb) {
WASMExecEnv *exec_env = NULL;
#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode)
exec_env =
((WASMModuleInstanceExtra *)module->e)->common.cur_exec_env;
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT)
exec_env =
((AOTModuleInstanceExtra *)module->e)->common.cur_exec_env;
#endif
enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
failure_reason,
(WASMModuleInstanceCommon *)module, exec_env,
enlarge_memory_error_user_data);
}
return ret; return ret;
} }
#else #else
@ -636,12 +728,16 @@ bool
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
{ {
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
uint32 num_bytes_per_page, total_size_old; uint32 num_bytes_per_page, total_size_old = 0;
uint32 cur_page_count, max_page_count, total_page_count; uint32 cur_page_count, max_page_count, total_page_count;
uint64 total_size_new; uint64 total_size_new;
bool ret = true;
enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR;
if (!memory) if (!memory) {
return false; ret = false;
goto return_func;
}
num_bytes_per_page = memory->num_bytes_per_page; num_bytes_per_page = memory->num_bytes_per_page;
cur_page_count = memory->cur_page_count; cur_page_count = memory->cur_page_count;
@ -654,9 +750,15 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
/* No need to enlarge memory */ /* No need to enlarge memory */
return true; return true;
if (total_page_count < cur_page_count /* integer overflow */ if (total_page_count < cur_page_count) { /* integer overflow */
|| total_page_count > max_page_count) { ret = false;
return false; goto return_func;
}
if (total_page_count > max_page_count) {
failure_reason = MAX_SIZE_REACHED;
ret = false;
goto return_func;
} }
bh_assert(total_size_new <= 4 * (uint64)BH_GB); bh_assert(total_size_new <= 4 * (uint64)BH_GB);
@ -671,7 +773,8 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
if (!os_mem_commit(memory->memory_data_end, if (!os_mem_commit(memory->memory_data_end,
(uint32)total_size_new - total_size_old, (uint32)total_size_new - total_size_old,
MMAP_PROT_READ | MMAP_PROT_WRITE)) { MMAP_PROT_READ | MMAP_PROT_WRITE)) {
return false; ret = false;
goto return_func;
} }
#endif #endif
@ -683,7 +786,8 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
os_mem_decommit(memory->memory_data_end, os_mem_decommit(memory->memory_data_end,
(uint32)total_size_new - total_size_old); (uint32)total_size_new - total_size_old);
#endif #endif
return false; ret = false;
goto return_func;
} }
/* The increased pages are filled with zero by the OS when os_mmap, /* The increased pages are filled with zero by the OS when os_mmap,
@ -703,62 +807,53 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
memory->mem_bound_check_16bytes.u64 = total_size_new - 16; memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
#endif #endif
return true; return_func:
if (!ret && enlarge_memory_error_cb) {
WASMExecEnv *exec_env = NULL;
#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode)
exec_env =
((WASMModuleInstanceExtra *)module->e)->common.cur_exec_env;
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT)
exec_env =
((AOTModuleInstanceExtra *)module->e)->common.cur_exec_env;
#endif
enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
failure_reason,
(WASMModuleInstanceCommon *)module, exec_env,
enlarge_memory_error_user_data);
}
return ret;
} }
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
void
wasm_runtime_set_enlarge_mem_error_callback(
const enlarge_memory_error_callback_t callback, void *user_data)
{
enlarge_memory_error_cb = callback;
enlarge_memory_error_user_data = user_data;
}
bool bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{ {
bool ret = false; bool ret = false;
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node = if (module->memory_count > 0)
wasm_module_get_shared_memory((WASMModuleCommon *)module->module); shared_memory_lock(module->memories[0]);
if (node)
os_mutex_lock(&node->shared_mem_lock);
#endif #endif
ret = wasm_enlarge_memory_internal(module, inc_page_count); ret = wasm_enlarge_memory_internal(module, inc_page_count);
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (node) if (module->memory_count > 0)
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(module->memories[0]);
#endif #endif
return ret; return ret;
} }
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0
uint32
wasm_get_num_bytes_per_page(WASMMemoryInstance *memory, void *node)
{
uint32 num_bytes_per_page;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_lock(&((WASMSharedMemNode *)node)->shared_mem_lock);
#endif
num_bytes_per_page = memory->num_bytes_per_page;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_unlock(&((WASMSharedMemNode *)node)->shared_mem_lock);
#endif
return num_bytes_per_page;
}
uint32
wasm_get_linear_memory_size(WASMMemoryInstance *memory, void *node)
{
uint32 linear_mem_size;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_lock(&((WASMSharedMemNode *)node)->shared_mem_lock);
#endif
linear_mem_size = memory->num_bytes_per_page * memory->cur_page_count;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_unlock(&((WASMSharedMemNode *)node)->shared_mem_lock);
#endif
return linear_mem_size;
}
#endif

View File

@ -24,15 +24,9 @@ wasm_runtime_memory_destroy();
unsigned unsigned
wasm_runtime_memory_pool_size(); wasm_runtime_memory_pool_size();
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \ void
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ wasm_runtime_set_enlarge_mem_error_callback(
|| WASM_ENABLE_BULK_MEMORY != 0 const enlarge_memory_error_callback_t callback, void *user_data);
uint32
wasm_get_num_bytes_per_page(WASMMemoryInstance *memory, void *node);
uint32
wasm_get_linear_memory_size(WASMMemoryInstance *memory, void *node);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,6 +6,15 @@
#include "wasm_native.h" #include "wasm_native.h"
#include "wasm_runtime_common.h" #include "wasm_runtime_common.h"
#include "bh_log.h" #include "bh_log.h"
#if WASM_ENABLE_INTERP != 0
#include "../interpreter/wasm_runtime.h"
#endif
#if WASM_ENABLE_AOT != 0
#include "../aot/aot_runtime.h"
#endif
#if WASM_ENABLE_THREAD_MGR != 0
#include "../libraries/thread-mgr/thread_manager.h"
#endif
#if !defined(BH_PLATFORM_ZEPHYR) && !defined(BH_PLATFORM_ALIOS_THINGS) \ #if !defined(BH_PLATFORM_ZEPHYR) && !defined(BH_PLATFORM_ALIOS_THINGS) \
&& !defined(BH_PLATFORM_OPENRTOS) && !defined(BH_PLATFORM_ESP_IDF) && !defined(BH_PLATFORM_OPENRTOS) && !defined(BH_PLATFORM_ESP_IDF)
@ -22,6 +31,10 @@
static NativeSymbolsList g_native_symbols_list = NULL; static NativeSymbolsList g_native_symbols_list = NULL;
#if WASM_ENABLE_LIBC_WASI != 0
static void *g_wasi_context_key;
#endif /* WASM_ENABLE_LIBC_WASI */
uint32 uint32
get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis); get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis);
@ -394,6 +407,155 @@ wasm_native_unregister_natives(const char *module_name,
return false; return false;
} }
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
static uint32
context_key_to_idx(void *key)
{
bh_assert(key != NULL);
uint32 idx = (uint32)(uintptr_t)key;
bh_assert(idx > 0);
bh_assert(idx <= WASM_MAX_INSTANCE_CONTEXTS);
return idx - 1;
}
static void *
context_idx_to_key(uint32 idx)
{
bh_assert(idx < WASM_MAX_INSTANCE_CONTEXTS);
return (void *)(uintptr_t)(idx + 1);
}
typedef void (*dtor_t)(WASMModuleInstanceCommon *, void *);
static dtor_t g_context_dtors[WASM_MAX_INSTANCE_CONTEXTS];
static void
dtor_noop(WASMModuleInstanceCommon *inst, void *ctx)
{}
void *
wasm_native_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
void *ctx))
{
uint32 i;
for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) {
if (g_context_dtors[i] == NULL) {
if (dtor == NULL) {
dtor = dtor_noop;
}
g_context_dtors[i] = dtor;
return context_idx_to_key(i);
}
}
LOG_ERROR("failed to allocate instance context key");
return NULL;
}
void
wasm_native_destroy_context_key(void *key)
{
uint32 idx = context_key_to_idx(key);
bh_assert(g_context_dtors[idx] != NULL);
g_context_dtors[idx] = NULL;
}
static WASMModuleInstanceExtraCommon *
wasm_module_inst_extra_common(WASMModuleInstanceCommon *inst)
{
#if WASM_ENABLE_INTERP != 0
if (inst->module_type == Wasm_Module_Bytecode) {
return &((WASMModuleInstance *)inst)->e->common;
}
#endif
#if WASM_ENABLE_AOT != 0
if (inst->module_type == Wasm_Module_AoT) {
return &((AOTModuleInstanceExtra *)((AOTModuleInstance *)inst)->e)
->common;
}
#endif
bh_assert(false);
return NULL;
}
void
wasm_native_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx)
{
uint32 idx = context_key_to_idx(key);
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
common->contexts[idx] = ctx;
}
void
wasm_native_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
void *ctx)
{
#if WASM_ENABLE_THREAD_MGR != 0
wasm_cluster_set_context(inst, key, ctx);
#else
wasm_native_set_context(inst, key, ctx);
#endif
}
void *
wasm_native_get_context(WASMModuleInstanceCommon *inst, void *key)
{
uint32 idx = context_key_to_idx(key);
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
return common->contexts[idx];
}
void
wasm_native_call_context_dtors(WASMModuleInstanceCommon *inst)
{
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
uint32 i;
for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) {
dtor_t dtor = g_context_dtors[i];
if (dtor != NULL) {
dtor(inst, common->contexts[i]);
}
}
}
void
wasm_native_inherit_contexts(WASMModuleInstanceCommon *child,
WASMModuleInstanceCommon *parent)
{
WASMModuleInstanceExtraCommon *parent_common =
wasm_module_inst_extra_common(parent);
WASMModuleInstanceExtraCommon *child_common =
wasm_module_inst_extra_common(child);
bh_memcpy_s(child_common->contexts,
sizeof(*child_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS,
parent_common->contexts,
sizeof(*parent_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS);
}
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
#if WASM_ENABLE_LIBC_WASI != 0
WASIContext *
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
{
return wasm_native_get_context(module_inst_comm, g_wasi_context_key);
}
void
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
WASIContext *wasi_ctx)
{
return wasm_native_set_context(module_inst_comm, g_wasi_context_key,
wasi_ctx);
}
static void
wasi_context_dtor(WASMModuleInstanceCommon *inst, void *ctx)
{
if (ctx == NULL) {
return;
}
wasm_runtime_destroy_wasi(inst);
}
#endif /* end of WASM_ENABLE_LIBC_WASI */
bool bool
wasm_native_init() wasm_native_init()
{ {
@ -420,6 +582,10 @@ wasm_native_init()
#endif /* WASM_ENABLE_SPEC_TEST */ #endif /* WASM_ENABLE_SPEC_TEST */
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
g_wasi_context_key = wasm_native_create_context_key(wasi_context_dtor);
if (g_wasi_context_key == NULL) {
goto fail;
}
n_native_symbols = get_libc_wasi_export_apis(&native_symbols); n_native_symbols = get_libc_wasi_export_apis(&native_symbols);
if (!wasm_native_register_natives("wasi_unstable", native_symbols, if (!wasm_native_register_natives("wasi_unstable", native_symbols,
n_native_symbols)) n_native_symbols))
@ -507,6 +673,12 @@ wasm_native_destroy()
{ {
NativeSymbolsNode *node, *node_next; NativeSymbolsNode *node, *node_next;
#if WASM_ENABLE_LIBC_WASI != 0
if (g_wasi_context_key != NULL) {
wasm_native_destroy_context_key(g_wasi_context_key);
g_wasi_context_key = NULL;
}
#endif
#if WASM_ENABLE_LIB_PTHREAD != 0 #if WASM_ENABLE_LIB_PTHREAD != 0
lib_pthread_destroy(); lib_pthread_destroy();
#endif #endif

View File

@ -68,6 +68,36 @@ bool
wasm_native_unregister_natives(const char *module_name, wasm_native_unregister_natives(const char *module_name,
NativeSymbol *native_symbols); NativeSymbol *native_symbols);
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
struct WASMModuleInstanceCommon;
void *
wasm_native_create_context_key(
void (*dtor)(struct WASMModuleInstanceCommon *inst, void *ctx));
void
wasm_native_destroy_context_key(void *key);
void
wasm_native_set_context(struct WASMModuleInstanceCommon *inst, void *key,
void *ctx);
void
wasm_native_set_context_spread(struct WASMModuleInstanceCommon *inst, void *key,
void *ctx);
void *
wasm_native_get_context(struct WASMModuleInstanceCommon *inst, void *key);
void
wasm_native_call_context_dtors(struct WASMModuleInstanceCommon *inst);
void
wasm_native_inherit_contexts(struct WASMModuleInstanceCommon *child,
struct WASMModuleInstanceCommon *parent);
#else /* WASM_ENABLE_MODULE_INST_CONTEXT */
#define wasm_native_call_context_dtors(inst) (void)(inst)
#define wasm_native_inherit_contexts(child, parent) (void)(parent)
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT */
bool bool
wasm_native_init(); wasm_native_init();

View File

@ -199,7 +199,90 @@ runtime_signal_handler(void *sig_addr)
} }
} }
} }
#else #else /* else of BH_PLATFORM_WINDOWS */
#if WASM_ENABLE_AOT != 0
#include <Zydis/Zydis.h>
static uint32
decode_insn(uint8 *insn)
{
uint8 *data = (uint8 *)insn;
uint32 length = 32; /* reserve enough size */
/* Initialize decoder context */
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64,
ZYDIS_STACK_WIDTH_64);
/* Initialize formatter */
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
/* Loop over the instructions in our buffer */
ZyanU64 runtime_address = (ZyanU64)(uintptr_t)data;
ZyanUSize offset = 0;
ZydisDecodedInstruction instruction;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE];
char buffer[256];
if (ZYAN_SUCCESS(ZydisDecoderDecodeFull(
&decoder, data + offset, length - offset, &instruction, operands,
ZYDIS_MAX_OPERAND_COUNT_VISIBLE,
ZYDIS_DFLAG_VISIBLE_OPERANDS_ONLY))) {
/* Format & print the binary instruction structure to
human readable format */
ZydisFormatterFormatInstruction(&formatter, &instruction, operands,
instruction.operand_count_visible,
buffer, sizeof(buffer),
runtime_address);
/* Print current instruction */
/*
os_printf("%012" PRIX64 " ", runtime_address);
puts(buffer);
*/
return instruction.length;
}
/* Decode failed */
return 0;
}
#endif /* end of WASM_ENABLE_AOT != 0 */
static LONG
next_action(WASMModuleInstance *module_inst, EXCEPTION_POINTERS *exce_info)
{
#if WASM_ENABLE_AOT != 0
uint32 insn_size;
#endif
if (module_inst->module_type == Wasm_Module_Bytecode
&& module_inst->e->running_mode == Mode_Interp) {
/* Continue to search next exception handler for
interpreter mode as it can be caught by
`__try { .. } __except { .. }` sentences in
wasm_runtime.c */
return EXCEPTION_CONTINUE_SEARCH;
}
#if WASM_ENABLE_AOT != 0
/* Skip current instruction and continue to run for AOT/JIT mode.
TODO: implement unwind support for AOT/JIT code in Windows platform */
insn_size = decode_insn((uint8 *)exce_info->ContextRecord->Rip);
if (insn_size > 0) {
exce_info->ContextRecord->Rip += insn_size;
return EXCEPTION_CONTINUE_EXECUTION;
}
#endif
/* return different value from EXCEPTION_CONTINUE_SEARCH (= 0)
and EXCEPTION_CONTINUE_EXECUTION (= -1) */
return -2;
}
static LONG static LONG
runtime_exception_handler(EXCEPTION_POINTERS *exce_info) runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
{ {
@ -211,6 +294,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
uint8 *mapped_mem_start_addr = NULL; uint8 *mapped_mem_start_addr = NULL;
uint8 *mapped_mem_end_addr = NULL; uint8 *mapped_mem_end_addr = NULL;
uint32 page_size = os_getpagesize(); uint32 page_size = os_getpagesize();
LONG ret;
if (exec_env_tls && exec_env_tls->handle == os_self_thread() if (exec_env_tls && exec_env_tls->handle == os_self_thread()
&& (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) { && (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
@ -232,32 +316,19 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
the wasm func returns, the caller will check whether the the wasm func returns, the caller will check whether the
exception is thrown and return to runtime. */ exception is thrown and return to runtime. */
wasm_set_exception(module_inst, "out of bounds memory access"); wasm_set_exception(module_inst, "out of bounds memory access");
if (module_inst->module_type == Wasm_Module_Bytecode) { ret = next_action(module_inst, exce_info);
/* Continue to search next exception handler for if (ret == EXCEPTION_CONTINUE_SEARCH
interpreter mode as it can be caught by || ret == EXCEPTION_CONTINUE_EXECUTION)
`__try { .. } __except { .. }` sentences in return ret;
wasm_runtime.c */
return EXCEPTION_CONTINUE_SEARCH;
}
else {
/* Skip current instruction and continue to run for
AOT mode. TODO: implement unwind support for AOT
code in Windows platform */
exce_info->ContextRecord->Rip++;
return EXCEPTION_CONTINUE_EXECUTION;
}
} }
else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
&& (uint8 *)sig_addr && (uint8 *)sig_addr
< exec_env_tls->exce_check_guard_page + page_size) { < exec_env_tls->exce_check_guard_page + page_size) {
bh_assert(wasm_copy_exception(module_inst, NULL)); bh_assert(wasm_copy_exception(module_inst, NULL));
if (module_inst->module_type == Wasm_Module_Bytecode) { ret = next_action(module_inst, exce_info);
return EXCEPTION_CONTINUE_SEARCH; if (ret == EXCEPTION_CONTINUE_SEARCH
} || ret == EXCEPTION_CONTINUE_EXECUTION)
else { return ret;
exce_info->ContextRecord->Rip++;
return EXCEPTION_CONTINUE_EXECUTION;
}
} }
} }
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
@ -267,12 +338,10 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
whether the exception is thrown and return to runtime, and whether the exception is thrown and return to runtime, and
the damaged stack will be recovered by _resetstkoflw(). */ the damaged stack will be recovered by _resetstkoflw(). */
wasm_set_exception(module_inst, "native stack overflow"); wasm_set_exception(module_inst, "native stack overflow");
if (module_inst->module_type == Wasm_Module_Bytecode) { ret = next_action(module_inst, exce_info);
return EXCEPTION_CONTINUE_SEARCH; if (ret == EXCEPTION_CONTINUE_SEARCH
} || ret == EXCEPTION_CONTINUE_EXECUTION)
else { return ret;
return EXCEPTION_CONTINUE_EXECUTION;
}
} }
#endif #endif
} }
@ -388,8 +457,21 @@ wasm_runtime_env_init()
} }
#endif #endif
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
if (os_blocking_op_init() != BHT_OK) {
goto fail11;
}
os_end_blocking_op();
#endif
return true; return true;
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
fail11:
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
aot_compiler_destroy();
#endif
#endif
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
fail10: fail10:
#if WASM_ENABLE_FAST_JIT != 0 #if WASM_ENABLE_FAST_JIT != 0
@ -1196,7 +1278,8 @@ wasm_runtime_unload(WASMModuleCommon *module)
} }
WASMModuleInstanceCommon * WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst, wasm_runtime_instantiate_internal(WASMModuleCommon *module,
WASMModuleInstanceCommon *parent,
WASMExecEnv *exec_env_main, uint32 stack_size, WASMExecEnv *exec_env_main, uint32 stack_size,
uint32 heap_size, char *error_buf, uint32 heap_size, char *error_buf,
uint32 error_buf_size) uint32 error_buf_size)
@ -1204,14 +1287,14 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
#if WASM_ENABLE_INTERP != 0 #if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode) if (module->module_type == Wasm_Module_Bytecode)
return (WASMModuleInstanceCommon *)wasm_instantiate( return (WASMModuleInstanceCommon *)wasm_instantiate(
(WASMModule *)module, is_sub_inst, exec_env_main, stack_size, (WASMModule *)module, (WASMModuleInstance *)parent, exec_env_main,
heap_size, error_buf, error_buf_size); stack_size, heap_size, error_buf, error_buf_size);
#endif #endif
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT) if (module->module_type == Wasm_Module_AoT)
return (WASMModuleInstanceCommon *)aot_instantiate( return (WASMModuleInstanceCommon *)aot_instantiate(
(AOTModule *)module, is_sub_inst, exec_env_main, stack_size, (AOTModule *)module, (AOTModuleInstance *)parent, exec_env_main,
heap_size, error_buf, error_buf_size); stack_size, heap_size, error_buf, error_buf_size);
#endif #endif
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate module failed, invalid module type"); "Instantiate module failed, invalid module type");
@ -1224,7 +1307,7 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
uint32 error_buf_size) uint32 error_buf_size)
{ {
return wasm_runtime_instantiate_internal( return wasm_runtime_instantiate_internal(
module, false, NULL, stack_size, heap_size, error_buf, error_buf_size); module, NULL, NULL, stack_size, heap_size, error_buf, error_buf_size);
} }
void void
@ -1322,6 +1405,10 @@ wasm_runtime_init_thread_env(void)
} }
#endif #endif
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
os_end_blocking_op();
#endif
return true; return true;
} }
@ -1868,33 +1955,6 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
} }
#endif #endif
static bool
clear_wasi_proc_exit_exception(WASMModuleInstanceCommon *module_inst_comm)
{
#if WASM_ENABLE_LIBC_WASI != 0
bool has_exception;
char exception[EXCEPTION_BUF_LEN];
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
has_exception = wasm_copy_exception(module_inst, exception);
if (has_exception && !strcmp(exception, "Exception: wasi proc exit")) {
/* The "wasi proc exit" exception is thrown by native lib to
let wasm app exit, which is a normal behavior, we clear
the exception here. And just clear the exception of current
thread, don't call `wasm_set_exception(module_inst, NULL)`
which will clear the exception of all threads. */
module_inst->cur_exception[0] = '\0';
return true;
}
return false;
#else
return false;
#endif
}
bool bool
wasm_runtime_call_wasm(WASMExecEnv *exec_env, wasm_runtime_call_wasm(WASMExecEnv *exec_env,
WASMFunctionInstanceCommon *function, uint32 argc, WASMFunctionInstanceCommon *function, uint32 argc,
@ -1935,15 +1995,10 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
param_argc, new_argv); param_argc, new_argv);
#endif #endif
if (!ret) { if (!ret) {
if (clear_wasi_proc_exit_exception(exec_env->module_inst)) { if (new_argv != argv) {
ret = true; wasm_runtime_free(new_argv);
}
else {
if (new_argv != argv) {
wasm_runtime_free(new_argv);
}
return false;
} }
return false;
} }
#if WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_REF_TYPES != 0
@ -2304,17 +2359,10 @@ wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst_comm)
return module_inst->exec_env_singleton; return module_inst->exec_env_singleton;
} }
void static void
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception) wasm_set_exception_local(WASMModuleInstance *module_inst, const char *exception)
{ {
WASMExecEnv *exec_env = NULL; exception_lock(module_inst);
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module_inst->module);
if (node)
os_mutex_lock(&node->shared_mem_lock);
#endif
if (exception) { if (exception) {
snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception), snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception),
"Exception: %s", exception); "Exception: %s", exception);
@ -2322,19 +2370,23 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
else { else {
module_inst->cur_exception[0] = '\0'; module_inst->cur_exception[0] = '\0';
} }
#if WASM_ENABLE_SHARED_MEMORY != 0 exception_unlock(module_inst);
if (node) }
os_mutex_unlock(&node->shared_mem_lock);
#endif
void
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
{
#if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_THREAD_MGR != 0
exec_env = WASMExecEnv *exec_env =
wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst); wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
if (exec_env) { if (exec_env) {
wasm_cluster_spread_exception(exec_env, exception ? false : true); wasm_cluster_set_exception(exec_env, exception);
}
else {
wasm_set_exception_local(module_inst, exception);
} }
#else #else
(void)exec_env; wasm_set_exception_local(module_inst, exception);
#endif #endif
} }
@ -2385,12 +2437,7 @@ wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
{ {
bool has_exception = false; bool has_exception = false;
#if WASM_ENABLE_SHARED_MEMORY != 0 exception_lock(module_inst);
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module_inst->module);
if (node)
os_mutex_lock(&node->shared_mem_lock);
#endif
if (module_inst->cur_exception[0] != '\0') { if (module_inst->cur_exception[0] != '\0') {
/* NULL is passed if the caller is not interested in getting the /* NULL is passed if the caller is not interested in getting the
* exception content, but only in knowing if an exception has been * exception content, but only in knowing if an exception has been
@ -2402,10 +2449,7 @@ wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
sizeof(module_inst->cur_exception)); sizeof(module_inst->cur_exception));
has_exception = true; has_exception = true;
} }
#if WASM_ENABLE_SHARED_MEMORY != 0 exception_unlock(module_inst);
if (node)
os_mutex_unlock(&node->shared_mem_lock);
#endif
return has_exception; return has_exception;
} }
@ -2450,6 +2494,18 @@ wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm)
wasm_runtime_set_exception(module_inst_comm, NULL); wasm_runtime_set_exception(module_inst_comm, NULL);
} }
#if WASM_ENABLE_THREAD_MGR != 0
void
wasm_runtime_terminate(WASMModuleInstanceCommon *module_inst_comm)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
wasm_set_exception(module_inst, "terminated by user");
}
#endif
void void
wasm_runtime_set_custom_data_internal( wasm_runtime_set_custom_data_internal(
WASMModuleInstanceCommon *module_inst_comm, void *custom_data) WASMModuleInstanceCommon *module_inst_comm, void *custom_data)
@ -2482,6 +2538,54 @@ wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst_comm)
return module_inst->custom_data; return module_inst->custom_data;
} }
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
void
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
bool enable)
{
/* Alwary disable bounds checks if hw bounds checks enabled */
#ifdef OS_ENABLE_HW_BOUND_CHECK
enable = false;
#endif
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
->common.disable_bounds_checks = enable ? false : true;
}
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
->common.disable_bounds_checks = enable ? false : true;
}
#endif
}
bool
wasm_runtime_is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
{
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
return !((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)
->e)
->common.disable_bounds_checks;
}
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
return !((AOTModuleInstanceExtra *)((WASMModuleInstance *)module_inst)
->e)
->common.disable_bounds_checks;
}
#endif
return true;
}
#endif
uint32 uint32
wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst, wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst,
WASMExecEnv *exec_env, uint32 size, WASMExecEnv *exec_env, uint32 size,
@ -3213,27 +3317,6 @@ wasm_runtime_get_wasi_exit_code(WASMModuleInstanceCommon *module_inst)
#endif #endif
return wasi_ctx->exit_code; return wasi_ctx->exit_code;
} }
WASIContext *
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
return module_inst->wasi_ctx;
}
void
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
WASIContext *wasi_ctx)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
module_inst->wasi_ctx = wasi_ctx;
}
#endif /* end of WASM_ENABLE_LIBC_WASI */ #endif /* end of WASM_ENABLE_LIBC_WASI */
WASMModuleCommon * WASMModuleCommon *
@ -4496,10 +4579,6 @@ wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_index,
ret = aot_call_indirect(exec_env, 0, element_index, argc, argv); ret = aot_call_indirect(exec_env, 0, element_index, argc, argv);
#endif #endif
if (!ret && clear_wasi_proc_exit_exception(exec_env->module_inst)) {
ret = true;
}
return ret; return ret;
} }
@ -4636,6 +4715,8 @@ typedef struct ExternRefMapNode {
bool retained; bool retained;
/* Whether it is marked by runtime */ /* Whether it is marked by runtime */
bool marked; bool marked;
/* cleanup function called when the externref is freed */
void (*cleanup)(void *);
} ExternRefMapNode; } ExternRefMapNode;
static uint32 static uint32
@ -4698,6 +4779,81 @@ lookup_extobj_callback(void *key, void *value, void *user_data)
} }
} }
static void
delete_externref(void *key, ExternRefMapNode *node)
{
bh_hash_map_remove(externref_map, key, NULL, NULL);
if (node->cleanup) {
(*node->cleanup)(node->extern_obj);
}
wasm_runtime_free(node);
}
static void
delete_extobj_callback(void *key, void *value, void *user_data)
{
ExternRefMapNode *node = (ExternRefMapNode *)value;
LookupExtObj_UserData *lookup_user_data =
(LookupExtObj_UserData *)user_data;
if (node->extern_obj == lookup_user_data->node.extern_obj
&& node->module_inst == lookup_user_data->node.module_inst) {
lookup_user_data->found = true;
delete_externref(key, node);
}
}
bool
wasm_externref_objdel(WASMModuleInstanceCommon *module_inst, void *extern_obj)
{
LookupExtObj_UserData lookup_user_data = { 0 };
bool ok = false;
/* in a wrapper, extern_obj could be any value */
lookup_user_data.node.extern_obj = extern_obj;
lookup_user_data.node.module_inst = module_inst;
lookup_user_data.found = false;
os_mutex_lock(&externref_lock);
/* Lookup hashmap firstly */
bh_hash_map_traverse(externref_map, delete_extobj_callback,
(void *)&lookup_user_data);
if (lookup_user_data.found) {
ok = true;
}
os_mutex_unlock(&externref_lock);
return ok;
}
bool
wasm_externref_set_cleanup(WASMModuleInstanceCommon *module_inst,
void *extern_obj, void (*extern_obj_cleanup)(void *))
{
LookupExtObj_UserData lookup_user_data = { 0 };
bool ok = false;
/* in a wrapper, extern_obj could be any value */
lookup_user_data.node.extern_obj = extern_obj;
lookup_user_data.node.module_inst = module_inst;
lookup_user_data.found = false;
os_mutex_lock(&externref_lock);
/* Lookup hashmap firstly */
bh_hash_map_traverse(externref_map, lookup_extobj_callback,
(void *)&lookup_user_data);
if (lookup_user_data.found) {
void *key = (void *)(uintptr_t)lookup_user_data.externref_idx;
ExternRefMapNode *node = bh_hash_map_find(externref_map, key);
node->cleanup = extern_obj_cleanup;
ok = true;
}
os_mutex_unlock(&externref_lock);
return ok;
}
bool bool
wasm_externref_obj2ref(WASMModuleInstanceCommon *module_inst, void *extern_obj, wasm_externref_obj2ref(WASMModuleInstanceCommon *module_inst, void *extern_obj,
uint32 *p_externref_idx) uint32 *p_externref_idx)
@ -4747,6 +4903,7 @@ wasm_externref_obj2ref(WASMModuleInstanceCommon *module_inst, void *extern_obj,
memset(node, 0, sizeof(ExternRefMapNode)); memset(node, 0, sizeof(ExternRefMapNode));
node->extern_obj = extern_obj; node->extern_obj = extern_obj;
node->module_inst = module_inst; node->module_inst = module_inst;
node->cleanup = NULL;
externref_idx = externref_global_id; externref_idx = externref_global_id;
@ -4797,8 +4954,7 @@ reclaim_extobj_callback(void *key, void *value, void *user_data)
if (node->module_inst == module_inst) { if (node->module_inst == module_inst) {
if (!node->marked && !node->retained) { if (!node->marked && !node->retained) {
bh_hash_map_remove(externref_map, key, NULL, NULL); delete_externref(key, node);
wasm_runtime_free(value);
} }
else { else {
node->marked = false; node->marked = false;
@ -4913,8 +5069,7 @@ cleanup_extobj_callback(void *key, void *value, void *user_data)
(WASMModuleInstanceCommon *)user_data; (WASMModuleInstanceCommon *)user_data;
if (node->module_inst == module_inst) { if (node->module_inst == module_inst) {
bh_hash_map_remove(externref_map, key, NULL, NULL); delete_externref(key, node);
wasm_runtime_free(value);
} }
} }
@ -5507,3 +5662,37 @@ wasm_runtime_is_import_global_linked(const char *module_name,
return false; return false;
#endif #endif
} }
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
void *
wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
void *ctx))
{
return wasm_native_create_context_key(dtor);
}
void
wasm_runtime_destroy_context_key(void *key)
{
wasm_native_destroy_context_key(key);
}
void
wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx)
{
wasm_native_set_context(inst, key, ctx);
}
void
wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
void *ctx)
{
wasm_native_set_context_spread(inst, key, ctx);
}
void *
wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key)
{
return wasm_native_get_context(inst, key);
}
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */

View File

@ -498,7 +498,8 @@ wasm_runtime_unload(WASMModuleCommon *module);
/* Internal API */ /* Internal API */
WASMModuleInstanceCommon * WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst, wasm_runtime_instantiate_internal(WASMModuleCommon *module,
WASMModuleInstanceCommon *parent,
WASMExecEnv *exec_env_main, uint32 stack_size, WASMExecEnv *exec_env_main, uint32 stack_size,
uint32 heap_size, char *error_buf, uint32 heap_size, char *error_buf,
uint32 error_buf_size); uint32 error_buf_size);
@ -593,6 +594,17 @@ wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data);
WASM_RUNTIME_API_EXTERN void * WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_user_data(WASMExecEnv *exec_env); wasm_runtime_get_user_data(WASMExecEnv *exec_env);
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
bool enable);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst);
#endif
#ifdef OS_ENABLE_HW_BOUND_CHECK #ifdef OS_ENABLE_HW_BOUND_CHECK
/* Access exception check guard page to trigger the signal handler */ /* Access exception check guard page to trigger the signal handler */
void void
@ -663,6 +675,10 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module);
WASM_RUNTIME_API_EXTERN void WASM_RUNTIME_API_EXTERN void
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst); wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_terminate(WASMModuleInstanceCommon *module);
/* Internal API */ /* Internal API */
void void
wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst, wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst,
@ -927,6 +943,26 @@ WASM_RUNTIME_API_EXTERN bool
wasm_runtime_unregister_natives(const char *module_name, wasm_runtime_unregister_natives(const char *module_name,
NativeSymbol *native_symbols); NativeSymbol *native_symbols);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
void *ctx));
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_destroy_context_key(void *key);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
void *ctx);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key);
bool bool
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
const WASMType *func_type, const char *signature, const WASMType *func_type, const char *signature,
@ -1004,6 +1040,15 @@ WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_import_global_linked(const char *module_name, wasm_runtime_is_import_global_linked(const char *module_name,
const char *global_name); const char *global_name);
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_begin_blocking_op(WASMExecEnv *exec_env);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_end_blocking_op(WASMExecEnv *exec_env);
void
wasm_runtime_interrupt_blocking_op(WASMExecEnv *exec_env);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -9,9 +9,16 @@
#include "../libraries/thread-mgr/thread_manager.h" #include "../libraries/thread-mgr/thread_manager.h"
#endif #endif
static bh_list shared_memory_list_head; /*
static bh_list *const shared_memory_list = &shared_memory_list_head; * Note: this lock can be per memory.
static korp_mutex shared_memory_list_lock; *
* For now, just use a global because:
* - it's a bit cumbersome to extend WASMMemoryInstance w/o breaking
* the AOT ABI.
* - If you care performance, it's better to make the interpreters
* use atomic ops.
*/
static korp_mutex _shared_memory_lock;
/* clang-format off */ /* clang-format off */
enum { enum {
@ -37,7 +44,7 @@ typedef struct AtomicWaitNode {
static HashMap *wait_map; static HashMap *wait_map;
static uint32 static uint32
wait_address_hash(void *address); wait_address_hash(const void *address);
static bool static bool
wait_address_equal(void *h1, void *h2); wait_address_equal(void *h1, void *h2);
@ -48,17 +55,15 @@ destroy_wait_info(void *wait_info);
bool bool
wasm_shared_memory_init() wasm_shared_memory_init()
{ {
if (os_mutex_init(&shared_memory_list_lock) != 0) if (os_mutex_init(&_shared_memory_lock) != 0)
return false; return false;
/* wait map not exists, create new map */ /* wait map not exists, create new map */
if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash, if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash,
(KeyEqualFunc)wait_address_equal, NULL, (KeyEqualFunc)wait_address_equal, NULL,
destroy_wait_info))) { destroy_wait_info))) {
os_mutex_destroy(&shared_memory_list_lock); os_mutex_destroy(&_shared_memory_lock);
return false; return false;
} }
return true; return true;
} }
@ -66,115 +71,84 @@ void
wasm_shared_memory_destroy() wasm_shared_memory_destroy()
{ {
bh_hash_map_destroy(wait_map); bh_hash_map_destroy(wait_map);
os_mutex_destroy(&shared_memory_list_lock); os_mutex_destroy(&_shared_memory_lock);
} }
static WASMSharedMemNode * uint32
search_module(WASMModuleCommon *module) shared_memory_inc_reference(WASMMemoryInstance *memory)
{ {
WASMSharedMemNode *node; bh_assert(shared_memory_is_shared(memory));
uint32 old;
os_mutex_lock(&shared_memory_list_lock); #if BH_ATOMIC_32_IS_ATOMIC == 0
node = bh_list_first_elem(shared_memory_list); os_mutex_lock(&_shared_memory_lock);
#endif
while (node) { old = BH_ATOMIC_32_FETCH_ADD(memory->ref_count, 1);
if (module == node->module) { #if BH_ATOMIC_32_IS_ATOMIC == 0
os_mutex_unlock(&shared_memory_list_lock); os_mutex_unlock(&_shared_memory_lock);
return node; #endif
} bh_assert(old >= 1);
node = bh_list_elem_next(node); bh_assert(old < UINT32_MAX);
} return old + 1;
os_mutex_unlock(&shared_memory_list_lock);
return NULL;
} }
WASMSharedMemNode * uint32
wasm_module_get_shared_memory(WASMModuleCommon *module) shared_memory_dec_reference(WASMMemoryInstance *memory)
{ {
return search_module(module); bh_assert(shared_memory_is_shared(memory));
uint32 old;
#if BH_ATOMIC_32_IS_ATOMIC == 0
os_mutex_lock(&_shared_memory_lock);
#endif
old = BH_ATOMIC_32_FETCH_SUB(memory->ref_count, 1);
#if BH_ATOMIC_32_IS_ATOMIC == 0
os_mutex_unlock(&_shared_memory_lock);
#endif
bh_assert(old > 0);
return old - 1;
} }
int32 bool
shared_memory_inc_reference(WASMModuleCommon *module) shared_memory_is_shared(WASMMemoryInstance *memory)
{ {
WASMSharedMemNode *node = search_module(module); uint32 old;
uint32 ref_count = -1; #if BH_ATOMIC_32_IS_ATOMIC == 0
if (node) { os_mutex_lock(&_shared_memory_lock);
os_mutex_lock(&node->lock); #endif
ref_count = ++node->ref_count; old = BH_ATOMIC_32_LOAD(memory->ref_count);
os_mutex_unlock(&node->lock); #if BH_ATOMIC_32_IS_ATOMIC == 0
} os_mutex_unlock(&_shared_memory_lock);
return ref_count; #endif
return old > 0;
} }
int32 static korp_mutex *
shared_memory_dec_reference(WASMModuleCommon *module) shared_memory_get_lock_pointer(WASMMemoryInstance *memory)
{ {
WASMSharedMemNode *node = search_module(module); bh_assert(memory != NULL);
uint32 ref_count = 0; return &_shared_memory_lock;
if (node) {
os_mutex_lock(&node->lock);
ref_count = --node->ref_count;
os_mutex_unlock(&node->lock);
if (ref_count == 0) {
os_mutex_lock(&shared_memory_list_lock);
bh_list_remove(shared_memory_list, node);
os_mutex_unlock(&shared_memory_list_lock);
os_mutex_destroy(&node->shared_mem_lock);
os_mutex_destroy(&node->lock);
wasm_runtime_free(node);
}
return ref_count;
}
return -1;
} }
WASMMemoryInstanceCommon * void
shared_memory_get_memory_inst(WASMSharedMemNode *node) shared_memory_lock(WASMMemoryInstance *memory)
{ {
return node->memory_inst; /*
* Note: exception logic is currently abusing this lock.
* cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407
*/
bh_assert(memory != NULL);
os_mutex_lock(&_shared_memory_lock);
} }
WASMSharedMemNode * void
shared_memory_set_memory_inst(WASMModuleCommon *module, shared_memory_unlock(WASMMemoryInstance *memory)
WASMMemoryInstanceCommon *memory)
{ {
WASMSharedMemNode *node; bh_assert(memory != NULL);
bh_list_status ret; os_mutex_unlock(&_shared_memory_lock);
if (!(node = wasm_runtime_malloc(sizeof(WASMSharedMemNode))))
return NULL;
node->module = module;
node->memory_inst = memory;
node->ref_count = 1;
if (os_mutex_init(&node->shared_mem_lock) != 0) {
wasm_runtime_free(node);
return NULL;
}
if (os_mutex_init(&node->lock) != 0) {
os_mutex_destroy(&node->shared_mem_lock);
wasm_runtime_free(node);
return NULL;
}
os_mutex_lock(&shared_memory_list_lock);
ret = bh_list_insert(shared_memory_list, node);
bh_assert(ret == BH_LIST_SUCCESS);
os_mutex_unlock(&shared_memory_list_lock);
(void)ret;
return node;
} }
/* Atomics wait && notify APIs */ /* Atomics wait && notify APIs */
static uint32 static uint32
wait_address_hash(void *address) wait_address_hash(const void *address)
{ {
return (uint32)(uintptr_t)address; return (uint32)(uintptr_t)address;
} }
@ -307,7 +281,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
WASMModuleInstance *module_inst = (WASMModuleInstance *)module; WASMModuleInstance *module_inst = (WASMModuleInstance *)module;
AtomicWaitInfo *wait_info; AtomicWaitInfo *wait_info;
AtomicWaitNode *wait_node; AtomicWaitNode *wait_node;
WASMSharedMemNode *node; korp_mutex *lock;
#if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_THREAD_MGR != 0
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
#endif #endif
@ -322,7 +296,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
} }
/* Currently we have only one memory instance */ /* Currently we have only one memory instance */
if (!module_inst->memories[0]->is_shared) { if (!shared_memory_is_shared(module_inst->memories[0])) {
wasm_runtime_set_exception(module, "expected shared memory"); wasm_runtime_set_exception(module, "expected shared memory");
return -1; return -1;
} }
@ -340,30 +314,29 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
bh_assert(exec_env); bh_assert(exec_env);
#endif #endif
node = search_module((WASMModuleCommon *)module_inst->module); lock = shared_memory_get_lock_pointer(module_inst->memories[0]);
bh_assert(node);
/* Lock the shared_mem_lock for the whole atomic wait process, /* Lock the shared_mem_lock for the whole atomic wait process,
and use it to os_cond_reltimedwait */ and use it to os_cond_reltimedwait */
os_mutex_lock(&node->shared_mem_lock); os_mutex_lock(lock);
no_wait = (!wait64 && *(uint32 *)address != (uint32)expect) no_wait = (!wait64 && *(uint32 *)address != (uint32)expect)
|| (wait64 && *(uint64 *)address != expect); || (wait64 && *(uint64 *)address != expect);
if (no_wait) { if (no_wait) {
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(lock);
return 1; return 1;
} }
if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) { if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) {
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(lock);
wasm_runtime_set_exception(module, "failed to create wait node"); wasm_runtime_set_exception(module, "failed to create wait node");
return -1; return -1;
} }
memset(wait_node, 0, sizeof(AtomicWaitNode)); memset(wait_node, 0, sizeof(AtomicWaitNode));
if (0 != os_cond_init(&wait_node->wait_cond)) { if (0 != os_cond_init(&wait_node->wait_cond)) {
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(lock);
wasm_runtime_free(wait_node); wasm_runtime_free(wait_node);
wasm_runtime_set_exception(module, "failed to init wait cond"); wasm_runtime_set_exception(module, "failed to init wait cond");
return -1; return -1;
@ -375,7 +348,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
wait_info = acquire_wait_info(address, wait_node); wait_info = acquire_wait_info(address, wait_node);
if (!wait_info) { if (!wait_info) {
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(lock);
os_cond_destroy(&wait_node->wait_cond); os_cond_destroy(&wait_node->wait_cond);
wasm_runtime_free(wait_node); wasm_runtime_free(wait_node);
wasm_runtime_set_exception(module, "failed to acquire wait_info"); wasm_runtime_set_exception(module, "failed to acquire wait_info");
@ -390,7 +363,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
if (timeout < 0) { if (timeout < 0) {
/* wait forever until it is notified or terminatied /* wait forever until it is notified or terminatied
here we keep waiting and checking every second */ here we keep waiting and checking every second */
os_cond_reltimedwait(&wait_node->wait_cond, &node->shared_mem_lock, os_cond_reltimedwait(&wait_node->wait_cond, lock,
(uint64)timeout_1sec); (uint64)timeout_1sec);
if (wait_node->status == S_NOTIFIED /* notified by atomic.notify */ if (wait_node->status == S_NOTIFIED /* notified by atomic.notify */
#if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_THREAD_MGR != 0
@ -404,8 +377,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
else { else {
timeout_wait = timeout_wait =
timeout_left < timeout_1sec ? timeout_left : timeout_1sec; timeout_left < timeout_1sec ? timeout_left : timeout_1sec;
os_cond_reltimedwait(&wait_node->wait_cond, &node->shared_mem_lock, os_cond_reltimedwait(&wait_node->wait_cond, lock, timeout_wait);
timeout_wait);
if (wait_node->status == S_NOTIFIED /* notified by atomic.notify */ if (wait_node->status == S_NOTIFIED /* notified by atomic.notify */
|| timeout_left <= timeout_wait /* time out */ || timeout_left <= timeout_wait /* time out */
#if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_THREAD_MGR != 0
@ -433,7 +405,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
/* Release wait info if no wait nodes are attached */ /* Release wait info if no wait nodes are attached */
map_try_release_wait_info(wait_map, wait_info, address); map_try_release_wait_info(wait_map, wait_info, address);
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(lock);
return is_timeout ? 2 : 0; return is_timeout ? 2 : 0;
} }
@ -445,7 +417,7 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
WASMModuleInstance *module_inst = (WASMModuleInstance *)module; WASMModuleInstance *module_inst = (WASMModuleInstance *)module;
uint32 notify_result; uint32 notify_result;
AtomicWaitInfo *wait_info; AtomicWaitInfo *wait_info;
WASMSharedMemNode *node; korp_mutex *lock;
bool out_of_bounds; bool out_of_bounds;
bh_assert(module->module_type == Wasm_Module_Bytecode bh_assert(module->module_type == Wasm_Module_Bytecode
@ -461,31 +433,30 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
} }
/* Currently we have only one memory instance */ /* Currently we have only one memory instance */
if (!module_inst->memories[0]->is_shared) { if (!shared_memory_is_shared(module_inst->memories[0])) {
/* Always return 0 for ushared linear memory since there is /* Always return 0 for ushared linear memory since there is
no way to create a waiter on it */ no way to create a waiter on it */
return 0; return 0;
} }
node = search_module((WASMModuleCommon *)module_inst->module); lock = shared_memory_get_lock_pointer(module_inst->memories[0]);
bh_assert(node);
/* Lock the shared_mem_lock for the whole atomic notify process, /* Lock the shared_mem_lock for the whole atomic notify process,
and use it to os_cond_signal */ and use it to os_cond_signal */
os_mutex_lock(&node->shared_mem_lock); os_mutex_lock(lock);
wait_info = acquire_wait_info(address, NULL); wait_info = acquire_wait_info(address, NULL);
/* Nobody wait on this address */ /* Nobody wait on this address */
if (!wait_info) { if (!wait_info) {
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(lock);
return 0; return 0;
} }
/* Notify each wait node in the wait list */ /* Notify each wait node in the wait list */
notify_result = notify_wait_list(wait_info->wait_list, count); notify_result = notify_wait_list(wait_info->wait_list, count);
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(lock);
return notify_result; return notify_result;
} }

View File

@ -7,53 +7,33 @@
#define _WASM_SHARED_MEMORY_H #define _WASM_SHARED_MEMORY_H
#include "bh_common.h" #include "bh_common.h"
#if WASM_ENABLE_INTERP != 0 #include "../interpreter/wasm_runtime.h"
#include "wasm_runtime.h" #include "wasm_runtime_common.h"
#endif
#if WASM_ENABLE_AOT != 0
#include "aot_runtime.h"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct WASMSharedMemNode {
bh_list_link l;
/* Lock */
korp_mutex lock;
/* The module reference */
WASMModuleCommon *module;
/* The memory information */
WASMMemoryInstanceCommon *memory_inst;
/* Lock used for atomic operations */
korp_mutex shared_mem_lock;
/* reference count */
uint32 ref_count;
} WASMSharedMemNode;
bool bool
wasm_shared_memory_init(); wasm_shared_memory_init();
void void
wasm_shared_memory_destroy(); wasm_shared_memory_destroy();
WASMSharedMemNode * uint32
wasm_module_get_shared_memory(WASMModuleCommon *module); shared_memory_inc_reference(WASMMemoryInstance *memory);
int32 uint32
shared_memory_inc_reference(WASMModuleCommon *module); shared_memory_dec_reference(WASMMemoryInstance *memory);
int32 bool
shared_memory_dec_reference(WASMModuleCommon *module); shared_memory_is_shared(WASMMemoryInstance *memory);
WASMMemoryInstanceCommon * void
shared_memory_get_memory_inst(WASMSharedMemNode *node); shared_memory_lock(WASMMemoryInstance *memory);
WASMSharedMemNode * void
shared_memory_set_memory_inst(WASMModuleCommon *module, shared_memory_unlock(WASMMemoryInstance *memory);
WASMMemoryInstanceCommon *memory);
uint32 uint32
wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2023 Amazon Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _WASM_SUSPEND_FLAGS_H
#define _WASM_SUSPEND_FLAGS_H
#include "bh_atomic.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Need to terminate */
#define WASM_SUSPEND_FLAG_TERMINATE 0x1
/* Need to suspend */
#define WASM_SUSPEND_FLAG_SUSPEND 0x2
/* Need to go into breakpoint */
#define WASM_SUSPEND_FLAG_BREAKPOINT 0x4
/* Return from pthread_exit */
#define WASM_SUSPEND_FLAG_EXIT 0x8
/* The thread might be blocking */
#define WASM_SUSPEND_FLAG_BLOCKING 0x10
typedef union WASMSuspendFlags {
bh_atomic_32_t flags;
uintptr_t __padding__;
} WASMSuspendFlags;
#define WASM_SUSPEND_FLAGS_IS_ATOMIC BH_ATOMIC_32_IS_ATOMIC
#define WASM_SUSPEND_FLAGS_GET(s_flags) BH_ATOMIC_32_LOAD(s_flags.flags)
#define WASM_SUSPEND_FLAGS_FETCH_OR(s_flags, val) \
BH_ATOMIC_32_FETCH_OR(s_flags.flags, val)
#define WASM_SUSPEND_FLAGS_FETCH_AND(s_flags, val) \
BH_ATOMIC_32_FETCH_AND(s_flags.flags, val)
#if WASM_SUSPEND_FLAGS_IS_ATOMIC != 0
#define WASM_SUSPEND_FLAGS_LOCK(lock) (void)0
#define WASM_SUSPEND_FLAGS_UNLOCK(lock) (void)0
#else /* else of WASM_SUSPEND_FLAGS_IS_ATOMIC */
#define WASM_SUSPEND_FLAGS_LOCK(lock) os_mutex_lock(&lock)
#define WASM_SUSPEND_FLAGS_UNLOCK(lock) os_mutex_unlock(&lock);
#endif /* WASM_SUSPEND_FLAGS_IS_ATOMIC */
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_SUSPEND_FLAGS_H */

View File

@ -43,7 +43,7 @@ typedef WASMType AOTFuncType;
typedef WASMExport AOTExport; typedef WASMExport AOTExport;
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
typedef void *dwar_extractor_handle_t; typedef void *dwarf_extractor_handle_t;
#endif #endif
typedef enum AOTIntCond { typedef enum AOTIntCond {
@ -285,7 +285,7 @@ typedef struct AOTCompData {
WASMModule *wasm_module; WASMModule *wasm_module;
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
dwar_extractor_handle_t extractor; dwarf_extractor_handle_t extractor;
#endif #endif
} AOTCompData; } AOTCompData;

View File

@ -2617,64 +2617,6 @@ verify_module(AOTCompContext *comp_ctx)
return true; return true;
} }
/* Check whether the target supports hardware atomic instructions */
static bool
aot_require_lower_atomic_pass(AOTCompContext *comp_ctx)
{
bool ret = false;
if (!strncmp(comp_ctx->target_arch, "riscv", 5)) {
char *feature =
LLVMGetTargetMachineFeatureString(comp_ctx->target_machine);
if (feature) {
if (!strstr(feature, "+a")) {
ret = true;
}
LLVMDisposeMessage(feature);
}
}
return ret;
}
/* Check whether the target needs to expand switch to if/else */
static bool
aot_require_lower_switch_pass(AOTCompContext *comp_ctx)
{
bool ret = false;
/* IR switch/case will cause .rodata relocation on riscv/xtensa */
if (!strncmp(comp_ctx->target_arch, "riscv", 5)
|| !strncmp(comp_ctx->target_arch, "xtensa", 6)) {
ret = true;
}
return ret;
}
static bool
apply_passes_for_indirect_mode(AOTCompContext *comp_ctx)
{
LLVMPassManagerRef common_pass_mgr;
if (!(common_pass_mgr = LLVMCreatePassManager())) {
aot_set_last_error("create pass manager failed");
return false;
}
aot_add_expand_memory_op_pass(common_pass_mgr);
if (aot_require_lower_atomic_pass(comp_ctx))
LLVMAddLowerAtomicPass(common_pass_mgr);
if (aot_require_lower_switch_pass(comp_ctx))
LLVMAddLowerSwitchPass(common_pass_mgr);
LLVMRunPassManager(common_pass_mgr, comp_ctx->module);
LLVMDisposePassManager(common_pass_mgr);
return true;
}
bool bool
aot_compile_wasm(AOTCompContext *comp_ctx) aot_compile_wasm(AOTCompContext *comp_ctx)
{ {
@ -2714,17 +2656,6 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
possible core dump. */ possible core dump. */
bh_print_time("Begin to run llvm optimization passes"); bh_print_time("Begin to run llvm optimization passes");
aot_apply_llvm_new_pass_manager(comp_ctx, comp_ctx->module); aot_apply_llvm_new_pass_manager(comp_ctx, comp_ctx->module);
/* Run specific passes for AOT indirect mode in last since general
optimization may create some intrinsic function calls like
llvm.memset, so let's remove these function calls here. */
if (!comp_ctx->is_jit_mode && comp_ctx->is_indirect_mode) {
bh_print_time("Begin to run optimization passes "
"for indirect mode");
if (!apply_passes_for_indirect_mode(comp_ctx)) {
return false;
}
}
bh_print_time("Finish llvm optimization passes"); bh_print_time("Finish llvm optimization passes");
} }
@ -2765,7 +2696,7 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
if (comp_ctx->stack_sizes != NULL) { if (comp_ctx->stack_sizes != NULL) {
LLVMOrcJITTargetAddress addr; LLVMOrcJITTargetAddress addr;
if ((err = LLVMOrcLLLazyJITLookup(comp_ctx->orc_jit, &addr, if ((err = LLVMOrcLLLazyJITLookup(comp_ctx->orc_jit, &addr,
aot_stack_sizes_name))) { aot_stack_sizes_alias_name))) {
aot_handle_llvm_errmsg("failed to look up stack_sizes", err); aot_handle_llvm_errmsg("failed to look up stack_sizes", err);
return false; return false;
} }
@ -2804,6 +2735,33 @@ aot_generate_tempfile_name(const char *prefix, const char *extension,
snprintf(buffer + name_len, len - name_len, ".%s", extension); snprintf(buffer + name_len, len - name_len, ".%s", extension);
return buffer; return buffer;
} }
#else
errno_t
_mktemp_s(char *nameTemplate, size_t sizeInChars);
char *
aot_generate_tempfile_name(const char *prefix, const char *extension,
char *buffer, uint32 len)
{
int name_len;
name_len = snprintf(buffer, len, "%s-XXXXXX", prefix);
if (_mktemp_s(buffer, name_len + 1) != 0) {
return NULL;
}
/* Check if buffer length is enough */
/* name_len + '.' + extension + '\0' */
if (name_len + 1 + strlen(extension) + 1 > len) {
aot_set_last_error("temp file name too long.");
return NULL;
}
snprintf(buffer + name_len, len - name_len, ".%s", extension);
return buffer;
}
#endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */ #endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */
bool bool

View File

@ -93,7 +93,10 @@ check_utf8_str(const uint8 *str, uint32 len)
/* Internal function in object file */ /* Internal function in object file */
typedef struct AOTObjectFunc { typedef struct AOTObjectFunc {
char *func_name; char *func_name;
/* text offset of aot_func#n */
uint64 text_offset; uint64 text_offset;
/* text offset of aot_func_internal#n */
uint64 text_offset_of_aot_func_internal;
} AOTObjectFunc; } AOTObjectFunc;
/* Symbol table list node */ /* Symbol table list node */
@ -637,13 +640,33 @@ get_relocation_size(AOTRelocation *relocation, bool is_32bin)
} }
static uint32 static uint32
get_relocations_size(AOTRelocation *relocations, uint32 relocation_count, get_relocations_size(AOTObjectData *obj_data,
AOTRelocationGroup *relocation_group,
AOTRelocation *relocations, uint32 relocation_count,
bool is_32bin) bool is_32bin)
{ {
AOTRelocation *relocation = relocations; AOTRelocation *relocation = relocations;
uint32 size = 0, i; uint32 size = 0, i;
for (i = 0; i < relocation_count; i++, relocation++) { for (i = 0; i < relocation_count; i++, relocation++) {
/* ignore the relocations to aot_func_internal#n in text section
for windows platform since they will be applied in
aot_emit_text_section */
if (!strcmp(relocation_group->section_name, ".text")
&& !strncmp(relocation->symbol_name, AOT_FUNC_INTERNAL_PREFIX,
strlen(AOT_FUNC_INTERNAL_PREFIX))
&& ((!strncmp(obj_data->comp_ctx->target_arch, "x86_64", 6)
/* Windows AOT_COFF64_BIN_TYPE */
&& obj_data->target_info.bin_type == 6
/* IMAGE_REL_AMD64_REL32 in windows x86_64 */
&& relocation->relocation_type == 4)
|| (!strncmp(obj_data->comp_ctx->target_arch, "i386", 4)
/* Windows AOT_COFF32_BIN_TYPE */
&& obj_data->target_info.bin_type == 4
/* IMAGE_REL_I386_REL32 in windows x86_32 */
&& relocation->relocation_type == 20))) {
continue;
}
size = align_uint(size, 4); size = align_uint(size, 4);
size += get_relocation_size(relocation, is_32bin); size += get_relocation_size(relocation, is_32bin);
} }
@ -651,19 +674,22 @@ get_relocations_size(AOTRelocation *relocations, uint32 relocation_count,
} }
static uint32 static uint32
get_relocation_group_size(AOTRelocationGroup *relocation_group, bool is_32bin) get_relocation_group_size(AOTObjectData *obj_data,
AOTRelocationGroup *relocation_group, bool is_32bin)
{ {
uint32 size = 0; uint32 size = 0;
/* section name index + relocation count + relocations */ /* section name index + relocation count + relocations */
size += (uint32)sizeof(uint32); size += (uint32)sizeof(uint32);
size += (uint32)sizeof(uint32); size += (uint32)sizeof(uint32);
size += get_relocations_size(relocation_group->relocations, size += get_relocations_size(obj_data, relocation_group,
relocation_group->relocations,
relocation_group->relocation_count, is_32bin); relocation_group->relocation_count, is_32bin);
return size; return size;
} }
static uint32 static uint32
get_relocation_groups_size(AOTRelocationGroup *relocation_groups, get_relocation_groups_size(AOTObjectData *obj_data,
AOTRelocationGroup *relocation_groups,
uint32 relocation_group_count, bool is_32bin) uint32 relocation_group_count, bool is_32bin)
{ {
AOTRelocationGroup *relocation_group = relocation_groups; AOTRelocationGroup *relocation_group = relocation_groups;
@ -671,7 +697,7 @@ get_relocation_groups_size(AOTRelocationGroup *relocation_groups,
for (i = 0; i < relocation_group_count; i++, relocation_group++) { for (i = 0; i < relocation_group_count; i++, relocation_group++) {
size = align_uint(size, 4); size = align_uint(size, 4);
size += get_relocation_group_size(relocation_group, is_32bin); size += get_relocation_group_size(obj_data, relocation_group, is_32bin);
} }
return size; return size;
} }
@ -864,7 +890,7 @@ get_relocation_section_size(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
/* relocation group count + symbol_table + relocation groups */ /* relocation group count + symbol_table + relocation groups */
return (uint32)sizeof(uint32) + symbol_table_size return (uint32)sizeof(uint32) + symbol_table_size
+ get_relocation_groups_size(relocation_groups, + get_relocation_groups_size(obj_data, relocation_groups,
relocation_group_count, relocation_group_count,
is_32bit_binary(obj_data)); is_32bit_binary(obj_data));
} }
@ -1734,6 +1760,10 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
uint32 section_size = get_text_section_size(obj_data); uint32 section_size = get_text_section_size(obj_data);
uint32 offset = *p_offset; uint32 offset = *p_offset;
uint8 placeholder = 0; uint8 placeholder = 0;
AOTRelocationGroup *relocation_group;
AOTRelocation *relocation;
uint32 i, j, relocation_count;
uint8 *text;
*p_offset = offset = align_uint(offset, 4); *p_offset = offset = align_uint(offset, 4);
@ -1747,6 +1777,8 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_BUF(&placeholder, 1); EMIT_BUF(&placeholder, 1);
} }
text = buf + offset;
if (obj_data->text_size > 0) { if (obj_data->text_size > 0) {
EMIT_BUF(obj_data->text, obj_data->text_size); EMIT_BUF(obj_data->text, obj_data->text_size);
while (offset & 3) while (offset & 3)
@ -1768,6 +1800,67 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
return false; return false;
} }
/* apply relocations to aot_func_internal#n in text section for
windows platform */
if ((!strncmp(obj_data->comp_ctx->target_arch, "x86_64", 6)
/* Windows AOT_COFF64_BIN_TYPE */
&& obj_data->target_info.bin_type == 6)
|| (!strncmp(obj_data->comp_ctx->target_arch, "i386", 4)
/* Windows AOT_COFF32_BIN_TYPE */
&& obj_data->target_info.bin_type == 4)) {
relocation_group = obj_data->relocation_groups;
for (i = 0; i < obj_data->relocation_group_count;
i++, relocation_group++) {
/* relocation in text section */
if (!strcmp(relocation_group->section_name, ".text")) {
relocation = relocation_group->relocations;
relocation_count = relocation_group->relocation_count;
for (j = 0; j < relocation_count; j++) {
/* relocation to aot_func_internal#n */
if (str_starts_with(relocation->symbol_name,
AOT_FUNC_INTERNAL_PREFIX)
&& ((obj_data->target_info.bin_type
== 6 /* AOT_COFF64_BIN_TYPE */
&& relocation->relocation_type
== 4 /* IMAGE_REL_AMD64_REL32 */)
|| (obj_data->target_info.bin_type
== 4 /* AOT_COFF32_BIN_TYPE */
&& relocation->relocation_type
== 20 /* IMAGE_REL_I386_REL32 */))) {
uint32 func_idx =
atoi(relocation->symbol_name
+ strlen(AOT_FUNC_INTERNAL_PREFIX));
uint64 text_offset, reloc_offset, reloc_addend;
bh_assert(func_idx < obj_data->func_count);
text_offset = obj_data->funcs[func_idx]
.text_offset_of_aot_func_internal;
reloc_offset = relocation->relocation_offset;
reloc_addend = relocation->relocation_addend;
/* S + A - P */
*(uint32 *)(text + reloc_offset) =
(uint32)(text_offset + reloc_addend - reloc_offset
- 4);
/* remove current relocation as it has been applied */
if (j < relocation_count - 1) {
uint32 move_size =
(uint32)(sizeof(AOTRelocation)
* (relocation_count - 1 - j));
bh_memmove_s(relocation, move_size, relocation + 1,
move_size);
}
relocation_group->relocation_count--;
}
else {
relocation++;
}
}
}
}
}
*p_offset = offset; *p_offset = offset;
return true; return true;
@ -2403,7 +2496,7 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
&& !strcmp(name, "__llvm_prf_cnts")) { && !strcmp(name, "__llvm_prf_cnts")) {
snprintf(buf, sizeof(buf), "%s%u", name, snprintf(buf, sizeof(buf), "%s%u", name,
llvm_prf_cnts_idx++); llvm_prf_cnts_idx++);
size = strlen(buf) + 1; size = (uint32)(strlen(buf) + 1);
if (!(data_section->name = wasm_runtime_malloc(size))) { if (!(data_section->name = wasm_runtime_malloc(size))) {
aot_set_last_error( aot_set_last_error(
"allocate memory for data section name failed."); "allocate memory for data section name failed.");
@ -2416,7 +2509,7 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
&& !strcmp(name, "__llvm_prf_data")) { && !strcmp(name, "__llvm_prf_data")) {
snprintf(buf, sizeof(buf), "%s%u", name, snprintf(buf, sizeof(buf), "%s%u", name,
llvm_prf_data_idx++); llvm_prf_data_idx++);
size = strlen(buf) + 1; size = (uint32)(strlen(buf) + 1);
if (!(data_section->name = wasm_runtime_malloc(size))) { if (!(data_section->name = wasm_runtime_malloc(size))) {
aot_set_last_error( aot_set_last_error(
"allocate memory for data section name failed."); "allocate memory for data section name failed.");
@ -2520,15 +2613,15 @@ read_stack_usage_file(const AOTCompContext *comp_ctx, const char *filename,
} }
if (prefix == aot_func_prefix) { if (prefix == aot_func_prefix) {
if (sz < precheck_stack_size_min) { if (sz < precheck_stack_size_min) {
precheck_stack_size_min = sz; precheck_stack_size_min = (uint32)sz;
} }
if (sz > precheck_stack_size_max) { if (sz > precheck_stack_size_max) {
precheck_stack_size_max = sz; precheck_stack_size_max = (uint32)sz;
} }
precheck_found++; precheck_found++;
continue; continue;
} }
sizes[func_idx] = sz; sizes[func_idx] = (uint32)sz;
found++; found++;
} }
fclose(fp); fclose(fp);
@ -2605,9 +2698,16 @@ aot_resolve_stack_sizes(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
while (!LLVMObjectFileIsSymbolIteratorAtEnd(obj_data->binary, sym_itr)) { while (!LLVMObjectFileIsSymbolIteratorAtEnd(obj_data->binary, sym_itr)) {
if ((name = LLVMGetSymbolName(sym_itr)) if ((name = LLVMGetSymbolName(sym_itr))
&& !strcmp(name, aot_stack_sizes_alias_name)) { && (!strcmp(name, aot_stack_sizes_alias_name)
/* symbol of COFF32 starts with "_" */
|| (obj_data->target_info.bin_type == AOT_COFF32_BIN_TYPE
&& !strncmp(name, "_", 1)
&& !strcmp(name + 1, aot_stack_sizes_alias_name)))) {
uint64 sz = LLVMGetSymbolSize(sym_itr); uint64 sz = LLVMGetSymbolSize(sym_itr);
if (sz != sizeof(uint32) * obj_data->func_count) { if (sz != sizeof(uint32) * obj_data->func_count
/* sz of COFF64/COFF32 is 0, ignore the check */
&& obj_data->target_info.bin_type != AOT_COFF64_BIN_TYPE
&& obj_data->target_info.bin_type != AOT_COFF32_BIN_TYPE) {
aot_set_last_error("stack_sizes had unexpected size."); aot_set_last_error("stack_sizes had unexpected size.");
goto fail; goto fail;
} }
@ -2642,16 +2742,12 @@ aot_resolve_stack_sizes(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
goto fail; goto fail;
} }
} }
if (addr > UINT32_MAX) {
aot_set_last_error("too large stack_sizes offset.");
goto fail;
}
/* /*
* Record section/offset and construct a copy of stack_sizes. * Record section/offset and construct a copy of stack_sizes.
* aot_emit_object_data_section_info will emit this copy. * aot_emit_object_data_section_info will emit this copy.
*/ */
obj_data->stack_sizes_section_name = sec_name; obj_data->stack_sizes_section_name = sec_name;
obj_data->stack_sizes_offset = addr; obj_data->stack_sizes_offset = (uint32)addr;
obj_data->stack_sizes = wasm_runtime_malloc( obj_data->stack_sizes = wasm_runtime_malloc(
obj_data->func_count * sizeof(*obj_data->stack_sizes)); obj_data->func_count * sizeof(*obj_data->stack_sizes));
if (obj_data->stack_sizes == NULL) { if (obj_data->stack_sizes == NULL) {
@ -2770,6 +2866,7 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
while (!LLVMObjectFileIsSymbolIteratorAtEnd(obj_data->binary, sym_itr)) { while (!LLVMObjectFileIsSymbolIteratorAtEnd(obj_data->binary, sym_itr)) {
if ((name = (char *)LLVMGetSymbolName(sym_itr)) if ((name = (char *)LLVMGetSymbolName(sym_itr))
&& str_starts_with(name, prefix)) { && str_starts_with(name, prefix)) {
/* symbol aot_func#n */
func_index = (uint32)atoi(name + strlen(prefix)); func_index = (uint32)atoi(name + strlen(prefix));
if (func_index < obj_data->func_count) { if (func_index < obj_data->func_count) {
LLVMSectionIteratorRef contain_section; LLVMSectionIteratorRef contain_section;
@ -2804,6 +2901,44 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
} }
} }
} }
else if ((name = (char *)LLVMGetSymbolName(sym_itr))
&& str_starts_with(name, AOT_FUNC_INTERNAL_PREFIX)) {
/* symbol aot_func_internal#n */
func_index = (uint32)atoi(name + strlen(AOT_FUNC_INTERNAL_PREFIX));
if (func_index < obj_data->func_count) {
LLVMSectionIteratorRef contain_section;
char *contain_section_name;
func = obj_data->funcs + func_index;
if (!(contain_section = LLVMObjectFileCopySectionIterator(
obj_data->binary))) {
aot_set_last_error("llvm get section iterator failed.");
LLVMDisposeSymbolIterator(sym_itr);
return false;
}
LLVMMoveToContainingSection(contain_section, sym_itr);
contain_section_name =
(char *)LLVMGetSectionName(contain_section);
LLVMDisposeSectionIterator(contain_section);
if (!strcmp(contain_section_name, ".text.unlikely.")) {
func->text_offset_of_aot_func_internal =
align_uint(obj_data->text_size, 4)
+ LLVMGetSymbolAddress(sym_itr);
}
else if (!strcmp(contain_section_name, ".text.hot.")) {
func->text_offset_of_aot_func_internal =
align_uint(obj_data->text_size, 4)
+ align_uint(obj_data->text_unlikely_size, 4)
+ LLVMGetSymbolAddress(sym_itr);
}
else {
func->text_offset_of_aot_func_internal =
LLVMGetSymbolAddress(sym_itr);
}
}
}
LLVMMoveToNextSymbol(sym_itr); LLVMMoveToNextSymbol(sym_itr);
} }
LLVMDisposeSymbolIterator(sym_itr); LLVMDisposeSymbolIterator(sym_itr);
@ -2975,7 +3110,7 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
|| !strcmp(group->section_name, ".rel.text")) { || !strcmp(group->section_name, ".rel.text")) {
snprintf(buf, sizeof(buf), "%s%u", relocation->symbol_name, snprintf(buf, sizeof(buf), "%s%u", relocation->symbol_name,
prof_section_idx); prof_section_idx);
size = strlen(buf) + 1; size = (uint32)(strlen(buf) + 1);
if (!(relocation->symbol_name = wasm_runtime_malloc(size))) { if (!(relocation->symbol_name = wasm_runtime_malloc(size))) {
aot_set_last_error( aot_set_last_error(
"allocate memory for relocation symbol name failed."); "allocate memory for relocation symbol name failed.");
@ -2990,7 +3125,7 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
19)) { 19)) {
snprintf(buf, sizeof(buf), "%s%u", relocation->symbol_name, snprintf(buf, sizeof(buf), "%s%u", relocation->symbol_name,
prof_section_idx); prof_section_idx);
size = strlen(buf) + 1; size = (uint32)(strlen(buf) + 1);
if (!(relocation->symbol_name = wasm_runtime_malloc(size))) { if (!(relocation->symbol_name = wasm_runtime_malloc(size))) {
aot_set_last_error( aot_set_last_error(
"allocate memory for relocation symbol name failed."); "allocate memory for relocation symbol name failed.");
@ -3087,6 +3222,13 @@ is_relocation_section(AOTObjectData *obj_data, LLVMSectionIteratorRef sec_itr)
return false; return false;
} }
static bool
is_readonly_section(const char *name)
{
return !strcmp(name, ".rel.text") || !strcmp(name, ".rela.text")
|| !strcmp(name, ".rela.literal") || !strcmp(name, ".text");
}
static bool static bool
get_relocation_groups_count(AOTObjectData *obj_data, uint32 *p_count) get_relocation_groups_count(AOTObjectData *obj_data, uint32 *p_count)
{ {
@ -3149,7 +3291,7 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
|| !strcmp(name, ".rel__llvm_prf_data"))) { || !strcmp(name, ".rel__llvm_prf_data"))) {
char buf[32]; char buf[32];
snprintf(buf, sizeof(buf), "%s%u", name, llvm_prf_data_idx); snprintf(buf, sizeof(buf), "%s%u", name, llvm_prf_data_idx);
size = strlen(buf) + 1; size = (uint32)(strlen(buf) + 1);
if (!(relocation_group->section_name = if (!(relocation_group->section_name =
wasm_runtime_malloc(size))) { wasm_runtime_malloc(size))) {
aot_set_last_error( aot_set_last_error(
@ -3184,6 +3326,19 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
relocation_group->section_name = ".rel.text"; relocation_group->section_name = ".rel.text";
} }
/*
* Relocations in read-only sections are problematic,
* especially for XIP on platforms which don't have
* copy-on-write mappings.
*/
if (obj_data->comp_ctx->is_indirect_mode
&& is_readonly_section(relocation_group->section_name)) {
LOG_WARNING("%" PRIu32
" text relocations in %s section for indirect mode",
relocation_group->relocation_count,
relocation_group->section_name);
}
relocation_group++; relocation_group++;
} }
LLVMMoveToNextSection(sec_itr); LLVMMoveToNextSection(sec_itr);

View File

@ -234,13 +234,15 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
else { else {
/* Store extra return values to function parameters */ /* Store extra return values to function parameters */
if (i != 0) { if (i != 0) {
LLVMValueRef res;
uint32 param_index = func_type->param_count + i; uint32 param_index = func_type->param_count + i;
if (!LLVMBuildStore( if (!(res = LLVMBuildStore(
comp_ctx->builder, block->result_phis[i], comp_ctx->builder, block->result_phis[i],
LLVMGetParam(func_ctx->func, param_index))) { LLVMGetParam(func_ctx->func, param_index)))) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
goto fail; goto fail;
} }
LLVMSetAlignment(res, 1);
} }
} }
} }
@ -1102,14 +1104,17 @@ aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (block_func->result_count) { if (block_func->result_count) {
/* Store extra result values to function parameters */ /* Store extra result values to function parameters */
for (i = 0; i < block_func->result_count - 1; i++) { for (i = 0; i < block_func->result_count - 1; i++) {
LLVMValueRef res;
result_index = block_func->result_count - 1 - i; result_index = block_func->result_count - 1 - i;
POP(value, block_func->result_types[result_index]); POP(value, block_func->result_types[result_index]);
param_index = func_type->param_count + result_index; param_index = func_type->param_count + result_index;
if (!LLVMBuildStore(comp_ctx->builder, value, if (!(res = LLVMBuildStore(
LLVMGetParam(func_ctx->func, param_index))) { comp_ctx->builder, value,
LLVMGetParam(func_ctx->func, param_index)))) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
goto fail; goto fail;
} }
LLVMSetAlignment(res, 1);
} }
/* Return the first result value */ /* Return the first result value */
POP(value, block_func->result_types[0]); POP(value, block_func->result_types[0]);

View File

@ -18,6 +18,17 @@
} \ } \
} while (0) } while (0)
static bool
is_win_platform(AOTCompContext *comp_ctx)
{
char *triple = LLVMGetTargetMachineTriple(comp_ctx->target_machine);
bh_assert(triple);
if (strstr(triple, "win32") || strstr(triple, "win"))
return true;
return false;
}
static bool static bool
create_func_return_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) create_func_return_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{ {
@ -458,7 +469,7 @@ check_app_addr_and_convert(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* Check whether exception was thrown when executing the function */ /* Check whether exception was thrown when executing the function */
if (comp_ctx->enable_bound_check if ((comp_ctx->enable_bound_check || is_win_platform(comp_ctx))
&& !check_call_return(comp_ctx, func_ctx, res)) { && !check_call_return(comp_ctx, func_ctx, res)) {
return false; return false;
} }
@ -696,7 +707,7 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
/* Check whether there was exception thrown when executing /* Check whether there was exception thrown when executing
the function */ the function */
if (comp_ctx->enable_bound_check if ((comp_ctx->enable_bound_check || is_win_platform(comp_ctx))
&& !check_call_return(comp_ctx, func_ctx, res)) && !check_call_return(comp_ctx, func_ctx, res))
goto fail; goto fail;
} }
@ -849,7 +860,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Check whether there was exception thrown when executing /* Check whether there was exception thrown when executing
the function */ the function */
if (!tail_call && comp_ctx->enable_bound_check if (!tail_call
&& (comp_ctx->enable_bound_check || is_win_platform(comp_ctx))
&& !check_exception_thrown(comp_ctx, func_ctx)) && !check_exception_thrown(comp_ctx, func_ctx))
goto fail; goto fail;
} }
@ -1431,7 +1443,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
/* Check whether exception was thrown when executing the function */ /* Check whether exception was thrown when executing the function */
if (comp_ctx->enable_bound_check if ((comp_ctx->enable_bound_check || is_win_platform(comp_ctx))
&& !check_call_return(comp_ctx, func_ctx, res)) && !check_call_return(comp_ctx, func_ctx, res))
goto fail; goto fail;
@ -1483,7 +1495,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* Check whether exception was thrown when executing the function */ /* Check whether exception was thrown when executing the function */
if (comp_ctx->enable_bound_check if ((comp_ctx->enable_bound_check || is_win_platform(comp_ctx))
&& !check_exception_thrown(comp_ctx, func_ctx)) && !check_exception_thrown(comp_ctx, func_ctx))
goto fail; goto fail;

View File

@ -146,6 +146,13 @@ aot_target_precheck_can_use_musttail(const AOTCompContext *comp_ctx)
*/ */
return false; return false;
} }
if (!strcmp(comp_ctx->target_arch, "mips")) {
/*
* cf.
* https://github.com/bytecodealliance/wasm-micro-runtime/issues/2412
*/
return false;
}
/* /*
* x86-64/i386: true * x86-64/i386: true
* *
@ -237,9 +244,10 @@ get_inst_extra_offset(AOTCompContext *comp_ctx)
const AOTCompData *comp_data = comp_ctx->comp_data; const AOTCompData *comp_data = comp_ctx->comp_data;
uint32 table_count = comp_data->import_table_count + comp_data->table_count; uint32 table_count = comp_data->import_table_count + comp_data->table_count;
uint64 offset = get_tbl_inst_offset(comp_ctx, NULL, table_count); uint64 offset = get_tbl_inst_offset(comp_ctx, NULL, table_count);
bh_assert(offset <= UINT_MAX); uint32 offset_32 = (uint32)offset;
offset = align_uint(offset, 8); bh_assert(offset <= UINT32_MAX);
return offset; offset_32 = align_uint((uint32)offset_32, 8);
return offset_32;
} }
/* /*
@ -309,8 +317,8 @@ aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
goto fail; goto fail;
} }
unsigned int param_count = LLVMCountParams(precheck_func); uint32 param_count = LLVMCountParams(precheck_func);
uint64 sz = param_count * sizeof(LLVMValueRef); uint32 sz = param_count * (uint32)sizeof(LLVMValueRef);
params = wasm_runtime_malloc(sz); params = wasm_runtime_malloc(sz);
if (params == NULL) { if (params == NULL) {
goto fail; goto fail;
@ -518,12 +526,18 @@ aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
} }
wasm_runtime_free(params); wasm_runtime_free(params);
params = NULL; params = NULL;
#if LLVM_VERSION_MAJOR < 17
if (aot_target_precheck_can_use_musttail(comp_ctx)) { if (aot_target_precheck_can_use_musttail(comp_ctx)) {
LLVMSetTailCallKind(retval, LLVMTailCallKindMustTail); LLVMSetTailCallKind(retval, LLVMTailCallKindMustTail);
} }
else { else {
LLVMSetTailCallKind(retval, LLVMTailCallKindTail); LLVMSetTailCallKind(retval, LLVMTailCallKindTail);
} }
#else
LLVMSetTailCall(retval, true);
#endif
if (ret_type == VOID_TYPE) { if (ret_type == VOID_TYPE) {
if (!LLVMBuildRetVoid(b)) { if (!LLVMBuildRetVoid(b)) {
goto fail; goto fail;
@ -623,6 +637,15 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
prefix))) prefix)))
goto fail; goto fail;
if (comp_ctx->is_indirect_mode) {
/* avoid LUT relocations ("switch-table") */
LLVMAttributeRef attr_no_jump_tables = LLVMCreateStringAttribute(
comp_ctx->context, "no-jump-tables",
(uint32)strlen("no-jump-tables"), "true", (uint32)strlen("true"));
LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex,
attr_no_jump_tables);
}
if (need_precheck) { if (need_precheck) {
if (!comp_ctx->is_jit_mode) if (!comp_ctx->is_jit_mode)
LLVMSetLinkage(func, LLVMInternalLinkage); LLVMSetLinkage(func, LLVMInternalLinkage);
@ -2072,7 +2095,7 @@ jit_stack_size_callback(void *user_data, const char *name, size_t namelen,
return; return;
} }
/* ensure NUL termination */ /* ensure NUL termination */
bh_memcpy_s(buf, sizeof(buf), name, namelen); bh_memcpy_s(buf, (uint32)sizeof(buf), name, (uint32)namelen);
buf[namelen] = 0; buf[namelen] = 0;
ret = sscanf(buf, AOT_FUNC_INTERNAL_PREFIX "%" SCNu32, &func_idx); ret = sscanf(buf, AOT_FUNC_INTERNAL_PREFIX "%" SCNu32, &func_idx);
@ -2093,7 +2116,7 @@ jit_stack_size_callback(void *user_data, const char *name, size_t namelen,
/* Note: -1 == AOT_NEG_ONE from aot_create_stack_sizes */ /* Note: -1 == AOT_NEG_ONE from aot_create_stack_sizes */
bh_assert(comp_ctx->jit_stack_sizes[func_idx] == (uint32)-1); bh_assert(comp_ctx->jit_stack_sizes[func_idx] == (uint32)-1);
comp_ctx->jit_stack_sizes[func_idx] = stack_size + call_size; comp_ctx->jit_stack_sizes[func_idx] = (uint32)stack_size + call_size;
} }
static bool static bool
@ -2155,8 +2178,10 @@ bool
aot_compiler_init(void) aot_compiler_init(void)
{ {
/* Initialize LLVM environment */ /* Initialize LLVM environment */
#if LLVM_VERSION_MAJOR < 17
LLVMInitializeCore(LLVMGetGlobalPassRegistry()); LLVMInitializeCore(LLVMGetGlobalPassRegistry());
#endif
#if WASM_ENABLE_WAMR_COMPILER != 0 #if WASM_ENABLE_WAMR_COMPILER != 0
/* Init environment of all targets for AOT compiler */ /* Init environment of all targets for AOT compiler */
LLVMInitializeAllTargetInfos(); LLVMInitializeAllTargetInfos();
@ -2296,6 +2321,12 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
if (option->enable_stack_estimation) if (option->enable_stack_estimation)
comp_ctx->enable_stack_estimation = true; comp_ctx->enable_stack_estimation = true;
if (option->llvm_passes)
comp_ctx->llvm_passes = option->llvm_passes;
if (option->builtin_intrinsics)
comp_ctx->builtin_intrinsics = option->builtin_intrinsics;
comp_ctx->opt_level = option->opt_level; comp_ctx->opt_level = option->opt_level;
comp_ctx->size_level = option->size_level; comp_ctx->size_level = option->size_level;
@ -2729,6 +2760,16 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
aot_set_last_error("create LLVM target machine failed."); aot_set_last_error("create LLVM target machine failed.");
goto fail; goto fail;
} }
/* If only to create target machine for querying information, early stop
*/
if ((arch && !strcmp(arch, "help")) || (abi && !strcmp(abi, "help"))
|| (cpu && !strcmp(cpu, "help"))
|| (features && !strcmp(features, "+help"))) {
LOG_DEBUG(
"create LLVM target machine only for printing help info.");
goto fail;
}
} }
triple = LLVMGetTargetMachineTriple(comp_ctx->target_machine); triple = LLVMGetTargetMachineTriple(comp_ctx->target_machine);

View File

@ -15,15 +15,18 @@
#include "llvm-c/ExecutionEngine.h" #include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Analysis.h" #include "llvm-c/Analysis.h"
#include "llvm-c/BitWriter.h" #include "llvm-c/BitWriter.h"
#if LLVM_VERSION_MAJOR < 17
#include "llvm-c/Transforms/Utils.h" #include "llvm-c/Transforms/Utils.h"
#include "llvm-c/Transforms/Scalar.h" #include "llvm-c/Transforms/Scalar.h"
#include "llvm-c/Transforms/Vectorize.h" #include "llvm-c/Transforms/Vectorize.h"
#include "llvm-c/Transforms/PassManagerBuilder.h" #include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm-c/Initialization.h"
#endif
#include "llvm-c/Orc.h" #include "llvm-c/Orc.h"
#include "llvm-c/Error.h" #include "llvm-c/Error.h"
#include "llvm-c/Support.h" #include "llvm-c/Support.h"
#include "llvm-c/Initialization.h"
#include "llvm-c/TargetMachine.h" #include "llvm-c/TargetMachine.h"
#include "llvm-c/LLJIT.h" #include "llvm-c/LLJIT.h"
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
@ -417,6 +420,8 @@ typedef struct AOTCompContext {
const char *stack_usage_file; const char *stack_usage_file;
char stack_usage_temp_file[64]; char stack_usage_temp_file[64];
const char *llvm_passes;
const char *builtin_intrinsics;
} AOTCompContext; } AOTCompContext;
enum { enum {
@ -455,6 +460,8 @@ typedef struct AOTCompOption {
char **custom_sections; char **custom_sections;
uint32 custom_sections_count; uint32 custom_sections_count;
const char *stack_usage_file; const char *stack_usage_file;
const char *llvm_passes;
const char *builtin_intrinsics;
} AOTCompOption, *aot_comp_option_t; } AOTCompOption, *aot_comp_option_t;
bool bool

View File

@ -5,11 +5,13 @@
#include <llvm/Passes/StandardInstrumentations.h> #include <llvm/Passes/StandardInstrumentations.h>
#include <llvm/Support/Error.h> #include <llvm/Support/Error.h>
#if LLVM_VERSION_MAJOR < 17
#include <llvm/ADT/None.h> #include <llvm/ADT/None.h>
#include <llvm/ADT/Optional.h> #include <llvm/ADT/Optional.h>
#include <llvm/ADT/Triple.h>
#endif
#include <llvm/ADT/SmallVector.h> #include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/Twine.h> #include <llvm/ADT/Twine.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Analysis/TargetTransformInfo.h> #include <llvm/Analysis/TargetTransformInfo.h>
#include <llvm/CodeGen/TargetPassConfig.h> #include <llvm/CodeGen/TargetPassConfig.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/ExecutionEngine/ExecutionEngine.h>
@ -18,7 +20,9 @@
#include <llvm/Target/TargetMachine.h> #include <llvm/Target/TargetMachine.h>
#include <llvm-c/Core.h> #include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h> #include <llvm-c/ExecutionEngine.h>
#if LLVM_VERSION_MAJOR < 17
#include <llvm-c/Initialization.h> #include <llvm-c/Initialization.h>
#endif
#include <llvm/ExecutionEngine/GenericValue.h> #include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/JITEventListener.h> #include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/ExecutionEngine/RTDyldMemoryManager.h> #include <llvm/ExecutionEngine/RTDyldMemoryManager.h>
@ -27,9 +31,12 @@
#include <llvm/IR/Module.h> #include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h> #include <llvm/IR/Instructions.h>
#include <llvm/IR/IntrinsicInst.h> #include <llvm/IR/IntrinsicInst.h>
#include <llvm/IR/LegacyPassManager.h> #include <llvm/IR/PassManager.h>
#include <llvm/Support/CommandLine.h> #include <llvm/Support/CommandLine.h>
#include <llvm/Support/ErrorHandling.h> #include <llvm/Support/ErrorHandling.h>
#if LLVM_VERSION_MAJOR >= 17
#include <llvm/Support/PGOOptions.h>
#endif
#include <llvm/Target/CodeGenCWrappers.h> #include <llvm/Target/CodeGenCWrappers.h>
#include <llvm/Target/TargetMachine.h> #include <llvm/Target/TargetMachine.h>
#include <llvm/Target/TargetOptions.h> #include <llvm/Target/TargetOptions.h>
@ -55,6 +62,13 @@
using namespace llvm; using namespace llvm;
using namespace llvm::orc; using namespace llvm::orc;
#if LLVM_VERSION_MAJOR >= 17
namespace llvm {
template<typename T>
using Optional = std::optional<T>;
}
#endif
LLVM_C_EXTERN_C_BEGIN LLVM_C_EXTERN_C_BEGIN
bool bool
@ -73,115 +87,63 @@ LLVM_C_EXTERN_C_END
ExitOnError ExitOnErr; ExitOnError ExitOnErr;
class ExpandMemoryOpPass : public llvm::ModulePass class ExpandMemoryOpPass : public PassInfoMixin<ExpandMemoryOpPass>
{ {
public: public:
static char ID; PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
ExpandMemoryOpPass()
: ModulePass(ID)
{}
bool runOnModule(Module &M) override;
bool expandMemIntrinsicUses(Function &F);
StringRef getPassName() const override
{
return "Expand memory operation intrinsics";
}
void getAnalysisUsage(AnalysisUsage &AU) const override
{
AU.addRequired<TargetTransformInfoWrapperPass>();
}
}; };
char ExpandMemoryOpPass::ID = 0; PreservedAnalyses
ExpandMemoryOpPass::run(Function &F, FunctionAnalysisManager &AM)
bool
ExpandMemoryOpPass::expandMemIntrinsicUses(Function &F)
{ {
Intrinsic::ID ID = F.getIntrinsicID(); SmallVector<MemIntrinsic *, 16> MemCalls;
bool Changed = false;
for (auto I = F.user_begin(), E = F.user_end(); I != E;) { /* Iterate over all instructions in the function, looking for memcpy,
Instruction *Inst = cast<Instruction>(*I); * memmove, and memset. When we find one, expand it into a loop. */
++I;
switch (ID) { for (auto &BB : F) {
case Intrinsic::memcpy: for (auto &Inst : BB) {
{ if (auto *Memcpy = dyn_cast_or_null<MemCpyInst>(&Inst)) {
auto *Memcpy = cast<MemCpyInst>(Inst); MemCalls.push_back(Memcpy);
Function *ParentFunc = Memcpy->getParent()->getParent();
const TargetTransformInfo &TTI =
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
*ParentFunc);
expandMemCpyAsLoop(Memcpy, TTI);
Changed = true;
Memcpy->eraseFromParent();
break;
} }
case Intrinsic::memmove: else if (auto *Memmove = dyn_cast_or_null<MemMoveInst>(&Inst)) {
{ MemCalls.push_back(Memmove);
auto *Memmove = cast<MemMoveInst>(Inst);
expandMemMoveAsLoop(Memmove);
Changed = true;
Memmove->eraseFromParent();
break;
} }
case Intrinsic::memset: else if (auto *Memset = dyn_cast_or_null<MemSetInst>(&Inst)) {
{ MemCalls.push_back(Memset);
auto *Memset = cast<MemSetInst>(Inst);
expandMemSetAsLoop(Memset);
Changed = true;
Memset->eraseFromParent();
break;
} }
default:
break;
} }
} }
return Changed; for (MemIntrinsic *MemCall : MemCalls) {
} if (MemCpyInst *Memcpy = dyn_cast<MemCpyInst>(MemCall)) {
Function *ParentFunc = Memcpy->getParent()->getParent();
bool const TargetTransformInfo &TTI =
ExpandMemoryOpPass::runOnModule(Module &M) AM.getResult<TargetIRAnalysis>(*ParentFunc);
{ expandMemCpyAsLoop(Memcpy, TTI);
bool Changed = false; Memcpy->eraseFromParent();
}
for (Function &F : M) { else if (MemMoveInst *Memmove = dyn_cast<MemMoveInst>(MemCall)) {
if (!F.isDeclaration()) #if LLVM_VERSION_MAJOR >= 17
continue; Function *ParentFunc = Memmove->getParent()->getParent();
const TargetTransformInfo &TTI =
switch (F.getIntrinsicID()) { AM.getResult<TargetIRAnalysis>(*ParentFunc);
case Intrinsic::memcpy: expandMemMoveAsLoop(Memmove, TTI);
case Intrinsic::memmove: #else
case Intrinsic::memset: expandMemMoveAsLoop(Memmove);
if (expandMemIntrinsicUses(F)) #endif
Changed = true; Memmove->eraseFromParent();
break; }
else if (MemSetInst *Memset = dyn_cast<MemSetInst>(MemCall)) {
default: expandMemSetAsLoop(Memset);
break; Memset->eraseFromParent();
} }
} }
return Changed; PreservedAnalyses PA;
} PA.preserveSet<CFGAnalyses>();
void return PA;
aot_add_expand_memory_op_pass(LLVMPassManagerRef pass)
{
reinterpret_cast<legacy::PassManager *>(pass)->add(
new ExpandMemoryOpPass());
}
void
aot_add_simple_loop_unswitch_pass(LLVMPassManagerRef pass)
{
reinterpret_cast<legacy::PassManager *>(pass)->add(
createSimpleLoopUnswitchLegacyPass());
} }
bool bool
@ -240,6 +202,9 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
#else #else
Optional<PGOOptions> PGO = llvm::None; Optional<PGOOptions> PGO = llvm::None;
#endif #endif
// TODO
#if LLVM_VERSION_MAJOR < 17
if (comp_ctx->enable_llvm_pgo) { if (comp_ctx->enable_llvm_pgo) {
/* Disable static counter allocation for value profiler, /* Disable static counter allocation for value profiler,
it will be allocated by runtime */ it will be allocated by runtime */
@ -250,6 +215,7 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
else if (comp_ctx->use_prof_file) { else if (comp_ctx->use_prof_file) {
PGO = PGOOptions(comp_ctx->use_prof_file, "", "", PGOOptions::IRUse); PGO = PGOOptions(comp_ctx->use_prof_file, "", "", PGOOptions::IRUse);
} }
#endif
#ifdef DEBUG_PASS #ifdef DEBUG_PASS
PassInstrumentationCallbacks PIC; PassInstrumentationCallbacks PIC;
@ -373,6 +339,10 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
if (comp_ctx->llvm_passes) {
ExitOnErr(PB.parsePassPipeline(MPM, comp_ctx->llvm_passes));
}
if (!disable_llvm_lto) { if (!disable_llvm_lto) {
/* Apply LTO for AOT mode */ /* Apply LTO for AOT mode */
if (comp_ctx->comp_data->func_count >= 10 if (comp_ctx->comp_data->func_count >= 10
@ -386,6 +356,15 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
else { else {
MPM.addPass(PB.buildPerModuleDefaultPipeline(OL)); MPM.addPass(PB.buildPerModuleDefaultPipeline(OL));
} }
/* Run specific passes for AOT indirect mode in last since general
optimization may create some intrinsic function calls like
llvm.memset, so let's remove these function calls here. */
if (comp_ctx->is_indirect_mode) {
FunctionPassManager FPM1;
FPM1.addPass(ExpandMemoryOpPass());
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM1)));
}
} }
MPM.run(*M, MAM); MPM.run(*M, MAM);

View File

@ -4,8 +4,10 @@
*/ */
#include <llvm-c/TargetMachine.h> #include <llvm-c/TargetMachine.h>
#if LLVM_VERSION_MAJOR < 17
#include <llvm/ADT/None.h> #include <llvm/ADT/None.h>
#include <llvm/ADT/Optional.h> #include <llvm/ADT/Optional.h>
#endif
#include <llvm/IR/Instructions.h> #include <llvm/IR/Instructions.h>
#if LLVM_VERSION_MAJOR >= 14 #if LLVM_VERSION_MAJOR >= 14
#include <llvm/MC/TargetRegistry.h> #include <llvm/MC/TargetRegistry.h>
@ -18,6 +20,13 @@
#include "aot_llvm_extra2.h" #include "aot_llvm_extra2.h"
#if LLVM_VERSION_MAJOR >= 17
namespace llvm {
template<typename T>
using Optional = std::optional<T>;
}
#endif
static llvm::Optional<llvm::Reloc::Model> static llvm::Optional<llvm::Reloc::Model>
convert(LLVMRelocMode reloc_mode) convert(LLVMRelocMode reloc_mode)
{ {

View File

@ -8,8 +8,10 @@
#include "llvm-c/OrcEE.h" #include "llvm-c/OrcEE.h"
#include "llvm-c/TargetMachine.h" #include "llvm-c/TargetMachine.h"
#if LLVM_VERSION_MAJOR < 17
#include "llvm/ADT/None.h" #include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#endif
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
@ -21,6 +23,13 @@
#include "aot_orc_extra.h" #include "aot_orc_extra.h"
#include "aot.h" #include "aot.h"
#if LLVM_VERSION_MAJOR >= 17
namespace llvm {
template<typename T>
using Optional = std::optional<T>;
}
#endif
using namespace llvm; using namespace llvm;
using namespace llvm::orc; using namespace llvm::orc;
using GlobalValueSet = std::set<const GlobalValue *>; using GlobalValueSet = std::set<const GlobalValue *>;

View File

@ -28,25 +28,25 @@
using namespace lldb; using namespace lldb;
typedef struct dwar_extractor { typedef struct dwarf_extractor {
SBDebugger debugger; SBDebugger debugger;
SBTarget target; SBTarget target;
SBModule module; SBModule module;
} dwar_extractor; } dwarf_extractor;
#define TO_HANDLE(extractor) (dwar_extractor_handle_t)(extractor) #define TO_HANDLE(extractor) (dwarf_extractor_handle_t)(extractor)
#define TO_EXTACTOR(handle) (dwar_extractor *)(handle) #define TO_EXTACTOR(handle) (dwarf_extractor *)(handle)
static bool is_debugger_initialized; static bool is_debugger_initialized;
dwar_extractor_handle_t dwarf_extractor_handle_t
create_dwarf_extractor(AOTCompData *comp_data, char *file_name) create_dwarf_extractor(AOTCompData *comp_data, char *file_name)
{ {
char *arch = NULL; char *arch = NULL;
char *platform = NULL; char *platform = NULL;
dwar_extractor *extractor = NULL; dwarf_extractor *extractor = NULL;
//__attribute__((constructor)) may be better? //__attribute__((constructor)) may be better?
if (!is_debugger_initialized) { if (!is_debugger_initialized) {
@ -61,7 +61,7 @@ create_dwarf_extractor(AOTCompData *comp_data, char *file_name)
SBError error; SBError error;
SBFileSpec exe_file_spec(file_name, true); SBFileSpec exe_file_spec(file_name, true);
if (!(extractor = new dwar_extractor())) { if (!(extractor = new dwarf_extractor())) {
LOG_ERROR("Create Dwarf Extractor error: failed to allocate memory"); LOG_ERROR("Create Dwarf Extractor error: failed to allocate memory");
goto fail3; goto fail3;
} }
@ -101,9 +101,9 @@ fail3:
} }
void void
destroy_dwarf_extractor(dwar_extractor_handle_t handle) destroy_dwarf_extractor(dwarf_extractor_handle_t handle)
{ {
dwar_extractor *extractor = TO_EXTACTOR(handle); dwarf_extractor *extractor = TO_EXTACTOR(handle);
if (!extractor) if (!extractor)
return; return;
extractor->debugger.DeleteTarget(extractor->target); extractor->debugger.DeleteTarget(extractor->target);
@ -116,7 +116,7 @@ destroy_dwarf_extractor(dwar_extractor_handle_t handle)
LLVMMetadataRef LLVMMetadataRef
dwarf_gen_file_info(const AOTCompContext *comp_ctx) dwarf_gen_file_info(const AOTCompContext *comp_ctx)
{ {
dwar_extractor *extractor; dwarf_extractor *extractor;
int units_number; int units_number;
LLVMMetadataRef file_info = NULL; LLVMMetadataRef file_info = NULL;
const char *file_name; const char *file_name;
@ -193,7 +193,7 @@ dwarf_gen_mock_vm_info(AOTCompContext *comp_ctx)
LLVMMetadataRef LLVMMetadataRef
dwarf_gen_comp_unit_info(const AOTCompContext *comp_ctx) dwarf_gen_comp_unit_info(const AOTCompContext *comp_ctx)
{ {
dwar_extractor *extractor; dwarf_extractor *extractor;
int units_number; int units_number;
LLVMMetadataRef comp_unit = NULL; LLVMMetadataRef comp_unit = NULL;
@ -292,7 +292,7 @@ lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
SBTypeList function_args = function.GetType().GetFunctionArgumentTypes(); SBTypeList function_args = function.GetType().GetFunctionArgumentTypes();
SBType return_type = function.GetType().GetFunctionReturnType(); SBType return_type = function.GetType().GetFunctionReturnType();
const size_t num_function_args = function_args.GetSize(); const size_t num_function_args = function_args.GetSize();
dwar_extractor *extractor; dwarf_extractor *extractor;
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor))) if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
return NULL; return NULL;
@ -393,7 +393,7 @@ dwarf_gen_func_info(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx) const AOTFuncContext *func_ctx)
{ {
LLVMMetadataRef func_info = NULL; LLVMMetadataRef func_info = NULL;
dwar_extractor *extractor; dwarf_extractor *extractor;
uint64_t vm_offset; uint64_t vm_offset;
AOTFunc *func = func_ctx->aot_func; AOTFunc *func = func_ctx->aot_func;
@ -423,7 +423,7 @@ dwarf_get_func_name(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, char *name, int len) const AOTFuncContext *func_ctx, char *name, int len)
{ {
LLVMMetadataRef func_info = NULL; LLVMMetadataRef func_info = NULL;
dwar_extractor *extractor; dwarf_extractor *extractor;
uint64_t vm_offset; uint64_t vm_offset;
AOTFunc *func = func_ctx->aot_func; AOTFunc *func = func_ctx->aot_func;
@ -454,7 +454,7 @@ dwarf_gen_location(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, uint64_t vm_offset) const AOTFuncContext *func_ctx, uint64_t vm_offset)
{ {
LLVMMetadataRef location_info = NULL; LLVMMetadataRef location_info = NULL;
dwar_extractor *extractor; dwarf_extractor *extractor;
AOTFunc *func = func_ctx->aot_func; AOTFunc *func = func_ctx->aot_func;
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor))) if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
@ -493,7 +493,7 @@ dwarf_gen_func_ret_location(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx) const AOTFuncContext *func_ctx)
{ {
LLVMMetadataRef func_info = NULL; LLVMMetadataRef func_info = NULL;
dwar_extractor *extractor; dwarf_extractor *extractor;
uint64_t vm_offset; uint64_t vm_offset;
AOTFunc *func = func_ctx->aot_func; AOTFunc *func = func_ctx->aot_func;
LLVMMetadataRef location_info = NULL; LLVMMetadataRef location_info = NULL;

View File

@ -18,7 +18,7 @@ typedef unsigned int LLDBLangType;
struct AOTCompData; struct AOTCompData;
typedef struct AOTCompData *aot_comp_data_t; typedef struct AOTCompData *aot_comp_data_t;
typedef void *dwar_extractor_handle_t; typedef void *dwarf_extractor_handle_t;
struct AOTCompContext; struct AOTCompContext;
typedef struct AOTCompContext AOTCompContext; typedef struct AOTCompContext AOTCompContext;
@ -26,7 +26,7 @@ typedef struct AOTCompContext AOTCompContext;
struct AOTFuncContext; struct AOTFuncContext;
typedef struct AOTFuncContext AOTFuncContext; typedef struct AOTFuncContext AOTFuncContext;
dwar_extractor_handle_t dwarf_extractor_handle_t
create_dwarf_extractor(aot_comp_data_t comp_data, char *file_name); create_dwarf_extractor(aot_comp_data_t comp_data, char *file_name);
LLVMMetadataRef LLVMMetadataRef

View File

@ -298,7 +298,15 @@ fail:
/* macros for integer binary operations (ibinop) */ /* macros for integer binary operations (ibinop) */
#if defined(__GNUC__)
#define NO_SANITIZER_INTEGER \
__attribute__((no_sanitize("signed-integer-overflow")))
#else
#define NO_SANITIZER_INTEGER
#endif
#define __DEF_BI_INT_CONST_OPS(bits, opname, op) \ #define __DEF_BI_INT_CONST_OPS(bits, opname, op) \
NO_SANITIZER_INTEGER \
static int##bits do_i##bits##_const_##opname(int##bits lhs, int##bits rhs) \ static int##bits do_i##bits##_const_##opname(int##bits lhs, int##bits rhs) \
{ \ { \
return lhs op rhs; \ return lhs op rhs; \

View File

@ -88,27 +88,28 @@ fail:
static int static int
wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx, wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx,
uint32 dst, uint32 len, uint32 src) uint32 dst_offset, uint32 len, uint32 src_offset)
{ {
WASMTableInstance *tbl; WASMTableInstance *tbl;
uint32 tbl_sz; uint32 tbl_sz;
WASMTableSeg *elem; WASMTableSeg *elem;
uint32 elem_len; uint32 elem_len;
tbl = inst->tables[tbl_idx];
tbl_sz = tbl->cur_size;
if (dst > tbl_sz || tbl_sz - dst < len)
goto out_of_bounds;
elem = inst->module->table_segments + elem_idx; elem = inst->module->table_segments + elem_idx;
elem_len = elem->function_count; elem_len = elem->function_count;
if (src > elem_len || elem_len - src < len) if (offset_len_out_of_bounds(src_offset, len, elem_len))
goto out_of_bounds;
tbl = inst->tables[tbl_idx];
tbl_sz = tbl->cur_size;
if (offset_len_out_of_bounds(dst_offset, len, tbl_sz))
goto out_of_bounds; goto out_of_bounds;
bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems) bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems)
+ dst * sizeof(uint32), + dst_offset * sizeof(uint32),
(uint32)((tbl_sz - dst) * sizeof(uint32)), (uint32)((tbl_sz - dst_offset) * sizeof(uint32)),
elem->func_indexes + src, (uint32)(len * sizeof(uint32))); elem->func_indexes + src_offset,
(uint32)(len * sizeof(uint32)));
return 0; return 0;
out_of_bounds: out_of_bounds:
@ -157,14 +158,14 @@ wasm_copy_table(WASMModuleInstance *inst, uint32 src_tbl_idx,
WASMTableInstance *src_tbl, *dst_tbl; WASMTableInstance *src_tbl, *dst_tbl;
uint32 src_tbl_sz, dst_tbl_sz; uint32 src_tbl_sz, dst_tbl_sz;
src_tbl = inst->tables[src_tbl_idx];
src_tbl_sz = src_tbl->cur_size;
if (src_offset > src_tbl_sz || src_tbl_sz - src_offset < len)
goto out_of_bounds;
dst_tbl = inst->tables[dst_tbl_idx]; dst_tbl = inst->tables[dst_tbl_idx];
dst_tbl_sz = dst_tbl->cur_size; dst_tbl_sz = dst_tbl->cur_size;
if (dst_offset > dst_tbl_sz || dst_tbl_sz - dst_offset < len) if (offset_len_out_of_bounds(dst_offset, len, dst_tbl_sz))
goto out_of_bounds;
src_tbl = inst->tables[src_tbl_idx];
src_tbl_sz = src_tbl->cur_size;
if (offset_len_out_of_bounds(src_offset, len, src_tbl_sz))
goto out_of_bounds; goto out_of_bounds;
bh_memmove_s((uint8 *)dst_tbl + offsetof(WASMTableInstance, elems) bh_memmove_s((uint8 *)dst_tbl + offsetof(WASMTableInstance, elems)
@ -263,7 +264,7 @@ fail:
} }
static int static int
wasm_fill_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 dst, wasm_fill_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 dst_offset,
uint32 val, uint32 len) uint32 val, uint32 len)
{ {
WASMTableInstance *tbl; WASMTableInstance *tbl;
@ -272,11 +273,11 @@ wasm_fill_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 dst,
tbl = inst->tables[tbl_idx]; tbl = inst->tables[tbl_idx];
tbl_sz = tbl->cur_size; tbl_sz = tbl->cur_size;
if (dst > tbl_sz || tbl_sz - dst < len) if (offset_len_out_of_bounds(dst_offset, len, tbl_sz))
goto out_of_bounds; goto out_of_bounds;
for (; len != 0; dst++, len--) { for (; len != 0; dst_offset++, len--) {
tbl->elems[dst] = val; tbl->elems[dst_offset] = val;
} }
return 0; return 0;

View File

@ -26,8 +26,8 @@ void
aot_destroy_comp_data(aot_comp_data_t comp_data); aot_destroy_comp_data(aot_comp_data_t comp_data);
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
typedef void *dwar_extractor_handle_t; typedef void *dwarf_extractor_handle_t;
dwar_extractor_handle_t dwarf_extractor_handle_t
create_dwarf_extractor(aot_comp_data_t comp_data, char *file_name); create_dwarf_extractor(aot_comp_data_t comp_data, char *file_name);
#endif #endif
@ -67,6 +67,8 @@ typedef struct AOTCompOption {
char **custom_sections; char **custom_sections;
uint32_t custom_sections_count; uint32_t custom_sections_count;
const char *stack_usage_file; const char *stack_usage_file;
const char *llvm_passes;
const char *builtin_intrinsics;
} AOTCompOption, *aot_comp_option_t; } AOTCompOption, *aot_comp_option_t;
bool bool

View File

@ -186,6 +186,7 @@ enum wasm_valkind_enum {
#ifndef WASM_VAL_T_DEFINED #ifndef WASM_VAL_T_DEFINED
#define WASM_VAL_T_DEFINED #define WASM_VAL_T_DEFINED
struct wasm_ref_t;
typedef struct wasm_val_t { typedef struct wasm_val_t {
wasm_valkind_t kind; wasm_valkind_t kind;
@ -197,6 +198,7 @@ typedef struct wasm_val_t {
double f64; double f64;
/* represent a foreign object, aka externref in .wat */ /* represent a foreign object, aka externref in .wat */
uintptr_t foreign; uintptr_t foreign;
struct wasm_ref_t *ref;
} of; } of;
} wasm_val_t; } wasm_val_t;
#endif #endif
@ -892,6 +894,27 @@ wasm_runtime_set_exception(wasm_module_inst_t module_inst,
WASM_RUNTIME_API_EXTERN void WASM_RUNTIME_API_EXTERN void
wasm_runtime_clear_exception(wasm_module_inst_t module_inst); wasm_runtime_clear_exception(wasm_module_inst_t module_inst);
/**
* Terminate the WASM module instance.
*
* This function causes the module instance fail as if it raised a trap.
*
* This is intended to be used in situations like:
*
* - A thread is executing the WASM module instance
* (eg. it's in the middle of `wasm_application_execute_main`)
*
* - Another thread has a copy of `wasm_module_inst_t` of
* the module instance and wants to terminate it asynchronously.
*
* This function is provided only when WAMR is built with threading enabled.
* (`WASM_ENABLE_THREAD_MGR=1`)
*
* @param module_inst the WASM module instance
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_terminate(wasm_module_inst_t module_inst);
/** /**
* Set custom data to WASM module instance. * Set custom data to WASM module instance.
* Note: * Note:
@ -914,6 +937,25 @@ wasm_runtime_set_custom_data(wasm_module_inst_t module_inst,
WASM_RUNTIME_API_EXTERN void * WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_custom_data(wasm_module_inst_t module_inst); wasm_runtime_get_custom_data(wasm_module_inst_t module_inst);
/**
* Set the memory bounds checks flag of a WASM module instance.
*
* @param module_inst the WASM module instance
* @param enable the flag to enable/disable the memory bounds checks
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
bool enable);
/**
* Check if the memory bounds checks flag is enabled for a WASM module instance.
*
* @param module_inst the WASM module instance
*
* @return true if the memory bounds checks flag is enabled, false otherwise
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_bounds_checks_enabled(
wasm_module_inst_t module_inst);
/** /**
* Allocate memory from the heap of WASM module instance * Allocate memory from the heap of WASM module instance
* *
@ -1271,6 +1313,32 @@ WASM_RUNTIME_API_EXTERN bool
wasm_externref_obj2ref(wasm_module_inst_t module_inst, wasm_externref_obj2ref(wasm_module_inst_t module_inst,
void *extern_obj, uint32_t *p_externref_idx); void *extern_obj, uint32_t *p_externref_idx);
/**
* Delete external object registered by `wasm_externref_obj2ref`.
*
* @param module_inst the WASM module instance that the extern object
* belongs to
* @param extern_obj the external object to be deleted
*
* @return true if success, false otherwise
*/
WASM_RUNTIME_API_EXTERN bool
wasm_externref_objdel(wasm_module_inst_t module_inst, void *extern_obj);
/**
* Set cleanup callback to release external object.
*
* @param module_inst the WASM module instance that the extern object
* belongs to
* @param extern_obj the external object to which to set the `extern_obj_cleanup` cleanup callback.
* @param extern_obj_cleanup a callback to release `extern_obj`
*
* @return true if success, false otherwise
*/
WASM_RUNTIME_API_EXTERN bool
wasm_externref_set_cleanup(wasm_module_inst_t module_inst, void *extern_obj,
void (*extern_obj_cleanup)(void *));
/** /**
* Retrieve the external object from an internal externref index * Retrieve the external object from an internal externref index
* *
@ -1392,6 +1460,136 @@ WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_import_global_linked(const char *module_name, wasm_runtime_is_import_global_linked(const char *module_name,
const char *global_name); const char *global_name);
typedef enum {
INTERNAL_ERROR,
MAX_SIZE_REACHED,
} enlarge_memory_error_reason_t;
typedef void (*enlarge_memory_error_callback_t)(
uint32_t inc_page_count, uint64_t current_memory_size,
uint32_t memory_index, enlarge_memory_error_reason_t failure_reason,
wasm_module_inst_t instance, wasm_exec_env_t exec_env,
void* user_data);
/**
* Setup callback invoked when memory.grow fails
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_enlarge_mem_error_callback(
const enlarge_memory_error_callback_t callback, void *user_data);
/*
* module instance context APIs
* wasm_runtime_create_context_key
* wasm_runtime_destroy_context_key
* wasm_runtime_set_context
* wasm_runtime_set_context_spread
* wasm_runtime_get_context
*
* This set of APIs is intended to be used by an embedder which provides
* extra sets of native functions, which need per module instance state
* and are maintained outside of the WAMR tree.
*
* It's modelled after the pthread specific API.
*
* wasm_runtime_set_context_spread is similar to
* wasm_runtime_set_context, except that
* wasm_runtime_set_context_spread applies the change
* 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
* serialization if necessary. For example:
*
* if (wasm_runtime_get_context(inst, key) == NULL) {
* newctx = alloc_and_init(...);
* lock(some_lock);
* if (wasm_runtime_get_context(inst, key) == NULL) {
* // this thread won the race
* wasm_runtime_set_context_spread(inst, key, newctx);
* newctx = NULL;
* }
* unlock(some_lock);
* if (newctx != NULL) {
* // this thread lost the race, free it
* cleanup_and_free(newctx);
* }
* }
*
* 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
* before calling wasm_runtime_create_context_key or
* wasm_runtime_destroy_context_key.
* otherwise, it's an undefined behavior.
*
* Note about threads:
* - When spawning a thread, the contexts (the pointers given to
* wasm_runtime_set_context) are copied from the parent
* instance.
* - The destructor is called only on the main instance.
*/
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_create_context_key(
void (*dtor)(wasm_module_inst_t inst, void *ctx));
WASM_RUNTIME_API_EXTERN void
wasm_runtime_destroy_context_key(void *key);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_context(wasm_module_inst_t inst, void *key,
void *ctx);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key,
void *ctx);
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_context(wasm_module_inst_t inst, void *key);
/*
* wasm_runtime_begin_blocking_op/wasm_runtime_end_blocking_op
*
* These APIs are intended to be used by the implementations of
* host functions. It wraps an operation which possibly blocks for long
* to prepare for async termination.
*
* eg.
*
* if (!wasm_runtime_begin_blocking_op(exec_env)) {
* return EINTR;
* }
* ret = possibly_blocking_op();
* wasm_runtime_end_blocking_op(exec_env);
* return ret;
*
* If threading support (WASM_ENABLE_THREAD_MGR) is not enabled,
* these functions are no-op.
*
* If the underlying platform support (OS_ENABLE_WAKEUP_BLOCKING_OP) is
* not available, these functions are no-op. In that case, the runtime
* might not terminate a blocking thread in a timely manner.
*
* If the underlying platform support is available, it's used to wake up
* the thread for async termination. The expectation here is that a
* `os_wakeup_blocking_op` call makes the blocking operation
* (`possibly_blocking_op` in the above example) return in a timely manner.
*
* 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.
*
* For example, on POSIX-like platforms, a signal (by default SIGUSR1) is
* used. The signal delivery configurations (eg. signal handler, signal mask,
* etc) for the signal are set up by the runtime. You can change the signal
* to use for this purpose by calling os_set_signal_number_for_blocking_op
* before the runtime initialization.
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_begin_blocking_op(wasm_exec_env_t exec_env);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_end_blocking_op(wasm_exec_env_t exec_env);
/* clang-format on */ /* clang-format on */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -627,7 +627,6 @@ typedef struct WASMBranchBlock {
uint32 cell_num; uint32 cell_num;
} WASMBranchBlock; } WASMBranchBlock;
/* Execution environment, e.g. stack info */
/** /**
* Align an unsigned value on a alignment boundary. * Align an unsigned value on a alignment boundary.
* *
@ -643,6 +642,24 @@ align_uint(unsigned v, unsigned b)
return (v + m) & ~m; return (v + m) & ~m;
} }
/**
* Check whether a piece of data is out of range
*
* @param offset the offset that the data starts
* @param len the length of the data
* @param max_size the maximum size of the data range
*
* @return true if out of range, false otherwise
*/
inline static bool
offset_len_out_of_bounds(uint32 offset, uint32 len, uint32 max_size)
{
if (offset + len < offset /* integer overflow */
|| offset + len > max_size)
return true;
return false;
}
/** /**
* Return the hash value of c string. * Return the hash value of c string.
*/ */

View File

@ -41,26 +41,28 @@ typedef float64 CellType_F64;
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \ #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
#define CHECK_MEMORY_OVERFLOW(bytes) \ #define CHECK_MEMORY_OVERFLOW(bytes) \
do { \ do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \ uint64 offset1 = (uint64)offset + (uint64)addr; \
if (offset1 + bytes <= (uint64)get_linear_mem_size()) \ if (disable_bounds_checks \
/* If offset1 is in valid range, maddr must also \ || offset1 + bytes <= (uint64)get_linear_mem_size()) \
be in valid range, no need to check it again. */ \ /* If offset1 is in valid range, maddr must also \
maddr = memory->memory_data + offset1; \ be in valid range, no need to check it again. */ \
else \ maddr = memory->memory_data + offset1; \
goto out_of_bounds; \ else \
goto out_of_bounds; \
} while (0) } while (0)
#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
do { \ do { \
uint64 offset1 = (uint32)(start); \ uint64 offset1 = (uint32)(start); \
if (offset1 + bytes <= (uint64)get_linear_mem_size()) \ if (disable_bounds_checks \
/* App heap space is not valid space for \ || offset1 + bytes <= (uint64)get_linear_mem_size()) \
bulk memory operation */ \ /* App heap space is not valid space for \
maddr = memory->memory_data + offset1; \ bulk memory operation */ \
else \ maddr = memory->memory_data + offset1; \
goto out_of_bounds; \ else \
goto out_of_bounds; \
} while (0) } while (0)
#else #else
#define CHECK_MEMORY_OVERFLOW(bytes) \ #define CHECK_MEMORY_OVERFLOW(bytes) \
@ -708,28 +710,28 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(); \ CHECK_ATOMIC_MEMORY_ACCESS(); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint32)(*(uint8 *)maddr); \ readv = (uint32)(*(uint8 *)maddr); \
*(uint8 *)maddr = (uint8)(readv op sval); \ *(uint8 *)maddr = (uint8)(readv op sval); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \ else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(); \ CHECK_ATOMIC_MEMORY_ACCESS(); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint32)LOAD_U16(maddr); \ readv = (uint32)LOAD_U16(maddr); \
STORE_U16(maddr, (uint16)(readv op sval)); \ STORE_U16(maddr, (uint16)(readv op sval)); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else { \ else { \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(); \ CHECK_ATOMIC_MEMORY_ACCESS(); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = LOAD_I32(maddr); \ readv = LOAD_I32(maddr); \
STORE_U32(maddr, readv op sval); \ STORE_U32(maddr, readv op sval); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
PUSH_I32(readv); \ PUSH_I32(readv); \
break; \ break; \
@ -748,39 +750,39 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(); \ CHECK_ATOMIC_MEMORY_ACCESS(); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint64)(*(uint8 *)maddr); \ readv = (uint64)(*(uint8 *)maddr); \
*(uint8 *)maddr = (uint8)(readv op sval); \ *(uint8 *)maddr = (uint8)(readv op sval); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \ else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(); \ CHECK_ATOMIC_MEMORY_ACCESS(); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint64)LOAD_U16(maddr); \ readv = (uint64)LOAD_U16(maddr); \
STORE_U16(maddr, (uint16)(readv op sval)); \ STORE_U16(maddr, (uint16)(readv op sval)); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \ else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(); \ CHECK_ATOMIC_MEMORY_ACCESS(); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint64)LOAD_U32(maddr); \ readv = (uint64)LOAD_U32(maddr); \
STORE_U32(maddr, (uint32)(readv op sval)); \ STORE_U32(maddr, (uint32)(readv op sval)); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else { \ else { \
uint64 op_result; \ uint64 op_result; \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(); \ CHECK_ATOMIC_MEMORY_ACCESS(); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint64)LOAD_I64(maddr); \ readv = (uint64)LOAD_I64(maddr); \
op_result = readv op sval; \ op_result = readv op sval; \
STORE_I64(maddr, op_result); \ STORE_I64(maddr, op_result); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
PUSH_I64(readv); \ PUSH_I64(readv); \
break; \ break; \
@ -903,8 +905,9 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
if (!func_import->call_conv_wasm_c_api) { if (!func_import->call_conv_wasm_c_api) {
native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
} }
else if (module_inst->e->c_api_func_imports) { else if (module_inst->e->common.c_api_func_imports) {
c_api_func_import = module_inst->e->c_api_func_imports + cur_func_index; c_api_func_import =
module_inst->e->common.c_api_func_imports + cur_func_index;
native_func_pointer = c_api_func_import->func_ptr_linked; native_func_pointer = c_api_func_import->func_ptr_linked;
} }
@ -1060,21 +1063,33 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
os_mutex_unlock(&exec_env->wait_lock); \ os_mutex_unlock(&exec_env->wait_lock); \
} while (0) } while (0)
#else #else
#define CHECK_SUSPEND_FLAGS() \ #if WASM_SUSPEND_FLAGS_IS_ATOMIC != 0
do { \ /* The lock is only needed when the suspend_flags is atomic; otherwise
os_mutex_lock(&exec_env->wait_lock); \ the lock is already taken at the time when SUSPENSION_LOCK() is called. */
if (exec_env->suspend_flags.flags != 0) { \ #define SUSPENSION_LOCK() os_mutex_lock(&exec_env->wait_lock);
if (exec_env->suspend_flags.flags & 0x01) { \ #define SUSPENSION_UNLOCK() os_mutex_unlock(&exec_env->wait_lock);
/* terminate current thread */ \ #else
os_mutex_unlock(&exec_env->wait_lock); \ #define SUSPENSION_LOCK()
return; \ #define SUSPENSION_UNLOCK()
} \ #endif
while (exec_env->suspend_flags.flags & 0x02) { \
/* suspend current thread */ \ #define CHECK_SUSPEND_FLAGS() \
os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock); \ do { \
} \ WASM_SUSPEND_FLAGS_LOCK(exec_env->wait_lock); \
} \ if (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) \
os_mutex_unlock(&exec_env->wait_lock); \ & WASM_SUSPEND_FLAG_TERMINATE) { \
/* terminate current thread */ \
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
return; \
} \
while (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) \
& WASM_SUSPEND_FLAG_SUSPEND) { \
/* suspend current thread */ \
SUSPENSION_LOCK() \
os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock); \
SUSPENSION_UNLOCK() \
} \
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
} while (0) } while (0)
#endif /* WASM_ENABLE_DEBUG_INTERP */ #endif /* WASM_ENABLE_DEBUG_INTERP */
#endif /* WASM_ENABLE_THREAD_MGR */ #endif /* WASM_ENABLE_THREAD_MGR */
@ -1142,10 +1157,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMFunctionInstance *cur_func, WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
#endif
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \ #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
@ -1174,6 +1185,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 local_type, *global_addr; uint8 local_type, *global_addr;
uint32 cache_index, type_index, param_cell_num, cell_num; uint32 cache_index, type_index, param_cell_num, cell_num;
uint8 value_type; uint8 value_type;
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
(WASMModuleInstanceCommon *)module);
#else
bool disable_bounds_checks = false;
#endif
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_DEBUG_INTERP != 0
uint8 *frame_ip_orig = NULL; uint8 *frame_ip_orig = NULL;
@ -3238,7 +3258,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
case WASM_OP_TABLE_INIT: case WASM_OP_TABLE_INIT:
{ {
uint32 tbl_idx, elem_idx; uint32 tbl_idx, elem_idx;
uint64 n, s, d; uint32 n, s, d;
WASMTableInstance *tbl_inst; WASMTableInstance *tbl_inst;
read_leb_uint32(frame_ip, frame_ip_end, elem_idx); read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
@ -3253,20 +3273,21 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
s = (uint32)POP_I32(); s = (uint32)POP_I32();
d = (uint32)POP_I32(); d = (uint32)POP_I32();
/* TODO: what if the element is not passive? */ if (offset_len_out_of_bounds(
s, n,
if (!n) { module->module->table_segments[elem_idx]
break; .function_count)
} || offset_len_out_of_bounds(d, n,
tbl_inst->cur_size)) {
if (n + s > module->module->table_segments[elem_idx]
.function_count
|| d + n > tbl_inst->cur_size) {
wasm_set_exception(module, wasm_set_exception(module,
"out of bounds table access"); "out of bounds table access");
goto got_exception; goto got_exception;
} }
if (!n) {
break;
}
if (module->module->table_segments[elem_idx] if (module->module->table_segments[elem_idx]
.is_dropped) { .is_dropped) {
wasm_set_exception(module, wasm_set_exception(module,
@ -3307,7 +3328,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
case WASM_OP_TABLE_COPY: case WASM_OP_TABLE_COPY:
{ {
uint32 src_tbl_idx, dst_tbl_idx; uint32 src_tbl_idx, dst_tbl_idx;
uint64 n, s, d; uint32 n, s, d;
WASMTableInstance *src_tbl_inst, *dst_tbl_inst; WASMTableInstance *src_tbl_inst, *dst_tbl_inst;
read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx); read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx);
@ -3324,8 +3345,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
s = (uint32)POP_I32(); s = (uint32)POP_I32();
d = (uint32)POP_I32(); d = (uint32)POP_I32();
if (d + n > dst_tbl_inst->cur_size if (offset_len_out_of_bounds(d, n,
|| s + n > src_tbl_inst->cur_size) { dst_tbl_inst->cur_size)
|| offset_len_out_of_bounds(
s, n, src_tbl_inst->cur_size)) {
wasm_set_exception(module, wasm_set_exception(module,
"out of bounds table access"); "out of bounds table access");
goto got_exception; goto got_exception;
@ -3395,11 +3418,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
fill_val = POP_I32(); fill_val = POP_I32();
i = POP_I32(); i = POP_I32();
/* TODO: what if the element is not passive? */ if (offset_len_out_of_bounds(i, n,
/* TODO: what if the element is dropped? */ tbl_inst->cur_size)) {
if (i + n > tbl_inst->cur_size) {
/* TODO: verify warning content */
wasm_set_exception(module, wasm_set_exception(module,
"out of bounds table access"); "out of bounds table access");
goto got_exception; goto got_exception;
@ -3517,23 +3537,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) { if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint32)(*(uint8 *)maddr); readv = (uint32)(*(uint8 *)maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) { else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint32)LOAD_U16(maddr); readv = (uint32)LOAD_U16(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = LOAD_I32(maddr); readv = LOAD_I32(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
PUSH_I32(readv); PUSH_I32(readv);
@ -3552,30 +3572,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) { if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)(*(uint8 *)maddr); readv = (uint64)(*(uint8 *)maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) { else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_U16(maddr); readv = (uint64)LOAD_U16(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) { else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_U32(maddr); readv = (uint64)LOAD_U32(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = LOAD_I64(maddr); readv = LOAD_I64(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
PUSH_I64(readv); PUSH_I64(readv);
@ -3594,23 +3614,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode == WASM_OP_ATOMIC_I32_STORE8) { if (opcode == WASM_OP_ATOMIC_I32_STORE8) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
*(uint8 *)maddr = (uint8)sval; *(uint8 *)maddr = (uint8)sval;
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I32_STORE16) { else if (opcode == WASM_OP_ATOMIC_I32_STORE16) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_U16(maddr, (uint16)sval); STORE_U16(maddr, (uint16)sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_U32(maddr, sval); STORE_U32(maddr, sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
break; break;
} }
@ -3628,30 +3648,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode == WASM_OP_ATOMIC_I64_STORE8) { if (opcode == WASM_OP_ATOMIC_I64_STORE8) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
*(uint8 *)maddr = (uint8)sval; *(uint8 *)maddr = (uint8)sval;
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I64_STORE16) { else if (opcode == WASM_OP_ATOMIC_I64_STORE16) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_U16(maddr, (uint16)sval); STORE_U16(maddr, (uint16)sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I64_STORE32) { else if (opcode == WASM_OP_ATOMIC_I64_STORE32) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_U32(maddr, (uint32)sval); STORE_U32(maddr, (uint32)sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
PUT_I64_TO_ADDR((uint32 *)maddr, sval); PUT_I64_TO_ADDR((uint32 *)maddr, sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
break; break;
} }
@ -3671,32 +3691,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
expect = (uint8)expect; expect = (uint8)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint32)(*(uint8 *)maddr); readv = (uint32)(*(uint8 *)maddr);
if (readv == expect) if (readv == expect)
*(uint8 *)maddr = (uint8)(sval); *(uint8 *)maddr = (uint8)(sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) { else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
expect = (uint16)expect; expect = (uint16)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint32)LOAD_U16(maddr); readv = (uint32)LOAD_U16(maddr);
if (readv == expect) if (readv == expect)
STORE_U16(maddr, (uint16)(sval)); STORE_U16(maddr, (uint16)(sval));
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = LOAD_I32(maddr); readv = LOAD_I32(maddr);
if (readv == expect) if (readv == expect)
STORE_U32(maddr, sval); STORE_U32(maddr, sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
PUSH_I32(readv); PUSH_I32(readv);
break; break;
@ -3717,43 +3737,43 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
expect = (uint8)expect; expect = (uint8)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)(*(uint8 *)maddr); readv = (uint64)(*(uint8 *)maddr);
if (readv == expect) if (readv == expect)
*(uint8 *)maddr = (uint8)(sval); *(uint8 *)maddr = (uint8)(sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) { else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
expect = (uint16)expect; expect = (uint16)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_U16(maddr); readv = (uint64)LOAD_U16(maddr);
if (readv == expect) if (readv == expect)
STORE_U16(maddr, (uint16)(sval)); STORE_U16(maddr, (uint16)(sval));
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) { else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
expect = (uint32)expect; expect = (uint32)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_U32(maddr); readv = (uint64)LOAD_U32(maddr);
if (readv == expect) if (readv == expect)
STORE_U32(maddr, (uint32)(sval)); STORE_U32(maddr, (uint32)(sval));
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_I64(maddr); readv = (uint64)LOAD_I64(maddr);
if (readv == expect) if (readv == expect)
STORE_I64(maddr, sval); STORE_I64(maddr, sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
PUSH_I64(readv); PUSH_I64(readv);
break; break;
@ -3786,7 +3806,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(DEBUG_OP_BREAK) HANDLE_OP(DEBUG_OP_BREAK)
{ {
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP); wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP);
exec_env->suspend_flags.flags |= 2; WASM_SUSPEND_FLAGS_FETCH_OR(exec_env->suspend_flags,
WASM_SUSPEND_FLAG_SUSPEND);
frame_ip--; frame_ip--;
SYNC_ALL_TO_FRAME(); SYNC_ALL_TO_FRAME();
CHECK_SUSPEND_FLAGS(); CHECK_SUSPEND_FLAGS();

View File

@ -35,7 +35,8 @@ typedef float64 CellType_F64;
#define CHECK_MEMORY_OVERFLOW(bytes) \ #define CHECK_MEMORY_OVERFLOW(bytes) \
do { \ do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \ uint64 offset1 = (uint64)offset + (uint64)addr; \
if (offset1 + bytes <= (uint64)get_linear_mem_size()) \ if (disable_bounds_checks \
|| offset1 + bytes <= (uint64)get_linear_mem_size()) \
/* If offset1 is in valid range, maddr must also \ /* If offset1 is in valid range, maddr must also \
be in valid range, no need to check it again. */ \ be in valid range, no need to check it again. */ \
maddr = memory->memory_data + offset1; \ maddr = memory->memory_data + offset1; \
@ -43,15 +44,15 @@ typedef float64 CellType_F64;
goto out_of_bounds; \ goto out_of_bounds; \
} while (0) } while (0)
#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
do { \ do { \
uint64 offset1 = (uint32)(start); \ uint64 offset1 = (uint32)(start); \
if (offset1 + bytes <= get_linear_mem_size()) \ if (disable_bounds_checks || offset1 + bytes <= get_linear_mem_size()) \
/* App heap space is not valid space for \ /* App heap space is not valid space for \
bulk memory operation */ \ bulk memory operation */ \
maddr = memory->memory_data + offset1; \ maddr = memory->memory_data + offset1; \
else \ else \
goto out_of_bounds; \ goto out_of_bounds; \
} while (0) } while (0)
#else #else
#define CHECK_MEMORY_OVERFLOW(bytes) \ #define CHECK_MEMORY_OVERFLOW(bytes) \
@ -481,28 +482,28 @@ LOAD_PTR(void *addr)
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(1); \ CHECK_ATOMIC_MEMORY_ACCESS(1); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint32)(*(uint8 *)maddr); \ readv = (uint32)(*(uint8 *)maddr); \
*(uint8 *)maddr = (uint8)(readv op sval); \ *(uint8 *)maddr = (uint8)(readv op sval); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \ else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(2); \ CHECK_ATOMIC_MEMORY_ACCESS(2); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint32)LOAD_U16(maddr); \ readv = (uint32)LOAD_U16(maddr); \
STORE_U16(maddr, (uint16)(readv op sval)); \ STORE_U16(maddr, (uint16)(readv op sval)); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else { \ else { \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(4); \ CHECK_ATOMIC_MEMORY_ACCESS(4); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = LOAD_I32(maddr); \ readv = LOAD_I32(maddr); \
STORE_U32(maddr, readv op sval); \ STORE_U32(maddr, readv op sval); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
PUSH_I32(readv); \ PUSH_I32(readv); \
break; \ break; \
@ -521,39 +522,39 @@ LOAD_PTR(void *addr)
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(1); \ CHECK_ATOMIC_MEMORY_ACCESS(1); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint64)(*(uint8 *)maddr); \ readv = (uint64)(*(uint8 *)maddr); \
*(uint8 *)maddr = (uint8)(readv op sval); \ *(uint8 *)maddr = (uint8)(readv op sval); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \ else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(2); \ CHECK_ATOMIC_MEMORY_ACCESS(2); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint64)LOAD_U16(maddr); \ readv = (uint64)LOAD_U16(maddr); \
STORE_U16(maddr, (uint16)(readv op sval)); \ STORE_U16(maddr, (uint16)(readv op sval)); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \ else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(4); \ CHECK_ATOMIC_MEMORY_ACCESS(4); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint64)LOAD_U32(maddr); \ readv = (uint64)LOAD_U32(maddr); \
STORE_U32(maddr, (uint32)(readv op sval)); \ STORE_U32(maddr, (uint32)(readv op sval)); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
else { \ else { \
uint64 op_result; \ uint64 op_result; \
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); \
CHECK_ATOMIC_MEMORY_ACCESS(8); \ CHECK_ATOMIC_MEMORY_ACCESS(8); \
\ \
os_mutex_lock(&node->shared_mem_lock); \ shared_memory_lock(memory); \
readv = (uint64)LOAD_I64(maddr); \ readv = (uint64)LOAD_I64(maddr); \
op_result = readv op sval; \ op_result = readv op sval; \
STORE_I64(maddr, op_result); \ STORE_I64(maddr, op_result); \
os_mutex_unlock(&node->shared_mem_lock); \ shared_memory_unlock(memory); \
} \ } \
PUSH_I64(readv); \ PUSH_I64(readv); \
break; \ break; \
@ -937,8 +938,9 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
if (!func_import->call_conv_wasm_c_api) { if (!func_import->call_conv_wasm_c_api) {
native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
} }
else if (module_inst->e->c_api_func_imports) { else if (module_inst->e->common.c_api_func_imports) {
c_api_func_import = module_inst->e->c_api_func_imports + cur_func_index; c_api_func_import =
module_inst->e->common.c_api_func_imports + cur_func_index;
native_func_pointer = c_api_func_import->func_ptr_linked; native_func_pointer = c_api_func_import->func_ptr_linked;
} }
@ -1064,18 +1066,17 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
#endif #endif
#if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_THREAD_MGR != 0
#define CHECK_SUSPEND_FLAGS() \ #define CHECK_SUSPEND_FLAGS() \
do { \ do { \
os_mutex_lock(&exec_env->wait_lock); \ WASM_SUSPEND_FLAGS_LOCK(exec_env->wait_lock); \
if (exec_env->suspend_flags.flags != 0) { \ if (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) \
if (exec_env->suspend_flags.flags & 0x01) { \ & WASM_SUSPEND_FLAG_TERMINATE) { \
/* terminate current thread */ \ /* terminate current thread */ \
os_mutex_unlock(&exec_env->wait_lock); \ WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
return; \ return; \
} \ } \
/* TODO: support suspend and breakpoint */ \ /* TODO: support suspend and breakpoint */ \
} \ WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
os_mutex_unlock(&exec_env->wait_lock); \
} while (0) } while (0)
#endif #endif
@ -1166,10 +1167,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMFunctionInstance *cur_func, WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
#endif
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \ #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
@ -1199,6 +1196,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 *maddr = NULL; uint8 *maddr = NULL;
uint32 local_idx, local_offset, global_idx; uint32 local_idx, local_offset, global_idx;
uint8 opcode, local_type, *global_addr; uint8 opcode, local_type, *global_addr;
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
(WASMModuleInstanceCommon *)module);
#else
bool disable_bounds_checks = false;
#endif
#endif
#if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_ENABLE_LABELS_AS_VALUES != 0
#define HANDLE_OPCODE(op) &&HANDLE_##op #define HANDLE_OPCODE(op) &&HANDLE_##op
@ -3083,7 +3089,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
case WASM_OP_TABLE_INIT: case WASM_OP_TABLE_INIT:
{ {
uint32 tbl_idx, elem_idx; uint32 tbl_idx, elem_idx;
uint64 n, s, d; uint32 n, s, d;
WASMTableInstance *tbl_inst; WASMTableInstance *tbl_inst;
elem_idx = read_uint32(frame_ip); elem_idx = read_uint32(frame_ip);
@ -3098,18 +3104,21 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
s = (uint32)POP_I32(); s = (uint32)POP_I32();
d = (uint32)POP_I32(); d = (uint32)POP_I32();
if (!n) { if (offset_len_out_of_bounds(
break; s, n,
} module->module->table_segments[elem_idx]
.function_count)
if (n + s > module->module->table_segments[elem_idx] || offset_len_out_of_bounds(d, n,
.function_count tbl_inst->cur_size)) {
|| d + n > tbl_inst->cur_size) {
wasm_set_exception(module, wasm_set_exception(module,
"out of bounds table access"); "out of bounds table access");
goto got_exception; goto got_exception;
} }
if (!n) {
break;
}
if (module->module->table_segments[elem_idx] if (module->module->table_segments[elem_idx]
.is_dropped) { .is_dropped) {
wasm_set_exception(module, wasm_set_exception(module,
@ -3148,7 +3157,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
case WASM_OP_TABLE_COPY: case WASM_OP_TABLE_COPY:
{ {
uint32 src_tbl_idx, dst_tbl_idx; uint32 src_tbl_idx, dst_tbl_idx;
uint64 n, s, d; uint32 n, s, d;
WASMTableInstance *src_tbl_inst, *dst_tbl_inst; WASMTableInstance *src_tbl_inst, *dst_tbl_inst;
dst_tbl_idx = read_uint32(frame_ip); dst_tbl_idx = read_uint32(frame_ip);
@ -3165,8 +3174,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
s = (uint32)POP_I32(); s = (uint32)POP_I32();
d = (uint32)POP_I32(); d = (uint32)POP_I32();
if (d + n > dst_tbl_inst->cur_size if (offset_len_out_of_bounds(d, n,
|| s + n > src_tbl_inst->cur_size) { dst_tbl_inst->cur_size)
|| offset_len_out_of_bounds(
s, n, src_tbl_inst->cur_size)) {
wasm_set_exception(module, wasm_set_exception(module,
"out of bounds table access"); "out of bounds table access");
goto got_exception; goto got_exception;
@ -3237,7 +3248,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
fill_val = POP_I32(); fill_val = POP_I32();
i = POP_I32(); i = POP_I32();
if (i + n > tbl_inst->cur_size) { if (offset_len_out_of_bounds(i, n,
tbl_inst->cur_size)) {
wasm_set_exception(module, wasm_set_exception(module,
"out of bounds table access"); "out of bounds table access");
goto got_exception; goto got_exception;
@ -3352,23 +3364,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) { if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(1); CHECK_ATOMIC_MEMORY_ACCESS(1);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint32)(*(uint8 *)maddr); readv = (uint32)(*(uint8 *)maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) { else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(2); CHECK_ATOMIC_MEMORY_ACCESS(2);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint32)LOAD_U16(maddr); readv = (uint32)LOAD_U16(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(4); CHECK_ATOMIC_MEMORY_ACCESS(4);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = LOAD_I32(maddr); readv = LOAD_I32(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
PUSH_I32(readv); PUSH_I32(readv);
@ -3387,30 +3399,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) { if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(1); CHECK_ATOMIC_MEMORY_ACCESS(1);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)(*(uint8 *)maddr); readv = (uint64)(*(uint8 *)maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) { else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(2); CHECK_ATOMIC_MEMORY_ACCESS(2);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_U16(maddr); readv = (uint64)LOAD_U16(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) { else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(4); CHECK_ATOMIC_MEMORY_ACCESS(4);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_U32(maddr); readv = (uint64)LOAD_U32(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(8); CHECK_ATOMIC_MEMORY_ACCESS(8);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = LOAD_I64(maddr); readv = LOAD_I64(maddr);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
PUSH_I64(readv); PUSH_I64(readv);
@ -3428,23 +3440,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode == WASM_OP_ATOMIC_I32_STORE8) { if (opcode == WASM_OP_ATOMIC_I32_STORE8) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(1); CHECK_ATOMIC_MEMORY_ACCESS(1);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
*(uint8 *)maddr = (uint8)sval; *(uint8 *)maddr = (uint8)sval;
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I32_STORE16) { else if (opcode == WASM_OP_ATOMIC_I32_STORE16) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(2); CHECK_ATOMIC_MEMORY_ACCESS(2);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_U16(maddr, (uint16)sval); STORE_U16(maddr, (uint16)sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(4); CHECK_ATOMIC_MEMORY_ACCESS(4);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_U32(maddr, sval); STORE_U32(maddr, sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
break; break;
} }
@ -3462,30 +3474,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode == WASM_OP_ATOMIC_I64_STORE8) { if (opcode == WASM_OP_ATOMIC_I64_STORE8) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(1); CHECK_ATOMIC_MEMORY_ACCESS(1);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
*(uint8 *)maddr = (uint8)sval; *(uint8 *)maddr = (uint8)sval;
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I64_STORE16) { else if (opcode == WASM_OP_ATOMIC_I64_STORE16) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(2); CHECK_ATOMIC_MEMORY_ACCESS(2);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_U16(maddr, (uint16)sval); STORE_U16(maddr, (uint16)sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_I64_STORE32) { else if (opcode == WASM_OP_ATOMIC_I64_STORE32) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(4); CHECK_ATOMIC_MEMORY_ACCESS(4);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_U32(maddr, (uint32)sval); STORE_U32(maddr, (uint32)sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(8); CHECK_ATOMIC_MEMORY_ACCESS(8);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
STORE_I64(maddr, sval); STORE_I64(maddr, sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
break; break;
} }
@ -3505,32 +3517,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_ATOMIC_MEMORY_ACCESS(1); CHECK_ATOMIC_MEMORY_ACCESS(1);
expect = (uint8)expect; expect = (uint8)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint32)(*(uint8 *)maddr); readv = (uint32)(*(uint8 *)maddr);
if (readv == expect) if (readv == expect)
*(uint8 *)maddr = (uint8)(sval); *(uint8 *)maddr = (uint8)(sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) { else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(2); CHECK_ATOMIC_MEMORY_ACCESS(2);
expect = (uint16)expect; expect = (uint16)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint32)LOAD_U16(maddr); readv = (uint32)LOAD_U16(maddr);
if (readv == expect) if (readv == expect)
STORE_U16(maddr, (uint16)(sval)); STORE_U16(maddr, (uint16)(sval));
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(4); CHECK_ATOMIC_MEMORY_ACCESS(4);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = LOAD_I32(maddr); readv = LOAD_I32(maddr);
if (readv == expect) if (readv == expect)
STORE_U32(maddr, sval); STORE_U32(maddr, sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
PUSH_I32(readv); PUSH_I32(readv);
break; break;
@ -3551,43 +3563,43 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_ATOMIC_MEMORY_ACCESS(1); CHECK_ATOMIC_MEMORY_ACCESS(1);
expect = (uint8)expect; expect = (uint8)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)(*(uint8 *)maddr); readv = (uint64)(*(uint8 *)maddr);
if (readv == expect) if (readv == expect)
*(uint8 *)maddr = (uint8)(sval); *(uint8 *)maddr = (uint8)(sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) { else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(2); CHECK_ATOMIC_MEMORY_ACCESS(2);
expect = (uint16)expect; expect = (uint16)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_U16(maddr); readv = (uint64)LOAD_U16(maddr);
if (readv == expect) if (readv == expect)
STORE_U16(maddr, (uint16)(sval)); STORE_U16(maddr, (uint16)(sval));
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) { else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(4); CHECK_ATOMIC_MEMORY_ACCESS(4);
expect = (uint32)expect; expect = (uint32)expect;
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_U32(maddr); readv = (uint64)LOAD_U32(maddr);
if (readv == expect) if (readv == expect)
STORE_U32(maddr, (uint32)(sval)); STORE_U32(maddr, (uint32)(sval));
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
else { else {
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
CHECK_ATOMIC_MEMORY_ACCESS(8); CHECK_ATOMIC_MEMORY_ACCESS(8);
os_mutex_lock(&node->shared_mem_lock); shared_memory_lock(memory);
readv = (uint64)LOAD_I64(maddr); readv = (uint64)LOAD_I64(maddr);
if (readv == expect) if (readv == expect)
STORE_I64(maddr, sval); STORE_I64(maddr, sval);
os_mutex_unlock(&node->shared_mem_lock); shared_memory_unlock(memory);
} }
PUSH_I64(readv); PUSH_I64(readv);
break; break;

View File

@ -5487,6 +5487,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
return true; return true;
} }
#if WASM_ENABLE_FAST_INTERP == 0
static bool static bool
wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt, wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
uint8 type_push, uint8 type_pop, char *error_buf, uint8 type_push, uint8 type_pop, char *error_buf,
@ -5501,6 +5502,7 @@ wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
return false; return false;
return true; return true;
} }
#endif
static bool static bool
wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type, wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type,
@ -6177,27 +6179,6 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type,
return true; return true;
} }
static bool
wasm_loader_push_pop_frame_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
uint8 type_push, uint8 type_pop,
bool disable_emit, int16 operand_offset,
char *error_buf, uint32 error_buf_size)
{
uint8 i;
for (i = 0; i < pop_cnt; i++) {
if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf,
error_buf_size))
return false;
}
if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit,
operand_offset, error_buf,
error_buf_size))
return false;
return true;
}
static bool static bool
wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type, wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
bool disable_emit, int16 operand_offset, bool disable_emit, int16 operand_offset,
@ -6231,12 +6212,24 @@ wasm_loader_push_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
bool disable_emit, int16 operand_offset, bool disable_emit, int16 operand_offset,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
if (!wasm_loader_push_pop_frame_offset(ctx, pop_cnt, type_push, type_pop, uint8 i;
disable_emit, operand_offset,
error_buf, error_buf_size)) for (i = 0; i < pop_cnt; i++) {
if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf,
error_buf_size))
return false;
if (!wasm_loader_pop_frame_ref(ctx, type_pop, error_buf,
error_buf_size))
return false;
}
if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit,
operand_offset, error_buf,
error_buf_size))
return false; return false;
if (!wasm_loader_push_pop_frame_ref(ctx, pop_cnt, type_push, type_pop,
error_buf, error_buf_size)) if (!wasm_loader_push_frame_ref(ctx, type_push, error_buf, error_buf_size))
return false; return false;
return true; return true;
@ -7025,6 +7018,7 @@ static bool
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block, copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
bool ret = false;
int16 *frame_offset = NULL; int16 *frame_offset = NULL;
uint8 *cells = NULL, cell; uint8 *cells = NULL, cell;
int16 *src_offsets = NULL; int16 *src_offsets = NULL;
@ -7095,13 +7089,13 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
if (is_if_block) if (is_if_block)
PUSH_OFFSET_TYPE(VALUE_TYPE_I32); PUSH_OFFSET_TYPE(VALUE_TYPE_I32);
ret = true;
fail:
/* Free the emit data */ /* Free the emit data */
wasm_runtime_free(emit_data); wasm_runtime_free(emit_data);
return true; return ret;
fail:
return false;
} }
#endif #endif
@ -8087,9 +8081,13 @@ re_scan:
case WASM_OP_SELECT_T: case WASM_OP_SELECT_T:
{ {
uint8 vec_len, ref_type; uint8 vec_len, ref_type;
#if WASM_ENABLE_FAST_INTERP != 0
uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
#endif
read_leb_uint32(p, p_end, vec_len); read_leb_uint32(p, p_end, vec_len);
if (!vec_len) { if (vec_len != 1) {
/* typed select must have exactly one result */
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"invalid result arity"); "invalid result arity");
goto fail; goto fail;
@ -8108,8 +8106,6 @@ re_scan:
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
if (loader_ctx->p_code_compiled) { if (loader_ctx->p_code_compiled) {
uint8 opcode_tmp = WASM_OP_SELECT; uint8 opcode_tmp = WASM_OP_SELECT;
uint8 *p_code_compiled_tmp =
loader_ctx->p_code_compiled - 2;
if (ref_type == VALUE_TYPE_V128) { if (ref_type == VALUE_TYPE_V128) {
#if (WASM_ENABLE_SIMD == 0) \ #if (WASM_ENABLE_SIMD == 0) \

View File

@ -3948,6 +3948,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
return true; return true;
} }
#if WASM_ENABLE_FAST_INTERP == 0
static bool static bool
wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt, wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
uint8 type_push, uint8 type_pop, char *error_buf, uint8 type_push, uint8 type_pop, char *error_buf,
@ -3962,6 +3963,7 @@ wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
return false; return false;
return true; return true;
} }
#endif
static bool static bool
wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type, wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type,
@ -4619,25 +4621,6 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type,
return true; return true;
} }
static bool
wasm_loader_push_pop_frame_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
uint8 type_push, uint8 type_pop,
bool disable_emit, int16 operand_offset,
char *error_buf, uint32 error_buf_size)
{
for (int i = 0; i < pop_cnt; i++) {
if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf,
error_buf_size))
return false;
}
if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit,
operand_offset, error_buf,
error_buf_size))
return false;
return true;
}
static bool static bool
wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type, wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
bool disable_emit, int16 operand_offset, bool disable_emit, int16 operand_offset,
@ -4671,12 +4654,24 @@ wasm_loader_push_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
bool disable_emit, int16 operand_offset, bool disable_emit, int16 operand_offset,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
if (!wasm_loader_push_pop_frame_offset(ctx, pop_cnt, type_push, type_pop, uint8 i;
disable_emit, operand_offset,
error_buf, error_buf_size)) for (i = 0; i < pop_cnt; i++) {
if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf,
error_buf_size))
return false;
if (!wasm_loader_pop_frame_ref(ctx, type_pop, error_buf,
error_buf_size))
return false;
}
if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit,
operand_offset, error_buf,
error_buf_size))
return false; return false;
if (!wasm_loader_push_pop_frame_ref(ctx, pop_cnt, type_push, type_pop,
error_buf, error_buf_size)) if (!wasm_loader_push_frame_ref(ctx, type_push, error_buf, error_buf_size))
return false; return false;
return true; return true;
@ -6256,9 +6251,13 @@ re_scan:
case WASM_OP_SELECT_T: case WASM_OP_SELECT_T:
{ {
uint8 vec_len, ref_type; uint8 vec_len, ref_type;
#if WASM_ENABLE_FAST_INTERP != 0
uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
#endif
read_leb_uint32(p, p_end, vec_len); read_leb_uint32(p, p_end, vec_len);
if (!vec_len) { if (vec_len != 1) {
/* typed select must have exactly one result */
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"invalid result arity"); "invalid result arity");
goto fail; goto fail;
@ -6277,8 +6276,6 @@ re_scan:
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
if (loader_ctx->p_code_compiled) { if (loader_ctx->p_code_compiled) {
uint8 opcode_tmp = WASM_OP_SELECT; uint8 opcode_tmp = WASM_OP_SELECT;
uint8 *p_code_compiled_tmp =
loader_ctx->p_code_compiled - 2;
if (ref_type == VALUE_TYPE_F64 if (ref_type == VALUE_TYPE_F64
|| ref_type == VALUE_TYPE_I64) || ref_type == VALUE_TYPE_I64)

View File

@ -122,11 +122,8 @@ memories_deinstantiate(WASMModuleInstance *module_inst,
} }
#endif #endif
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (memories[i]->is_shared) { if (shared_memory_is_shared(memories[i])) {
int32 ref_count = shared_memory_dec_reference( uint32 ref_count = shared_memory_dec_reference(memories[i]);
(WASMModuleCommon *)module_inst->module);
bh_assert(ref_count >= 0);
/* if the reference count is not zero, /* if the reference count is not zero,
don't free the memory */ don't free the memory */
if (ref_count > 0) if (ref_count > 0)
@ -159,7 +156,8 @@ memories_deinstantiate(WASMModuleInstance *module_inst,
} }
static WASMMemoryInstance * static WASMMemoryInstance *
memory_instantiate(WASMModuleInstance *module_inst, WASMMemoryInstance *memory, memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
WASMMemoryInstance *memory, uint32 memory_idx,
uint32 num_bytes_per_page, uint32 init_page_count, uint32 num_bytes_per_page, uint32 init_page_count,
uint32 max_page_count, uint32 heap_size, uint32 flags, uint32 max_page_count, uint32 heap_size, uint32 flags,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
@ -180,22 +178,11 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMMemoryInstance *memory,
bool is_shared_memory = flags & 0x02 ? true : false; bool is_shared_memory = flags & 0x02 ? true : false;
/* shared memory */ /* shared memory */
if (is_shared_memory) { if (is_shared_memory && parent != NULL) {
WASMSharedMemNode *node = wasm_module_get_shared_memory( bh_assert(parent->memory_count > memory_idx);
(WASMModuleCommon *)module_inst->module); memory = parent->memories[memory_idx];
/* If the memory of this module has been instantiated, shared_memory_inc_reference(memory);
return the memory instance directly */ return memory;
if (node) {
uint32 ref_count;
ref_count = shared_memory_inc_reference(
(WASMModuleCommon *)module_inst->module);
bh_assert(ref_count > 0);
memory = (WASMMemoryInstance *)shared_memory_get_memory_inst(node);
bh_assert(memory);
(void)ref_count;
return memory;
}
} }
#endif /* end of WASM_ENABLE_SHARED_MEMORY */ #endif /* end of WASM_ENABLE_SHARED_MEMORY */
@ -215,7 +202,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMMemoryInstance *memory,
if (num_bytes_per_page < heap_size) { if (num_bytes_per_page < heap_size) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, " "failed to insert app heap into linear memory, "
"try using `--heap_size=0` option"); "try using `--heap-size=0` option");
return NULL; return NULL;
} }
} }
@ -274,7 +261,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMMemoryInstance *memory,
if (init_page_count > DEFAULT_MAX_PAGES) { if (init_page_count > DEFAULT_MAX_PAGES) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, " "failed to insert app heap into linear memory, "
"try using `--heap_size=0` option"); "try using `--heap-size=0` option");
return NULL; return NULL;
} }
else if (init_page_count == DEFAULT_MAX_PAGES) { else if (init_page_count == DEFAULT_MAX_PAGES) {
@ -388,24 +375,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMMemoryInstance *memory,
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (is_shared_memory) { if (is_shared_memory) {
memory->is_shared = true; memory->ref_count = 1;
if (!shared_memory_set_memory_inst(
(WASMModuleCommon *)module_inst->module,
(WASMMemoryInstanceCommon *)memory)) {
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
goto fail4;
}
} }
#endif #endif
LOG_VERBOSE("Memory instantiate success."); LOG_VERBOSE("Memory instantiate success.");
return memory; return memory;
#if WASM_ENABLE_SHARED_MEMORY != 0
fail4:
if (heap_size > 0)
mem_allocator_destroy(memory->heap_handle);
#endif
fail3: fail3:
if (heap_size > 0) if (heap_size > 0)
wasm_runtime_free(memory->heap_handle); wasm_runtime_free(memory->heap_handle);
@ -428,7 +404,8 @@ fail1:
*/ */
static WASMMemoryInstance ** static WASMMemoryInstance **
memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
uint32 heap_size, char *error_buf, uint32 error_buf_size) WASMModuleInstance *parent, uint32 heap_size,
char *error_buf, uint32 error_buf_size)
{ {
WASMImport *import; WASMImport *import;
uint32 mem_index = 0, i, uint32 mem_index = 0, i,
@ -474,26 +451,29 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
else else
#endif #endif
{ {
if (!(memories[mem_index++] = memory_instantiate( if (!(memories[mem_index] = memory_instantiate(
module_inst, memory, num_bytes_per_page, init_page_count, module_inst, parent, memory, mem_index,
max_page_count, actual_heap_size, flags, error_buf, num_bytes_per_page, init_page_count, max_page_count,
error_buf_size))) { actual_heap_size, flags, error_buf, error_buf_size))) {
memories_deinstantiate(module_inst, memories, memory_count); memories_deinstantiate(module_inst, memories, memory_count);
return NULL; return NULL;
} }
mem_index++;
} }
} }
/* instantiate memories from memory section */ /* instantiate memories from memory section */
for (i = 0; i < module->memory_count; i++, memory++) { for (i = 0; i < module->memory_count; i++, memory++) {
if (!(memories[mem_index++] = memory_instantiate( if (!(memories[mem_index] = memory_instantiate(
module_inst, memory, module->memories[i].num_bytes_per_page, module_inst, parent, memory, mem_index,
module->memories[i].num_bytes_per_page,
module->memories[i].init_page_count, module->memories[i].init_page_count,
module->memories[i].max_page_count, heap_size, module->memories[i].max_page_count, heap_size,
module->memories[i].flags, error_buf, error_buf_size))) { module->memories[i].flags, error_buf, error_buf_size))) {
memories_deinstantiate(module_inst, memories, memory_count); memories_deinstantiate(module_inst, memories, memory_count);
return NULL; return NULL;
} }
mem_index++;
} }
bh_assert(mem_index == memory_count); bh_assert(mem_index == memory_count);
@ -1104,10 +1084,14 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
goto fail; goto fail;
} }
#if WASM_ENABLE_LIBC_WASI != 0
if (initialize_func if (initialize_func
&& !wasm_call_function(exec_env, initialize_func, 0, NULL)) { && !wasm_call_function(exec_env, initialize_func, 0, NULL)) {
goto fail; goto fail;
} }
#else
(void)initialize_func;
#endif
if (post_inst_func if (post_inst_func
&& !wasm_call_function(exec_env, post_inst_func, 0, NULL)) { && !wasm_call_function(exec_env, post_inst_func, 0, NULL)) {
@ -1297,7 +1281,7 @@ sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
WASMModuleInstance *sub_module_inst = NULL; WASMModuleInstance *sub_module_inst = NULL;
sub_module_inst = sub_module_inst =
wasm_instantiate(sub_module, false, NULL, stack_size, heap_size, wasm_instantiate(sub_module, NULL, NULL, stack_size, heap_size,
error_buf, error_buf_size); error_buf, error_buf_size);
if (!sub_module_inst) { if (!sub_module_inst) {
LOG_DEBUG("instantiate %s failed", LOG_DEBUG("instantiate %s failed",
@ -1642,7 +1626,7 @@ wasm_set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode)
* Instantiate module * Instantiate module
*/ */
WASMModuleInstance * WASMModuleInstance *
wasm_instantiate(WASMModule *module, bool is_sub_inst, wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
WASMExecEnv *exec_env_main, uint32 stack_size, WASMExecEnv *exec_env_main, uint32 stack_size,
uint32 heap_size, char *error_buf, uint32 error_buf_size) uint32 heap_size, char *error_buf, uint32 error_buf_size)
{ {
@ -1659,6 +1643,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
bool ret = false; bool ret = false;
#endif #endif
const bool is_sub_inst = parent != NULL;
if (!module) if (!module)
return NULL; return NULL;
@ -1777,8 +1762,9 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
/* Instantiate memories/tables/functions */ /* Instantiate memories/tables/functions */
if ((module_inst->memory_count > 0 if ((module_inst->memory_count > 0
&& !(module_inst->memories = memories_instantiate( && !(module_inst->memories =
module, module_inst, heap_size, error_buf, error_buf_size))) memories_instantiate(module, module_inst, parent, heap_size,
error_buf, error_buf_size)))
|| (module_inst->table_count > 0 || (module_inst->table_count > 0
&& !(module_inst->tables = && !(module_inst->tables =
tables_instantiate(module, module_inst, first_table, tables_instantiate(module, module_inst, first_table,
@ -1853,7 +1839,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
for (i = 0; i < module->data_seg_count; i++) { for (i = 0; i < module->data_seg_count; i++) {
WASMMemoryInstance *memory = NULL; WASMMemoryInstance *memory = NULL;
uint8 *memory_data = NULL; uint8 *memory_data = NULL;
uint32 memory_size = 0; uint64 memory_size = 0;
WASMDataSeg *data_seg = module->data_segments[i]; WASMDataSeg *data_seg = module->data_segments[i];
#if WASM_ENABLE_BULK_MEMORY != 0 #if WASM_ENABLE_BULK_MEMORY != 0
@ -1866,7 +1852,8 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
bh_assert(memory); bh_assert(memory);
memory_data = memory->memory_data; memory_data = memory->memory_data;
memory_size = memory->num_bytes_per_page * memory->cur_page_count; memory_size =
(uint64)memory->num_bytes_per_page * memory->cur_page_count;
bh_assert(memory_data || memory_size == 0); bh_assert(memory_data || memory_size == 0);
bh_assert(data_seg->base_offset.init_expr_type bh_assert(data_seg->base_offset.init_expr_type
@ -1912,7 +1899,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
/* check offset + length(could be zero) */ /* check offset + length(could be zero) */
length = data_seg->data_length; length = data_seg->data_length;
if (base_offset + length > memory_size) { if ((uint64)base_offset + length > memory_size) {
LOG_DEBUG("base_offset(%d) + length(%d) > memory_size(%d)", LOG_DEBUG("base_offset(%d) + length(%d) > memory_size(%d)",
base_offset, length, memory_size); base_offset, length, memory_size);
#if WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_REF_TYPES != 0
@ -1926,8 +1913,9 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
} }
if (memory_data) { if (memory_data) {
bh_memcpy_s(memory_data + base_offset, memory_size - base_offset, bh_memcpy_s(memory_data + base_offset,
data_seg->data, length); (uint32)memory_size - base_offset, data_seg->data,
length);
} }
} }
@ -2212,16 +2200,6 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
sub_module_deinstantiate(module_inst); sub_module_deinstantiate(module_inst);
#endif #endif
#if WASM_ENABLE_LIBC_WASI != 0
/* Destroy wasi resource before freeing app heap, since some fields of
wasi contex are allocated from app heap, and if app heap is freed,
these fields will be set to NULL, we cannot free their internal data
which may allocated from global heap. */
/* Only destroy wasi ctx in the main module instance */
if (!is_sub_inst)
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst);
#endif
if (module_inst->memory_count > 0) if (module_inst->memory_count > 0)
memories_deinstantiate(module_inst, module_inst->memories, memories_deinstantiate(module_inst, module_inst->memories,
module_inst->memory_count); module_inst->memory_count);
@ -2251,13 +2229,15 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
} }
#endif #endif
if (module_inst->e->c_api_func_imports) if (module_inst->e->common.c_api_func_imports)
wasm_runtime_free(module_inst->e->c_api_func_imports); wasm_runtime_free(module_inst->e->common.c_api_func_imports);
if (!is_sub_inst) {
#if WASM_ENABLE_WASI_NN != 0 #if WASM_ENABLE_WASI_NN != 0
if (!is_sub_inst)
wasi_nn_destroy(module_inst); wasi_nn_destroy(module_inst);
#endif #endif
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
}
wasm_runtime_free(module_inst); wasm_runtime_free(module_inst);
} }
@ -2418,6 +2398,9 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
/* set thread handle and stack boundary */ /* set thread handle and stack boundary */
wasm_exec_env_set_thread_info(exec_env); wasm_exec_env_set_thread_info(exec_env);
/* set exec env so it can be later retrieved from instance */
module_inst->e->common.cur_exec_env = exec_env;
interp_call_wasm(module_inst, exec_env, function, argc, argv); interp_call_wasm(module_inst, exec_env, function, argc, argv);
return !wasm_copy_exception(module_inst, NULL); return !wasm_copy_exception(module_inst, NULL);
} }
@ -3113,11 +3096,7 @@ llvm_jit_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
{ {
bool ret; bool ret;
#if WASM_ENABLE_JIT != 0 bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == exec_env->module_inst->module_type) {
return aot_call_indirect(exec_env, tbl_idx, elem_idx, argc, argv);
}
#endif
ret = call_indirect(exec_env, tbl_idx, elem_idx, argc, argv, false, 0); ret = call_indirect(exec_env, tbl_idx, elem_idx, argc, argv, false, 0);
#ifdef OS_ENABLE_HW_BOUND_CHECK #ifdef OS_ENABLE_HW_BOUND_CHECK
@ -3144,11 +3123,7 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
char buf[96]; char buf[96];
bool ret = false; bool ret = false;
#if WASM_ENABLE_JIT != 0 bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == exec_env->module_inst->module_type) {
return aot_invoke_native(exec_env, func_idx, argc, argv);
}
#endif
module_inst = (WASMModuleInstance *)wasm_runtime_get_module_inst(exec_env); module_inst = (WASMModuleInstance *)wasm_runtime_get_module_inst(exec_env);
module = module_inst->module; module = module_inst->module;
@ -3161,8 +3136,9 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
import_func = &module->import_functions[func_idx].u.function; import_func = &module->import_functions[func_idx].u.function;
if (import_func->call_conv_wasm_c_api) { if (import_func->call_conv_wasm_c_api) {
if (module_inst->e->c_api_func_imports) { if (module_inst->e->common.c_api_func_imports) {
c_api_func_import = module_inst->e->c_api_func_imports + func_idx; c_api_func_import =
module_inst->e->common.c_api_func_imports + func_idx;
func_ptr = c_api_func_import->func_ptr_linked; func_ptr = c_api_func_import->func_ptr_linked;
} }
else { else {
@ -3217,11 +3193,7 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
uint8 *maddr; uint8 *maddr;
uint64 seg_len = 0; uint64 seg_len = 0;
#if WASM_ENABLE_JIT != 0 bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == module_inst->module_type) {
return aot_memory_init(module_inst, seg_index, offset, len, dst);
}
#endif
memory_inst = wasm_get_default_memory(module_inst); memory_inst = wasm_get_default_memory(module_inst);
module = module_inst->module; module = module_inst->module;
@ -3247,11 +3219,7 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
bool bool
llvm_jit_data_drop(WASMModuleInstance *module_inst, uint32 seg_index) llvm_jit_data_drop(WASMModuleInstance *module_inst, uint32 seg_index)
{ {
#if WASM_ENABLE_JIT != 0 bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == module_inst->module_type) {
return aot_data_drop(module_inst, seg_index);
}
#endif
module_inst->module->data_segments[seg_index]->data_length = 0; module_inst->module->data_segments[seg_index]->data_length = 0;
/* Currently we can't free the dropped data segment /* Currently we can't free the dropped data segment
@ -3266,11 +3234,7 @@ llvm_jit_drop_table_seg(WASMModuleInstance *module_inst, uint32 tbl_seg_idx)
{ {
WASMTableSeg *tbl_segs; WASMTableSeg *tbl_segs;
#if WASM_ENABLE_JIT != 0 bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == module_inst->module_type) {
return aot_drop_table_seg(module_inst, tbl_seg_idx);
}
#endif
tbl_segs = module_inst->module->table_segments; tbl_segs = module_inst->module->table_segments;
tbl_segs[tbl_seg_idx].is_dropped = true; tbl_segs[tbl_seg_idx].is_dropped = true;
@ -3284,12 +3248,7 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
WASMTableInstance *tbl_inst; WASMTableInstance *tbl_inst;
WASMTableSeg *tbl_seg; WASMTableSeg *tbl_seg;
#if WASM_ENABLE_JIT != 0 bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == module_inst->module_type) {
return aot_table_init(module_inst, tbl_idx, tbl_seg_idx, length,
src_offset, dst_offset);
}
#endif
tbl_inst = wasm_get_table_inst(module_inst, tbl_idx); tbl_inst = wasm_get_table_inst(module_inst, tbl_idx);
tbl_seg = module_inst->module->table_segments + tbl_seg_idx; tbl_seg = module_inst->module->table_segments + tbl_seg_idx;
@ -3297,13 +3256,13 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
bh_assert(tbl_inst); bh_assert(tbl_inst);
bh_assert(tbl_seg); bh_assert(tbl_seg);
if (!length) { if (offset_len_out_of_bounds(src_offset, length, tbl_seg->function_count)
|| offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
return; return;
} }
if (length + src_offset > tbl_seg->function_count if (!length) {
|| dst_offset + length > tbl_inst->cur_size) {
jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
return; return;
} }
@ -3332,21 +3291,16 @@ llvm_jit_table_copy(WASMModuleInstance *module_inst, uint32 src_tbl_idx,
WASMTableInstance *src_tbl_inst; WASMTableInstance *src_tbl_inst;
WASMTableInstance *dst_tbl_inst; WASMTableInstance *dst_tbl_inst;
#if WASM_ENABLE_JIT != 0 bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == module_inst->module_type) {
aot_table_copy(module_inst, src_tbl_idx, dst_tbl_idx, length,
src_offset, dst_offset);
return;
}
#endif
src_tbl_inst = wasm_get_table_inst(module_inst, src_tbl_idx); src_tbl_inst = wasm_get_table_inst(module_inst, src_tbl_idx);
dst_tbl_inst = wasm_get_table_inst(module_inst, dst_tbl_idx); dst_tbl_inst = wasm_get_table_inst(module_inst, dst_tbl_idx);
bh_assert(src_tbl_inst); bh_assert(src_tbl_inst);
bh_assert(dst_tbl_inst); bh_assert(dst_tbl_inst);
if ((uint64)dst_offset + length > dst_tbl_inst->cur_size if (offset_len_out_of_bounds(dst_offset, length, dst_tbl_inst->cur_size)
|| (uint64)src_offset + length > src_tbl_inst->cur_size) { || offset_len_out_of_bounds(src_offset, length,
src_tbl_inst->cur_size)) {
jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
return; return;
} }
@ -3368,17 +3322,12 @@ llvm_jit_table_fill(WASMModuleInstance *module_inst, uint32 tbl_idx,
{ {
WASMTableInstance *tbl_inst; WASMTableInstance *tbl_inst;
#if WASM_ENABLE_JIT != 0 bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == module_inst->module_type) {
aot_table_fill(module_inst, tbl_idx, length, val, data_offset);
return;
}
#endif
tbl_inst = wasm_get_table_inst(module_inst, tbl_idx); tbl_inst = wasm_get_table_inst(module_inst, tbl_idx);
bh_assert(tbl_inst); bh_assert(tbl_inst);
if (data_offset + length > tbl_inst->cur_size) { if (offset_len_out_of_bounds(data_offset, length, tbl_inst->cur_size)) {
jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
return; return;
} }
@ -3395,11 +3344,7 @@ llvm_jit_table_grow(WASMModuleInstance *module_inst, uint32 tbl_idx,
WASMTableInstance *tbl_inst; WASMTableInstance *tbl_inst;
uint32 i, orig_size, total_size; uint32 i, orig_size, total_size;
#if WASM_ENABLE_JIT != 0 bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == module_inst->module_type) {
return aot_table_grow(module_inst, tbl_idx, inc_size, init_val);
}
#endif
tbl_inst = wasm_get_table_inst(module_inst, tbl_idx); tbl_inst = wasm_get_table_inst(module_inst, tbl_idx);
if (!tbl_inst) { if (!tbl_inst) {
@ -3439,11 +3384,7 @@ llvm_jit_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
WASMInterpFrame *frame; WASMInterpFrame *frame;
uint32 size; uint32 size;
#if WASM_ENABLE_JIT != 0 bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == exec_env->module_inst->module_type) {
return aot_alloc_frame(exec_env, func_index);
}
#endif
module_inst = (WASMModuleInstance *)exec_env->module_inst; module_inst = (WASMModuleInstance *)exec_env->module_inst;
size = wasm_interp_interp_frame_size(0); size = wasm_interp_interp_frame_size(0);
@ -3472,12 +3413,7 @@ llvm_jit_free_frame(WASMExecEnv *exec_env)
WASMInterpFrame *frame; WASMInterpFrame *frame;
WASMInterpFrame *prev_frame; WASMInterpFrame *prev_frame;
#if WASM_ENABLE_JIT != 0 bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
if (Wasm_Module_AoT == exec_env->module_inst->module_type) {
aot_free_frame(exec_env);
return;
}
#endif
frame = wasm_exec_env_get_cur_frame(exec_env); frame = wasm_exec_env_get_cur_frame(exec_env);
prev_frame = frame->prev_frame; prev_frame = frame->prev_frame;

View File

@ -7,6 +7,7 @@
#define _WASM_RUNTIME_H #define _WASM_RUNTIME_H
#include "wasm.h" #include "wasm.h"
#include "bh_atomic.h"
#include "bh_hashmap.h" #include "bh_hashmap.h"
#include "../common/wasm_runtime_common.h" #include "../common/wasm_runtime_common.h"
#include "../common/wasm_exec_env.h" #include "../common/wasm_exec_env.h"
@ -79,7 +80,7 @@ struct WASMMemoryInstance {
/* Module type */ /* Module type */
uint32 module_type; uint32 module_type;
/* Shared memory flag */ /* Shared memory flag */
bool is_shared; bh_atomic_32_t ref_count; /* 0: non-shared, > 0: reference count */
/* Number bytes per page */ /* Number bytes per page */
uint32 num_bytes_per_page; uint32 num_bytes_per_page;
@ -209,8 +210,22 @@ typedef struct CApiFuncImport {
void *env_arg; void *env_arg;
} CApiFuncImport; } CApiFuncImport;
/* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */
typedef struct WASMModuleInstanceExtraCommon {
void *contexts[WASM_MAX_INSTANCE_CONTEXTS];
CApiFuncImport *c_api_func_imports;
/* pointer to the exec env currently used */
WASMExecEnv *cur_exec_env;
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
/* Disable bounds checks or not */
bool disable_bounds_checks;
#endif
} WASMModuleInstanceExtraCommon;
/* Extra info of WASM module instance for interpreter/jit mode */ /* Extra info of WASM module instance for interpreter/jit mode */
typedef struct WASMModuleInstanceExtra { typedef struct WASMModuleInstanceExtra {
WASMModuleInstanceExtraCommon common;
WASMGlobalInstance *globals; WASMGlobalInstance *globals;
WASMFunctionInstance *functions; WASMFunctionInstance *functions;
@ -222,7 +237,6 @@ typedef struct WASMModuleInstanceExtra {
WASMFunctionInstance *free_function; WASMFunctionInstance *free_function;
WASMFunctionInstance *retain_function; WASMFunctionInstance *retain_function;
CApiFuncImport *c_api_func_imports;
RunningMode running_mode; RunningMode running_mode;
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
@ -286,12 +300,8 @@ struct WASMModuleInstance {
it denotes `AOTModule *` */ it denotes `AOTModule *` */
DefPointer(WASMModule *, module); DefPointer(WASMModule *, module);
#if WASM_ENABLE_LIBC_WASI DefPointer(void *, used_to_be_wasi_ctx); /* unused */
/* WASI context */
DefPointer(WASIContext *, wasi_ctx);
#else
DefPointer(void *, wasi_ctx);
#endif
DefPointer(WASMExecEnv *, exec_env_singleton); DefPointer(WASMExecEnv *, exec_env_singleton);
/* Array of function pointers to import functions, /* Array of function pointers to import functions,
not available in AOTModuleInstance */ not available in AOTModuleInstance */
@ -396,7 +406,7 @@ void
wasm_unload(WASMModule *module); wasm_unload(WASMModule *module);
WASMModuleInstance * WASMModuleInstance *
wasm_instantiate(WASMModule *module, bool is_sub_inst, wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
WASMExecEnv *exec_env_main, uint32 stack_size, WASMExecEnv *exec_env_main, uint32 stack_size,
uint32 heap_size, char *error_buf, uint32 error_buf_size); uint32 heap_size, char *error_buf, uint32 error_buf_size);
@ -657,6 +667,16 @@ void
wasm_propagate_wasi_args(WASMModule *module); wasm_propagate_wasi_args(WASMModule *module);
#endif #endif
#if WASM_ENABLE_THREAD_MGR != 0
void
exception_lock(WASMModuleInstance *module_inst);
void
exception_unlock(WASMModuleInstance *module_inst);
#else
#define exception_lock(module_inst) (void)(module_inst)
#define exception_unlock(module_inst) (void)(module_inst)
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -531,7 +531,8 @@ pthread_start_routine(void *arg)
else { else {
info_node->u.ret = (void *)(uintptr_t)argv[0]; info_node->u.ret = (void *)(uintptr_t)argv[0];
#ifdef OS_ENABLE_HW_BOUND_CHECK #ifdef OS_ENABLE_HW_BOUND_CHECK
if (exec_env->suspend_flags.flags & 0x08) if (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags)
& WASM_SUSPEND_FLAG_EXIT)
/* argv[0] isn't set after longjmp(1) to /* argv[0] isn't set after longjmp(1) to
invoke_native_with_hw_bound_check */ invoke_native_with_hw_bound_check */
info_node->u.ret = exec_env->thread_ret_value; info_node->u.ret = exec_env->thread_ret_value;
@ -558,9 +559,6 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
uint32 thread_handle; uint32 thread_handle;
uint32 stack_size = 8192; uint32 stack_size = 8192;
int32 ret = -1; int32 ret = -1;
#if WASM_ENABLE_LIBC_WASI != 0
WASIContext *wasi_ctx;
#endif
bh_assert(module); bh_assert(module);
bh_assert(module_inst); bh_assert(module_inst);
@ -580,18 +578,14 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
#endif #endif
if (!(new_module_inst = wasm_runtime_instantiate_internal( if (!(new_module_inst = wasm_runtime_instantiate_internal(
module, true, exec_env, stack_size, 0, NULL, 0))) module, module_inst, exec_env, stack_size, 0, NULL, 0)))
return -1; return -1;
/* Set custom_data to new module instance */ /* Set custom_data to new module instance */
wasm_runtime_set_custom_data_internal( wasm_runtime_set_custom_data_internal(
new_module_inst, wasm_runtime_get_custom_data(module_inst)); new_module_inst, wasm_runtime_get_custom_data(module_inst));
#if WASM_ENABLE_LIBC_WASI != 0 wasm_native_inherit_contexts(new_module_inst, module_inst);
wasi_ctx = get_wasi_ctx(module_inst);
if (wasi_ctx)
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
#endif
if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst))) if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst)))
goto fail; goto fail;
@ -690,6 +684,14 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
bh_assert(node->joinable); bh_assert(node->joinable);
join_ret = 0; join_ret = 0;
ret = node->u.ret; ret = node->u.ret;
/* The target thread changes the node's status before calling
wasm_cluster_exit_thread to exit, so here its resources may
haven't been destroyed yet, we wait enough time to ensure that
they are actually destroyed to avoid unexpected behavior. */
os_mutex_lock(&exec_env->wait_lock);
os_cond_reltimedwait(&exec_env->wait_cond, &exec_env->wait_lock, 1000);
os_mutex_unlock(&exec_env->wait_lock);
} }
if (retval_offset != 0) if (retval_offset != 0)
@ -757,7 +759,6 @@ __pthread_self_wrapper(wasm_exec_env_t exec_env)
static void static void
pthread_exit_wrapper(wasm_exec_env_t exec_env, int32 retval_offset) pthread_exit_wrapper(wasm_exec_env_t exec_env, int32 retval_offset)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env);
ThreadRoutineArgs *args = get_thread_arg(exec_env); ThreadRoutineArgs *args = get_thread_arg(exec_env);
/* Currently exit main thread is not allowed */ /* Currently exit main thread is not allowed */
if (!args) if (!args)
@ -775,9 +776,6 @@ pthread_exit_wrapper(wasm_exec_env_t exec_env, int32 retval_offset)
/* destroy pthread key values */ /* destroy pthread key values */
call_key_destructor(exec_env); call_key_destructor(exec_env);
/* routine exit, destroy instance */
wasm_runtime_deinstantiate_internal(module_inst, true);
if (!args->info_node->joinable) { if (!args->info_node->joinable) {
delete_thread_info_node(args->info_node); delete_thread_info_node(args->info_node);
} }
@ -789,6 +787,8 @@ pthread_exit_wrapper(wasm_exec_env_t exec_env, int32 retval_offset)
wasm_runtime_free(args); wasm_runtime_free(args);
/* Don't destroy exec_env->module_inst in this functuntion since
it will be destroyed in wasm_cluster_exit_thread */
wasm_cluster_exit_thread(exec_env, (void *)(uintptr_t)retval_offset); wasm_cluster_exit_thread(exec_env, (void *)(uintptr_t)retval_offset);
} }

View File

@ -23,6 +23,7 @@ include(FetchContent)
set(RATS_BUILD_MODE "sgx" set(RATS_BUILD_MODE "sgx"
CACHE INTERNAL "Select build mode for librats(host|occlum|sgxwasm)") CACHE INTERNAL "Select build mode for librats(host|occlum|sgxwasm)")
set(RATS_INSTALL_PATH "${CMAKE_BINARY_DIR}/librats" CACHE INTERNAL "") set(RATS_INSTALL_PATH "${CMAKE_BINARY_DIR}/librats" CACHE INTERNAL "")
set(BUILD_SAMPLES OFF CACHE BOOL "Disable de compilation of the librats samples" FORCE)
FetchContent_Declare( FetchContent_Declare(
librats librats
@ -34,8 +35,17 @@ if (NOT librats_POPULATED)
message("-- Fetching librats ..") message("-- Fetching librats ..")
FetchContent_Populate(librats) FetchContent_Populate(librats)
include_directories("${librats_SOURCE_DIR}/include") include_directories("${librats_SOURCE_DIR}/include")
# Prevent the propagation of the CMAKE_C_FLAGS of WAMR into librats
set(SAVED_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_C_FLAGS "")
# Import the building scripts of librats
add_subdirectory(${librats_SOURCE_DIR} ${librats_BINARY_DIR} EXCLUDE_FROM_ALL) add_subdirectory(${librats_SOURCE_DIR} ${librats_BINARY_DIR} EXCLUDE_FROM_ALL)
# Restore the CMAKE_C_FLAGS of WAMR
set(CMAKE_C_FLAGS ${SAVED_CMAKE_C_FLAGS})
endif() endif()
file (GLOB source_all ${LIB_RATS_DIR}/*.c) file (GLOB source_all ${LIB_RATS_DIR}/*.c)

View File

@ -17,6 +17,8 @@ extern "C" {
#endif #endif
typedef enum { typedef enum {
/* Used only for sock_addr_resolve hints */
SOCKET_ANY = -1,
SOCKET_DGRAM = 0, SOCKET_DGRAM = 0,
SOCKET_STREAM, SOCKET_STREAM,
} __wasi_sock_type_t; } __wasi_sock_type_t;
@ -84,7 +86,7 @@ typedef struct __wasi_addr_t {
} addr; } addr;
} __wasi_addr_t; } __wasi_addr_t;
typedef enum { INET4 = 0, INET6 } __wasi_address_family_t; typedef enum { INET4 = 0, INET6, INET_UNSPEC } __wasi_address_family_t;
typedef struct __wasi_addr_info_t { typedef struct __wasi_addr_info_t {
__wasi_addr_t addr; __wasi_addr_t addr;

View File

@ -430,6 +430,9 @@ addrinfo_hints_to_wasi_hints(const struct addrinfo *hints,
case AF_INET6: case AF_INET6:
wasi_hints->family = INET6; wasi_hints->family = INET6;
break; break;
case AF_UNSPEC:
wasi_hints->family = INET_UNSPEC;
break;
default: default:
return __WASI_ERRNO_AFNOSUPPORT; return __WASI_ERRNO_AFNOSUPPORT;
} }
@ -440,6 +443,8 @@ addrinfo_hints_to_wasi_hints(const struct addrinfo *hints,
case SOCK_DGRAM: case SOCK_DGRAM:
wasi_hints->type = SOCKET_DGRAM; wasi_hints->type = SOCKET_DGRAM;
break; break;
case 0:
wasi_hints->type = SOCKET_ANY;
default: default:
return __WASI_ERRNO_NOTSUP; return __WASI_ERRNO_NOTSUP;
} }

View File

@ -5,6 +5,8 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include <pthread.h>
#ifdef __wasi__ #ifdef __wasi__
#include <wasi/api.h> #include <wasi/api.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -39,11 +41,28 @@ test_nslookup(int af)
freeaddrinfo(res); freeaddrinfo(res);
} }
void *
test_nslookup_mt(void *params)
{
int *af = (int *)params;
test_nslookup(*af);
return NULL;
}
int int
main() main()
{ {
test_nslookup(AF_INET); /* for ipv4 */ int afs[] = { AF_INET, AF_INET6 };
test_nslookup(AF_INET6); /* for ipv6 */
for (int i = 0; i < sizeof(afs) / sizeof(afs[0]); i++) {
pthread_t th;
printf("Testing %d in main thread...\n", afs[i]);
test_nslookup(afs[i]);
printf("Testing %d in a new thread...\n", afs[i]);
pthread_create(&th, NULL, test_nslookup_mt, &afs[i]);
pthread_join(th, NULL);
}
return 0; return 0;
} }

View File

@ -5,6 +5,8 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <errno.h>
#include <time.h>
#ifdef __wasi__ #ifdef __wasi__
#include <wasi/api.h> #include <wasi/api.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -12,105 +14,123 @@
#endif #endif
#include <arpa/inet.h> #include <arpa/inet.h>
#include <pthread.h> #include <pthread.h>
#include <stdio.h>
#define SERVER_MSG "Message from server." #define SERVER_MSG "Message from server."
#define PORT 8989 #define PORT 8989
pthread_mutex_t mut;
pthread_cond_t cond; pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int server_init_complete = 0; int server_init_complete = 0;
char buffer[sizeof(SERVER_MSG) + 1];
struct socket_info { typedef struct {
union { struct sockaddr_storage addr;
struct sockaddr_in addr_ipv4; socklen_t addr_len;
struct sockaddr_in6 addr_ipv6;
} addr;
int sock; int sock;
};
struct thread_args {
int family;
int protocol; int protocol;
}; } socket_info_t;
struct socket_info void
init_socket_addr(int family, int protocol) wait_for_server(int wait_time_seconds)
{ {
int sock = socket(family, protocol, 0); int res = 0;
assert(sock != -1); struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += wait_time_seconds;
struct socket_info info; pthread_mutex_lock(&mut);
if (family == AF_INET) { while (server_init_complete == 0) {
struct sockaddr_in addr; res = pthread_cond_timedwait(&cond, &mut, &ts);
memset(&addr, 0, sizeof(addr)); if (res == ETIMEDOUT)
addr.sin_family = AF_INET; break;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
info.addr.addr_ipv4 = addr;
} }
else if (family == AF_INET6) { pthread_mutex_unlock(&mut);
struct sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr)); assert(res == 0);
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(PORT);
addr.sin6_addr = in6addr_loopback;
info.addr.addr_ipv6 = addr;
}
info.sock = sock;
return info;
} }
void void
assert_thread_args(struct thread_args *args) notify_server_started()
{ {
assert(args->family == AF_INET || args->family == AF_INET6); pthread_mutex_lock(&mut);
assert(args->protocol == SOCK_STREAM || args->protocol == SOCK_DGRAM); server_init_complete = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mut);
}
socket_info_t
init_socket_addr(int family, int protocol)
{
socket_info_t info;
info.sock = socket(family, protocol, 0);
assert(info.sock != -1);
info.protocol = protocol;
memset(&info.addr, 0, sizeof(info.addr));
if (family == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *)&info.addr;
addr->sin_family = AF_INET;
addr->sin_port = htons(PORT);
addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
info.addr_len = sizeof(struct sockaddr_in);
}
else if (family == AF_INET6) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&info.addr;
addr->sin6_family = AF_INET6;
addr->sin6_port = htons(PORT);
addr->sin6_addr = in6addr_loopback;
info.addr_len = sizeof(struct sockaddr_in6);
}
return info;
} }
void * void *
server(void *arg) server(void *arg)
{ {
server_init_complete = 0; char buffer[sizeof(SERVER_MSG) + 1] = { 0 };
struct thread_args *args = (struct thread_args *)arg;
assert_thread_args(args);
struct socket_info init_server_sock =
init_socket_addr(args->family, args->protocol);
int server_sock = init_server_sock.sock;
socklen_t addr_size;
struct sockaddr_storage client_addr; struct sockaddr_storage client_addr;
strcpy(buffer, SERVER_MSG); socket_info_t *info = (socket_info_t *)arg;
struct sockaddr *server_addr = (struct sockaddr *)&info->addr;
int server_sock = info->sock;
struct sockaddr *server_addr = (struct sockaddr *)&init_server_sock.addr; int optval = 1;
int ret = bind(server_sock, server_addr, assert(setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &optval,
args->family == AF_INET ? sizeof(struct sockaddr_in) sizeof(optval))
: sizeof(struct sockaddr_in6)); == 0);
assert(ret == 0);
(args->protocol == SOCK_STREAM) && listen(server_sock, 1); assert(bind(server_sock, server_addr, info->addr_len) == 0);
pthread_mutex_lock(&mut);
server_init_complete = 1;
pthread_mutex_unlock(&mut);
pthread_cond_signal(&cond);
addr_size = sizeof(client_addr); if (info->protocol == SOCK_STREAM)
if (args->protocol == SOCK_STREAM) { listen(server_sock, 1);
notify_server_started();
socklen_t addr_size = info->addr_len;
if (info->protocol == SOCK_STREAM) {
int client_sock = int client_sock =
accept(server_sock, (struct sockaddr *)&client_addr, &addr_size); accept(server_sock, (struct sockaddr *)&client_addr, &addr_size);
assert(client_sock >= 0); assert(client_sock >= 0);
sendto(client_sock, buffer, strlen(buffer), 0, assert(recv(client_sock, buffer, sizeof(buffer), 0) > 0);
(struct sockaddr *)&client_addr, addr_size); strcpy(buffer, SERVER_MSG);
assert(send(client_sock, buffer, sizeof(buffer), 0) > 0);
assert(close(client_sock) == 0); assert(recv(client_sock, buffer, sizeof(buffer), 0) > 0);
} }
else { else {
recvfrom(server_sock, buffer, sizeof(buffer), 0, assert(recvfrom(server_sock, buffer, sizeof(buffer), 0,
(struct sockaddr *)&client_addr, &addr_size); (struct sockaddr *)&client_addr, &addr_size)
sendto(server_sock, buffer, strlen(buffer), 0, > 0);
(struct sockaddr *)&client_addr, addr_size); strcpy(buffer, SERVER_MSG);
assert(sendto(server_sock, buffer, strlen(buffer), 0,
assert(close(server_sock) == 0); (struct sockaddr *)&client_addr, addr_size)
> 0);
assert(recvfrom(server_sock, buffer, sizeof(buffer), 0,
(struct sockaddr *)&client_addr, &addr_size)
> 0);
} }
assert(close(server_sock) == 0);
return NULL; return NULL;
} }
@ -118,46 +138,23 @@ server(void *arg)
void * void *
client(void *arg) client(void *arg)
{ {
struct thread_args *args = (struct thread_args *)arg; char buffer[sizeof(SERVER_MSG) + 1];
assert_thread_args(args); socket_info_t *info = (socket_info_t *)arg;
int sock = info->sock;
struct sockaddr *addr = (struct sockaddr *)&info->addr;
pthread_mutex_lock(&mut); wait_for_server(1);
while (server_init_complete == 0) { if (info->protocol == SOCK_STREAM) {
pthread_cond_wait(&cond, &mut); assert(connect(sock, addr, info->addr_len) != -1);
} }
struct socket_info init_client_sock = assert(sendto(sock, "open", strlen("open"), 0, addr, info->addr_len) > 0);
init_socket_addr(args->family, args->protocol); assert(recv(sock, buffer, sizeof(buffer), 0) > 0);
int sock = init_client_sock.sock; assert(strncmp(buffer, SERVER_MSG, strlen(SERVER_MSG)) == 0);
pthread_mutex_unlock(&mut); assert(sendto(sock, "close", sizeof("close"), 0, addr, info->addr_len) > 0);
if (args->family == AF_INET) {
struct sockaddr_in addr = init_client_sock.addr.addr_ipv4;
if (args->protocol == SOCK_STREAM) {
assert(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != -1);
}
else {
assert(sendto(sock, buffer, strlen(buffer), 0,
(struct sockaddr *)&addr, sizeof(addr))
!= -1);
}
}
else {
struct sockaddr_in6 addr = init_client_sock.addr.addr_ipv6;
if (args->protocol == SOCK_STREAM) {
assert(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != -1);
}
else {
assert(sendto(sock, buffer, strlen(buffer), 0,
(struct sockaddr *)&addr, sizeof(addr))
!= -1);
}
}
recv(sock, buffer, sizeof(buffer), 0);
assert(strcmp(buffer, SERVER_MSG) == 0);
assert(close(sock) == 0); assert(close(sock) == 0);
return NULL; return NULL;
} }
@ -165,17 +162,19 @@ void
test_protocol(int family, int protocol) test_protocol(int family, int protocol)
{ {
pthread_t server_thread, client_thread; pthread_t server_thread, client_thread;
assert(pthread_cond_init(&cond, NULL) == 0); socket_info_t server_info = init_socket_addr(family, protocol);
assert(pthread_mutex_init(&mut, NULL) == 0); socket_info_t client_info = init_socket_addr(family, protocol);
struct thread_args args = { family, protocol }; printf("Testing address family: %d protocol: %d\n", family, protocol);
assert(pthread_create(&server_thread, NULL, server, (void *)&args) == 0);
assert(pthread_create(&client_thread, NULL, client, (void *)&args) == 0); server_init_complete = 0;
assert(pthread_create(&server_thread, NULL, server, (void *)&server_info)
== 0);
assert(pthread_create(&client_thread, NULL, client, (void *)&client_info)
== 0);
assert(pthread_join(server_thread, NULL) == 0); assert(pthread_join(server_thread, NULL) == 0);
assert(pthread_join(client_thread, NULL) == 0); assert(pthread_join(client_thread, NULL) == 0);
assert(pthread_mutex_destroy(&mut) == 0);
assert(pthread_cond_destroy(&cond) == 0);
} }
int int
@ -190,4 +189,4 @@ main(int argc, char **argv)
test_protocol(AF_INET6, SOCK_DGRAM); test_protocol(AF_INET6, SOCK_DGRAM);
return 0; return 0;
} }

View File

@ -80,9 +80,6 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
int32 thread_id; int32 thread_id;
uint32 stack_size = 8192; uint32 stack_size = 8192;
int32 ret = -1; int32 ret = -1;
#if WASM_ENABLE_LIBC_WASI != 0
WASIContext *wasi_ctx;
#endif
bh_assert(module); bh_assert(module);
bh_assert(module_inst); bh_assert(module_inst);
@ -90,7 +87,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
stack_size = ((WASMModuleInstance *)module_inst)->default_wasm_stack_size; stack_size = ((WASMModuleInstance *)module_inst)->default_wasm_stack_size;
if (!(new_module_inst = wasm_runtime_instantiate_internal( if (!(new_module_inst = wasm_runtime_instantiate_internal(
module, true, exec_env, stack_size, 0, NULL, 0))) module, module_inst, exec_env, stack_size, 0, NULL, 0)))
return -1; return -1;
wasm_runtime_set_custom_data_internal( wasm_runtime_set_custom_data_internal(
@ -99,11 +96,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst))) if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst)))
goto thread_preparation_fail; goto thread_preparation_fail;
#if WASM_ENABLE_LIBC_WASI != 0 wasm_native_inherit_contexts(new_module_inst, module_inst);
wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
if (wasi_ctx)
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
#endif
start_func = wasm_runtime_lookup_function(new_module_inst, start_func = wasm_runtime_lookup_function(new_module_inst,
THREAD_START_FUNCTION, NULL); THREAD_START_FUNCTION, NULL);

View File

@ -0,0 +1,65 @@
#!/bin/bash
#
# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
set -eo pipefail
CC=${CC:=/opt/wasi-sdk/bin/clang}
WAMR_DIR=../../../../..
show_usage() {
echo "Usage: $0 [--sysroot PATH_TO_SYSROOT]"
echo "--sysroot PATH_TO_SYSROOT specify to build with custom sysroot for wasi-libc"
}
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--sysroot)
sysroot_path="$2"
shift
shift
;;
--help)
show_usage
exit
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
rm -rf *.wasm
rm -rf *.aot
for test_c in *.c; do
test_wasm="$(basename $test_c .c).wasm"
if [[ -n "$sysroot_path" ]]; then
if [ ! -d "$sysroot_path" ]; then
echo "Directory $sysroot_path doesn't exist. Aborting"
exit 1
fi
sysroot_command="--sysroot $sysroot_path"
fi
echo "Compiling $test_c to $test_wasm"
$CC \
-target wasm32-wasi-threads \
-O2 \
-Wall \
-pthread \
-z stack-size=32768 \
-Wl,--export=__heap_base \
-Wl,--export=__data_end \
-Wl,--shared-memory,--max-memory=1966080 \
-Wl,--export=wasi_thread_start \
-Wl,--export=malloc \
-Wl,--export=free \
$sysroot_command \
$test_c -o $test_wasm
done

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <pthread.h>
#include <errno.h>
#include "mutex_common.h"
int
main()
{
pthread_mutex_t mutex;
// Set mutex type to errorcheck. This type provides some additional checks
// (for example returns EDEADLK instead of deadlocking in some cases)
pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex, &mutex_attr);
pthread_mutexattr_destroy(&mutex_attr);
run_common_tests(&mutex);
fprintf(stderr, "Errorcheck mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}

View File

@ -0,0 +1,3 @@
{
"name": "lib-wasi-threads stress tests"
}

View File

@ -0,0 +1,229 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef MUTEX_COMMON_H
#define MUTEX_COMMON_H
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <stdbool.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
enum Constants {
NUM_ITER = 250000,
NUM_THREADS = 12,
NUM_RETRY = 8,
RETRY_SLEEP_TIME_US = 1000,
};
// We're counting how many times each thread was called using this array
// Main thread is also counted here so we need to make arrays bigger
typedef struct {
int tids[NUM_THREADS + 1];
int calls[NUM_THREADS + 1];
} StatCollector;
typedef struct {
pthread_mutex_t *mutex;
StatCollector stat;
int counter;
bool is_sleeping;
} MutexCounter;
// This enum defines whether thread should sleep to increase contention
enum SleepState {
NON_SLEEP = 0,
SLEEP = 1,
};
void
mutex_counter_init(MutexCounter *mutex_counter, pthread_mutex_t *mutex,
enum SleepState is_sleeping)
{
memset(mutex_counter, 0, sizeof(*mutex_counter));
mutex_counter->mutex = mutex;
mutex_counter->is_sleeping = is_sleeping;
}
// This function spawns the thread using exponential retries if it receives
// EAGAIN
static inline void
spawn_thread(pthread_t *tid, void *func, void *arg)
{
int status_code = -1;
int timeout_us = RETRY_SLEEP_TIME_US;
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
status_code = pthread_create(tid, NULL, (void *(*)(void *))func, arg);
assert(status_code == 0 || status_code == EAGAIN);
if (status_code == EAGAIN) {
usleep(timeout_us);
timeout_us *= 2;
}
}
assert(status_code == 0 && "Thread creation should succeed");
}
// This function adds tid to our stat
static inline void
add_to_stat(StatCollector *stat, int tid)
{
int tid_num = 0;
for (; tid_num < NUM_THREADS + 1 && stat->tids[tid_num] != 0; ++tid_num) {
if (stat->tids[tid_num] == tid) {
stat->calls[tid_num]++;
return;
}
}
assert(tid_num < NUM_THREADS + 1);
stat->tids[tid_num] = tid;
stat->calls[tid_num] = 1;
}
// This function prints number of calls by TID
static inline void
print_stat(StatCollector *stat)
{
fprintf(stderr, "Thread calls count by TID\n");
for (int i = 0; i < NUM_THREADS + 1; ++i) {
if (stat->tids[i] != 0) {
fprintf(stderr, "TID: %d; Calls: %d\n", stat->tids[i],
stat->calls[i]);
}
}
}
// This function is run by the threads, it increases counter in a loop and then
// sleeps after unlocking the mutex to provide better contention
static inline void *
inc_shared_variable(void *arg)
{
MutexCounter *mutex_counter = (MutexCounter *)(arg);
int sleep_us = 0;
while (!pthread_mutex_lock(mutex_counter->mutex)
&& mutex_counter->counter < NUM_ITER) {
mutex_counter->counter++;
add_to_stat(&mutex_counter->stat, (int)(pthread_self()));
if (mutex_counter->is_sleeping) {
sleep_us = rand() % 1000;
}
assert(pthread_mutex_unlock(mutex_counter->mutex) == 0
&& "Should be able to unlock a mutex");
if (mutex_counter->is_sleeping) {
usleep(sleep_us);
}
}
assert(mutex_counter->counter == NUM_ITER);
assert(pthread_mutex_unlock(mutex_counter->mutex) == 0
&& "Should be able to unlock the mutex after test execution");
return NULL;
}
// Locking and unlocking a mutex in a single thread.
static inline void *
same_thread_lock_unlock_test(void *mutex)
{
for (int i = 0; i < NUM_ITER; ++i) {
assert(pthread_mutex_lock(mutex) == 0
&& "Main thread should be able to lock a mutex");
assert(pthread_mutex_unlock(mutex) == 0
&& "Main thread should be able to unlock a mutex");
}
return NULL;
}
// This function spawns a thread that locks and unlocks a mutex `NUM_ITER` times
// in a row
static inline void
same_non_main_thread_lock_unlock_test(pthread_mutex_t *mutex)
{
pthread_t tid = 0;
spawn_thread(&tid, same_thread_lock_unlock_test, mutex);
assert(tid != 0 && "TID can't be 0 after successful thread creation");
assert(pthread_join(tid, NULL) == 0
&& "Thread should be joined successfully");
}
// This function checks basic contention between main and non-main thread
// increasing the shared variable
static inline void
two_threads_inc_test(pthread_mutex_t *mutex)
{
MutexCounter mutex_counter;
mutex_counter_init(&mutex_counter, mutex, false);
pthread_t tid = 0;
spawn_thread(&tid, inc_shared_variable, &mutex_counter);
assert(tid != 0 && "TID can't be 0 after successful thread creation");
inc_shared_variable(&mutex_counter);
assert(pthread_join(tid, NULL) == 0
&& "Thread should be joined without errors");
assert(mutex_counter.counter == NUM_ITER);
}
// This function creates number of threads specified by NUM_THREADS and run
// concurrent increasing of shared variable
static inline void
max_threads_inc_test(pthread_mutex_t *mutex, int threads_num,
enum SleepState is_sleeping)
{
MutexCounter mutex_counter;
mutex_counter_init(&mutex_counter, mutex, is_sleeping);
pthread_t tids[threads_num];
for (int i = 0; i < threads_num; ++i) {
spawn_thread(&tids[i], inc_shared_variable, &mutex_counter);
}
inc_shared_variable(&mutex_counter);
for (int i = 0; i < threads_num; ++i) {
assert(pthread_join(tids[i], NULL) == 0
&& "Thread should be joined without errors");
}
print_stat(&mutex_counter.stat);
}
// This function just runs all the tests described above
static inline void
run_common_tests(pthread_mutex_t *mutex)
{
srand(time(NULL));
fprintf(stderr, "Starting same_thread_lock_unlock_test test\n");
same_thread_lock_unlock_test(mutex);
fprintf(stderr, "Finished same_thread_lock_unlock_test test\n");
fprintf(stderr, "Starting same_non_main_thread_lock_unlock_test test\n");
same_non_main_thread_lock_unlock_test(mutex);
fprintf(stderr, "Finished same_non_main_thread_lock_unlock_test test\n");
fprintf(stderr, "Starting two_threads_inc_test test\n");
two_threads_inc_test(mutex);
fprintf(stderr, "Finished two_threads_inc_test test\n");
fprintf(stderr, "Starting max_threads_inc_test_sleep test\n");
max_threads_inc_test(mutex, NUM_THREADS, SLEEP);
fprintf(stderr, "Finished concurrent_inc sleep test\n");
fprintf(stderr, "Starting max_threads_inc_test_non_sleep test\n");
max_threads_inc_test(mutex, NUM_THREADS, NON_SLEEP);
fprintf(stderr, "Finished max_threads_inc_test test\n");
}
#endif // MUTEX_COMMON_H

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <pthread.h>
#include <errno.h>
#include "mutex_common.h"
int
main()
{
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
run_common_tests(&mutex);
fprintf(stderr, "Normal mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <pthread.h>
#include <errno.h>
#include "mutex_common.h"
void
multiple_same_thread_lock(void *mutex)
{
for (int i = 0; i < 100; ++i) {
assert(pthread_mutex_lock(mutex) == 0
&& "Recursive mutex should allow multiple locking");
}
for (int i = 0; i < 100; ++i) {
assert(pthread_mutex_unlock(mutex) == 0
&& "Recursive mutex should allow multiple unlocking");
}
}
void *
same_thread_multiple_rec_mutex_lock(void *mutex)
{
for (int i = 0; i < NUM_ITER; ++i) {
multiple_same_thread_lock(mutex);
}
return NULL;
}
int
main()
{
pthread_mutex_t mutex;
// Set mutex type to recursive. This type allows multiple locking and
// unlocking within the same thread
pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &mutex_attr);
pthread_mutexattr_destroy(&mutex_attr);
run_common_tests(&mutex);
fprintf(stderr, "Starting same_thread_multiple_rec_mutex_lock test\n");
same_thread_multiple_rec_mutex_lock(&mutex);
fprintf(stderr, "Finished same_thread_multiple_rec_mutex_lock test\n");
fprintf(stderr, "Starting same_thread_multiple_rec_mutex_lock test in "
"non-main thread\n");
pthread_t tid;
spawn_thread(&tid, same_thread_multiple_rec_mutex_lock, &mutex);
assert(pthread_join(tid, NULL) == 0
&& "Non-main thread should be joined successfully");
fprintf(stderr, "Finished same_thread_multiple_rec_mutex_lock test in "
"non-main thread\n");
fprintf(stderr, "Recursive mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}

View File

@ -0,0 +1,117 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef __wasi__
#error This example only compiles to WASM/WASI target
#endif
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
enum CONSTANTS {
NUM_ITER = 100000,
NUM_RETRY = 8,
MAX_NUM_THREADS = 12,
RETRY_SLEEP_TIME_US = 2000,
};
unsigned prime_numbers_count = 0;
bool
is_prime(unsigned int num)
{
for (unsigned int i = 2; i <= (unsigned int)(sqrt(num)); ++i) {
if (num % i == 0) {
return false;
}
}
return true;
}
void *
check_if_prime(void *value)
{
unsigned int *num = (unsigned int *)(value);
usleep(10000);
if (is_prime(*num)) {
__atomic_fetch_add(&prime_numbers_count, 1, __ATOMIC_SEQ_CST);
}
return NULL;
}
unsigned int
validate()
{
unsigned int counter = 0;
for (unsigned int i = 2; i <= NUM_ITER; ++i) {
counter += is_prime(i);
}
return counter;
}
void
spawn_thread(pthread_t *thread, unsigned int *arg)
{
int status_code = -1;
int timeout_us = RETRY_SLEEP_TIME_US;
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
status_code = pthread_create(thread, NULL, &check_if_prime, arg);
assert(status_code == 0 || status_code == EAGAIN);
if (status_code == EAGAIN) {
usleep(timeout_us);
timeout_us *= 2;
}
}
assert(status_code == 0 && "Thread creation should succeed");
}
int
main(int argc, char **argv)
{
pthread_t threads[MAX_NUM_THREADS];
unsigned int args[MAX_NUM_THREADS];
double percentage = 0.1;
for (unsigned int factorised_number = 2; factorised_number < NUM_ITER;
++factorised_number) {
if (factorised_number > NUM_ITER * percentage) {
fprintf(stderr, "Stress test is %d%% finished\n",
(unsigned int)(percentage * 100));
percentage += 0.1;
}
unsigned int thread_num = factorised_number % MAX_NUM_THREADS;
if (threads[thread_num] != 0) {
assert(pthread_join(threads[thread_num], NULL) == 0);
}
args[thread_num] = factorised_number;
usleep(RETRY_SLEEP_TIME_US);
spawn_thread(&threads[thread_num], &args[thread_num]);
assert(threads[thread_num] != 0);
}
for (int i = 0; i < MAX_NUM_THREADS; ++i) {
assert(threads[i] == 0 || pthread_join(threads[i], NULL) == 0);
}
// Check the test results
assert(
prime_numbers_count == validate()
&& "Answer mismatch between tested code and reference implementation");
fprintf(stderr, "Stress test finished successfully\n");
return 0;
}

View File

@ -0,0 +1,95 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
enum CONSTANTS {
NUM_ITER = 200000,
NUM_RETRY = 8,
MAX_NUM_THREADS = 12,
RETRY_SLEEP_TIME_US = 4000,
SECOND = 1000 * 1000 * 1000
};
int threads_executed = 0;
unsigned int threads_creation_tried = 0;
unsigned int threads_in_use = 0;
void *
thread_func(void *arg)
{
(void)(arg);
__atomic_fetch_add(&threads_executed, 1, __ATOMIC_RELAXED);
__atomic_fetch_sub(&threads_in_use, 1, __ATOMIC_SEQ_CST);
return NULL;
}
void
spawn_thread(pthread_t *thread)
{
int status_code = -1;
int timeout_us = RETRY_SLEEP_TIME_US;
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
status_code = pthread_create(thread, NULL, &thread_func, NULL);
__atomic_fetch_add(&threads_creation_tried, 1, __ATOMIC_RELAXED);
assert(status_code == 0 || status_code == EAGAIN);
if (status_code == EAGAIN) {
usleep(timeout_us);
timeout_us *= 2;
}
}
assert(status_code == 0 && "Thread creation should succeed");
}
int
main(int argc, char **argv)
{
double percentage = 0.1;
for (int iter = 0; iter < NUM_ITER; ++iter) {
if (iter > NUM_ITER * percentage) {
fprintf(stderr, "Spawning stress test is %d%% finished\n",
(unsigned int)(percentage * 100));
percentage += 0.1;
}
while (__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST)
== MAX_NUM_THREADS) {
usleep(100);
}
__atomic_fetch_add(&threads_in_use, 1, __ATOMIC_SEQ_CST);
pthread_t tmp;
spawn_thread(&tmp);
pthread_detach(tmp);
}
while ((__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) != 0)) {
// Casting to int* to supress compiler warning
__builtin_wasm_memory_atomic_wait32((int *)(&threads_in_use), 0,
SECOND);
}
assert(__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) == 0);
// Validation
assert(threads_creation_tried >= threads_executed
&& "Test executed more threads than were created");
assert((1. * threads_creation_tried) / threads_executed < 2.5
&& "Ensuring that we're retrying thread creation less than 2.5 "
"times on average ");
fprintf(stderr,
"Spawning stress test finished successfully executed %d threads "
"with retry ratio %f\n",
threads_creation_tried,
(1. * threads_creation_tried) / threads_executed);
return 0;
}

View File

@ -9,18 +9,57 @@ set -eo pipefail
CC=${CC:=/opt/wasi-sdk/bin/clang} CC=${CC:=/opt/wasi-sdk/bin/clang}
WAMR_DIR=../../../../.. WAMR_DIR=../../../../..
show_usage() {
echo "Usage: $0 [--sysroot PATH_TO_SYSROOT]"
echo "--sysroot PATH_TO_SYSROOT specify to build with custom sysroot for wasi-libc"
}
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--sysroot)
sysroot_path="$2"
shift
shift
;;
--help)
show_usage
exit
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Stress tests names
thread_start_file_exclusions=("linear_memory_size_update.wasm")
rm -rf *.wasm
rm -rf *.aot
for test_c in *.c; do for test_c in *.c; do
test_wasm="$(basename $test_c .c).wasm" test_wasm="$(basename $test_c .c).wasm"
if [ $test_wasm = "linear_memory_size_update.wasm" ]; then if [[ " ${thread_start_file_exclusions[@]} " =~ " ${test_wasm} " ]] ; then
thread_start_file="" thread_start_file=""
else else
thread_start_file=$WAMR_DIR/samples/wasi-threads/wasm-apps/wasi_thread_start.S thread_start_file=$WAMR_DIR/samples/wasi-threads/wasm-apps/wasi_thread_start.S
fi fi
if [[ -n "$sysroot_path" ]]; then
if [ ! -d "$sysroot_path" ]; then
echo "Directory $sysroot_path doesn't exist. Aborting"
exit 1
fi
sysroot_command="--sysroot $sysroot_path"
fi
echo "Compiling $test_c to $test_wasm" echo "Compiling $test_c to $test_wasm"
$CC \ $CC \
-target wasm32-wasi-threads \ -target wasm32-wasi-threads \
-O2 \
-pthread -ftls-model=local-exec \ -pthread -ftls-model=local-exec \
-z stack-size=32768 \ -z stack-size=32768 \
-Wl,--export=__heap_base \ -Wl,--export=__heap_base \
@ -30,6 +69,7 @@ for test_c in *.c; do
-Wl,--export=malloc \ -Wl,--export=malloc \
-Wl,--export=free \ -Wl,--export=free \
-I $WAMR_DIR/samples/wasi-threads/wasm-apps \ -I $WAMR_DIR/samples/wasi-threads/wasm-apps \
$sysroot_command \
$thread_start_file \ $thread_start_file \
$test_c -o $test_wasm $test_c -o $test_wasm
done done

View File

@ -65,7 +65,7 @@ main(int argc, char **argv)
assert(start_args_init(&data[i].base)); assert(start_args_init(&data[i].base));
thread_ids[i] = __wasi_thread_spawn(&data[i]); thread_ids[i] = __wasi_thread_spawn(&data[i]);
printf("Thread created with id=%d\n", thread_ids[i]); printf("Thread created with id=%d\n", thread_ids[i]);
assert(thread_ids[i] > 0 && "Thread creation failed"); ASSERT_VALID_TID(thread_ids[i]);
for (int j = 0; j < i; j++) { for (int j = 0; j < i; j++) {
assert(thread_ids[i] != thread_ids[j] && "Duplicated TIDs"); assert(thread_ids[i] != thread_ids[j] && "Duplicated TIDs");

View File

@ -49,7 +49,7 @@ main(int argc, char **argv)
for (int i = 0; i < NUM_THREADS; i++) { for (int i = 0; i < NUM_THREADS; i++) {
assert(start_args_init(&data[i].base)); assert(start_args_init(&data[i].base));
thread_ids[i] = __wasi_thread_spawn(&data[i]); thread_ids[i] = __wasi_thread_spawn(&data[i]);
assert(thread_ids[i] > 0 && "Thread creation failed"); ASSERT_VALID_TID(thread_ids[i]);
} }
printf("Wait for threads to finish\n"); printf("Wait for threads to finish\n");

View File

@ -61,7 +61,7 @@ main(int argc, char **argv)
for (int i = 0; i < NUM_THREADS; i++) { for (int i = 0; i < NUM_THREADS; i++) {
assert(start_args_init(&data[i].base)); assert(start_args_init(&data[i].base));
thread_ids[i] = __wasi_thread_spawn(&data[i]); thread_ids[i] = __wasi_thread_spawn(&data[i]);
assert(thread_ids[i] > 0 && "Thread creation failed"); ASSERT_VALID_TID(thread_ids[i]);
} }
printf("Wait for threads to finish\n"); printf("Wait for threads to finish\n");

View File

@ -0,0 +1,3 @@
{
"name": "lib-wasi-threads tests"
}

View File

@ -38,7 +38,7 @@ main(int argc, char **argv)
assert(start_args_init(&data.base)); assert(start_args_init(&data.base));
int thread_id = __wasi_thread_spawn(&data); int thread_id = __wasi_thread_spawn(&data);
assert(thread_id > 0 && "Thread creation failed"); ASSERT_VALID_TID(thread_id);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -69,7 +69,7 @@ main(int argc, char **argv)
data[i].iteration = i; data[i].iteration = i;
thread_ids[i] = __wasi_thread_spawn(&data[i]); thread_ids[i] = __wasi_thread_spawn(&data[i]);
assert(thread_ids[i] > 0 && "Thread creation failed"); ASSERT_VALID_TID(thread_ids[i]);
} }
printf("Wait for threads to finish\n"); printf("Wait for threads to finish\n");

View File

@ -21,7 +21,8 @@ tid_allocator_init(TidAllocator *tid_allocator)
return false; return false;
for (int64 i = tid_allocator->pos - 1; i >= 0; i--) for (int64 i = tid_allocator->pos - 1; i >= 0; i--)
tid_allocator->ids[i] = TID_MIN + (tid_allocator->pos - 1 - i); tid_allocator->ids[i] =
(uint32)(TID_MIN + (tid_allocator->pos - 1 - i));
return true; return true;
} }
@ -54,7 +55,8 @@ tid_allocator_get_tid(TidAllocator *tid_allocator)
LOG_ERROR("Overflow detected during realloc"); LOG_ERROR("Overflow detected during realloc");
return -1; return -1;
} }
int32 *tmp = wasm_runtime_realloc(tid_allocator->ids, realloc_size); int32 *tmp =
wasm_runtime_realloc(tid_allocator->ids, (uint32)realloc_size);
if (tmp == NULL) { if (tmp == NULL) {
LOG_ERROR("Thread ID allocator realloc failed"); LOG_ERROR("Thread ID allocator realloc failed");
return -1; return -1;
@ -64,7 +66,8 @@ tid_allocator_get_tid(TidAllocator *tid_allocator)
tid_allocator->pos = new_size - old_size; tid_allocator->pos = new_size - old_size;
tid_allocator->ids = tmp; tid_allocator->ids = tmp;
for (int64 i = tid_allocator->pos - 1; i >= 0; i--) for (int64 i = tid_allocator->pos - 1; i >= 0; i--)
tid_allocator->ids[i] = TID_MIN + (tid_allocator->size - 1 - i); tid_allocator->ids[i] =
(uint32)(TID_MIN + (tid_allocator->size - 1 - i));
} }
// Pop available thread identifier from the stack // Pop available thread identifier from the stack
@ -77,4 +80,4 @@ tid_allocator_release_tid(TidAllocator *tid_allocator, int32 thread_id)
// Release thread identifier by pushing it into the stack // Release thread identifier by pushing it into the stack
bh_assert(tid_allocator->pos < tid_allocator->size); bh_assert(tid_allocator->pos < tid_allocator->size);
tid_allocator->ids[tid_allocator->pos++] = thread_id; tid_allocator->ids[tid_allocator->pos++] = thread_id;
} }

View File

@ -8,8 +8,14 @@
#include "platform_common.h" #include "platform_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TID_ALLOCATOR_INIT_SIZE CLUSTER_MAX_THREAD_NUM #define TID_ALLOCATOR_INIT_SIZE CLUSTER_MAX_THREAD_NUM
enum { enum {
/* Keep it in sync with
https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids */
TID_MIN = 1, TID_MIN = 1,
TID_MAX = 0x1FFFFFFF TID_MAX = 0x1FFFFFFF
}; // Reserved TIDs (WASI specification) }; // Reserved TIDs (WASI specification)
@ -33,4 +39,8 @@ tid_allocator_get_tid(TidAllocator *tid_allocator);
void void
tid_allocator_release_tid(TidAllocator *tid_allocator, int32 thread_id); tid_allocator_release_tid(TidAllocator *tid_allocator, int32 thread_id);
#ifdef __cplusplus
}
#endif
#endif /* _TID_ALLOCATOR_H */ #endif /* _TID_ALLOCATOR_H */

View File

@ -0,0 +1,6 @@
# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
create_wamr_unit_test(wasi_threads
${CMAKE_CURRENT_LIST_DIR}/test_tid_allocator.cpp
)

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <gtest/gtest.h>
#include "tid_allocator.h"
#include <stdint.h>
class TidAllocatorTest : public ::testing::Test
{
protected:
void SetUp() override { ASSERT_TRUE(tid_allocator_init(&_allocator)); }
void TearDown() override { tid_allocator_deinit(&_allocator); }
TidAllocator _allocator;
};
static bool
is_tid_valid(int32 tid)
{
/* See: https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids
*/
return tid >= TID_MIN && tid <= TID_MAX;
}
TEST_F(TidAllocatorTest, BasicTest)
{
int32 tid = tid_allocator_get_tid(&_allocator);
ASSERT_TRUE(is_tid_valid(tid));
}
TEST_F(TidAllocatorTest, ShouldFailOnAllocatingMoreThanAllowedThreadIDs)
{
int32 last_tid = 0;
for (int32 i = 0; i < TID_MAX + 1; i++) {
last_tid = tid_allocator_get_tid(&_allocator);
if (last_tid < 0) {
break;
}
ASSERT_TRUE(is_tid_valid(last_tid));
}
ASSERT_LT(last_tid, 0);
}
TEST_F(TidAllocatorTest, ShouldAllocateMoreThanAllowedTIDsIfOldTIDsAreReleased)
{
int32 last_tid = 0;
for (int32 i = 0; i < TID_MAX + 1; i++) {
if (last_tid != 0) {
tid_allocator_release_tid(&_allocator, last_tid);
}
last_tid = tid_allocator_get_tid(&_allocator);
ASSERT_TRUE(is_tid_valid(last_tid));
}
}

View File

@ -3,7 +3,7 @@
set (LIBC_WASI_DIR ${CMAKE_CURRENT_LIST_DIR}) set (LIBC_WASI_DIR ${CMAKE_CURRENT_LIST_DIR})
set (LIBUV_VERSION v1.44.2) set (LIBUV_VERSION v1.46.0)
add_definitions (-DWASM_ENABLE_LIBC_WASI=1 -DWASM_ENABLE_UVWASI=1) add_definitions (-DWASM_ENABLE_LIBC_WASI=1 -DWASM_ENABLE_UVWASI=1)

View File

@ -335,7 +335,7 @@ wasi_fd_close(wasm_exec_env_t exec_env, wasi_fd_t fd)
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_close(curfds, prestats, fd); return wasmtime_ssp_fd_close(exec_env, curfds, prestats, fd);
} }
static wasi_errno_t static wasi_errno_t
@ -348,7 +348,7 @@ wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd)
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_datasync(curfds, fd); return wasmtime_ssp_fd_datasync(exec_env, curfds, fd);
} }
static wasi_errno_t static wasi_errno_t
@ -389,8 +389,8 @@ wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
iovec->buf_len = iovec_app->buf_len; iovec->buf_len = iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, iovs_len, offset, err = wasmtime_ssp_fd_pread(exec_env, curfds, fd, iovec_begin, iovs_len,
&nread); offset, &nread);
if (err) if (err)
goto fail; goto fail;
@ -443,8 +443,8 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec->buf_len = iovec_app->buf_len; ciovec->buf_len = iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, iovs_len, offset, err = wasmtime_ssp_fd_pwrite(exec_env, curfds, fd, ciovec_begin, iovs_len,
&nwritten); offset, &nwritten);
if (err) if (err)
goto fail; goto fail;
@ -496,7 +496,8 @@ wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
iovec->buf_len = iovec_app->buf_len; iovec->buf_len = iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread); err = wasmtime_ssp_fd_read(exec_env, curfds, fd, iovec_begin, iovs_len,
&nread);
if (err) if (err)
goto fail; goto fail;
@ -521,7 +522,7 @@ wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to)
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_renumber(curfds, prestats, from, to); return wasmtime_ssp_fd_renumber(exec_env, curfds, prestats, from, to);
} }
static wasi_errno_t static wasi_errno_t
@ -538,7 +539,8 @@ wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t))) if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_seek(curfds, fd, offset, whence, newoffset); return wasmtime_ssp_fd_seek(exec_env, curfds, fd, offset, whence,
newoffset);
} }
static wasi_errno_t static wasi_errno_t
@ -554,7 +556,7 @@ wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t))) if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_tell(curfds, fd, newoffset); return wasmtime_ssp_fd_tell(exec_env, curfds, fd, newoffset);
} }
static wasi_errno_t static wasi_errno_t
@ -573,7 +575,7 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t))) if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_fdstat_get(curfds, fd, &fdstat); err = wasmtime_ssp_fd_fdstat_get(exec_env, curfds, fd, &fdstat);
if (err) if (err)
return err; return err;
@ -592,7 +594,7 @@ wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_fdstat_set_flags(curfds, fd, flags); return wasmtime_ssp_fd_fdstat_set_flags(exec_env, curfds, fd, flags);
} }
static wasi_errno_t static wasi_errno_t
@ -607,8 +609,8 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd, fs_rights_base, return wasmtime_ssp_fd_fdstat_set_rights(
fs_rights_inheriting); exec_env, curfds, fd, fs_rights_base, fs_rights_inheriting);
} }
static wasi_errno_t static wasi_errno_t
@ -621,7 +623,7 @@ wasi_fd_sync(wasm_exec_env_t exec_env, wasi_fd_t fd)
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_sync(curfds, fd); return wasmtime_ssp_fd_sync(exec_env, curfds, fd);
} }
static wasi_errno_t static wasi_errno_t
@ -663,7 +665,8 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec->buf_len = iovec_app->buf_len; ciovec->buf_len = iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten); err = wasmtime_ssp_fd_write(exec_env, curfds, fd, ciovec_begin, iovs_len,
&nwritten);
if (err) if (err)
goto fail; goto fail;
@ -688,7 +691,7 @@ wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_advise(curfds, fd, offset, len, advice); return wasmtime_ssp_fd_advise(exec_env, curfds, fd, offset, len, advice);
} }
static wasi_errno_t static wasi_errno_t
@ -702,7 +705,7 @@ wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_allocate(curfds, fd, offset, len); return wasmtime_ssp_fd_allocate(exec_env, curfds, fd, offset, len);
} }
static wasi_errno_t static wasi_errno_t
@ -716,7 +719,8 @@ wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_create_directory(curfds, fd, path, path_len); return wasmtime_ssp_path_create_directory(exec_env, curfds, fd, path,
path_len);
} }
static wasi_errno_t static wasi_errno_t
@ -733,8 +737,9 @@ wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, old_path, return wasmtime_ssp_path_link(exec_env, curfds, prestats, old_fd, old_flags,
old_path_len, new_fd, new_path, new_path_len); old_path, old_path_len, new_fd, new_path,
new_path_len);
} }
static wasi_errno_t static wasi_errno_t
@ -756,9 +761,9 @@ wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
if (!validate_native_addr(fd_app, sizeof(wasi_fd_t))) if (!validate_native_addr(fd_app, sizeof(wasi_fd_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_path_open(curfds, dirfd, dirflags, path, path_len, err = wasmtime_ssp_path_open(exec_env, curfds, dirfd, dirflags, path,
oflags, fs_rights_base, fs_rights_inheriting, path_len, oflags, fs_rights_base,
fs_flags, &fd); fs_rights_inheriting, fs_flags, &fd);
*fd_app = fd; *fd_app = fd;
return err; return err;
@ -780,7 +785,8 @@ wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
if (!validate_native_addr(bufused_app, sizeof(uint32))) if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_readdir(curfds, fd, buf, buf_len, cookie, &bufused); err = wasmtime_ssp_fd_readdir(exec_env, curfds, fd, buf, buf_len, cookie,
&bufused);
if (err) if (err)
return err; return err;
@ -805,8 +811,8 @@ wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
if (!validate_native_addr(bufused_app, sizeof(uint32))) if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_path_readlink(curfds, fd, path, path_len, buf, buf_len, err = wasmtime_ssp_path_readlink(exec_env, curfds, fd, path, path_len, buf,
&bufused); buf_len, &bufused);
if (err) if (err)
return err; return err;
@ -826,8 +832,9 @@ wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_rename(curfds, old_fd, old_path, old_path_len, return wasmtime_ssp_path_rename(exec_env, curfds, old_fd, old_path,
new_fd, new_path, new_path_len); old_path_len, new_fd, new_path,
new_path_len);
} }
static wasi_errno_t static wasi_errno_t
@ -844,7 +851,7 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t))) if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_get(curfds, fd, filestat); return wasmtime_ssp_fd_filestat_get(exec_env, curfds, fd, filestat);
} }
static wasi_errno_t static wasi_errno_t
@ -859,8 +866,8 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_set_times(curfds, fd, st_atim, st_mtim, return wasmtime_ssp_fd_filestat_set_times(exec_env, curfds, fd, st_atim,
fstflags); st_mtim, fstflags);
} }
static wasi_errno_t static wasi_errno_t
@ -874,7 +881,7 @@ wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_set_size(curfds, fd, st_size); return wasmtime_ssp_fd_filestat_set_size(exec_env, curfds, fd, st_size);
} }
static wasi_errno_t static wasi_errno_t
@ -892,8 +899,8 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t))) if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_get(curfds, fd, flags, path, path_len, return wasmtime_ssp_path_filestat_get(exec_env, curfds, fd, flags, path,
filestat); path_len, filestat);
} }
static wasi_errno_t static wasi_errno_t
@ -909,8 +916,9 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_set_times( return wasmtime_ssp_path_filestat_set_times(exec_env, curfds, fd, flags,
curfds, fd, flags, path, path_len, st_atim, st_mtim, fstflags); path, path_len, st_atim,
st_mtim, fstflags);
} }
static wasi_errno_t static wasi_errno_t
@ -926,8 +934,8 @@ wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_symlink(curfds, prestats, old_path, old_path_len, return wasmtime_ssp_path_symlink(exec_env, curfds, prestats, old_path,
fd, new_path, new_path_len); old_path_len, fd, new_path, new_path_len);
} }
static wasi_errno_t static wasi_errno_t
@ -941,7 +949,7 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_unlink_file(curfds, fd, path, path_len); return wasmtime_ssp_path_unlink_file(exec_env, curfds, fd, path, path_len);
} }
static wasi_errno_t static wasi_errno_t
@ -955,7 +963,8 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len); return wasmtime_ssp_path_remove_directory(exec_env, curfds, fd, path,
path_len);
} }
#if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_THREAD_MGR != 0
@ -1026,8 +1035,8 @@ execute_interruptible_poll_oneoff(
/* update timeout for clock subscription events */ /* update timeout for clock subscription events */
update_clock_subscription_data( update_clock_subscription_data(
in_copy, nsubscriptions, min_uint64(time_quant, timeout - elapsed)); in_copy, nsubscriptions, min_uint64(time_quant, timeout - elapsed));
err = wasmtime_ssp_poll_oneoff(curfds, in_copy, out, nsubscriptions, err = wasmtime_ssp_poll_oneoff(exec_env, curfds, in_copy, out,
nevents); nsubscriptions, nevents);
elapsed += time_quant; elapsed += time_quant;
if (err) { if (err) {
@ -1079,7 +1088,8 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
#if WASM_ENABLE_THREAD_MGR == 0 #if WASM_ENABLE_THREAD_MGR == 0
err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents); err = wasmtime_ssp_poll_oneoff(exec_env, curfds, in, out, nsubscriptions,
&nevents);
#else #else
err = execute_interruptible_poll_oneoff(curfds, in, out, nsubscriptions, err = execute_interruptible_poll_oneoff(curfds, in, out, nsubscriptions,
&nevents, exec_env); &nevents, exec_env);
@ -1133,7 +1143,7 @@ wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fdflags_t flags,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_accept(curfds, fd, flags, fd_new); return wasi_ssp_sock_accept(exec_env, curfds, fd, flags, fd_new);
} }
static wasi_errno_t static wasi_errno_t
@ -1152,7 +1162,7 @@ wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_addr_local(curfds, fd, addr); return wasi_ssp_sock_addr_local(exec_env, curfds, fd, addr);
} }
static wasi_errno_t static wasi_errno_t
@ -1171,7 +1181,7 @@ wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_addr_remote(curfds, fd, addr); return wasi_ssp_sock_addr_remote(exec_env, curfds, fd, addr);
} }
static wasi_errno_t static wasi_errno_t
@ -1192,8 +1202,8 @@ wasi_sock_addr_resolve(wasm_exec_env_t exec_env, const char *host,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
ns_lookup_list = wasi_ctx_get_ns_lookup_list(wasi_ctx); ns_lookup_list = wasi_ctx_get_ns_lookup_list(wasi_ctx);
return wasi_ssp_sock_addr_resolve(curfds, ns_lookup_list, host, service, return wasi_ssp_sock_addr_resolve(exec_env, curfds, ns_lookup_list, host,
hints, addr_info, addr_info_size, service, hints, addr_info, addr_info_size,
max_info_size); max_info_size);
} }
@ -1211,7 +1221,7 @@ wasi_sock_bind(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx); addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
return wasi_ssp_sock_bind(curfds, addr_pool, fd, addr); return wasi_ssp_sock_bind(exec_env, curfds, addr_pool, fd, addr);
} }
static wasi_errno_t static wasi_errno_t
@ -1234,7 +1244,7 @@ wasi_sock_connect(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx); addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
return wasi_ssp_sock_connect(curfds, addr_pool, fd, addr); return wasi_ssp_sock_connect(exec_env, curfds, addr_pool, fd, addr);
} }
static wasi_errno_t static wasi_errno_t
@ -1253,7 +1263,7 @@ wasi_sock_get_broadcast(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_broadcast(curfds, fd, is_enabled); return wasmtime_ssp_sock_get_broadcast(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1272,7 +1282,7 @@ wasi_sock_get_keep_alive(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_keep_alive(curfds, fd, is_enabled); return wasmtime_ssp_sock_get_keep_alive(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1292,7 +1302,8 @@ wasi_sock_get_linger(wasm_exec_env_t exec_env, wasi_fd_t fd, bool *is_enabled,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_linger(curfds, fd, is_enabled, linger_s); return wasmtime_ssp_sock_get_linger(exec_env, curfds, fd, is_enabled,
linger_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1311,7 +1322,7 @@ wasi_sock_get_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_recv_buf_size(curfds, fd, size); return wasmtime_ssp_sock_get_recv_buf_size(exec_env, curfds, fd, size);
} }
static wasi_errno_t static wasi_errno_t
@ -1330,7 +1341,7 @@ wasi_sock_get_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_recv_timeout(curfds, fd, timeout_us); return wasmtime_ssp_sock_get_recv_timeout(exec_env, curfds, fd, timeout_us);
} }
static wasi_errno_t static wasi_errno_t
@ -1349,7 +1360,7 @@ wasi_sock_get_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_reuse_addr(curfds, fd, is_enabled); return wasmtime_ssp_sock_get_reuse_addr(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1368,7 +1379,7 @@ wasi_sock_get_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_reuse_port(curfds, fd, is_enabled); return wasmtime_ssp_sock_get_reuse_port(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1387,7 +1398,7 @@ wasi_sock_get_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_send_buf_size(curfds, fd, size); return wasmtime_ssp_sock_get_send_buf_size(exec_env, curfds, fd, size);
} }
static wasi_errno_t static wasi_errno_t
@ -1406,7 +1417,7 @@ wasi_sock_get_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_send_timeout(curfds, fd, timeout_us); return wasmtime_ssp_sock_get_send_timeout(exec_env, curfds, fd, timeout_us);
} }
static wasi_errno_t static wasi_errno_t
@ -1425,7 +1436,8 @@ wasi_sock_get_tcp_fastopen_connect(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_fastopen_connect(curfds, fd, is_enabled); return wasmtime_ssp_sock_get_tcp_fastopen_connect(exec_env, curfds, fd,
is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1444,7 +1456,7 @@ wasi_sock_get_tcp_no_delay(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_no_delay(curfds, fd, is_enabled); return wasmtime_ssp_sock_get_tcp_no_delay(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1463,7 +1475,8 @@ wasi_sock_get_tcp_quick_ack(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_quick_ack(curfds, fd, is_enabled); return wasmtime_ssp_sock_get_tcp_quick_ack(exec_env, curfds, fd,
is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1482,7 +1495,7 @@ wasi_sock_get_tcp_keep_idle(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_keep_idle(curfds, fd, time_s); return wasmtime_ssp_sock_get_tcp_keep_idle(exec_env, curfds, fd, time_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1501,7 +1514,7 @@ wasi_sock_get_tcp_keep_intvl(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_keep_intvl(curfds, fd, time_s); return wasmtime_ssp_sock_get_tcp_keep_intvl(exec_env, curfds, fd, time_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1520,7 +1533,7 @@ wasi_sock_get_ip_multicast_loop(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_ip_multicast_loop(curfds, fd, ipv6, return wasmtime_ssp_sock_get_ip_multicast_loop(exec_env, curfds, fd, ipv6,
is_enabled); is_enabled);
} }
@ -1539,7 +1552,7 @@ wasi_sock_get_ip_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8_t *ttl_s)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_ip_ttl(curfds, fd, ttl_s); return wasmtime_ssp_sock_get_ip_ttl(exec_env, curfds, fd, ttl_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1558,7 +1571,7 @@ wasi_sock_get_ip_multicast_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_ip_multicast_ttl(curfds, fd, ttl_s); return wasmtime_ssp_sock_get_ip_multicast_ttl(exec_env, curfds, fd, ttl_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1577,7 +1590,7 @@ wasi_sock_get_ipv6_only(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_ipv6_only(curfds, fd, is_enabled); return wasmtime_ssp_sock_get_ipv6_only(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1592,7 +1605,7 @@ wasi_sock_listen(wasm_exec_env_t exec_env, wasi_fd_t fd, uint32 backlog)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_listen(curfds, fd, backlog); return wasi_ssp_sock_listen(exec_env, curfds, fd, backlog);
} }
static wasi_errno_t static wasi_errno_t
@ -1609,7 +1622,7 @@ wasi_sock_open(wasm_exec_env_t exec_env, wasi_fd_t poolfd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_open(curfds, poolfd, af, socktype, sockfd); return wasi_ssp_sock_open(exec_env, curfds, poolfd, af, socktype, sockfd);
} }
static wasi_errno_t static wasi_errno_t
@ -1624,7 +1637,7 @@ wasi_sock_set_broadcast(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_broadcast(curfds, fd, is_enabled); return wasmtime_ssp_sock_set_broadcast(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1640,7 +1653,7 @@ wasi_sock_set_keep_alive(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_keep_alive(curfds, fd, is_enabled); return wasmtime_ssp_sock_set_keep_alive(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1656,7 +1669,8 @@ wasi_sock_set_linger(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_linger(curfds, fd, is_enabled, linger_s); return wasmtime_ssp_sock_set_linger(exec_env, curfds, fd, is_enabled,
linger_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1671,7 +1685,7 @@ wasi_sock_set_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, size_t size)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_recv_buf_size(curfds, fd, size); return wasmtime_ssp_sock_set_recv_buf_size(exec_env, curfds, fd, size);
} }
static wasi_errno_t static wasi_errno_t
@ -1687,7 +1701,7 @@ wasi_sock_set_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_recv_timeout(curfds, fd, timeout_us); return wasmtime_ssp_sock_set_recv_timeout(exec_env, curfds, fd, timeout_us);
} }
static wasi_errno_t static wasi_errno_t
@ -1703,7 +1717,7 @@ wasi_sock_set_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_reuse_addr(curfds, fd, is_enabled); return wasmtime_ssp_sock_set_reuse_addr(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1719,7 +1733,7 @@ wasi_sock_set_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_reuse_port(curfds, fd, is_enabled); return wasmtime_ssp_sock_set_reuse_port(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1734,7 +1748,7 @@ wasi_sock_set_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, size_t size)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_send_buf_size(curfds, fd, size); return wasmtime_ssp_sock_set_send_buf_size(exec_env, curfds, fd, size);
} }
static wasi_errno_t static wasi_errno_t
@ -1750,7 +1764,7 @@ wasi_sock_set_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_send_timeout(curfds, fd, timeout_us); return wasmtime_ssp_sock_set_send_timeout(exec_env, curfds, fd, timeout_us);
} }
static wasi_errno_t static wasi_errno_t
@ -1766,7 +1780,8 @@ wasi_sock_set_tcp_fastopen_connect(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_fastopen_connect(curfds, fd, is_enabled); return wasmtime_ssp_sock_set_tcp_fastopen_connect(exec_env, curfds, fd,
is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1782,7 +1797,7 @@ wasi_sock_set_tcp_no_delay(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_no_delay(curfds, fd, is_enabled); return wasmtime_ssp_sock_set_tcp_no_delay(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1798,7 +1813,8 @@ wasi_sock_set_tcp_quick_ack(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_quick_ack(curfds, fd, is_enabled); return wasmtime_ssp_sock_set_tcp_quick_ack(exec_env, curfds, fd,
is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -1814,7 +1830,7 @@ wasi_sock_set_tcp_keep_idle(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_keep_idle(curfds, fd, time_s); return wasmtime_ssp_sock_set_tcp_keep_idle(exec_env, curfds, fd, time_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1830,7 +1846,7 @@ wasi_sock_set_tcp_keep_intvl(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_keep_intvl(curfds, fd, time_s); return wasmtime_ssp_sock_set_tcp_keep_intvl(exec_env, curfds, fd, time_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1846,7 +1862,7 @@ wasi_sock_set_ip_multicast_loop(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_multicast_loop(curfds, fd, ipv6, return wasmtime_ssp_sock_set_ip_multicast_loop(exec_env, curfds, fd, ipv6,
is_enabled); is_enabled);
} }
@ -1867,8 +1883,8 @@ wasi_sock_set_ip_add_membership(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_add_membership(curfds, fd, imr_multiaddr, return wasmtime_ssp_sock_set_ip_add_membership(
imr_interface); exec_env, curfds, fd, imr_multiaddr, imr_interface);
} }
static wasi_errno_t static wasi_errno_t
@ -1888,8 +1904,8 @@ wasi_sock_set_ip_drop_membership(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_drop_membership(curfds, fd, imr_multiaddr, return wasmtime_ssp_sock_set_ip_drop_membership(
imr_interface); exec_env, curfds, fd, imr_multiaddr, imr_interface);
} }
static wasi_errno_t static wasi_errno_t
@ -1904,7 +1920,7 @@ wasi_sock_set_ip_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8_t ttl_s)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_ttl(curfds, fd, ttl_s); return wasmtime_ssp_sock_set_ip_ttl(exec_env, curfds, fd, ttl_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1920,7 +1936,7 @@ wasi_sock_set_ip_multicast_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_multicast_ttl(curfds, fd, ttl_s); return wasmtime_ssp_sock_set_ip_multicast_ttl(exec_env, curfds, fd, ttl_s);
} }
static wasi_errno_t static wasi_errno_t
@ -1935,7 +1951,7 @@ wasi_sock_set_ipv6_only(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ipv6_only(curfds, fd, is_enabled); return wasmtime_ssp_sock_set_ipv6_only(exec_env, curfds, fd, is_enabled);
} }
static wasi_errno_t static wasi_errno_t
@ -2053,8 +2069,9 @@ wasi_sock_recv_from(wasm_exec_env_t exec_env, wasi_fd_t sock,
memset(buf_begin, 0, total_size); memset(buf_begin, 0, total_size);
*ro_data_len = 0; *ro_data_len = 0;
err = wasmtime_ssp_sock_recv_from(curfds, sock, buf_begin, total_size, err = wasmtime_ssp_sock_recv_from(exec_env, curfds, sock, buf_begin,
ri_flags, src_addr, &recv_bytes); total_size, ri_flags, src_addr,
&recv_bytes);
if (err != __WASI_ESUCCESS) { if (err != __WASI_ESUCCESS) {
goto fail; goto fail;
} }
@ -2153,7 +2170,8 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
return err; return err;
*so_data_len = 0; *so_data_len = 0;
err = wasmtime_ssp_sock_send(curfds, sock, buf, buf_size, &send_bytes); err = wasmtime_ssp_sock_send(exec_env, curfds, sock, buf, buf_size,
&send_bytes);
*so_data_len = (uint32)send_bytes; *so_data_len = (uint32)send_bytes;
wasm_runtime_free(buf); wasm_runtime_free(buf);
@ -2193,8 +2211,8 @@ wasi_sock_send_to(wasm_exec_env_t exec_env, wasi_fd_t sock,
return err; return err;
*so_data_len = 0; *so_data_len = 0;
err = wasmtime_ssp_sock_send_to(curfds, addr_pool, sock, buf, buf_size, err = wasmtime_ssp_sock_send_to(exec_env, curfds, addr_pool, sock, buf,
si_flags, dest_addr, &send_bytes); buf_size, si_flags, dest_addr, &send_bytes);
*so_data_len = (uint32)send_bytes; *so_data_len = (uint32)send_bytes;
wasm_runtime_free(buf); wasm_runtime_free(buf);
@ -2212,7 +2230,7 @@ wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
if (!wasi_ctx) if (!wasi_ctx)
return __WASI_EINVAL; return __WASI_EINVAL;
return wasmtime_ssp_sock_shutdown(curfds, sock); return wasmtime_ssp_sock_shutdown(exec_env, curfds, sock);
} }
static wasi_errno_t static wasi_errno_t

View File

@ -22,6 +22,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "wasm_export.h"
/* clang-format off */ /* clang-format off */
#ifdef __cplusplus #ifdef __cplusplus
@ -264,37 +266,6 @@ typedef uint8_t __wasi_sdflags_t;
typedef uint16_t __wasi_siflags_t; typedef uint16_t __wasi_siflags_t;
typedef uint8_t __wasi_signal_t; typedef uint8_t __wasi_signal_t;
// 0 is reserved; POSIX has special semantics for kill(pid, 0).
#define __WASI_SIGHUP (1)
#define __WASI_SIGINT (2)
#define __WASI_SIGQUIT (3)
#define __WASI_SIGILL (4)
#define __WASI_SIGTRAP (5)
#define __WASI_SIGABRT (6)
#define __WASI_SIGBUS (7)
#define __WASI_SIGFPE (8)
#define __WASI_SIGKILL (9)
#define __WASI_SIGUSR1 (10)
#define __WASI_SIGSEGV (11)
#define __WASI_SIGUSR2 (12)
#define __WASI_SIGPIPE (13)
#define __WASI_SIGALRM (14)
#define __WASI_SIGTERM (15)
#define __WASI_SIGCHLD (16)
#define __WASI_SIGCONT (17)
#define __WASI_SIGSTOP (18)
#define __WASI_SIGTSTP (19)
#define __WASI_SIGTTIN (20)
#define __WASI_SIGTTOU (21)
#define __WASI_SIGURG (22)
#define __WASI_SIGXCPU (23)
#define __WASI_SIGXFSZ (24)
#define __WASI_SIGVTALRM (25)
#define __WASI_SIGPROF (26)
#define __WASI_SIGWINCH (27)
#define __WASI_SIGPOLL (28)
#define __WASI_SIGPWR (29)
#define __WASI_SIGSYS (30)
typedef uint16_t __wasi_subclockflags_t; typedef uint16_t __wasi_subclockflags_t;
#define __WASI_SUBSCRIPTION_CLOCK_ABSTIME (0x0001) #define __WASI_SUBSCRIPTION_CLOCK_ABSTIME (0x0001)
@ -552,6 +523,8 @@ _Static_assert(offsetof(__wasi_subscription_t, u) == 8, "witx calculated offset"
/* keep syncing with wasi_socket_ext.h */ /* keep syncing with wasi_socket_ext.h */
typedef enum { typedef enum {
/* Used only for sock_addr_resolve hints */
SOCKET_ANY = -1,
SOCKET_DGRAM = 0, SOCKET_DGRAM = 0,
SOCKET_STREAM, SOCKET_STREAM,
} __wasi_sock_type_t; } __wasi_sock_type_t;
@ -605,7 +578,7 @@ typedef struct __wasi_addr_t {
} addr; } addr;
} __wasi_addr_t; } __wasi_addr_t;
typedef enum { INET4 = 0, INET6 } __wasi_address_family_t; typedef enum { INET4 = 0, INET6, INET_UNSPEC } __wasi_address_family_t;
typedef struct __wasi_addr_info_t { typedef struct __wasi_addr_info_t {
__wasi_addr_t addr; __wasi_addr_t addr;
@ -627,17 +600,13 @@ typedef struct __wasi_addr_info_hints_t {
#endif #endif
__wasi_errno_t wasmtime_ssp_args_get( __wasi_errno_t wasmtime_ssp_args_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ, struct argv_environ_values *arg_environ,
#endif
char **argv, char **argv,
char *argv_buf char *argv_buf
) WASMTIME_SSP_SYSCALL_NAME(args_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(args_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_args_sizes_get( __wasi_errno_t wasmtime_ssp_args_sizes_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ, struct argv_environ_values *arg_environ,
#endif
size_t *argc, size_t *argc,
size_t *argv_buf_size size_t *argv_buf_size
) WASMTIME_SSP_SYSCALL_NAME(args_sizes_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(args_sizes_get) __attribute__((__warn_unused_result__));
@ -654,57 +623,46 @@ __wasi_errno_t wasmtime_ssp_clock_time_get(
) WASMTIME_SSP_SYSCALL_NAME(clock_time_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(clock_time_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_environ_get( __wasi_errno_t wasmtime_ssp_environ_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ, struct argv_environ_values *arg_environ,
#endif
char **environ, char **environ,
char *environ_buf char *environ_buf
) WASMTIME_SSP_SYSCALL_NAME(environ_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(environ_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_environ_sizes_get( __wasi_errno_t wasmtime_ssp_environ_sizes_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ, struct argv_environ_values *arg_environ,
#endif
size_t *environ_count, size_t *environ_count,
size_t *environ_buf_size size_t *environ_buf_size
) WASMTIME_SSP_SYSCALL_NAME(environ_sizes_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(environ_sizes_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_prestat_get( __wasi_errno_t wasmtime_ssp_fd_prestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats, struct fd_prestats *prestats,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_prestat_t *buf __wasi_prestat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_prestat_dir_name( __wasi_errno_t wasmtime_ssp_fd_prestat_dir_name(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats, struct fd_prestats *prestats,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
char *path, char *path,
size_t path_len size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_dir_name) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_dir_name) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_close( __wasi_errno_t wasmtime_ssp_fd_close(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
struct fd_prestats *prestats, struct fd_prestats *prestats,
#endif
__wasi_fd_t fd __wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_close) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_close) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_datasync( __wasi_errno_t wasmtime_ssp_fd_datasync(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd __wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_datasync) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_datasync) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_pread( __wasi_errno_t wasmtime_ssp_fd_pread(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
const __wasi_iovec_t *iovs, const __wasi_iovec_t *iovs,
size_t iovs_len, size_t iovs_len,
@ -713,9 +671,8 @@ __wasi_errno_t wasmtime_ssp_fd_pread(
) WASMTIME_SSP_SYSCALL_NAME(fd_pread) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_pread) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_pwrite( __wasi_errno_t wasmtime_ssp_fd_pwrite(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
const __wasi_ciovec_t *iovs, const __wasi_ciovec_t *iovs,
size_t iovs_len, size_t iovs_len,
@ -724,9 +681,8 @@ __wasi_errno_t wasmtime_ssp_fd_pwrite(
) WASMTIME_SSP_SYSCALL_NAME(fd_pwrite) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_pwrite) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_read( __wasi_errno_t wasmtime_ssp_fd_read(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
const __wasi_iovec_t *iovs, const __wasi_iovec_t *iovs,
size_t iovs_len, size_t iovs_len,
@ -734,18 +690,16 @@ __wasi_errno_t wasmtime_ssp_fd_read(
) WASMTIME_SSP_SYSCALL_NAME(fd_read) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_read) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_renumber( __wasi_errno_t wasmtime_ssp_fd_renumber(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
struct fd_prestats *prestats, struct fd_prestats *prestats,
#endif
__wasi_fd_t from, __wasi_fd_t from,
__wasi_fd_t to __wasi_fd_t to
) WASMTIME_SSP_SYSCALL_NAME(fd_renumber) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_renumber) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_seek( __wasi_errno_t wasmtime_ssp_fd_seek(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_filedelta_t offset, __wasi_filedelta_t offset,
__wasi_whence_t whence, __wasi_whence_t whence,
@ -753,49 +707,43 @@ __wasi_errno_t wasmtime_ssp_fd_seek(
) WASMTIME_SSP_SYSCALL_NAME(fd_seek) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_seek) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_tell( __wasi_errno_t wasmtime_ssp_fd_tell(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_filesize_t *newoffset __wasi_filesize_t *newoffset
) WASMTIME_SSP_SYSCALL_NAME(fd_tell) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_tell) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_fdstat_get( __wasi_errno_t wasmtime_ssp_fd_fdstat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_fdstat_t *buf __wasi_fdstat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_fdstat_set_flags( __wasi_errno_t wasmtime_ssp_fd_fdstat_set_flags(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_fdflags_t flags __wasi_fdflags_t flags
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_flags) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_flags) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_fdstat_set_rights( __wasi_errno_t wasmtime_ssp_fd_fdstat_set_rights(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_rights_t fs_rights_base, __wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting __wasi_rights_t fs_rights_inheriting
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_rights) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_rights) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_sync( __wasi_errno_t wasmtime_ssp_fd_sync(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd __wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_sync) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_sync) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_write( __wasi_errno_t wasmtime_ssp_fd_write(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
const __wasi_ciovec_t *iovs, const __wasi_ciovec_t *iovs,
size_t iovs_len, size_t iovs_len,
@ -803,9 +751,8 @@ __wasi_errno_t wasmtime_ssp_fd_write(
) WASMTIME_SSP_SYSCALL_NAME(fd_write) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_write) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_advise( __wasi_errno_t wasmtime_ssp_fd_advise(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_filesize_t offset, __wasi_filesize_t offset,
__wasi_filesize_t len, __wasi_filesize_t len,
@ -813,28 +760,25 @@ __wasi_errno_t wasmtime_ssp_fd_advise(
) WASMTIME_SSP_SYSCALL_NAME(fd_advise) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_advise) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_allocate( __wasi_errno_t wasmtime_ssp_fd_allocate(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_filesize_t offset, __wasi_filesize_t offset,
__wasi_filesize_t len __wasi_filesize_t len
) WASMTIME_SSP_SYSCALL_NAME(fd_allocate) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_allocate) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_create_directory( __wasi_errno_t wasmtime_ssp_path_create_directory(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
const char *path, const char *path,
size_t path_len size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_create_directory) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_create_directory) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_link( __wasi_errno_t wasmtime_ssp_path_link(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
struct fd_prestats *prestats, struct fd_prestats *prestats,
#endif
__wasi_fd_t old_fd, __wasi_fd_t old_fd,
__wasi_lookupflags_t old_flags, __wasi_lookupflags_t old_flags,
const char *old_path, const char *old_path,
@ -845,9 +789,8 @@ __wasi_errno_t wasmtime_ssp_path_link(
) WASMTIME_SSP_SYSCALL_NAME(path_link) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_link) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_open( __wasi_errno_t wasmtime_ssp_path_open(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t dirfd, __wasi_fd_t dirfd,
__wasi_lookupflags_t dirflags, __wasi_lookupflags_t dirflags,
const char *path, const char *path,
@ -860,9 +803,8 @@ __wasi_errno_t wasmtime_ssp_path_open(
) WASMTIME_SSP_SYSCALL_NAME(path_open) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_open) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_readdir( __wasi_errno_t wasmtime_ssp_fd_readdir(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
void *buf, void *buf,
size_t buf_len, size_t buf_len,
@ -871,9 +813,8 @@ __wasi_errno_t wasmtime_ssp_fd_readdir(
) WASMTIME_SSP_SYSCALL_NAME(fd_readdir) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_readdir) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_readlink( __wasi_errno_t wasmtime_ssp_path_readlink(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
const char *path, const char *path,
size_t path_len, size_t path_len,
@ -883,9 +824,8 @@ __wasi_errno_t wasmtime_ssp_path_readlink(
) WASMTIME_SSP_SYSCALL_NAME(path_readlink) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_readlink) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_rename( __wasi_errno_t wasmtime_ssp_path_rename(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t old_fd, __wasi_fd_t old_fd,
const char *old_path, const char *old_path,
size_t old_path_len, size_t old_path_len,
@ -895,17 +835,15 @@ __wasi_errno_t wasmtime_ssp_path_rename(
) WASMTIME_SSP_SYSCALL_NAME(path_rename) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_rename) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_filestat_get( __wasi_errno_t wasmtime_ssp_fd_filestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_filestat_t *buf __wasi_filestat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_filestat_set_times( __wasi_errno_t wasmtime_ssp_fd_filestat_set_times(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_timestamp_t st_atim, __wasi_timestamp_t st_atim,
__wasi_timestamp_t st_mtim, __wasi_timestamp_t st_mtim,
@ -913,17 +851,15 @@ __wasi_errno_t wasmtime_ssp_fd_filestat_set_times(
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_times) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_times) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_filestat_set_size( __wasi_errno_t wasmtime_ssp_fd_filestat_set_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_filesize_t st_size __wasi_filesize_t st_size
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_size) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_size) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_filestat_get( __wasi_errno_t wasmtime_ssp_path_filestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_lookupflags_t flags, __wasi_lookupflags_t flags,
const char *path, const char *path,
@ -932,9 +868,8 @@ __wasi_errno_t wasmtime_ssp_path_filestat_get(
) WASMTIME_SSP_SYSCALL_NAME(path_filestat_get) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_filestat_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_filestat_set_times( __wasi_errno_t wasmtime_ssp_path_filestat_set_times(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
__wasi_lookupflags_t flags, __wasi_lookupflags_t flags,
const char *path, const char *path,
@ -945,10 +880,9 @@ __wasi_errno_t wasmtime_ssp_path_filestat_set_times(
) WASMTIME_SSP_SYSCALL_NAME(path_filestat_set_times) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_filestat_set_times) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_symlink( __wasi_errno_t wasmtime_ssp_path_symlink(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
struct fd_prestats *prestats, struct fd_prestats *prestats,
#endif
const char *old_path, const char *old_path,
size_t old_path_len, size_t old_path_len,
__wasi_fd_t fd, __wasi_fd_t fd,
@ -957,47 +891,30 @@ __wasi_errno_t wasmtime_ssp_path_symlink(
) WASMTIME_SSP_SYSCALL_NAME(path_symlink) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_symlink) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_unlink_file( __wasi_errno_t wasmtime_ssp_path_unlink_file(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
const char *path, const char *path,
size_t path_len size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_unlink_file) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_unlink_file) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_remove_directory( __wasi_errno_t wasmtime_ssp_path_remove_directory(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t fd,
const char *path, const char *path,
size_t path_len size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_remove_directory) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(path_remove_directory) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_poll_oneoff( __wasi_errno_t wasmtime_ssp_poll_oneoff(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
const __wasi_subscription_t *in, const __wasi_subscription_t *in,
__wasi_event_t *out, __wasi_event_t *out,
size_t nsubscriptions, size_t nsubscriptions,
size_t *nevents size_t *nevents
) WASMTIME_SSP_SYSCALL_NAME(poll_oneoff) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(poll_oneoff) __attribute__((__warn_unused_result__));
#if 0
/**
* We throw exception in libc-wasi wrapper function wasi_proc_exit()
* but not call this function.
*/
_Noreturn void wasmtime_ssp_proc_exit(
__wasi_exitcode_t rval
) WASMTIME_SSP_SYSCALL_NAME(proc_exit);
#endif
__wasi_errno_t wasmtime_ssp_proc_raise(
__wasi_signal_t sig
) WASMTIME_SSP_SYSCALL_NAME(proc_raise) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_random_get( __wasi_errno_t wasmtime_ssp_random_get(
void *buf, void *buf,
size_t buf_len size_t buf_len
@ -1005,50 +922,44 @@ __wasi_errno_t wasmtime_ssp_random_get(
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_accept( wasi_ssp_sock_accept(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new __wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_addr_local( wasi_ssp_sock_addr_local(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr __wasi_fd_t fd, __wasi_addr_t *addr
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_addr_remote( wasi_ssp_sock_addr_remote(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr __wasi_fd_t fd, __wasi_addr_t *addr
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_open( wasi_ssp_sock_open(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype, __wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype,
__wasi_fd_t *sockfd __wasi_fd_t *sockfd
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_bind( wasi_ssp_sock_bind(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct addr_pool *addr_pool, struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr __wasi_fd_t fd, __wasi_addr_t *addr
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_addr_resolve( wasi_ssp_sock_addr_resolve(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, char **ns_lookup_list, struct fd_table *curfds, char **ns_lookup_list,
#endif
const char *host, const char* service, const char *host, const char* service,
__wasi_addr_info_hints_t *hints, __wasi_addr_info_t *addr_info, __wasi_addr_info_hints_t *hints, __wasi_addr_info_t *addr_info,
__wasi_size_t addr_info_size, __wasi_size_t *max_info_size __wasi_size_t addr_info_size, __wasi_size_t *max_info_size
@ -1056,88 +967,77 @@ wasi_ssp_sock_addr_resolve(
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_connect( wasi_ssp_sock_connect(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct addr_pool *addr_pool, struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr __wasi_fd_t fd, __wasi_addr_t *addr
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_get_recv_buf_size( wasi_ssp_sock_get_recv_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t *size __wasi_fd_t fd, __wasi_size_t *size
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_get_reuse_addr( wasi_ssp_sock_get_reuse_addr(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t *reuse __wasi_fd_t fd, uint8_t *reuse
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_get_reuse_port( wasi_ssp_sock_get_reuse_port(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t *reuse __wasi_fd_t fd, uint8_t *reuse
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_get_send_buf_size( wasi_ssp_sock_get_send_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t *size __wasi_fd_t fd, __wasi_size_t *size
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_set_recv_buf_size( wasi_ssp_sock_set_recv_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t size __wasi_fd_t fd, __wasi_size_t size
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_set_reuse_addr( wasi_ssp_sock_set_reuse_addr(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t reuse __wasi_fd_t fd, uint8_t reuse
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_set_reuse_port( wasi_ssp_sock_set_reuse_port(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t reuse __wasi_fd_t fd, uint8_t reuse
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_set_send_buf_size( wasi_ssp_sock_set_send_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t size __wasi_fd_t fd, __wasi_size_t size
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t
wasi_ssp_sock_listen( wasi_ssp_sock_listen(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t backlog __wasi_fd_t fd, __wasi_size_t backlog
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_recv( __wasi_errno_t wasmtime_ssp_sock_recv(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
void *buf, void *buf,
size_t buf_len, size_t buf_len,
@ -1145,9 +1045,8 @@ __wasi_errno_t wasmtime_ssp_sock_recv(
) WASMTIME_SSP_SYSCALL_NAME(sock_recv) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_recv) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_recv_from( __wasi_errno_t wasmtime_ssp_sock_recv_from(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
void *buf, void *buf,
size_t buf_len, size_t buf_len,
@ -1157,9 +1056,8 @@ __wasi_errno_t wasmtime_ssp_sock_recv_from(
) WASMTIME_SSP_SYSCALL_NAME(sock_recv_from) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_recv_from) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_send( __wasi_errno_t wasmtime_ssp_sock_send(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
const void *buf, const void *buf,
size_t buf_len, size_t buf_len,
@ -1167,9 +1065,8 @@ __wasi_errno_t wasmtime_ssp_sock_send(
) WASMTIME_SSP_SYSCALL_NAME(sock_send) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_send) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_send_to( __wasi_errno_t wasmtime_ssp_sock_send_to(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct addr_pool *addr_pool, struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
const void *buf, const void *buf,
size_t buf_len, size_t buf_len,
@ -1179,317 +1076,278 @@ __wasi_errno_t wasmtime_ssp_sock_send_to(
) WASMTIME_SSP_SYSCALL_NAME(sock_send_to) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_send_to) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_shutdown( __wasi_errno_t wasmtime_ssp_sock_shutdown(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock __wasi_fd_t sock
) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_recv_timeout( __wasi_errno_t wasmtime_ssp_sock_set_recv_timeout(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint64_t timeout_us uint64_t timeout_us
) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_timeout) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_timeout) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_recv_timeout( __wasi_errno_t wasmtime_ssp_sock_get_recv_timeout(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint64_t *timeout_us uint64_t *timeout_us
) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_timeout) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_timeout) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_send_timeout( __wasi_errno_t wasmtime_ssp_sock_set_send_timeout(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint64_t timeout_us uint64_t timeout_us
) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_timeout) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_timeout) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_send_timeout( __wasi_errno_t wasmtime_ssp_sock_get_send_timeout(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint64_t *timeout_us uint64_t *timeout_us
) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_timeout) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_timeout) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_send_buf_size( __wasi_errno_t wasmtime_ssp_sock_set_send_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
size_t bufsiz size_t bufsiz
) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_buf_size) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_buf_size) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_send_buf_size( __wasi_errno_t wasmtime_ssp_sock_get_send_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
size_t *bufsiz size_t *bufsiz
) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_buf_size) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_buf_size) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_recv_buf_size( __wasi_errno_t wasmtime_ssp_sock_set_recv_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
size_t bufsiz size_t bufsiz
) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_buf_size) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_buf_size) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_recv_buf_size( __wasi_errno_t wasmtime_ssp_sock_get_recv_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
size_t *bufsiz size_t *bufsiz
) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_buf_size) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_buf_size) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_keep_alive( __wasi_errno_t wasmtime_ssp_sock_set_keep_alive(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_keep_alive) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_keep_alive) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_keep_alive( __wasi_errno_t wasmtime_ssp_sock_get_keep_alive(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_keep_alive) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_keep_alive) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_reuse_addr( __wasi_errno_t wasmtime_ssp_sock_set_reuse_addr(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_addr) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_addr) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_reuse_addr( __wasi_errno_t wasmtime_ssp_sock_get_reuse_addr(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_addr) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_addr) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_reuse_port( __wasi_errno_t wasmtime_ssp_sock_set_reuse_port(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_port) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_port) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_reuse_port( __wasi_errno_t wasmtime_ssp_sock_get_reuse_port(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_port) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_port) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_linger( __wasi_errno_t wasmtime_ssp_sock_set_linger(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled, bool is_enabled,
int linger_s int linger_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_linger) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_linger) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_linger( __wasi_errno_t wasmtime_ssp_sock_get_linger(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, bool *is_enabled, int *linger_s __wasi_fd_t sock, bool *is_enabled, int *linger_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_linger) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_linger) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_broadcast( __wasi_errno_t wasmtime_ssp_sock_set_broadcast(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_broadcast) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_broadcast) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_broadcast( __wasi_errno_t wasmtime_ssp_sock_get_broadcast(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_broadcast) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_broadcast) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_tcp_no_delay( __wasi_errno_t wasmtime_ssp_sock_set_tcp_no_delay(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_no_delay) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_no_delay) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_tcp_no_delay( __wasi_errno_t wasmtime_ssp_sock_get_tcp_no_delay(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_no_delay) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_no_delay) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_tcp_quick_ack( __wasi_errno_t wasmtime_ssp_sock_set_tcp_quick_ack(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_quick_ack) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_quick_ack) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_tcp_quick_ack( __wasi_errno_t wasmtime_ssp_sock_get_tcp_quick_ack(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_quick_ack) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_quick_ack) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_idle( __wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_idle(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint32_t time_s uint32_t time_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_idle) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_idle) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_idle( __wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_idle(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint32_t *time_s uint32_t *time_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_idle) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_idle) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_intvl( __wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_intvl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint32_t time_s uint32_t time_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_intvl) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_intvl) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_intvl( __wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_intvl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint32_t *time_s uint32_t *time_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_intvl) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_intvl) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_tcp_fastopen_connect( __wasi_errno_t wasmtime_ssp_sock_set_tcp_fastopen_connect(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_fastopen_connect) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_fastopen_connect) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_tcp_fastopen_connect( __wasi_errno_t wasmtime_ssp_sock_get_tcp_fastopen_connect(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_fastopen_connect) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_fastopen_connect) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_loop( __wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_loop(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool ipv6, bool ipv6,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_loop) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_loop) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_loop( __wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_loop(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool ipv6, bool ipv6,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_loop) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_loop) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_ip_add_membership( __wasi_errno_t wasmtime_ssp_sock_set_ip_add_membership(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
__wasi_addr_ip_t *imr_multiaddr, __wasi_addr_ip_t *imr_multiaddr,
uint32_t imr_interface uint32_t imr_interface
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_add_membership) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_add_membership) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_ip_drop_membership( __wasi_errno_t wasmtime_ssp_sock_set_ip_drop_membership(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
__wasi_addr_ip_t *imr_multiaddr, __wasi_addr_ip_t *imr_multiaddr,
uint32_t imr_interface uint32_t imr_interface
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_drop_membership) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_drop_membership) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_ip_ttl( __wasi_errno_t wasmtime_ssp_sock_set_ip_ttl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint8_t ttl_s uint8_t ttl_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_ttl) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_ttl) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_ip_ttl( __wasi_errno_t wasmtime_ssp_sock_get_ip_ttl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint8_t *ttl_s uint8_t *ttl_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_ttl) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_ttl) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_ttl( __wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_ttl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint8_t ttl_s uint8_t ttl_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_ttl) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_ttl) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_ttl( __wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_ttl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
uint8_t *ttl_s uint8_t *ttl_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_ttl) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_ttl) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_set_ipv6_only( __wasi_errno_t wasmtime_ssp_sock_set_ipv6_only(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool is_enabled bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ipv6_only) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ipv6_only) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_get_ipv6_only( __wasi_errno_t wasmtime_ssp_sock_get_ipv6_only(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) wasm_exec_env_t exec_env,
struct fd_table *curfds, struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_fd_t sock,
bool *is_enabled bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_ipv6_only) __attribute__((__warn_unused_result__)); ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ipv6_only) __attribute__((__warn_unused_result__));

View File

@ -0,0 +1,201 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <errno.h>
#include "ssp_config.h"
#include "blocking_op.h"
int
blocking_op_close(wasm_exec_env_t exec_env, int fd)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = close(fd);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
ssize_t
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = readv(fd, iov, iovcnt);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#if CONFIG_HAS_PREADV
ssize_t
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = preadv(fd, iov, iovcnt, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#else /* CONFIG_HAS_PREADV */
ssize_t
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
off_t offset)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pread(fd, p, nb, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#endif /* CONFIG_HAS_PREADV */
ssize_t
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = writev(fd, iov, iovcnt);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#if CONFIG_HAS_PWRITEV
ssize_t
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pwritev(fd, iov, iovcnt, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#else /* CONFIG_HAS_PWRITEV */
ssize_t
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
off_t offset)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pwrite(fd, p, nb, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#endif /* CONFIG_HAS_PWRITEV */
int
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
bh_socket_t *sockp, void *addr,
unsigned int *addrlenp)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_accept(server_sock, sockp, addr, addrlenp);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_socket_connect(wasm_exec_env_t exec_env, bh_socket_t sock,
const char *addr, int port)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_connect(sock, addr, port);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_socket_recv_from(wasm_exec_env_t exec_env, bh_socket_t sock,
void *buf, unsigned int len, int flags,
bh_sockaddr_t *src_addr)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_recv_from(sock, buf, len, flags, src_addr);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_socket_send_to(wasm_exec_env_t exec_env, bh_socket_t sock,
const void *buf, unsigned int len, int flags,
const bh_sockaddr_t *dest_addr)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_send_to(sock, buf, len, flags, dest_addr);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
const char *service, uint8_t *hint_is_tcp,
uint8_t *hint_is_ipv4,
bh_addr_info_t *addr_info,
size_t addr_info_size, size_t *max_info_size)
{
/*
* Note: Unlike others, os_socket_addr_resolve() is not a simple system
* call. It's likely backed by a complex libc function, getaddrinfo().
* Depending on the implementation of getaddrinfo() and underlying
* DNS resolver, it might or might not be possible to make it return
* with os_wakeup_blocking_op().
*
* Unfortunately, many of ISC/bind based resolvers just keep going on
* interrupted system calls. It includes macOS and glibc.
*
* On the other hand, NuttX as of writing this returns EAI_AGAIN
* on EINTR.
*/
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_addr_resolve(host, service, hint_is_tcp, hint_is_ipv4,
addr_info, addr_info_size, max_info_size);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
int oflags, mode_t mode)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = openat(fd, path, oflags, mode);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "wasm_export.h"
int
blocking_op_close(wasm_exec_env_t exec_env, int fd);
ssize_t
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt);
ssize_t
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset);
ssize_t
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
off_t offset);
ssize_t
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt);
ssize_t
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset);
ssize_t
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
off_t offset);
int
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
bh_socket_t *sockp, void *addr,
unsigned int *addrlenp);
int
blocking_op_socket_connect(wasm_exec_env_t exec_env, bh_socket_t sock,
const char *addr, int port);
int
blocking_op_socket_recv_from(wasm_exec_env_t exec_env, bh_socket_t sock,
void *buf, unsigned int len, int flags,
bh_sockaddr_t *src_addr);
int
blocking_op_socket_send_to(wasm_exec_env_t exec_env, bh_socket_t sock,
const void *buf, unsigned int len, int flags,
const bh_sockaddr_t *dest_addr);
int
blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
const char *service, uint8_t *hint_is_tcp,
uint8_t *hint_is_ipv4,
bh_addr_info_t *addr_info,
size_t addr_info_size, size_t *max_info_size);
int
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
int oflags, mode_t mode);

View File

@ -101,12 +101,6 @@
#define st_mtim st_mtimespec #define st_mtim st_mtimespec
#endif #endif
#ifdef __APPLE__
#define CONFIG_TLS_USE_GSBASE 1
#else
#define CONFIG_TLS_USE_GSBASE 0
#endif
#if !defined(BH_PLATFORM_LINUX_SGX) #if !defined(BH_PLATFORM_LINUX_SGX)
/* Clang's __GNUC_PREREQ macro has a different meaning than GCC one, /* Clang's __GNUC_PREREQ macro has a different meaning than GCC one,
so we have to handle this case specially */ so we have to handle this case specially */

View File

@ -16,10 +16,6 @@
#include "debug_engine.h" #include "debug_engine.h"
#endif #endif
#if WASM_ENABLE_SHARED_MEMORY != 0
#include "wasm_shared_memory.h"
#endif
typedef struct { typedef struct {
bh_list_link l; bh_list_link l;
void (*destroy_cb)(WASMCluster *); void (*destroy_cb)(WASMCluster *);
@ -32,6 +28,8 @@ static bh_list cluster_list_head;
static bh_list *const cluster_list = &cluster_list_head; static bh_list *const cluster_list = &cluster_list_head;
static korp_mutex cluster_list_lock; static korp_mutex cluster_list_lock;
static korp_mutex _exception_lock;
typedef void (*list_visitor)(void *, void *); typedef void (*list_visitor)(void *, void *);
static uint32 cluster_max_thread_num = CLUSTER_MAX_THREAD_NUM; static uint32 cluster_max_thread_num = CLUSTER_MAX_THREAD_NUM;
@ -52,6 +50,10 @@ thread_manager_init()
return false; return false;
if (os_mutex_init(&cluster_list_lock) != 0) if (os_mutex_init(&cluster_list_lock) != 0)
return false; return false;
if (os_mutex_init(&_exception_lock) != 0) {
os_mutex_destroy(&cluster_list_lock);
return false;
}
return true; return true;
} }
@ -66,6 +68,7 @@ thread_manager_destroy()
cluster = next; cluster = next;
} }
wasm_cluster_cancel_all_callbacks(); wasm_cluster_cancel_all_callbacks();
os_mutex_destroy(&_exception_lock);
os_mutex_destroy(&cluster_list_lock); os_mutex_destroy(&cluster_list_lock);
} }
@ -477,9 +480,6 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_t module; wasm_module_t module;
wasm_module_inst_t new_module_inst; wasm_module_inst_t new_module_inst;
#if WASM_ENABLE_LIBC_WASI != 0
WASIContext *wasi_ctx;
#endif
WASMExecEnv *new_exec_env; WASMExecEnv *new_exec_env;
uint32 aux_stack_start, aux_stack_size; uint32 aux_stack_start, aux_stack_size;
uint32 stack_size = 8192; uint32 stack_size = 8192;
@ -509,7 +509,7 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
#endif #endif
if (!(new_module_inst = wasm_runtime_instantiate_internal( if (!(new_module_inst = wasm_runtime_instantiate_internal(
module, true, exec_env, stack_size, 0, NULL, 0))) { module, module_inst, exec_env, stack_size, 0, NULL, 0))) {
goto fail1; goto fail1;
} }
@ -517,10 +517,7 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
wasm_runtime_set_custom_data_internal( wasm_runtime_set_custom_data_internal(
new_module_inst, wasm_runtime_get_custom_data(module_inst)); new_module_inst, wasm_runtime_get_custom_data(module_inst));
#if WASM_ENABLE_LIBC_WASI != 0 wasm_native_inherit_contexts(new_module_inst, module_inst);
wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
#endif
new_exec_env = wasm_exec_env_create_internal(new_module_inst, new_exec_env = wasm_exec_env_create_internal(new_module_inst,
exec_env->wasm_stack_size); exec_env->wasm_stack_size);
@ -606,7 +603,8 @@ thread_manager_start_routine(void *arg)
#ifdef OS_ENABLE_HW_BOUND_CHECK #ifdef OS_ENABLE_HW_BOUND_CHECK
os_mutex_lock(&exec_env->wait_lock); os_mutex_lock(&exec_env->wait_lock);
if (exec_env->suspend_flags.flags & 0x08) if (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags)
& WASM_SUSPEND_FLAG_EXIT)
ret = exec_env->thread_ret_value; ret = exec_env->thread_ret_value;
os_mutex_unlock(&exec_env->wait_lock); os_mutex_unlock(&exec_env->wait_lock);
#endif #endif
@ -745,10 +743,10 @@ wasm_cluster_dup_c_api_imports(WASMModuleInstanceCommon *module_inst_dst,
#if WASM_ENABLE_INTERP != 0 #if WASM_ENABLE_INTERP != 0
if (module_inst_src->module_type == Wasm_Module_Bytecode) { if (module_inst_src->module_type == Wasm_Module_Bytecode) {
new_c_api_func_imports = new_c_api_func_imports = &(((WASMModuleInstance *)module_inst_dst)
&(((WASMModuleInstance *)module_inst_dst)->e->c_api_func_imports); ->e->common.c_api_func_imports);
c_api_func_imports = ((const WASMModuleInstance *)module_inst_src) c_api_func_imports = ((const WASMModuleInstance *)module_inst_src)
->e->c_api_func_imports; ->e->common.c_api_func_imports;
import_func_count = import_func_count =
((WASMModule *)(((const WASMModuleInstance *)module_inst_src) ((WASMModule *)(((const WASMModuleInstance *)module_inst_src)
->module)) ->module))
@ -759,10 +757,10 @@ wasm_cluster_dup_c_api_imports(WASMModuleInstanceCommon *module_inst_dst,
if (module_inst_src->module_type == Wasm_Module_AoT) { if (module_inst_src->module_type == Wasm_Module_AoT) {
AOTModuleInstanceExtra *e = AOTModuleInstanceExtra *e =
(AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_dst)->e; (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_dst)->e;
new_c_api_func_imports = &(e->c_api_func_imports); new_c_api_func_imports = &(e->common.c_api_func_imports);
e = (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_src)->e; e = (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_src)->e;
c_api_func_imports = e->c_api_func_imports; c_api_func_imports = e->common.c_api_func_imports;
import_func_count = import_func_count =
((AOTModule *)(((AOTModuleInstance *)module_inst_src)->module)) ((AOTModule *)(((AOTModuleInstance *)module_inst_src)->module))
@ -993,7 +991,9 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
if (exec_env->jmpbuf_stack_top) { if (exec_env->jmpbuf_stack_top) {
/* Store the return value in exec_env */ /* Store the return value in exec_env */
exec_env->thread_ret_value = retval; exec_env->thread_ret_value = retval;
exec_env->suspend_flags.flags |= 0x08;
WASM_SUSPEND_FLAGS_FETCH_OR(exec_env->suspend_flags,
WASM_SUSPEND_FLAG_EXIT);
#ifndef BH_PLATFORM_WINDOWS #ifndef BH_PLATFORM_WINDOWS
/* Pop all jmpbuf_node except the last one */ /* Pop all jmpbuf_node except the last one */
@ -1055,9 +1055,23 @@ set_thread_cancel_flags(WASMExecEnv *exec_env)
#if WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_DEBUG_INTERP != 0
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM); wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM);
#endif #endif
exec_env->suspend_flags.flags |= 0x01; WASM_SUSPEND_FLAGS_FETCH_OR(exec_env->suspend_flags,
WASM_SUSPEND_FLAG_TERMINATE);
os_mutex_unlock(&exec_env->wait_lock); os_mutex_unlock(&exec_env->wait_lock);
#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP
wasm_runtime_interrupt_blocking_op(exec_env);
#endif
}
static void
clear_thread_cancel_flags(WASMExecEnv *exec_env)
{
os_mutex_lock(&exec_env->wait_lock);
WASM_SUSPEND_FLAGS_FETCH_AND(exec_env->suspend_flags,
~WASM_SUSPEND_FLAG_TERMINATE);
os_mutex_unlock(&exec_env->wait_lock);
} }
int32 int32
@ -1178,7 +1192,8 @@ void
wasm_cluster_suspend_thread(WASMExecEnv *exec_env) wasm_cluster_suspend_thread(WASMExecEnv *exec_env)
{ {
/* Set the suspend flag */ /* Set the suspend flag */
exec_env->suspend_flags.flags |= 0x02; WASM_SUSPEND_FLAGS_FETCH_OR(exec_env->suspend_flags,
WASM_SUSPEND_FLAG_SUSPEND);
} }
static void static void
@ -1214,7 +1229,8 @@ wasm_cluster_suspend_all_except_self(WASMCluster *cluster,
void void
wasm_cluster_resume_thread(WASMExecEnv *exec_env) wasm_cluster_resume_thread(WASMExecEnv *exec_env)
{ {
exec_env->suspend_flags.flags &= ~0x02; WASM_SUSPEND_FLAGS_FETCH_AND(exec_env->suspend_flags,
~WASM_SUSPEND_FLAG_SUSPEND);
os_cond_signal(&exec_env->wait_cond); os_cond_signal(&exec_env->wait_cond);
} }
@ -1234,76 +1250,55 @@ wasm_cluster_resume_all(WASMCluster *cluster)
os_mutex_unlock(&cluster->lock); os_mutex_unlock(&cluster->lock);
} }
struct spread_exception_data {
WASMExecEnv *skip;
const char *exception;
};
static void static void
set_exception_visitor(void *node, void *user_data) set_exception_visitor(void *node, void *user_data)
{ {
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; const struct spread_exception_data *data = user_data;
WASMExecEnv *exec_env = (WASMExecEnv *)user_data; WASMExecEnv *exec_env = (WASMExecEnv *)node;
WASMModuleInstanceCommon *module_inst = get_module_inst(exec_env);
WASMModuleInstance *wasm_inst = (WASMModuleInstance *)module_inst;
if (curr_exec_env != exec_env) { if (exec_env != data->skip) {
WASMModuleInstance *curr_wasm_inst = WASMModuleInstance *wasm_inst =
(WASMModuleInstance *)get_module_inst(curr_exec_env); (WASMModuleInstance *)get_module_inst(exec_env);
/* Only spread non "wasi proc exit" exception */ exception_lock(wasm_inst);
#if WASM_ENABLE_SHARED_MEMORY != 0 if (data->exception != NULL) {
WASMSharedMemNode *shared_mem_node = wasm_module_get_shared_memory( snprintf(wasm_inst->cur_exception, sizeof(wasm_inst->cur_exception),
(WASMModuleCommon *)curr_wasm_inst->module); "Exception: %s", data->exception);
if (shared_mem_node)
os_mutex_lock(&shared_mem_node->shared_mem_lock);
#endif
if (!strstr(wasm_inst->cur_exception, "wasi proc exit")) {
bh_memcpy_s(curr_wasm_inst->cur_exception,
sizeof(curr_wasm_inst->cur_exception),
wasm_inst->cur_exception,
sizeof(wasm_inst->cur_exception));
} }
#if WASM_ENABLE_SHARED_MEMORY != 0 else {
if (shared_mem_node) wasm_inst->cur_exception[0] = '\0';
os_mutex_unlock(&shared_mem_node->shared_mem_lock); }
#endif exception_unlock(wasm_inst);
/* Terminate the thread so it can exit from dead loops */ /* Terminate the thread so it can exit from dead loops */
set_thread_cancel_flags(curr_exec_env); if (data->exception != NULL) {
} set_thread_cancel_flags(exec_env);
} }
else {
static void clear_thread_cancel_flags(exec_env);
clear_exception_visitor(void *node, void *user_data) }
{
WASMExecEnv *exec_env = (WASMExecEnv *)user_data;
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
if (curr_exec_env != exec_env) {
WASMModuleInstance *curr_wasm_inst =
(WASMModuleInstance *)get_module_inst(curr_exec_env);
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *shared_mem_node = wasm_module_get_shared_memory(
(WASMModuleCommon *)curr_wasm_inst->module);
if (shared_mem_node)
os_mutex_lock(&shared_mem_node->shared_mem_lock);
#endif
curr_wasm_inst->cur_exception[0] = '\0';
#if WASM_ENABLE_SHARED_MEMORY != 0
if (shared_mem_node)
os_mutex_unlock(&shared_mem_node->shared_mem_lock);
#endif
} }
} }
void void
wasm_cluster_spread_exception(WASMExecEnv *exec_env, bool clear) wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception)
{ {
const bool has_exception = exception != NULL;
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env); WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
bh_assert(cluster); bh_assert(cluster);
struct spread_exception_data data;
data.skip = NULL;
data.exception = exception;
os_mutex_lock(&cluster->lock); os_mutex_lock(&cluster->lock);
cluster->has_exception = !clear; cluster->has_exception = has_exception;
traverse_list(&cluster->exec_env_list, traverse_list(&cluster->exec_env_list, set_exception_visitor, &data);
clear ? clear_exception_visitor : set_exception_visitor,
exec_env);
os_mutex_unlock(&cluster->lock); os_mutex_unlock(&cluster->lock);
} }
@ -1339,13 +1334,75 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
} }
} }
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
struct inst_set_context_data {
void *key;
void *ctx;
};
static void
set_context_visitor(void *node, void *user_data)
{
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
WASMModuleInstanceCommon *module_inst = get_module_inst(curr_exec_env);
const struct inst_set_context_data *data = user_data;
wasm_runtime_set_context(module_inst, data->key, data->ctx);
}
void
wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key,
void *ctx)
{
WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst);
if (exec_env == NULL) {
/* Maybe threads have not been started yet. */
wasm_runtime_set_context(module_inst, key, ctx);
}
else {
WASMCluster *cluster;
struct inst_set_context_data data;
data.key = key;
data.ctx = ctx;
cluster = wasm_exec_env_get_cluster(exec_env);
bh_assert(cluster);
os_mutex_lock(&cluster->lock);
traverse_list(&cluster->exec_env_list, set_context_visitor, &data);
os_mutex_unlock(&cluster->lock);
}
}
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
bool bool
wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env) wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env)
{ {
os_mutex_lock(&exec_env->wait_lock); os_mutex_lock(&exec_env->wait_lock);
bool is_thread_terminated = bool is_thread_terminated = (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags)
(exec_env->suspend_flags.flags & 0x01) ? true : false; & WASM_SUSPEND_FLAG_TERMINATE)
? true
: false;
os_mutex_unlock(&exec_env->wait_lock); os_mutex_unlock(&exec_env->wait_lock);
return is_thread_terminated; return is_thread_terminated;
} }
void
exception_lock(WASMModuleInstance *module_inst)
{
/*
* Note: this lock could be per module instance if desirable.
* We can revisit on AOT version bump.
* It probably doesn't matter though because the exception handling
* logic should not be executed too frequently anyway.
*/
os_mutex_lock(&_exception_lock);
}
void
exception_unlock(WASMModuleInstance *module_inst)
{
os_mutex_unlock(&_exception_lock);
}

View File

@ -139,7 +139,7 @@ WASMExecEnv *
wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst); wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst);
void void
wasm_cluster_spread_exception(WASMExecEnv *exec_env, bool clear); wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception);
WASMExecEnv * WASMExecEnv *
wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env); wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env);
@ -151,6 +151,10 @@ void
wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst, wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
void *custom_data); void *custom_data);
void
wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key,
void *ctx);
bool bool
wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env); wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env);

View File

@ -0,0 +1,2 @@
**/*.wasm
**/*.tflite

View File

@ -25,6 +25,7 @@ Build the runtime image for your execution target type.
* `cpu` * `cpu`
* `nvidia-gpu` * `nvidia-gpu`
* `vx-delegate` * `vx-delegate`
* `tpu`
``` ```
EXECUTION_TYPE=cpu EXECUTION_TYPE=cpu
@ -64,6 +65,8 @@ docker run \
``` ```
* (NVIDIA) GPU * (NVIDIA) GPU
* Requirements:
* [NVIDIA docker](https://github.com/NVIDIA/nvidia-docker).
``` ```
docker run \ docker run \
@ -76,25 +79,36 @@ docker run \
/assets/test_tensorflow.wasm /assets/test_tensorflow.wasm
``` ```
* vx-delegate for NPU (x86 simulater) * vx-delegate for NPU (x86 simulator)
``` ```
docker run \ docker run \
-v $PWD/core/iwasm/libraries/wasi-nn/test:/assets wasi-nn-vx-delegate \ -v $PWD/core/iwasm/libraries/wasi-nn/test:/assets \
--dir=/assets \ wasi-nn-vx-delegate \
--dir=/ \
--env="TARGET=gpu" \ --env="TARGET=gpu" \
/assets/test_tensorflow.wasm /assets/test_tensorflow_quantized.wasm
``` ```
* (Coral) TPU
* Requirements:
* [Coral USB](https://coral.ai/products/accelerator/).
```
Requirements: docker run \
* [NVIDIA docker](https://github.com/NVIDIA/nvidia-docker). --privileged \
--device=/dev/bus/usb:/dev/bus/usb \
-v $PWD/core/iwasm/libraries/wasi-nn/test:/assets \
wasi-nn-tpu \
--dir=/ \
--env="TARGET=tpu" \
/assets/test_tensorflow_quantized.wasm
```
## What is missing ## What is missing
Supported: Supported:
* Graph encoding: `tensorflowlite`. * Graph encoding: `tensorflowlite`.
* Execution target: `cpu` and `gpu`. * Execution target: `cpu`, `gpu` and `tpu`.
* Tensor type: `fp32`. * Tensor type: `fp32`.

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