mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-14 13:41:31 +00:00
Merge branch main into dev/thread_suspension
This commit is contained in:
commit
78bea3ac3b
10
.github/workflows/build_llvm_libraries.yml
vendored
10
.github/workflows/build_llvm_libraries.yml
vendored
|
@ -11,6 +11,9 @@ on:
|
||||||
arch:
|
arch:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
container_image:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
outputs:
|
outputs:
|
||||||
cache_key:
|
cache_key:
|
||||||
description: "A cached key of LLVM libraries"
|
description: "A cached key of LLVM libraries"
|
||||||
|
@ -19,6 +22,10 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
build_llvm_libraries:
|
build_llvm_libraries:
|
||||||
runs-on: ${{ inputs.os }}
|
runs-on: ${{ inputs.os }}
|
||||||
|
# Using given container image if it is specified.
|
||||||
|
# Otherwise, it will be ignored by the runner.
|
||||||
|
container:
|
||||||
|
image: ${{ inputs.container_image }}
|
||||||
outputs:
|
outputs:
|
||||||
key: ${{ steps.create_lib_cache_key.outputs.key}}
|
key: ${{ steps.create_lib_cache_key.outputs.key}}
|
||||||
|
|
||||||
|
@ -71,8 +78,9 @@ jobs:
|
||||||
0-ccache-${{ inputs.os }}
|
0-ccache-${{ inputs.os }}
|
||||||
if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && inputs.os == 'ubuntu-22.04'
|
if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && inputs.os == 'ubuntu-22.04'
|
||||||
|
|
||||||
|
# Don't install dependencies if the cache is hit or running in docker container
|
||||||
- run: sudo apt install -y ccache ninja-build
|
- run: sudo apt install -y ccache ninja-build
|
||||||
if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && startsWith(inputs.os, 'ubuntu')
|
if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && startsWith(inputs.os, 'ubuntu') && inputs.container_image == ''
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -444,6 +444,12 @@ jobs:
|
||||||
cmake --build . --config Release --parallel 4
|
cmake --build . --config Release --parallel 4
|
||||||
./iwasm wasm-apps/no_pthread.wasm
|
./iwasm wasm-apps/no_pthread.wasm
|
||||||
|
|
||||||
|
- name: Build Sample [shared-module]
|
||||||
|
run: |
|
||||||
|
cd samples/shared-module
|
||||||
|
./build.sh
|
||||||
|
./run.sh
|
||||||
|
|
||||||
test:
|
test:
|
||||||
needs:
|
needs:
|
||||||
[
|
[
|
||||||
|
|
6
.github/workflows/compilation_on_macos.yml
vendored
6
.github/workflows/compilation_on_macos.yml
vendored
|
@ -327,3 +327,9 @@ jobs:
|
||||||
cmake ..
|
cmake ..
|
||||||
cmake --build . --config Release --parallel 4
|
cmake --build . --config Release --parallel 4
|
||||||
./iwasm wasm-apps/no_pthread.wasm
|
./iwasm wasm-apps/no_pthread.wasm
|
||||||
|
|
||||||
|
- name: Build Sample [shared-module]
|
||||||
|
run: |
|
||||||
|
cd samples/shared-module
|
||||||
|
./build.sh
|
||||||
|
./run.sh
|
||||||
|
|
42
.github/workflows/compilation_on_nuttx.yml
vendored
42
.github/workflows/compilation_on_nuttx.yml
vendored
|
@ -50,7 +50,10 @@ env:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_iwasm_on_nuttx:
|
build_iwasm_on_nuttx:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:4b4cbf0b70512e61ada9cdcb76b97e90ad478b85e4d0774d05a95fa32caa8c39
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
nuttx_board_config: [
|
nuttx_board_config: [
|
||||||
|
@ -60,12 +63,14 @@ jobs:
|
||||||
"boards/arm/rp2040/raspberrypi-pico/configs/nsh",
|
"boards/arm/rp2040/raspberrypi-pico/configs/nsh",
|
||||||
# cortex-m7
|
# cortex-m7
|
||||||
"boards/arm/stm32h7/nucleo-h743zi/configs/nsh",
|
"boards/arm/stm32h7/nucleo-h743zi/configs/nsh",
|
||||||
# riscv32imac
|
# riscv32imc
|
||||||
|
"boards/risc-v/espressif/esp32c3-generic/configs/nsh",
|
||||||
|
# riscv32gc
|
||||||
"boards/risc-v/qemu-rv/rv-virt/configs/nsh",
|
"boards/risc-v/qemu-rv/rv-virt/configs/nsh",
|
||||||
# riscv64imac
|
|
||||||
"boards/risc-v/qemu-rv/rv-virt/configs/nsh64",
|
|
||||||
# riscv64gc
|
# riscv64gc
|
||||||
"boards/risc-v/k210/maix-bit/configs/nsh",
|
"boards/risc-v/qemu-rv/rv-virt/configs/nsh64",
|
||||||
|
# arm64
|
||||||
|
"boards/arm64/qemu/qemu-armv8a/configs/nsh",
|
||||||
]
|
]
|
||||||
wamr_config_option: [
|
wamr_config_option: [
|
||||||
"CONFIG_INTERPRETERS_WAMR=y\\nCONFIG_INTERPRETERS_WAMR_AOT=y\\nCONFIG_INTERPRETERS_WAMR_FAST=y\\n",
|
"CONFIG_INTERPRETERS_WAMR=y\\nCONFIG_INTERPRETERS_WAMR_AOT=y\\nCONFIG_INTERPRETERS_WAMR_FAST=y\\n",
|
||||||
|
@ -81,39 +86,18 @@ jobs:
|
||||||
]
|
]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install Utilities
|
|
||||||
run: |
|
|
||||||
sudo apt install -y kconfig-frontends-nox genromfs
|
|
||||||
pip3 install pyelftools
|
|
||||||
pip3 install cxxfilt
|
|
||||||
|
|
||||||
- name: Install ARM Compilers
|
|
||||||
if: contains(matrix.nuttx_board_config, 'arm')
|
|
||||||
run: sudo apt install -y gcc-arm-none-eabi
|
|
||||||
|
|
||||||
- name: Install RISC-V Compilers
|
|
||||||
if: contains(matrix.nuttx_board_config, 'risc-v')
|
|
||||||
run: |
|
|
||||||
curl -L -k https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz > riscv.tar.gz
|
|
||||||
tar xvf riscv.tar.gz
|
|
||||||
echo "$PWD/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin" >> $GITHUB_PATH
|
|
||||||
|
|
||||||
- name: Install WASI-SDK
|
|
||||||
run: |
|
|
||||||
curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz > wasi-sdk.tar.gz
|
|
||||||
tar xvf wasi-sdk.tar.gz
|
|
||||||
sudo mv wasi-sdk-* /opt/wasi-sdk
|
|
||||||
|
|
||||||
- name: Checkout NuttX
|
- name: Checkout NuttX
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: apache/incubator-nuttx
|
repository: apache/incubator-nuttx
|
||||||
|
ref: releases/12.3
|
||||||
path: nuttx
|
path: nuttx
|
||||||
|
|
||||||
- name: Checkout NuttX Apps
|
- name: Checkout NuttX Apps
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: apache/incubator-nuttx-apps
|
repository: apache/incubator-nuttx-apps
|
||||||
|
ref: releases/12.3
|
||||||
path: apps
|
path: apps
|
||||||
|
|
||||||
- name: Checkout WAMR
|
- name: Checkout WAMR
|
||||||
|
@ -124,7 +108,7 @@ jobs:
|
||||||
|
|
||||||
- name: Enable WAMR for NuttX
|
- name: Enable WAMR for NuttX
|
||||||
run: |
|
run: |
|
||||||
find nuttx/boards -name defconfig | xargs sed -i '$a\CONFIG_EOL_IS_LF=y\nCONFIG_PSEUDOFS_SOFTLINKS=y\n${{ matrix.wamr_config_option }}'
|
find nuttx/boards -name defconfig | xargs sed -i '$a\CONFIG_EOL_IS_LF=y\n${{ matrix.wamr_config_option }}'
|
||||||
find nuttx/boards/sim -name defconfig | xargs sed -i '$a\CONFIG_LIBM=y\n'
|
find nuttx/boards/sim -name defconfig | xargs sed -i '$a\CONFIG_LIBM=y\n'
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|
61
.github/workflows/compilation_on_windows.yml
vendored
61
.github/workflows/compilation_on_windows.yml
vendored
|
@ -39,6 +39,16 @@ on:
|
||||||
# allow to be triggered manually
|
# allow to be triggered manually
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
# For Spec Test
|
||||||
|
DEFAULT_TEST_OPTIONS: "-s spec -b"
|
||||||
|
MULTI_MODULES_TEST_OPTIONS: "-s spec -b -M"
|
||||||
|
THREADS_TEST_OPTIONS: "-s spec -b -p"
|
||||||
|
WASI_TEST_OPTIONS: "-s wasi_certification -w"
|
||||||
|
WASI_TEST_FILTER: ${{ github.workspace }}/product-mini/platforms/windows/wasi_filtered_tests.json
|
||||||
|
# Used when building the WASI socket and thread tests
|
||||||
|
CC: ${{ github.workspace }}/wasi-sdk/bin/clang
|
||||||
|
|
||||||
# Cancel any in-flight jobs for the same PR/branch so there's only one active
|
# Cancel any in-flight jobs for the same PR/branch so there's only one active
|
||||||
# at a time
|
# at a time
|
||||||
concurrency:
|
concurrency:
|
||||||
|
@ -60,12 +70,14 @@ jobs:
|
||||||
"-DWAMR_BUILD_SIMD=1",
|
"-DWAMR_BUILD_SIMD=1",
|
||||||
"-DWAMR_BUILD_DEBUG_INTERP=1",
|
"-DWAMR_BUILD_DEBUG_INTERP=1",
|
||||||
"-DWAMR_BUILD_LIB_PTHREAD=1",
|
"-DWAMR_BUILD_LIB_PTHREAD=1",
|
||||||
"-DWAMR_BUILD_LIB_WASI_THREADS=1"
|
"-DWAMR_BUILD_LIB_WASI_THREADS=1",
|
||||||
|
"-DWAMR_BUILD_LIBC_UVWASI=0 -DWAMR_BUILD_LIBC_WASI=1"
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: clone uvwasi library
|
- name: clone uvwasi library
|
||||||
|
if: ${{ !contains(matrix.build_options, '-DWAMR_BUILD_LIBC_UVWASI=0') }}
|
||||||
run: |
|
run: |
|
||||||
cd core/deps
|
cd core/deps
|
||||||
git clone https://github.com/nodejs/uvwasi.git
|
git clone https://github.com/nodejs/uvwasi.git
|
||||||
|
@ -75,3 +87,50 @@ jobs:
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. ${{ matrix.build_options }}
|
cmake .. ${{ matrix.build_options }}
|
||||||
cmake --build . --config Release --parallel 4
|
cmake --build . --config Release --parallel 4
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: [build]
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
running_mode:
|
||||||
|
[
|
||||||
|
"classic-interp",
|
||||||
|
"fast-interp",
|
||||||
|
]
|
||||||
|
test_option:
|
||||||
|
[
|
||||||
|
$DEFAULT_TEST_OPTIONS,
|
||||||
|
$MULTI_MODULES_TEST_OPTIONS,
|
||||||
|
$THREADS_TEST_OPTIONS,
|
||||||
|
$WASI_TEST_OPTIONS,
|
||||||
|
]
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: download and install wasi-sdk
|
||||||
|
if: matrix.test_option == '$WASI_TEST_OPTIONS'
|
||||||
|
run: |
|
||||||
|
curl "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0.m-mingw.tar.gz" -o wasi-sdk.tar.gz -L
|
||||||
|
mkdir wasi-sdk
|
||||||
|
tar -xzf wasi-sdk.tar.gz -C wasi-sdk --strip-components 1
|
||||||
|
|
||||||
|
- name: build socket api tests
|
||||||
|
shell: bash
|
||||||
|
if: matrix.test_option == '$WASI_TEST_OPTIONS'
|
||||||
|
run: ./build.sh
|
||||||
|
working-directory: ./core/iwasm/libraries/lib-socket/test/
|
||||||
|
|
||||||
|
- name: Build WASI thread tests
|
||||||
|
shell: bash
|
||||||
|
if: matrix.test_option == '$WASI_TEST_OPTIONS'
|
||||||
|
run: ./build.sh
|
||||||
|
working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/
|
||||||
|
|
||||||
|
- name: run tests
|
||||||
|
shell: bash
|
||||||
|
timeout-minutes: 20
|
||||||
|
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
|
||||||
|
working-directory: ./tests/wamr-test-suites
|
||||||
|
|
44
.github/workflows/nightly_run.yml
vendored
44
.github/workflows/nightly_run.yml
vendored
|
@ -49,10 +49,17 @@ jobs:
|
||||||
with:
|
with:
|
||||||
os: "ubuntu-20.04"
|
os: "ubuntu-20.04"
|
||||||
arch: "X86"
|
arch: "X86"
|
||||||
|
build_llvm_libraries_on_ubuntu_2204:
|
||||||
|
uses: ./.github/workflows/build_llvm_libraries.yml
|
||||||
|
with:
|
||||||
|
os: "ubuntu-22.04"
|
||||||
|
arch: "X86"
|
||||||
|
|
||||||
build_wamrc:
|
build_wamrc:
|
||||||
needs:
|
needs:
|
||||||
[build_llvm_libraries_on_ubuntu_2004]
|
[
|
||||||
|
build_llvm_libraries_on_ubuntu_2004,
|
||||||
|
]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -90,7 +97,9 @@ jobs:
|
||||||
|
|
||||||
build_iwasm:
|
build_iwasm:
|
||||||
needs:
|
needs:
|
||||||
[build_llvm_libraries_on_ubuntu_2004]
|
[
|
||||||
|
build_llvm_libraries_on_ubuntu_2004,
|
||||||
|
]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -492,19 +501,26 @@ jobs:
|
||||||
cmake ..
|
cmake ..
|
||||||
cmake --build . --config Release --parallel 4
|
cmake --build . --config Release --parallel 4
|
||||||
./iwasm wasm-apps/no_pthread.wasm
|
./iwasm wasm-apps/no_pthread.wasm
|
||||||
|
|
||||||
|
- name: Build Sample [shared-module]
|
||||||
|
run: |
|
||||||
|
cd samples/shared-module
|
||||||
|
./build.sh
|
||||||
|
./run.sh
|
||||||
test:
|
test:
|
||||||
needs:
|
needs:
|
||||||
[
|
[
|
||||||
build_iwasm,
|
build_iwasm,
|
||||||
build_llvm_libraries_on_ubuntu_2004,
|
build_llvm_libraries_on_ubuntu_2004,
|
||||||
|
build_llvm_libraries_on_ubuntu_2204,
|
||||||
build_wamrc,
|
build_wamrc,
|
||||||
]
|
]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04]
|
os: [ubuntu-20.04, ubuntu-22.04]
|
||||||
sanitizer: ["", "ubsan", "asan"]
|
sanitizer: ["", "ubsan", "asan", "tsan"]
|
||||||
running_mode:
|
running_mode:
|
||||||
[
|
[
|
||||||
"classic-interp",
|
"classic-interp",
|
||||||
|
@ -530,11 +546,14 @@ jobs:
|
||||||
- os: ubuntu-20.04
|
- os: ubuntu-20.04
|
||||||
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
|
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
|
||||||
ubuntu_version: "20.04"
|
ubuntu_version: "20.04"
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
|
||||||
|
ubuntu_version: "22.04"
|
||||||
|
|
||||||
exclude:
|
exclude:
|
||||||
# uncompatiable modes and features
|
# uncompatiable modes and features
|
||||||
- os: ubuntu-20.04
|
- os: ubuntu-20.04
|
||||||
sanitizer: asan
|
sanitizer: tsan
|
||||||
# asan works only for aot now
|
# asan works only for aot now
|
||||||
- running_mode: "classic-interp"
|
- running_mode: "classic-interp"
|
||||||
sanitizer: asan
|
sanitizer: asan
|
||||||
|
@ -546,6 +565,14 @@ jobs:
|
||||||
sanitizer: asan
|
sanitizer: asan
|
||||||
- running_mode: "multi-tier-jit"
|
- running_mode: "multi-tier-jit"
|
||||||
sanitizer: asan
|
sanitizer: asan
|
||||||
|
- running_mode: "classic-interp"
|
||||||
|
sanitizer: tsan
|
||||||
|
- running_mode: "jit"
|
||||||
|
sanitizer: tsan
|
||||||
|
- running_mode: "fast-jit"
|
||||||
|
sanitizer: tsan
|
||||||
|
- running_mode: "multi-tier-jit"
|
||||||
|
sanitizer: tsan
|
||||||
# classic-interp and fast-interp don't support simd
|
# classic-interp and fast-interp don't support simd
|
||||||
- running_mode: "classic-interp"
|
- running_mode: "classic-interp"
|
||||||
test_option: $SIMD_TEST_OPTIONS
|
test_option: $SIMD_TEST_OPTIONS
|
||||||
|
@ -596,8 +623,9 @@ jobs:
|
||||||
&& matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit'
|
&& matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit'
|
||||||
run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV
|
run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: set sanitizer
|
- name: set additional tsan options
|
||||||
run: echo "WAMR_BUILD_SANITIZER=${{ matrix.sanitizer }}" >> $GITHUB_ENV
|
run: echo "TSAN_OPTIONS=suppressions=$PWD/tsan_suppressions.txt" >> $GITHUB_ENV
|
||||||
|
working-directory: tests/wamr-test-suites
|
||||||
|
|
||||||
#only download llvm libraries in jit and aot mode
|
#only download llvm libraries in jit and aot mode
|
||||||
- name: Get LLVM libraries
|
- name: Get LLVM libraries
|
||||||
|
@ -638,7 +666,7 @@ jobs:
|
||||||
|
|
||||||
- name: run tests
|
- name: run tests
|
||||||
timeout-minutes: 40
|
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 }} -T "${{ matrix.sanitizer }}"
|
||||||
working-directory: ./tests/wamr-test-suites
|
working-directory: ./tests/wamr-test-suites
|
||||||
|
|
||||||
#only install x32 support libraries when to run x86_32 cases
|
#only install x32 support libraries when to run x86_32 cases
|
||||||
|
|
6
.github/workflows/release_process.yml
vendored
6
.github/workflows/release_process.yml
vendored
|
@ -56,21 +56,21 @@ jobs:
|
||||||
uses: ./.github/workflows/build_llvm_libraries.yml
|
uses: ./.github/workflows/build_llvm_libraries.yml
|
||||||
with:
|
with:
|
||||||
os: "ubuntu-20.04"
|
os: "ubuntu-20.04"
|
||||||
arch: "X86"
|
arch: "AArch64 ARM Mips RISCV X86"
|
||||||
|
|
||||||
build_llvm_libraries_on_ubuntu_2204:
|
build_llvm_libraries_on_ubuntu_2204:
|
||||||
needs: [create_tag, create_release]
|
needs: [create_tag, create_release]
|
||||||
uses: ./.github/workflows/build_llvm_libraries.yml
|
uses: ./.github/workflows/build_llvm_libraries.yml
|
||||||
with:
|
with:
|
||||||
os: "ubuntu-22.04"
|
os: "ubuntu-22.04"
|
||||||
arch: "X86"
|
arch: "AArch64 ARM Mips RISCV X86"
|
||||||
|
|
||||||
build_llvm_libraries_on_macos:
|
build_llvm_libraries_on_macos:
|
||||||
needs: [create_tag, create_release]
|
needs: [create_tag, create_release]
|
||||||
uses: ./.github/workflows/build_llvm_libraries.yml
|
uses: ./.github/workflows/build_llvm_libraries.yml
|
||||||
with:
|
with:
|
||||||
os: "macos-latest"
|
os: "macos-latest"
|
||||||
arch: "X86"
|
arch: "AArch64 ARM Mips RISCV X86"
|
||||||
|
|
||||||
#
|
#
|
||||||
# WAMRC
|
# WAMRC
|
||||||
|
|
158
.github/workflows/spec_test_on_nuttx.yml
vendored
158
.github/workflows/spec_test_on_nuttx.yml
vendored
|
@ -4,6 +4,13 @@
|
||||||
name: spec test on nuttx
|
name: spec test on nuttx
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
paths:
|
||||||
|
- ".github/workflows/spec_test_on_nuttx.yml"
|
||||||
|
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
|
@ -12,6 +19,8 @@ on:
|
||||||
env:
|
env:
|
||||||
LLVM_CACHE_SUFFIX: "build-llvm_libraries_ex"
|
LLVM_CACHE_SUFFIX: "build-llvm_libraries_ex"
|
||||||
WASI_SDK_PATH: "/opt/wasi-sdk"
|
WASI_SDK_PATH: "/opt/wasi-sdk"
|
||||||
|
WAMR_COMMON_OPTION:
|
||||||
|
"CONFIG_INTERPRETERS_WAMR=y\\nCONFIG_INTERPRETERS_WAMR_STACKSIZE=32768\\nCONFIG_INTERPRETERS_WAMR_LOG=y\\nCONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN=y\\nCONFIG_INTERPRETERS_WAMR_REF_TYPES=y\\nCONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST=y\\nCONFIG_INTERPRETERS_WAMR_SHARED_MEMORY=y\\nCONFIG_INTERPRETERS_WAMR_BULK_MEMORY=y\\nCONFIG_EOL_IS_LF=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE=y\\nCONFIG_RISCV_SEMIHOSTING_HOSTFS=y\\nCONFIG_FS_HOSTFS=y\\nCONFIG_LIBC_FLOATINGPOINT=y\\n"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_llvm_libraries:
|
build_llvm_libraries:
|
||||||
|
@ -19,59 +28,85 @@ jobs:
|
||||||
with:
|
with:
|
||||||
os: "ubuntu-22.04"
|
os: "ubuntu-22.04"
|
||||||
arch: "ARM RISCV AArch64"
|
arch: "ARM RISCV AArch64"
|
||||||
|
container_image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:4b4cbf0b70512e61ada9cdcb76b97e90ad478b85e4d0774d05a95fa32caa8c39
|
||||||
|
|
||||||
spec_test_on_qemu:
|
spec_test_on_qemu:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ubuntu-latest
|
||||||
needs: [build_llvm_libraries]
|
needs: [build_llvm_libraries]
|
||||||
|
container:
|
||||||
|
image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:4b4cbf0b70512e61ada9cdcb76b97e90ad478b85e4d0774d05a95fa32caa8c39
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04]
|
target_config: [
|
||||||
nuttx_board_config: [
|
# {
|
||||||
# cortex-a9
|
# config: "boards/arm64/qemu/qemu-armv8a/configs/nsh",
|
||||||
"boards/arm/imx6/sabre-6quad/configs/nsh",
|
# target: "aarch64_vfp",
|
||||||
# riscv32imac
|
# fpu_type: "fp"
|
||||||
"boards/risc-v/qemu-rv/rv-virt/configs/nsh",
|
# },
|
||||||
# riscv64imac
|
# {
|
||||||
# "boards/risc-v/qemu-rv/rv-virt/configs/nsh64",
|
# config: "boards/arm/imx6/sabre-6quad/configs/nsh",
|
||||||
|
# target: "thumbv7",
|
||||||
|
# fpu_type: "none"
|
||||||
|
# },
|
||||||
|
{
|
||||||
|
config: "boards/arm/imx6/sabre-6quad/configs/nsh",
|
||||||
|
target: "thumbv7_vfp",
|
||||||
|
fpu_type: "dp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: "boards/risc-v/qemu-rv/rv-virt/configs/nsh",
|
||||||
|
target: "riscv32",
|
||||||
|
fpu_type: "none"
|
||||||
|
},
|
||||||
|
# {
|
||||||
|
# config: "boards/risc-v/qemu-rv/rv-virt/configs/nsh",
|
||||||
|
# target: "riscv32_ilp32d",
|
||||||
|
# fpu_type: "dp"
|
||||||
|
# },
|
||||||
|
{
|
||||||
|
config: "boards/risc-v/qemu-rv/rv-virt/configs/nsh64",
|
||||||
|
target: "riscv64",
|
||||||
|
fpu_type: "none"
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
wamr_test_option: [
|
wamr_test_option: [
|
||||||
# "-t fast-interp",
|
{
|
||||||
"-t aot",
|
mode: "-t aot",
|
||||||
"-t aot -X"
|
option: "CONFIG_INTERPRETERS_WAMR_AOT=y\\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mode: "-t aot -X",
|
||||||
|
option: "CONFIG_INTERPRETERS_WAMR_AOT=y\\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mode: "-t classic-interp",
|
||||||
|
option: "CONFIG_INTERPRETERS_WAMR_CLASSIC=y\\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mode: "-t fast-interp",
|
||||||
|
option: "CONFIG_INTERPRETERS_WAMR_FAST=y\\n"
|
||||||
|
},
|
||||||
]
|
]
|
||||||
llvm_cache_key: [ "${{ needs.build_llvm_libraries.outputs.cache_key }}" ]
|
|
||||||
|
exclude:
|
||||||
|
# XIP is not fully supported yet on RISCV64, some relocations can not be resolved
|
||||||
|
- target_config: { config: "boards/risc-v/qemu-rv/rv-virt/configs/nsh64" }
|
||||||
|
wamr_test_option: { mode: "-t aot -X" }
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install Utilities
|
|
||||||
run: |
|
|
||||||
sudo apt install -y kconfig-frontends-nox genromfs
|
|
||||||
|
|
||||||
- name: Install ARM Compilers
|
|
||||||
if: contains(matrix.nuttx_board_config, 'arm')
|
|
||||||
run: sudo apt install -y gcc-arm-none-eabi
|
|
||||||
|
|
||||||
- name: Install RISC-V Compilers
|
|
||||||
if: contains(matrix.nuttx_board_config, 'risc-v')
|
|
||||||
run: |
|
|
||||||
curl -L -k https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz > riscv.tar.gz
|
|
||||||
tar xvf riscv.tar.gz
|
|
||||||
echo "$PWD/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin" >> $GITHUB_PATH
|
|
||||||
|
|
||||||
- name: Install WASI-SDK
|
|
||||||
run: |
|
|
||||||
curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz > wasi-sdk.tar.gz
|
|
||||||
tar xvf wasi-sdk.tar.gz
|
|
||||||
sudo mv wasi-sdk-* /opt/wasi-sdk
|
|
||||||
|
|
||||||
- name: Checkout NuttX
|
- name: Checkout NuttX
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: apache/incubator-nuttx
|
repository: apache/incubator-nuttx
|
||||||
|
ref: releases/12.3
|
||||||
path: nuttx
|
path: nuttx
|
||||||
|
|
||||||
- name: Checkout NuttX Apps
|
- name: Checkout NuttX Apps
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: apache/incubator-nuttx-apps
|
repository: apache/incubator-nuttx-apps
|
||||||
|
ref: releases/12.3
|
||||||
path: apps
|
path: apps
|
||||||
|
|
||||||
- name: Checkout WAMR
|
- name: Checkout WAMR
|
||||||
|
@ -81,6 +116,7 @@ jobs:
|
||||||
path: apps/interpreters/wamr/wamr
|
path: apps/interpreters/wamr/wamr
|
||||||
|
|
||||||
- name: Get LLVM libraries
|
- name: Get LLVM libraries
|
||||||
|
if: contains(matrix.wamr_test_option.mode, 'aot')
|
||||||
id: retrieve_llvm_libs
|
id: retrieve_llvm_libs
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
|
@ -90,56 +126,50 @@ jobs:
|
||||||
./core/deps/llvm/build/lib
|
./core/deps/llvm/build/lib
|
||||||
./core/deps/llvm/build/libexec
|
./core/deps/llvm/build/libexec
|
||||||
./core/deps/llvm/build/share
|
./core/deps/llvm/build/share
|
||||||
key: ${{ matrix.llvm_cache_key }}
|
key: ${{ needs.build_llvm_libraries.outputs.cache_key }}
|
||||||
|
|
||||||
- name: Quit if cache miss
|
- name: Quit if cache miss
|
||||||
if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true'
|
if: contains(matrix.wamr_test_option.mode, 'aot') && steps.retrieve_llvm_libs.outputs.cache-hit != 'true'
|
||||||
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
|
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
|
||||||
|
|
||||||
- name: Copy LLVM
|
- name: Copy LLVM
|
||||||
|
if: contains(matrix.wamr_test_option.mode, 'aot')
|
||||||
run: cp -r core/deps/llvm apps/interpreters/wamr/wamr/core/deps/llvm
|
run: cp -r core/deps/llvm apps/interpreters/wamr/wamr/core/deps/llvm
|
||||||
|
|
||||||
- name: Enable WAMR for NuttX
|
- name: Enable WAMR for NuttX
|
||||||
run: |
|
run: |
|
||||||
find nuttx/boards -name defconfig | xargs sed -i '$a\CONFIG_INTERPRETERS_WAMR=y\nCONFIG_INTERPRETERS_WAMR_STACKSIZE=32768\nCONFIG_INTERPRETERS_WAMR_AOT=y\nCONFIG_INTERPRETERS_WAMR_FAST=y\nCONFIG_INTERPRETERS_WAMR_LOG=y\nCONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN=y\nCONFIG_INTERPRETERS_WAMR_REF_TYPES=y\nCONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST=y\nCONFIG_INTERPRETERS_WAMR_SHARED_MEMORY=y\nCONFIG_INTERPRETERS_WAMR_BULK_MEMORY=y\n'
|
find nuttx/boards -name defconfig | xargs sed -i '$a\${{ env.WAMR_COMMON_OPTION }}'
|
||||||
find nuttx/boards -name defconfig | xargs sed -i '$a\CONFIG_EOL_IS_LF=y\nCONFIG_ARM_SEMIHOSTING_HOSTFS=y\nCONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE=y\nCONFIG_RISCV_SEMIHOSTING_HOSTFS=y\nCONFIG_FS_HOSTFS=y\nCONFIG_LIBC_FLOATINGPOINT=y\n'
|
|
||||||
|
- name: Enable WAMR Interpreter for NuttX
|
||||||
|
run: |
|
||||||
|
find nuttx/boards -name defconfig | xargs sed -i '$a\${{ matrix.wamr_test_option.option }}'
|
||||||
|
|
||||||
|
- name: Disable FPU for NuttX
|
||||||
|
if: matrix.target_config.fpu_type == 'none'
|
||||||
|
run: |
|
||||||
|
find nuttx/boards -name defconfig | xargs sed -i '$a\# CONFIG_ARCH_FPU is not set\n'
|
||||||
|
|
||||||
|
- name: Disable DPFPU for NuttX
|
||||||
|
if: matrix.target_config.fpu_type == 'fp'
|
||||||
|
run: |
|
||||||
|
find nuttx/boards -name defconfig | xargs sed -i '$a\# CONFIG_ARCH_DPFPU is not set\n'
|
||||||
|
|
||||||
- name: Build wamrc
|
- name: Build wamrc
|
||||||
|
if: contains(matrix.wamr_test_option.mode, 'aot')
|
||||||
working-directory: apps/interpreters/wamr/wamr/wamr-compiler
|
working-directory: apps/interpreters/wamr/wamr/wamr-compiler
|
||||||
run: |
|
run: |
|
||||||
cmake -Bbuild .
|
cmake -Bbuild .
|
||||||
cmake --build build
|
cmake --build build
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
id: build_firmware
|
||||||
run: |
|
run: |
|
||||||
cd nuttx
|
cd nuttx
|
||||||
tools/configure.sh ${{ matrix.nuttx_board_config }}
|
tools/configure.sh ${{ matrix.target_config.config }}
|
||||||
make -j$(nproc)
|
make -j$(nproc)
|
||||||
echo "firmware=$PWD/nuttx" >> $GITHUB_ENV
|
echo "firmware=$PWD/nuttx" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Test on ARM
|
- name: Test
|
||||||
if: endsWith(matrix.nuttx_board_config, 'sabre-6quad/configs/nsh')
|
|
||||||
run: |
|
run: |
|
||||||
curl -L https://github.com/xpack-dev-tools/qemu-arm-xpack/releases/download/v7.1.0-1/xpack-qemu-arm-7.1.0-1-linux-x64.tar.gz > xpack-qemu-arm.tar.gz
|
|
||||||
tar xvf xpack-qemu-arm.tar.gz
|
|
||||||
export PATH=$PATH:$PWD/xpack-qemu-arm-7.1.0-1/bin
|
|
||||||
cd apps/interpreters/wamr/wamr/tests/wamr-test-suites
|
cd apps/interpreters/wamr/wamr/tests/wamr-test-suites
|
||||||
./test_wamr.sh -s spec ${{ matrix.wamr_test_option }} -m thumbv7_vfp -b -Q -P -F ${{ env.firmware }}
|
./test_wamr.sh -s spec ${{ matrix.wamr_test_option.mode }} -m ${{ matrix.target_config.target }} -b -Q -P -F ${{ steps.build_firmware.outputs.firmware }}
|
||||||
|
|
||||||
- name: Test on RISCV32
|
|
||||||
if: endsWith(matrix.nuttx_board_config, 'rv-virt/configs/nsh')
|
|
||||||
run: |
|
|
||||||
curl -L https://github.com/xpack-dev-tools/qemu-riscv-xpack/releases/download/v7.1.0-1/xpack-qemu-riscv-7.1.0-1-linux-x64.tar.gz > xpack-qemu-riscv.tar.gz
|
|
||||||
tar xvf xpack-qemu-riscv.tar.gz
|
|
||||||
export PATH=$PATH:$PWD/xpack-qemu-riscv-7.1.0-1/bin
|
|
||||||
cd apps/interpreters/wamr/wamr/tests/wamr-test-suites
|
|
||||||
./test_wamr.sh -s spec ${{ matrix.wamr_test_option }} -m RISCV32 -b -Q -P -F ${{ env.firmware }}
|
|
||||||
|
|
||||||
- name: Test on RISCV64
|
|
||||||
if: endsWith(matrix.nuttx_board_config, 'rv-virt/configs/nsh64')
|
|
||||||
run: |
|
|
||||||
curl -L https://github.com/xpack-dev-tools/qemu-riscv-xpack/releases/download/v7.1.0-1/xpack-qemu-riscv-7.1.0-1-linux-x64.tar.gz > xpack-qemu-riscv.tar.gz
|
|
||||||
tar xvf xpack-qemu-riscv.tar.gz
|
|
||||||
export PATH=$PATH:$PWD/xpack-qemu-riscv-7.1.0-1/bin
|
|
||||||
cd apps/interpreters/wamr/wamr/tests/wamr-test-suites
|
|
||||||
./test_wamr.sh -s spec ${{ matrix.wamr_test_option }} -m riscv64 -b -Q -P -F ${{ env.firmware }}
|
|
||||||
|
|
|
@ -107,11 +107,6 @@ 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")
|
||||||
|
@ -146,15 +141,6 @@ 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)
|
||||||
|
@ -176,12 +162,3 @@ 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 ()
|
|
||||||
|
|
|
@ -92,8 +92,10 @@ The current TSC members:
|
||||||
- [lum1n0us](https://github.com/lum1n0us) - **Liang He**, <liang.he@intel.com>
|
- [lum1n0us](https://github.com/lum1n0us) - **Liang He**, <liang.he@intel.com>
|
||||||
- [no1wudi](https://github.com/no1wudi) **Qi Huang**, <huangqi3@xiaomi.com>
|
- [no1wudi](https://github.com/no1wudi) **Qi Huang**, <huangqi3@xiaomi.com>
|
||||||
- [qinxk-inter](https://github.com/qinxk-inter) - **Xiaokang Qin**, <xiaokang.qxk@antgroup.com>
|
- [qinxk-inter](https://github.com/qinxk-inter) - **Xiaokang Qin**, <xiaokang.qxk@antgroup.com>
|
||||||
|
- [ttrenner ](https://github.com/ttrenner) - **Trenner, Thomas**, <trenner.thomas@siemens.com>
|
||||||
- [wei-tang](https://github.com/wei-tang) - **Wei Tang**, <tangwei.tang@antgroup.com>
|
- [wei-tang](https://github.com/wei-tang) - **Wei Tang**, <tangwei.tang@antgroup.com>
|
||||||
- [wenyongh](https://github.com/wenyongh) - **Wenyong Huang**, <wenyong.huang@intel.com>
|
- [wenyongh](https://github.com/wenyongh) - **Wenyong Huang**, <wenyong.huang@intel.com>
|
||||||
|
- [woodsmc](https://github.com/woodsmc) - **Woods, Chris**, <chris.woods@siemens.com>
|
||||||
- [xujuntwt95329](https://github.com/xujuntwt95329) - **Jun Xu**, <Jun1.Xu@intel.com>
|
- [xujuntwt95329](https://github.com/xujuntwt95329) - **Jun Xu**, <Jun1.Xu@intel.com>
|
||||||
- [xwang98](https://github.com/xwang98) - **Xin Wang**, <xin.wang@intel.com> (chair)
|
- [xwang98](https://github.com/xwang98) - **Xin Wang**, <xin.wang@intel.com> (chair)
|
||||||
- [yamt](https://github.com/yamt) - **Takashi Yamamoto**, <yamamoto@midokura.com>
|
- [yamt](https://github.com/yamt) - **Takashi Yamamoto**, <yamamoto@midokura.com>
|
||||||
|
|
169
RELEASE_NOTES.md
169
RELEASE_NOTES.md
|
@ -1,3 +1,172 @@
|
||||||
|
## WAMR-1.3.0
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
- Abstract POSIX filesystem functions (#2585)
|
||||||
|
- Change API wasm_runtime_set_wasi_args_ex's arguments
|
||||||
|
`int stdinfd/stdoutfd/stderrfd` to `int64_t stdinfd/stdoutfd/stderrfd`
|
||||||
|
- core/iwasm: Support mapped file system access on non-libuv WASI (#2628)
|
||||||
|
- Enable mapping host directories to guest directories by parsing
|
||||||
|
the `map_dir_list` argument in API `wasm_runtime_init_wasi` for libc-wasi
|
||||||
|
- Support muti-module for AOT mode (#2482)
|
||||||
|
- Add argument `package_type_t module_type` for module_reader callback
|
||||||
|
- Generate jitdump to support linux perf for LLVM JIT (#2788)
|
||||||
|
- Add a field `bool linux_perf_support` in RuntimeInitArgs
|
||||||
|
- Remove provision of unnecessary fd rights (#2579)
|
||||||
|
- libc-wasi: Conditionally support SYNC flags (#2581)
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
- Support muti-module for AOT mode (#2482)
|
||||||
|
- Implement libc-wasi for Windows platform (#2740)
|
||||||
|
- Implement module instance context APIs (#2436)
|
||||||
|
- Implement async termination of blocking thread (#2516)
|
||||||
|
- Generate jitdump to support linux perf for LLVM JIT (#2788)
|
||||||
|
- Add Cosmopolitan Libc Platform (#2598)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- sgx-ra: Disable the building of samples (#2507)
|
||||||
|
- Handle a return from wasi _start function correctly (#2529)
|
||||||
|
- fd_object_release: Preserve errno (#2535)
|
||||||
|
- Fix build error with ancient GCC (4.8) (#2553)
|
||||||
|
- Fix compiling error for RT-Thread (#2569)
|
||||||
|
- Fix potential unaligned store issue when extra return value is v128 (#2583)
|
||||||
|
- Fix loader push_pop_frame_ref_offset (#2590)
|
||||||
|
- Fix compilation error on Android platform (#2594)
|
||||||
|
- Ignore handling SIG_DFL/SIG_IGN for previous sig action (#2589)
|
||||||
|
- Fix nightly run sanitizer error in Fast JIT (#2601)
|
||||||
|
- Check ValueKind before extracting a constant int value (#2595)
|
||||||
|
- Patch implementations of vfbinop(min,max,pmin,pax) (#2584)
|
||||||
|
- Improve stack trace dump and fix coding guideline CI (#2599)
|
||||||
|
- aot_resolve_stack_sizes: Disable the size check for now (#2608)
|
||||||
|
- Remove module instance from hashmap in wasi_nn_destroy (#2613)
|
||||||
|
- Fix label index out-of-range references in op_br_table_cache (#2615)
|
||||||
|
- Fix compilation of shift opcodes on x86_64 and i386 architectures (#2619)
|
||||||
|
- Fix potential issue in aot compiler when translating block opcodes (#2622)
|
||||||
|
- Use another default pipeline when opt-level is 0 (#2624)
|
||||||
|
- Fix AOT shift operations for indirect constants (#2627)
|
||||||
|
- Fix fast-interp "pre-compiled label offset out of range" issue (#2659)
|
||||||
|
- Revert "Strip static and shared libraries of iwasm to reduce the binary size (#2431)" (#2669)
|
||||||
|
- Fix windows compilation on C++20 (#2670)
|
||||||
|
- Fix fast-jit f32/f64 truncate to i32/i64 (#2671)
|
||||||
|
- Fix use getrandom on cosmopolitan libc (#2674)
|
||||||
|
- Fix repeatedly initialize shared memory data and protect the memory's fields (#2673)
|
||||||
|
- Minor fixes for Go bindings (#2676)
|
||||||
|
- Fix issues reported by Coverity (#2681)
|
||||||
|
- Add more buffer boundary checks in wasm loader (#2734)
|
||||||
|
- Grab cluster->lock when modifying exec_env->module_inst (#2685)
|
||||||
|
- Fix CMSIS import with Zephyr 3.4+ (#2744)
|
||||||
|
- Fix log messages in Zephyr example (#2761)
|
||||||
|
- Fix fast-jit callnative translation (#2765)
|
||||||
|
- aot compiler: Disable musttail for thumb (#2771)
|
||||||
|
- Fix data/elem drop (#2747)
|
||||||
|
- Fix formatting in aot_dump_perf_profiling (#2796)
|
||||||
|
- Fix formatting in wasm_dump_perf_profiling (#2799)
|
||||||
|
- Fix memory.init opcode issue in fast-interp (#2798)
|
||||||
|
- aot compiler: Fix handle next reachable if block (#2793)
|
||||||
|
- Fix configurable bounds checks typo (#2809)
|
||||||
|
- Attestation: Free JSON from the Wasm module heap (#2803)
|
||||||
|
- Update Zephyr support to v3.5.0 and make instructions generic to boards (#2805)
|
||||||
|
- Return error when shutdown() fails (#2801)
|
||||||
|
- iwasm: Print help when meeting unknown cmd options (#2824)
|
||||||
|
- Fix fast-jit accessing shared memory's fields issue (#2841)
|
||||||
|
- Fix wasm loader handle op_br_table and op_drop (#2864)
|
||||||
|
- Fix block with type issue in fast interp (#2866)
|
||||||
|
- Fix float argument handling for riscv32 ilp32d (#2871)
|
||||||
|
- Portably handle fd_advise on directory fd (#2875)
|
||||||
|
- Fix sample basic intToStr was called with wrong length (#2876)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
- Implement strict validation of thread IDs according to the specification (#2521)
|
||||||
|
- Stop abusing shared memory lock to protect exception (#2509)
|
||||||
|
- Implement os_usleep for posix (#2517)
|
||||||
|
- set_exception_visitor: Remove the special case for wasi proc exit (#2525)
|
||||||
|
- Revert "Return error when exception was raised after main thread finishes" (#2524)
|
||||||
|
- libc-wasi: Remove unused code (#2528)
|
||||||
|
- Add callback to handle memory.grow failures (#2522)
|
||||||
|
- Add context to enlarge memory error callback (#2546)
|
||||||
|
- Add ARM aeabi symbol for clearing memory content in a specific range (#2531)
|
||||||
|
- Unifdef -U WASMTIME_SSP_STATIC_CURFDS (#2533)
|
||||||
|
- Fix typo for IP address buffer (#2532)
|
||||||
|
- Add an API to terminate instance (#2538)
|
||||||
|
- Add user to enlarge memory error callback (#2546)
|
||||||
|
- runtest.py: Show accurate case amount in summary (#2549)
|
||||||
|
- Allow using custom signal handler from non-main thread (#2551)
|
||||||
|
- Return __WASI_EINVAL from fd_prestat_dir_name (#2580)
|
||||||
|
- Support AOT compiler with LLVM 17 (#2567)
|
||||||
|
- Add support for closing/renumbering preopen fds (#2578)
|
||||||
|
- Enable AOT usage on M1 mac (#2618)
|
||||||
|
- core/iwasm: Support mapped file system access on non-libuv WASI (#2628)
|
||||||
|
- Enable MASM automatically in runtime_lib.cmake (#2634)
|
||||||
|
- Abstract POSIX filesystem functions (#2585)
|
||||||
|
- Implement wasi clock_time/clock_res get (#2637)
|
||||||
|
- Fix several typo/warning/unused-code issues (#2655)
|
||||||
|
- Partial windows filesystem implementation (#2657)
|
||||||
|
- Apply no_sanitize_address for clang compiler in several places (#2663)
|
||||||
|
- Refactor clock functions to use WASI types (#2666)
|
||||||
|
- Refine lock/unlock shared memory (#2682)
|
||||||
|
- Fix several AOT compiler issues (#2697)
|
||||||
|
- Fix AOT compiler simd shift opcodes (#2715)
|
||||||
|
- Fix invalid use of jit_reg_is_const_val in fast-jit (#2718)
|
||||||
|
- Use user defined malloc/free functions for user defined memory allocator (#2717)
|
||||||
|
- Move WASI types into separate header (#2724)
|
||||||
|
- Provide default vprintf on UWP (#2725)
|
||||||
|
- Fix typo in Zephyr simple example (#2738)
|
||||||
|
- Fix switch-case fallthrough compilation warning (#2753)
|
||||||
|
- Add eabihf ABI support and set vendor-sys of bare-metal targets (#2745)
|
||||||
|
- Return uint32 from WASI functions (#2749)
|
||||||
|
- Add compilation flag to enable/disable heap corruption check (#2766)
|
||||||
|
- Extend os_mmap to support map file from fd (#2763)
|
||||||
|
- Fix printing ref.extern addresses in wasm_application.c (#2774)
|
||||||
|
- Remove unused JitBitmap (#2775)
|
||||||
|
- Use next generation crypto API on Windows (#2769)
|
||||||
|
- More precise help info of enabled targets for wamrc (#2783)
|
||||||
|
- Refine atomic operation flags in bh_atomic.h (#2780)
|
||||||
|
- Fix comment in WAMR_MEM_DUAL_BUS_MIRROR (#2791)
|
||||||
|
- Fix return type in wasm_loader_get_custom_section (#2794)
|
||||||
|
- Add support for custom sections in nuttx (#2795)
|
||||||
|
- Change is_shared_memory type from bool to uint8 (#2800)
|
||||||
|
- Fix typos in zephyr platform struct descriptions (#2818)
|
||||||
|
- Access linear memory size atomically (#2834)
|
||||||
|
- Output warning and quit if import/export name contains '\00' (#2806)
|
||||||
|
- Use wasm_config_t to pass private configuration to wasm_engine_new (#2837)
|
||||||
|
- core/iwasm/interpreter/wasm_loader.c: remove an extra validation (#2845)
|
||||||
|
- Don't add "+d" to riscv cpu features if already given (#2855)
|
||||||
|
- Fix compilation warnings on Windows (#2868)
|
||||||
|
|
||||||
|
### Others
|
||||||
|
- Add mutex stress test (#2472)
|
||||||
|
- Add unit tests for the tid allocator (#2519)
|
||||||
|
- Add support for running tests on apple M1 macs (#2554)
|
||||||
|
- export_native_api.md: Add a note about thread termination (#2572)
|
||||||
|
- test_wamr.sh: Print a bit more meaningful message (#2574)
|
||||||
|
- run_wasi_tests.sh: Provide stdin by ourselves (#2576)
|
||||||
|
- Fix a few issues in "run_wasi_tests.sh: provide stdin by ourselves" (#2582)
|
||||||
|
- Fix compile error of tsf benchmark (#2588)
|
||||||
|
- test_wamr.sh: Bump wasi-testsuite version (#2568)
|
||||||
|
- samples/inst-context-threads: Add a brief explanation (#2592)
|
||||||
|
- doc/memory_tune.md: "remove malloc" hack is not relevant to wasi-threads (#2603)
|
||||||
|
- Refactor stress tests to make them runnable in reactor mode (#2614)
|
||||||
|
- Run rust tests from wasi-testsuite (#2484)
|
||||||
|
- spec-test-script: Fix NaN comparision between v128 values (#2605)
|
||||||
|
- CI: Enable testing AOT multi-module feature (#2621)
|
||||||
|
- Vote for nomination of Woods, Chris and Trenner, Thomas as TSC members (#2638)
|
||||||
|
- Add tsan for fast interp and aot (#2679)
|
||||||
|
- Enable WASI tests on Windows CI (#2699)
|
||||||
|
- docs: Fix typo in export native APIs doc (#2750)
|
||||||
|
- Update RISC-V compilers in Nuttx compilation CI and spec test CI (#2756)
|
||||||
|
- Enable more LLVM backends for the release wamrc binary (#2778)
|
||||||
|
- Disable FPU in NuttX spec test (#2781)
|
||||||
|
- Fix broken links in app-mgr README.md (#2786)
|
||||||
|
- Fix build error of libsodium benchmark (#2792)
|
||||||
|
- Fix wamr-test-suites script for macos (#2819)
|
||||||
|
- Run spec test for classic/fast-interp in NuttX CI (#2817)
|
||||||
|
- test_wamr.sh: Don't bother to build shared library (#2844)
|
||||||
|
- doc/build_wamr.md: Fix links to RISC-V named ABIs (#2852)
|
||||||
|
- Fix typos of CIDR in docs and help text (#2851)
|
||||||
|
- Enable spectest on riscv64 (#2843)
|
||||||
|
- Update FPU configuration in spec_test_on_nuttx.yml (#2856)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## WAMR-1.2.3
|
## WAMR-1.2.3
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
|
|
|
@ -55,8 +55,6 @@ def build_llvm(llvm_dir, platform, backends, projects, use_clang=False, extra_fl
|
||||||
"-DLLVM_APPEND_VC_REV:BOOL=ON",
|
"-DLLVM_APPEND_VC_REV:BOOL=ON",
|
||||||
"-DLLVM_BUILD_EXAMPLES:BOOL=OFF",
|
"-DLLVM_BUILD_EXAMPLES:BOOL=OFF",
|
||||||
"-DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF",
|
"-DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF",
|
||||||
"-DLLVM_BUILD_TESTS:BOOL=OFF",
|
|
||||||
"-DLLVM_CCACHE_BUILD:BOOL=ON",
|
|
||||||
"-DLLVM_ENABLE_BINDINGS:BOOL=OFF",
|
"-DLLVM_ENABLE_BINDINGS:BOOL=OFF",
|
||||||
"-DLLVM_ENABLE_IDE:BOOL=OFF",
|
"-DLLVM_ENABLE_IDE:BOOL=OFF",
|
||||||
"-DLLVM_ENABLE_LIBEDIT=OFF",
|
"-DLLVM_ENABLE_LIBEDIT=OFF",
|
||||||
|
@ -67,10 +65,16 @@ def build_llvm(llvm_dir, platform, backends, projects, use_clang=False, extra_fl
|
||||||
"-DLLVM_INCLUDE_EXAMPLES:BOOL=OFF",
|
"-DLLVM_INCLUDE_EXAMPLES:BOOL=OFF",
|
||||||
"-DLLVM_INCLUDE_UTILS:BOOL=OFF",
|
"-DLLVM_INCLUDE_UTILS:BOOL=OFF",
|
||||||
"-DLLVM_INCLUDE_TESTS:BOOL=OFF",
|
"-DLLVM_INCLUDE_TESTS:BOOL=OFF",
|
||||||
"-DLLVM_BUILD_TESTS:BOOL=OFF",
|
|
||||||
"-DLLVM_OPTIMIZED_TABLEGEN:BOOL=ON",
|
"-DLLVM_OPTIMIZED_TABLEGEN:BOOL=ON",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# ccache is not available on Windows
|
||||||
|
if not "windows" == platform:
|
||||||
|
LLVM_COMPILE_OPTIONS.append("-DLLVM_CCACHE_BUILD:BOOL=ON")
|
||||||
|
# perf support is available on Linux only
|
||||||
|
if "linux" == platform:
|
||||||
|
LLVM_COMPILE_OPTIONS.append("-DLLVM_USE_PERF:BOOL=ON")
|
||||||
|
|
||||||
# use clang/clang++/lld. but macos doesn't support lld
|
# use clang/clang++/lld. but macos doesn't support lld
|
||||||
if not sys.platform.startswith("darwin") and use_clang:
|
if not sys.platform.startswith("darwin") and use_clang:
|
||||||
if shutil.which("clang") and shutil.which("clang++") and shutil.which("lld"):
|
if shutil.which("clang") and shutil.which("clang++") and shutil.which("lld"):
|
||||||
|
|
|
@ -122,6 +122,11 @@ if (WAMR_BUILD_JIT EQUAL 1)
|
||||||
if (CXX_SUPPORTS_REDUNDANT_MOVE_FLAG)
|
if (CXX_SUPPORTS_REDUNDANT_MOVE_FLAG)
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-redundant-move")
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-redundant-move")
|
||||||
endif ()
|
endif ()
|
||||||
|
# Enable exporting symbols after llvm-17, or LLVM JIT may run failed
|
||||||
|
# with `llvm_orc_registerEHFrameSectionWrapper` symbol not found error
|
||||||
|
if (${LLVM_PACKAGE_VERSION} VERSION_GREATER_EQUAL "17.0.0")
|
||||||
|
set (CMAKE_ENABLE_EXPORTS 1)
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
else ()
|
else ()
|
||||||
unset (LLVM_AVAILABLE_LIBS)
|
unset (LLVM_AVAILABLE_LIBS)
|
||||||
|
|
|
@ -165,7 +165,11 @@ file (GLOB header
|
||||||
)
|
)
|
||||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
||||||
|
|
||||||
enable_language (ASM)
|
if (WAMR_BUILD_PLATFORM STREQUAL "windows")
|
||||||
|
enable_language (ASM_MASM)
|
||||||
|
else()
|
||||||
|
enable_language (ASM)
|
||||||
|
endif()
|
||||||
|
|
||||||
include (${SHARED_PLATFORM_CONFIG})
|
include (${SHARED_PLATFORM_CONFIG})
|
||||||
include (${SHARED_DIR}/mem-alloc/mem_alloc.cmake)
|
include (${SHARED_DIR}/mem-alloc/mem_alloc.cmake)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Remote application management
|
# Remote application management
|
||||||
|
|
||||||
The WAMR application manager supports [remote application management](../core/app-mgr) from the host environment or the cloud through any physical communications such as TCP, UPD, UART, BLE, etc. Its modular design makes it able to support application management for different managed runtimes.
|
The WAMR application manager supports [remote application management](../../core/app-mgr) from the host environment or the cloud through any physical communications such as TCP, UPD, UART, BLE, etc. Its modular design makes it able to support application management for different managed runtimes.
|
||||||
|
|
||||||
The tool [host_tool](../test-tools/host-tool) communicates to the WAMR app manager for installing/uninstalling the WASM applications on companion chip from the host system. And the [IoT App Store Demo](../test-tools/IoT-APP-Store-Demo/) shows the conception of remotely managing the device applications from the cloud.
|
The tool [host_tool](../../test-tools/host-tool) communicates to the WAMR app manager for installing/uninstalling the WASM applications on companion chip from the host system. And the [IoT App Store Demo](../../test-tools/IoT-APP-Store-Demo/) shows the conception of remotely managing the device applications from the cloud.
|
||||||
|
|
||||||
|
|
||||||
<img src="../../doc/pics/wamr-arch.JPG" width="80%">
|
<img src="../../doc/pics/wamr-arch.JPG" width="80%">
|
||||||
|
|
|
@ -1467,7 +1467,7 @@ wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
|
||||||
if (total_size >= UINT32_MAX
|
if (total_size >= UINT32_MAX
|
||||||
|| !(section->section_body =
|
|| !(section->section_body =
|
||||||
os_mmap(NULL, (uint32)total_size, map_prot,
|
os_mmap(NULL, (uint32)total_size, map_prot,
|
||||||
map_flags))) {
|
map_flags, os_get_invalid_handle()))) {
|
||||||
app_manager_printf(
|
app_manager_printf(
|
||||||
"Allocate executable memory failed!\n");
|
"Allocate executable memory failed!\n");
|
||||||
SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
|
SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
|
||||||
|
|
|
@ -6,8 +6,14 @@
|
||||||
#include "app_manager.h"
|
#include "app_manager.h"
|
||||||
#include "bh_platform.h"
|
#include "bh_platform.h"
|
||||||
#include <autoconf.h>
|
#include <autoconf.h>
|
||||||
|
|
||||||
|
#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */
|
||||||
#include <zephyr.h>
|
#include <zephyr.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
#else
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#include <sigverify.h>
|
#include <sigverify.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -315,6 +315,11 @@
|
||||||
#define BH_ENABLE_GC_VERIFY 0
|
#define BH_ENABLE_GC_VERIFY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Heap corruption check, enabled by default */
|
||||||
|
#ifndef BH_ENABLE_GC_CORRUPTION_CHECK
|
||||||
|
#define BH_ENABLE_GC_CORRUPTION_CHECK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enable global heap pool if heap verification is enabled */
|
/* Enable global heap pool if heap verification is enabled */
|
||||||
#if BH_ENABLE_GC_VERIFY != 0
|
#if BH_ENABLE_GC_VERIFY != 0
|
||||||
#define WASM_ENABLE_GLOBAL_HEAP_POOL 1
|
#define WASM_ENABLE_GLOBAL_HEAP_POOL 1
|
||||||
|
@ -472,7 +477,7 @@
|
||||||
/* Some chip cannot support external ram with rwx attr at the same time,
|
/* 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
|
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
|
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
|
the code, first, copy & do relocation in dbus space, and second execute
|
||||||
it in ibus space, since in the 2 spaces the contents are the same,
|
it in ibus space, since in the 2 spaces the contents are the same,
|
||||||
so we call it bus mirror.
|
so we call it bus mirror.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1095,7 +1095,6 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
|
|
||||||
data_list[i]->mode = mode;
|
data_list[i]->mode = mode;
|
||||||
data_list[i]->elem_type = elem_type;
|
data_list[i]->elem_type = elem_type;
|
||||||
data_list[i]->is_dropped = false;
|
|
||||||
data_list[i]->table_index = table_index;
|
data_list[i]->table_index = table_index;
|
||||||
data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
|
data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
|
||||||
data_list[i]->offset.u.i64 = (int64)init_expr_value;
|
data_list[i]->offset.u.i64 = (int64)init_expr_value;
|
||||||
|
@ -1574,8 +1573,9 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
|
|
||||||
/* Allocate memory for data */
|
/* Allocate memory for data */
|
||||||
if (data_sections[i].size > 0
|
if (data_sections[i].size > 0
|
||||||
&& !(data_sections[i].data = os_mmap(NULL, data_sections[i].size,
|
&& !(data_sections[i].data =
|
||||||
map_prot, map_flags))) {
|
os_mmap(NULL, data_sections[i].size, map_prot, map_flags,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
|
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2470,7 +2470,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
|
|
||||||
if (size > UINT32_MAX
|
if (size > UINT32_MAX
|
||||||
|| !(module->extra_plt_data =
|
|| !(module->extra_plt_data =
|
||||||
os_mmap(NULL, (uint32)size, map_prot, map_flags))) {
|
os_mmap(NULL, (uint32)size, map_prot, map_flags,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -2593,7 +2594,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
size = (uint64)sizeof(void *) * got_item_count;
|
size = (uint64)sizeof(void *) * got_item_count;
|
||||||
if (size > UINT32_MAX
|
if (size > UINT32_MAX
|
||||||
|| !(module->got_func_ptrs =
|
|| !(module->got_func_ptrs =
|
||||||
os_mmap(NULL, (uint32)size, map_prot, map_flags))) {
|
os_mmap(NULL, (uint32)size, map_prot, map_flags,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -3106,8 +3108,9 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
|
||||||
(uint64)section_size + aot_get_plt_table_size();
|
(uint64)section_size + aot_get_plt_table_size();
|
||||||
total_size = (total_size + 3) & ~((uint64)3);
|
total_size = (total_size + 3) & ~((uint64)3);
|
||||||
if (total_size >= UINT32_MAX
|
if (total_size >= UINT32_MAX
|
||||||
|| !(aot_text = os_mmap(NULL, (uint32)total_size,
|
|| !(aot_text =
|
||||||
map_prot, map_flags))) {
|
os_mmap(NULL, (uint32)total_size, map_prot,
|
||||||
|
map_flags, os_get_invalid_handle()))) {
|
||||||
wasm_runtime_free(section);
|
wasm_runtime_free(section);
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"mmap memory failed");
|
"mmap memory failed");
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "bh_log.h"
|
#include "bh_log.h"
|
||||||
#include "mem_alloc.h"
|
#include "mem_alloc.h"
|
||||||
#include "../common/wasm_runtime_common.h"
|
#include "../common/wasm_runtime_common.h"
|
||||||
|
#include "../common/wasm_memory.h"
|
||||||
#include "../interpreter/wasm_runtime.h"
|
#include "../interpreter/wasm_runtime.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"
|
||||||
|
@ -382,7 +383,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||||
uint32 inc_page_count, aux_heap_base, global_idx;
|
uint32 inc_page_count, aux_heap_base, global_idx;
|
||||||
uint32 bytes_of_last_page, bytes_to_page_end;
|
uint32 bytes_of_last_page, bytes_to_page_end;
|
||||||
uint32 heap_offset = num_bytes_per_page * init_page_count;
|
uint32 heap_offset = num_bytes_per_page * init_page_count;
|
||||||
uint64 total_size;
|
uint64 memory_data_size, max_memory_data_size;
|
||||||
uint8 *p = NULL, *global_addr;
|
uint8 *p = NULL, *global_addr;
|
||||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||||
uint8 *mapped_mem;
|
uint8 *mapped_mem;
|
||||||
|
@ -488,6 +489,12 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||||
if (max_page_count > DEFAULT_MAX_PAGES)
|
if (max_page_count > DEFAULT_MAX_PAGES)
|
||||||
max_page_count = DEFAULT_MAX_PAGES;
|
max_page_count = DEFAULT_MAX_PAGES;
|
||||||
}
|
}
|
||||||
|
else { /* heap_size == 0 */
|
||||||
|
if (init_page_count == DEFAULT_MAX_PAGES) {
|
||||||
|
num_bytes_per_page = UINT32_MAX;
|
||||||
|
init_page_count = max_page_count = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG_VERBOSE("Memory instantiate:");
|
LOG_VERBOSE("Memory instantiate:");
|
||||||
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
||||||
|
@ -496,67 +503,80 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||||
module->aux_stack_size);
|
module->aux_stack_size);
|
||||||
LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size);
|
LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size);
|
||||||
|
|
||||||
total_size = (uint64)num_bytes_per_page * init_page_count;
|
memory_data_size = (uint64)num_bytes_per_page * init_page_count;
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
|
||||||
if (is_shared_memory) {
|
bh_assert(memory_data_size <= UINT32_MAX);
|
||||||
/* Allocate max page for shared memory */
|
bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB);
|
||||||
total_size = (uint64)num_bytes_per_page * max_page_count;
|
(void)max_memory_data_size;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bh_assert(total_size <= UINT32_MAX);
|
|
||||||
|
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
/* Allocate memory */
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
if (total_size > 0
|
if (is_shared_memory) {
|
||||||
&& !(p = runtime_malloc(total_size, error_buf, error_buf_size))) {
|
/* Allocate maximum memory size when memory is shared */
|
||||||
|
if (max_memory_data_size > 0
|
||||||
|
&& !(p = runtime_malloc(max_memory_data_size, error_buf,
|
||||||
|
error_buf_size))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
total_size = (total_size + page_size - 1) & ~(page_size - 1);
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Allocate initial memory size when memory is not shared */
|
||||||
|
if (memory_data_size > 0
|
||||||
|
&& !(p = runtime_malloc(memory_data_size, error_buf,
|
||||||
|
error_buf_size))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* else of OS_ENABLE_HW_BOUND_CHECK */
|
||||||
|
memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1);
|
||||||
|
|
||||||
/* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
|
/* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
|
||||||
* ea = i + memarg.offset
|
* ea = i + memarg.offset
|
||||||
* both i and memarg.offset are u32 in range 0 to 4G
|
* both i and memarg.offset are u32 in range 0 to 4G
|
||||||
* so the range of ea is 0 to 8G
|
* so the range of ea is 0 to 8G
|
||||||
*/
|
*/
|
||||||
if (!(p = mapped_mem =
|
if (!(p = mapped_mem = os_mmap(NULL, map_size, MMAP_PROT_NONE,
|
||||||
os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
|
MMAP_MAP_NONE, os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BH_PLATFORM_WINDOWS
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
if (!os_mem_commit(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
if (!os_mem_commit(p, memory_data_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
||||||
set_error_buf(error_buf, error_buf_size, "commit memory failed");
|
set_error_buf(error_buf, error_buf_size, "commit memory failed");
|
||||||
os_munmap(mapped_mem, map_size);
|
os_munmap(mapped_mem, map_size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
|
if (os_mprotect(p, memory_data_size, MMAP_PROT_READ | MMAP_PROT_WRITE)
|
||||||
|
!= 0) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
|
set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
|
||||||
#ifdef BH_PLATFORM_WINDOWS
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
os_mem_decommit(p, total_size);
|
os_mem_decommit(p, memory_data_size);
|
||||||
#endif
|
#endif
|
||||||
os_munmap(mapped_mem, map_size);
|
os_munmap(mapped_mem, map_size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Newly allocated pages are filled with zero by the OS, we don't fill it
|
/* Newly allocated pages are filled with zero by the OS, we don't fill it
|
||||||
* again here */
|
* again here */
|
||||||
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
|
||||||
|
|
||||||
if (total_size > UINT32_MAX)
|
if (memory_data_size > UINT32_MAX)
|
||||||
total_size = UINT32_MAX;
|
memory_data_size = UINT32_MAX;
|
||||||
|
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
||||||
|
|
||||||
memory_inst->module_type = Wasm_Module_AoT;
|
memory_inst->module_type = Wasm_Module_AoT;
|
||||||
memory_inst->num_bytes_per_page = num_bytes_per_page;
|
memory_inst->num_bytes_per_page = num_bytes_per_page;
|
||||||
memory_inst->cur_page_count = init_page_count;
|
memory_inst->cur_page_count = init_page_count;
|
||||||
memory_inst->max_page_count = max_page_count;
|
memory_inst->max_page_count = max_page_count;
|
||||||
memory_inst->memory_data_size = (uint32)total_size;
|
memory_inst->memory_data_size = (uint32)memory_data_size;
|
||||||
|
|
||||||
/* Init memory info */
|
/* Init memory info */
|
||||||
memory_inst->memory_data = p;
|
memory_inst->memory_data = p;
|
||||||
memory_inst->memory_data_end = p + (uint32)total_size;
|
memory_inst->memory_data_end = p + (uint32)memory_data_size;
|
||||||
|
|
||||||
/* Initialize heap info */
|
/* Initialize heap info */
|
||||||
memory_inst->heap_data = p + heap_offset;
|
memory_inst->heap_data = p + heap_offset;
|
||||||
|
@ -579,24 +599,13 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total_size > 0) {
|
if (memory_data_size > 0) {
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
wasm_runtime_set_mem_bound_check_bytes(memory_inst, memory_data_size);
|
||||||
memory_inst->mem_bound_check_1byte.u64 = total_size - 1;
|
|
||||||
memory_inst->mem_bound_check_2bytes.u64 = total_size - 2;
|
|
||||||
memory_inst->mem_bound_check_4bytes.u64 = total_size - 4;
|
|
||||||
memory_inst->mem_bound_check_8bytes.u64 = total_size - 8;
|
|
||||||
memory_inst->mem_bound_check_16bytes.u64 = total_size - 16;
|
|
||||||
#else
|
|
||||||
memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1;
|
|
||||||
memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2;
|
|
||||||
memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4;
|
|
||||||
memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
|
|
||||||
memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
if (is_shared_memory) {
|
if (is_shared_memory) {
|
||||||
|
memory_inst->is_shared_memory = 1;
|
||||||
memory_inst->ref_count = 1;
|
memory_inst->ref_count = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -613,7 +622,7 @@ fail1:
|
||||||
#else
|
#else
|
||||||
#ifdef BH_PLATFORM_WINDOWS
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
if (memory_inst->memory_data)
|
if (memory_inst->memory_data)
|
||||||
os_mem_decommit(p, total_size);
|
os_mem_decommit(p, memory_data_size);
|
||||||
#endif
|
#endif
|
||||||
os_munmap(mapped_mem, map_size);
|
os_munmap(mapped_mem, map_size);
|
||||||
#endif
|
#endif
|
||||||
|
@ -673,6 +682,10 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||||
if (data_seg->is_passive)
|
if (data_seg->is_passive)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
if (parent != NULL)
|
||||||
|
/* Ignore setting memory init data if the memory has been
|
||||||
|
initialized */
|
||||||
|
continue;
|
||||||
|
|
||||||
bh_assert(data_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
|
bh_assert(data_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
|
||||||
|| data_seg->offset.init_expr_type
|
|| data_seg->offset.init_expr_type
|
||||||
|
@ -969,7 +982,8 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
|
||||||
wasm functions, and ensure that the exec_env's module inst
|
wasm functions, and ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_main = exec_env_main->module_inst;
|
module_inst_main = exec_env_main->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Try using the existing exec_env */
|
/* Try using the existing exec_env */
|
||||||
|
@ -994,7 +1008,8 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_main = exec_env->module_inst;
|
module_inst_main = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1044,12 +1059,12 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
|
||||||
fail:
|
fail:
|
||||||
if (is_sub_inst) {
|
if (is_sub_inst) {
|
||||||
/* Restore the parent exec_env's module inst */
|
/* Restore the parent exec_env's module inst */
|
||||||
exec_env_main->module_inst = module_inst_main;
|
wasm_exec_env_restore_module_inst(exec_env_main, module_inst_main);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (module_inst_main)
|
if (module_inst_main)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_main;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_main);
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
}
|
}
|
||||||
|
@ -1083,6 +1098,9 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
|
||||||
char *error_buf, uint32 error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
AOTModuleInstance *module_inst;
|
AOTModuleInstance *module_inst;
|
||||||
|
#if WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_REF_TYPES != 0
|
||||||
|
WASMModuleInstanceExtraCommon *common;
|
||||||
|
#endif
|
||||||
const uint32 module_inst_struct_size =
|
const uint32 module_inst_struct_size =
|
||||||
offsetof(AOTModuleInstance, global_table_data.bytes);
|
offsetof(AOTModuleInstance, global_table_data.bytes);
|
||||||
const uint64 module_inst_mem_inst_size =
|
const uint64 module_inst_mem_inst_size =
|
||||||
|
@ -1149,6 +1167,32 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_REF_TYPES != 0
|
||||||
|
common = &((AOTModuleInstanceExtra *)module_inst->e)->common;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
|
if (module->mem_init_data_count > 0) {
|
||||||
|
common->data_dropped = bh_bitmap_new(0, module->mem_init_data_count);
|
||||||
|
if (common->data_dropped == NULL) {
|
||||||
|
LOG_DEBUG("failed to allocate bitmaps");
|
||||||
|
set_error_buf(error_buf, error_buf_size,
|
||||||
|
"failed to allocate bitmaps");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
if (module->table_init_data_count > 0) {
|
||||||
|
common->elem_dropped = bh_bitmap_new(0, module->table_init_data_count);
|
||||||
|
if (common->elem_dropped == NULL) {
|
||||||
|
LOG_DEBUG("failed to allocate bitmaps");
|
||||||
|
set_error_buf(error_buf, error_buf_size,
|
||||||
|
"failed to allocate bitmaps");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize global info */
|
/* Initialize global info */
|
||||||
p = (uint8 *)module_inst + module_inst_struct_size
|
p = (uint8 *)module_inst + module_inst_struct_size
|
||||||
+ module_inst_mem_inst_size;
|
+ module_inst_mem_inst_size;
|
||||||
|
@ -1249,6 +1293,8 @@ fail:
|
||||||
void
|
void
|
||||||
aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
||||||
{
|
{
|
||||||
|
WASMModuleInstanceExtraCommon *common =
|
||||||
|
&((AOTModuleInstanceExtra *)module_inst->e)->common;
|
||||||
if (module_inst->exec_env_singleton) {
|
if (module_inst->exec_env_singleton) {
|
||||||
/* wasm_exec_env_destroy will call
|
/* wasm_exec_env_destroy will call
|
||||||
wasm_cluster_wait_for_all_except_self to wait for other
|
wasm_cluster_wait_for_all_except_self to wait for other
|
||||||
|
@ -1291,7 +1337,7 @@ 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)->common.c_api_func_imports)
|
if (common->c_api_func_imports)
|
||||||
wasm_runtime_free(((AOTModuleInstanceExtra *)module_inst->e)
|
wasm_runtime_free(((AOTModuleInstanceExtra *)module_inst->e)
|
||||||
->common.c_api_func_imports);
|
->common.c_api_func_imports);
|
||||||
|
|
||||||
|
@ -1302,6 +1348,13 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
||||||
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
|
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
|
bh_bitmap_delete(common->data_dropped);
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
bh_bitmap_delete(common->elem_dropped);
|
||||||
|
#endif
|
||||||
|
|
||||||
wasm_runtime_free(module_inst);
|
wasm_runtime_free(module_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1700,7 +1753,8 @@ execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_old = exec_env->module_inst;
|
module_inst_old = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1711,7 +1765,7 @@ execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (module_inst_old)
|
if (module_inst_old)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_old;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
|
||||||
|
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
|
@ -1767,7 +1821,8 @@ execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_old = exec_env->module_inst;
|
module_inst_old = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1775,7 +1830,7 @@ execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (module_inst_old)
|
if (module_inst_old)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_old;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
|
||||||
|
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
|
@ -1897,6 +1952,13 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
uint8 *addr = memory_inst->memory_data + ptr;
|
uint8 *addr = memory_inst->memory_data + ptr;
|
||||||
|
uint8 *memory_data_end;
|
||||||
|
|
||||||
|
/* memory->memory_data_end may be changed in memory grow */
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
|
memory_data_end = memory_inst->memory_data_end;
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
|
|
||||||
if (memory_inst->heap_handle && memory_inst->heap_data < addr
|
if (memory_inst->heap_handle && memory_inst->heap_data < addr
|
||||||
&& addr < memory_inst->heap_data_end) {
|
&& addr < memory_inst->heap_data_end) {
|
||||||
mem_allocator_free(memory_inst->heap_handle, addr);
|
mem_allocator_free(memory_inst->heap_handle, addr);
|
||||||
|
@ -1904,7 +1966,7 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
else if (module->malloc_func_index != (uint32)-1
|
else if (module->malloc_func_index != (uint32)-1
|
||||||
&& module->free_func_index != (uint32)-1
|
&& module->free_func_index != (uint32)-1
|
||||||
&& memory_inst->memory_data <= addr
|
&& memory_inst->memory_data <= addr
|
||||||
&& addr < memory_inst->memory_data_end) {
|
&& addr < memory_data_end) {
|
||||||
AOTFunctionInstance *free_func;
|
AOTFunctionInstance *free_func;
|
||||||
char *free_func_name;
|
char *free_func_name;
|
||||||
|
|
||||||
|
@ -2278,13 +2340,21 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
|
||||||
{
|
{
|
||||||
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
|
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
|
||||||
AOTModule *aot_module;
|
AOTModule *aot_module;
|
||||||
uint8 *data = NULL;
|
uint8 *data;
|
||||||
uint8 *maddr;
|
uint8 *maddr;
|
||||||
uint64 seg_len = 0;
|
uint64 seg_len;
|
||||||
|
|
||||||
|
if (bh_bitmap_get_bit(
|
||||||
|
((AOTModuleInstanceExtra *)module_inst->e)->common.data_dropped,
|
||||||
|
seg_index)) {
|
||||||
|
seg_len = 0;
|
||||||
|
data = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
aot_module = (AOTModule *)module_inst->module;
|
aot_module = (AOTModule *)module_inst->module;
|
||||||
seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
|
seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
|
||||||
data = aot_module->mem_init_data_list[seg_index]->bytes;
|
data = aot_module->mem_init_data_list[seg_index]->bytes;
|
||||||
|
}
|
||||||
|
|
||||||
if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
|
if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
|
||||||
dst, len))
|
dst, len))
|
||||||
|
@ -2298,16 +2368,18 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
|
||||||
maddr = wasm_runtime_addr_app_to_native(
|
maddr = wasm_runtime_addr_app_to_native(
|
||||||
(WASMModuleInstanceCommon *)module_inst, dst);
|
(WASMModuleInstanceCommon *)module_inst, dst);
|
||||||
|
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
|
bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
|
aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
|
||||||
{
|
{
|
||||||
AOTModule *aot_module = (AOTModule *)module_inst->module;
|
bh_bitmap_set_bit(
|
||||||
|
((AOTModuleInstanceExtra *)module_inst->e)->common.data_dropped,
|
||||||
aot_module->mem_init_data_list[seg_index]->byte_count = 0;
|
seg_index);
|
||||||
/* Currently we can't free the dropped data segment
|
/* Currently we can't free the dropped data segment
|
||||||
as the mem_init_data_count is a continuous array */
|
as the mem_init_data_count is a continuous array */
|
||||||
return true;
|
return true;
|
||||||
|
@ -2520,9 +2592,9 @@ aot_get_module_inst_mem_consumption(const AOTModuleInstance *module_inst,
|
||||||
void
|
void
|
||||||
aot_drop_table_seg(AOTModuleInstance *module_inst, uint32 tbl_seg_idx)
|
aot_drop_table_seg(AOTModuleInstance *module_inst, uint32 tbl_seg_idx)
|
||||||
{
|
{
|
||||||
AOTModule *module = (AOTModule *)module_inst->module;
|
bh_bitmap_set_bit(
|
||||||
AOTTableInitData *tbl_seg = module->table_init_data_list[tbl_seg_idx];
|
((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
|
||||||
tbl_seg->is_dropped = true;
|
tbl_seg_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2550,7 +2622,9 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tbl_seg->is_dropped) {
|
if (bh_bitmap_get_bit(
|
||||||
|
((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
|
||||||
|
tbl_seg_idx)) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -2891,13 +2965,15 @@ aot_dump_perf_profiling(const AOTModuleInstance *module_inst)
|
||||||
func_name = get_func_name_from_index(module_inst, i);
|
func_name = get_func_name_from_index(module_inst, i);
|
||||||
|
|
||||||
if (func_name)
|
if (func_name)
|
||||||
os_printf(" func %s, execution time: %.3f ms, execution count: %d "
|
os_printf(
|
||||||
"times\n",
|
" func %s, execution time: %.3f ms, execution count: %" PRIu32
|
||||||
|
" times\n",
|
||||||
func_name, perf_prof->total_exec_time / 1000.0f,
|
func_name, perf_prof->total_exec_time / 1000.0f,
|
||||||
perf_prof->total_exec_cnt);
|
perf_prof->total_exec_cnt);
|
||||||
else
|
else
|
||||||
os_printf(" func %d, execution time: %.3f ms, execution count: %d "
|
os_printf(" func %" PRIu32
|
||||||
"times\n",
|
", execution time: %.3f ms, execution count: %" PRIu32
|
||||||
|
" times\n",
|
||||||
i, perf_prof->total_exec_time / 1000.0f,
|
i, perf_prof->total_exec_time / 1000.0f,
|
||||||
perf_prof->total_exec_cnt);
|
perf_prof->total_exec_cnt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,21 +11,52 @@
|
||||||
#define R_RISCV_CALL_PLT 19
|
#define R_RISCV_CALL_PLT 19
|
||||||
#define R_RISCV_PCREL_HI20 23
|
#define R_RISCV_PCREL_HI20 23
|
||||||
#define R_RISCV_PCREL_LO12_I 24
|
#define R_RISCV_PCREL_LO12_I 24
|
||||||
|
#define R_RISCV_PCREL_LO12_S 25
|
||||||
#define R_RISCV_HI20 26
|
#define R_RISCV_HI20 26
|
||||||
#define R_RISCV_LO12_I 27
|
#define R_RISCV_LO12_I 27
|
||||||
#define R_RISCV_LO12_S 28
|
#define R_RISCV_LO12_S 28
|
||||||
|
|
||||||
#define RV_OPCODE_SW 0x23
|
#define RV_OPCODE_SW 0x23
|
||||||
|
|
||||||
|
#undef NEED_SOFT_FP
|
||||||
|
#undef NEED_SOFT_DP
|
||||||
|
#undef NEED_SOFT_I32_MUL
|
||||||
|
#undef NEED_SOFT_I32_DIV
|
||||||
|
#undef NEED_SOFT_I64_MUL
|
||||||
|
#undef NEED_SOFT_I64_DIV
|
||||||
|
|
||||||
|
#ifdef __riscv_flen
|
||||||
|
#if __riscv_flen == 32
|
||||||
|
#define NEED_SOFT_DP
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define NEED_SOFT_FP
|
||||||
|
#define NEED_SOFT_DP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __riscv_mul
|
||||||
|
#define NEED_SOFT_I32_MUL
|
||||||
|
#define NEED_SOFT_I64_MUL
|
||||||
|
#elif __riscv_xlen == 32
|
||||||
|
#define NEED_SOFT_I64_MUL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __riscv_div
|
||||||
|
#define NEED_SOFT_I32_DIV
|
||||||
|
#define NEED_SOFT_I64_DIV
|
||||||
|
#elif __riscv_xlen == 32
|
||||||
|
#define NEED_SOFT_I64_DIV
|
||||||
|
#endif
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
void __adddf3();
|
void __adddf3();
|
||||||
void __addsf3();
|
void __addsf3();
|
||||||
void __divdi3();
|
|
||||||
void __divsi3();
|
|
||||||
void __divdf3();
|
void __divdf3();
|
||||||
|
void __divdi3();
|
||||||
void __divsf3();
|
void __divsf3();
|
||||||
void __eqsf2();
|
void __divsi3();
|
||||||
void __eqdf2();
|
void __eqdf2();
|
||||||
|
void __eqsf2();
|
||||||
void __extendsfdf2();
|
void __extendsfdf2();
|
||||||
void __fixdfdi();
|
void __fixdfdi();
|
||||||
void __fixdfsi();
|
void __fixdfsi();
|
||||||
|
@ -37,12 +68,12 @@ void __fixunssfdi();
|
||||||
void __fixunssfsi();
|
void __fixunssfsi();
|
||||||
void __floatdidf();
|
void __floatdidf();
|
||||||
void __floatdisf();
|
void __floatdisf();
|
||||||
void __floatsisf();
|
|
||||||
void __floatsidf();
|
void __floatsidf();
|
||||||
|
void __floatsisf();
|
||||||
void __floatundidf();
|
void __floatundidf();
|
||||||
void __floatundisf();
|
void __floatundisf();
|
||||||
void __floatunsisf();
|
|
||||||
void __floatunsidf();
|
void __floatunsidf();
|
||||||
|
void __floatunsisf();
|
||||||
void __gedf2();
|
void __gedf2();
|
||||||
void __gesf2();
|
void __gesf2();
|
||||||
void __gtdf2();
|
void __gtdf2();
|
||||||
|
@ -58,6 +89,8 @@ void __muldi3();
|
||||||
void __mulsf3();
|
void __mulsf3();
|
||||||
void __mulsi3();
|
void __mulsi3();
|
||||||
void __nedf2();
|
void __nedf2();
|
||||||
|
void __negdf2();
|
||||||
|
void __negsf2();
|
||||||
void __nesf2();
|
void __nesf2();
|
||||||
void __subdf3();
|
void __subdf3();
|
||||||
void __subsf3();
|
void __subsf3();
|
||||||
|
@ -73,60 +106,74 @@ void __unordsf2();
|
||||||
static SymbolMap target_sym_map[] = {
|
static SymbolMap target_sym_map[] = {
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
REG_COMMON_SYMBOLS
|
REG_COMMON_SYMBOLS
|
||||||
#ifndef __riscv_flen
|
#ifdef NEED_SOFT_FP
|
||||||
REG_SYM(__adddf3),
|
|
||||||
REG_SYM(__addsf3),
|
REG_SYM(__addsf3),
|
||||||
REG_SYM(__divdf3),
|
|
||||||
REG_SYM(__divsf3),
|
REG_SYM(__divsf3),
|
||||||
REG_SYM(__eqdf2),
|
|
||||||
REG_SYM(__eqsf2),
|
REG_SYM(__eqsf2),
|
||||||
REG_SYM(__extendsfdf2),
|
REG_SYM(__fixsfdi),
|
||||||
REG_SYM(__fixunsdfdi),
|
|
||||||
REG_SYM(__fixunsdfsi),
|
|
||||||
REG_SYM(__fixunssfdi),
|
REG_SYM(__fixunssfdi),
|
||||||
REG_SYM(__fixunssfsi),
|
REG_SYM(__fixunssfsi),
|
||||||
REG_SYM(__gedf2),
|
REG_SYM(__floatsidf),
|
||||||
REG_SYM(__gesf2),
|
REG_SYM(__gesf2),
|
||||||
REG_SYM(__gtdf2),
|
|
||||||
REG_SYM(__gtsf2),
|
REG_SYM(__gtsf2),
|
||||||
REG_SYM(__ledf2),
|
|
||||||
REG_SYM(__lesf2),
|
REG_SYM(__lesf2),
|
||||||
REG_SYM(__ltdf2),
|
REG_SYM(__mulsf3),
|
||||||
REG_SYM(__ltsf2),
|
REG_SYM(__negsf2),
|
||||||
|
REG_SYM(__nesf2),
|
||||||
|
REG_SYM(__subsf3),
|
||||||
|
REG_SYM(__unordsf2),
|
||||||
|
#elif __riscv_xlen == 32
|
||||||
|
/* rv32f, support FP instruction but need soft routines
|
||||||
|
* to convert float and long long
|
||||||
|
*/
|
||||||
|
REG_SYM(__floatundisf),
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_SOFT_DP
|
||||||
|
REG_SYM(__adddf3),
|
||||||
|
REG_SYM(__divdf3),
|
||||||
|
REG_SYM(__eqdf2),
|
||||||
|
REG_SYM(__extendsfdf2),
|
||||||
|
REG_SYM(__fixdfdi),
|
||||||
|
REG_SYM(__fixunsdfdi),
|
||||||
|
REG_SYM(__fixunsdfsi),
|
||||||
|
REG_SYM(__floatdidf),
|
||||||
|
REG_SYM(__floatsidf),
|
||||||
|
REG_SYM(__floatundidf),
|
||||||
|
REG_SYM(__floatunsidf),
|
||||||
|
REG_SYM(__gedf2),
|
||||||
|
REG_SYM(__gtdf2),
|
||||||
|
REG_SYM(__ledf2),
|
||||||
REG_SYM(__muldf3),
|
REG_SYM(__muldf3),
|
||||||
REG_SYM(__nedf2),
|
REG_SYM(__nedf2),
|
||||||
REG_SYM(__nesf2),
|
REG_SYM(__negdf2),
|
||||||
REG_SYM(__subdf3),
|
REG_SYM(__subdf3),
|
||||||
REG_SYM(__subsf3),
|
|
||||||
REG_SYM(__truncdfsf2),
|
REG_SYM(__truncdfsf2),
|
||||||
REG_SYM(__unorddf2),
|
REG_SYM(__unorddf2),
|
||||||
REG_SYM(__unordsf2),
|
#elif __riscv_xlen == 32
|
||||||
#if __riscv_xlen == 32
|
/* rv32d, support DP instruction but need soft routines
|
||||||
|
* to convert double and long long
|
||||||
|
*/
|
||||||
REG_SYM(__fixdfdi),
|
REG_SYM(__fixdfdi),
|
||||||
REG_SYM(__fixdfsi),
|
|
||||||
REG_SYM(__fixsfdi),
|
|
||||||
REG_SYM(__fixsfsi),
|
|
||||||
REG_SYM(__floatdidf),
|
|
||||||
REG_SYM(__floatdisf),
|
|
||||||
REG_SYM(__floatsidf),
|
|
||||||
REG_SYM(__floatsisf),
|
|
||||||
REG_SYM(__floatundidf),
|
REG_SYM(__floatundidf),
|
||||||
REG_SYM(__floatundisf),
|
#endif
|
||||||
REG_SYM(__floatunsidf),
|
#ifdef NEED_SOFT_I32_MUL
|
||||||
REG_SYM(__floatunsisf),
|
|
||||||
REG_SYM(__mulsf3),
|
|
||||||
REG_SYM(__mulsi3),
|
REG_SYM(__mulsi3),
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#ifdef NEED_SOFT_I32_DIV
|
||||||
REG_SYM(__divdi3),
|
|
||||||
REG_SYM(__divsi3),
|
REG_SYM(__divsi3),
|
||||||
REG_SYM(__moddi3),
|
|
||||||
REG_SYM(__modsi3),
|
REG_SYM(__modsi3),
|
||||||
REG_SYM(__muldi3),
|
|
||||||
REG_SYM(__udivdi3),
|
|
||||||
REG_SYM(__udivsi3),
|
REG_SYM(__udivsi3),
|
||||||
REG_SYM(__umoddi3),
|
|
||||||
REG_SYM(__umodsi3),
|
REG_SYM(__umodsi3),
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_SOFT_I64_MUL
|
||||||
|
REG_SYM(__muldi3),
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_SOFT_I64_DIV
|
||||||
|
REG_SYM(__divdi3),
|
||||||
|
REG_SYM(__moddi3),
|
||||||
|
REG_SYM(__udivdi3),
|
||||||
|
REG_SYM(__umoddi3),
|
||||||
|
#endif
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -177,7 +224,11 @@ rv_set_val(uint16 *addr, uint32 val)
|
||||||
*addr = (val & 0xffff);
|
*addr = (val & 0xffff);
|
||||||
*(addr + 1) = (val >> 16);
|
*(addr + 1) = (val >> 16);
|
||||||
|
|
||||||
|
#ifdef __riscv_zifencei
|
||||||
__asm__ volatile("fence.i");
|
__asm__ volatile("fence.i");
|
||||||
|
#else
|
||||||
|
__asm__ volatile("fence");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a val to given address */
|
/* Add a val to given address */
|
||||||
|
@ -265,9 +316,10 @@ typedef struct RelocTypeStrMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
static RelocTypeStrMap reloc_type_str_maps[] = {
|
static RelocTypeStrMap reloc_type_str_maps[] = {
|
||||||
RELOC_TYPE_MAP(R_RISCV_32), RELOC_TYPE_MAP(R_RISCV_CALL),
|
RELOC_TYPE_MAP(R_RISCV_32), RELOC_TYPE_MAP(R_RISCV_64),
|
||||||
RELOC_TYPE_MAP(R_RISCV_CALL_PLT), RELOC_TYPE_MAP(R_RISCV_PCREL_HI20),
|
RELOC_TYPE_MAP(R_RISCV_CALL), RELOC_TYPE_MAP(R_RISCV_CALL_PLT),
|
||||||
RELOC_TYPE_MAP(R_RISCV_PCREL_LO12_I), RELOC_TYPE_MAP(R_RISCV_HI20),
|
RELOC_TYPE_MAP(R_RISCV_PCREL_HI20), RELOC_TYPE_MAP(R_RISCV_PCREL_LO12_I),
|
||||||
|
RELOC_TYPE_MAP(R_RISCV_PCREL_LO12_S), RELOC_TYPE_MAP(R_RISCV_HI20),
|
||||||
RELOC_TYPE_MAP(R_RISCV_LO12_I), RELOC_TYPE_MAP(R_RISCV_LO12_S),
|
RELOC_TYPE_MAP(R_RISCV_LO12_I), RELOC_TYPE_MAP(R_RISCV_LO12_S),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -323,21 +375,37 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
|
||||||
rv_set_val((uint16 *)addr, val_32);
|
rv_set_val((uint16 *)addr, val_32);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
case R_RISCV_64:
|
case R_RISCV_64:
|
||||||
{
|
{
|
||||||
uint64 val_64 =
|
uint64 val_64 =
|
||||||
(uint64)((uintptr_t)symbol_addr + (intptr_t)reloc_addend);
|
(uint64)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
|
||||||
|
|
||||||
CHECK_RELOC_OFFSET(sizeof(uint64));
|
CHECK_RELOC_OFFSET(sizeof(uint64));
|
||||||
|
if (val_64
|
||||||
|
!= (uint64)((intptr_t)symbol_addr + (intptr_t)reloc_addend)) {
|
||||||
|
goto fail_addr_out_of_range;
|
||||||
|
}
|
||||||
|
|
||||||
bh_memcpy_s(addr, 8, &val_64, 8);
|
bh_memcpy_s(addr, 8, &val_64, 8);
|
||||||
|
#ifdef __riscv_zifencei
|
||||||
|
__asm__ volatile("fence.i");
|
||||||
|
#else
|
||||||
|
__asm__ volatile("fence");
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case R_RISCV_CALL:
|
case R_RISCV_CALL:
|
||||||
case R_RISCV_CALL_PLT:
|
case R_RISCV_CALL_PLT:
|
||||||
|
case R_RISCV_PCREL_HI20: /* S + A - P */
|
||||||
{
|
{
|
||||||
val = (int32)(intptr_t)((uint8 *)symbol_addr - addr);
|
val = (int32)(intptr_t)((uint8 *)symbol_addr + reloc_addend - addr);
|
||||||
|
|
||||||
CHECK_RELOC_OFFSET(sizeof(uint32));
|
CHECK_RELOC_OFFSET(sizeof(uint32));
|
||||||
if (val != (intptr_t)((uint8 *)symbol_addr - addr)) {
|
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend - addr)) {
|
||||||
if (symbol_index >= 0) {
|
if (symbol_index >= 0) {
|
||||||
/* Call runtime function by plt code */
|
/* Call runtime function by plt code */
|
||||||
symbol_addr = (uint8 *)module->code + module->code_size
|
symbol_addr = (uint8 *)module->code + module->code_size
|
||||||
|
@ -347,7 +415,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val != (intptr_t)((uint8 *)symbol_addr - addr)) {
|
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend - addr)) {
|
||||||
goto fail_addr_out_of_range;
|
goto fail_addr_out_of_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,31 +437,14 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
case R_RISCV_HI20: /* S + A */
|
case R_RISCV_HI20: /* S + A */
|
||||||
case R_RISCV_PCREL_HI20: /* S + A - P */
|
|
||||||
{
|
{
|
||||||
if (reloc_type == R_RISCV_PCREL_HI20) {
|
|
||||||
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend
|
|
||||||
- (intptr_t)addr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
|
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
|
||||||
}
|
|
||||||
|
|
||||||
CHECK_RELOC_OFFSET(sizeof(uint32));
|
CHECK_RELOC_OFFSET(sizeof(uint32));
|
||||||
if (reloc_type == R_RISCV_PCREL_HI20) {
|
|
||||||
if (val
|
|
||||||
!= ((intptr_t)symbol_addr + (intptr_t)reloc_addend
|
|
||||||
- (intptr_t)addr)) {
|
|
||||||
goto fail_addr_out_of_range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (val != ((intptr_t)symbol_addr + (intptr_t)reloc_addend)) {
|
if (val != ((intptr_t)symbol_addr + (intptr_t)reloc_addend)) {
|
||||||
goto fail_addr_out_of_range;
|
goto fail_addr_out_of_range;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
addr = target_section_addr + reloc_offset;
|
|
||||||
insn = rv_get_val((uint16 *)addr);
|
insn = rv_get_val((uint16 *)addr);
|
||||||
rv_calc_imm(val, &imm_hi, &imm_lo);
|
rv_calc_imm(val, &imm_hi, &imm_lo);
|
||||||
insn = (insn & 0x00000fff) | (imm_hi << 12);
|
insn = (insn & 0x00000fff) | (imm_hi << 12);
|
||||||
|
@ -401,28 +452,45 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case R_RISCV_LO12_I: /* S + A */
|
|
||||||
case R_RISCV_PCREL_LO12_I: /* S - P */
|
case R_RISCV_PCREL_LO12_I: /* S - P */
|
||||||
|
case R_RISCV_PCREL_LO12_S: /* S - P */
|
||||||
{
|
{
|
||||||
if (reloc_type == R_RISCV_PCREL_LO12_I) {
|
/* Already handled in R_RISCV_PCREL_HI20, it should be skipped for
|
||||||
/* A = 0 */
|
* most cases. But it is still needed for some special cases, e.g.
|
||||||
val = (int32)((intptr_t)symbol_addr - (intptr_t)addr);
|
* ```
|
||||||
|
* label:
|
||||||
|
* auipc t0, %pcrel_hi(symbol) # R_RISCV_PCREL_HI20 (symbol)
|
||||||
|
* lui t1, 1
|
||||||
|
* lw t2, t0, %pcrel_lo(label) # R_RISCV_PCREL_LO12_I (label)
|
||||||
|
* add t2, t2, t1
|
||||||
|
* sw t2, t0, %pcrel_lo(label) # R_RISCV_PCREL_LO12_S (label)
|
||||||
|
* ```
|
||||||
|
* In this case, the R_RISCV_PCREL_LO12_I/S relocation should be
|
||||||
|
* handled after R_RISCV_PCREL_HI20 relocation.
|
||||||
|
*
|
||||||
|
* So, if the R_RISCV_PCREL_LO12_I/S relocation is not followed by
|
||||||
|
* R_RISCV_PCREL_HI20 relocation, it should be handled here but
|
||||||
|
* not implemented yet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((uintptr_t)addr - (uintptr_t)symbol_addr
|
||||||
|
- (uintptr_t)reloc_addend
|
||||||
|
!= 4) {
|
||||||
|
goto fail_addr_out_of_range;
|
||||||
}
|
}
|
||||||
else {
|
break;
|
||||||
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case R_RISCV_LO12_I: /* S + A */
|
||||||
|
{
|
||||||
|
|
||||||
|
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
|
||||||
|
|
||||||
CHECK_RELOC_OFFSET(sizeof(uint32));
|
CHECK_RELOC_OFFSET(sizeof(uint32));
|
||||||
if (reloc_type == R_RISCV_PCREL_LO12_I) {
|
|
||||||
if (val != (intptr_t)symbol_addr - (intptr_t)addr) {
|
|
||||||
goto fail_addr_out_of_range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (val != (intptr_t)symbol_addr + (intptr_t)reloc_addend) {
|
if (val != (intptr_t)symbol_addr + (intptr_t)reloc_addend) {
|
||||||
goto fail_addr_out_of_range;
|
goto fail_addr_out_of_range;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
addr = target_section_addr + reloc_offset;
|
addr = target_section_addr + reloc_offset;
|
||||||
insn = rv_get_val((uint16 *)addr);
|
insn = rv_get_val((uint16 *)addr);
|
||||||
|
|
|
@ -312,7 +312,6 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
#endif
|
#endif
|
||||||
int32 i, p, module_type;
|
int32 i, p, module_type;
|
||||||
uint64 total_size;
|
uint64 total_size;
|
||||||
const char *exception;
|
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
bh_assert(argc >= 0);
|
bh_assert(argc >= 0);
|
||||||
|
@ -389,6 +388,18 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
{
|
{
|
||||||
float32 f32 = strtof(argv[i], &endptr);
|
float32 f32 = strtof(argv[i], &endptr);
|
||||||
if (isnan(f32)) {
|
if (isnan(f32)) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/*
|
||||||
|
* Spec tests require the binary representation of NaN to be
|
||||||
|
* 0x7fc00000 for float and 0x7ff8000000000000 for float;
|
||||||
|
* however, in MSVC compiler, strtof doesn't return this
|
||||||
|
* exact value, causing some of the spec test failures. We
|
||||||
|
* use the value returned by nan/nanf as it is the one
|
||||||
|
* expected by spec tests.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
f32 = nanf("");
|
||||||
|
#endif
|
||||||
if (argv[i][0] == '-') {
|
if (argv[i][0] == '-') {
|
||||||
union ieee754_float u;
|
union ieee754_float u;
|
||||||
u.f = f32;
|
u.f = f32;
|
||||||
|
@ -423,6 +434,9 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
} u;
|
} u;
|
||||||
u.val = strtod(argv[i], &endptr);
|
u.val = strtod(argv[i], &endptr);
|
||||||
if (isnan(u.val)) {
|
if (isnan(u.val)) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
u.val = nan("");
|
||||||
|
#endif
|
||||||
if (argv[i][0] == '-') {
|
if (argv[i][0] == '-') {
|
||||||
union ieee754_double ud;
|
union ieee754_double ud;
|
||||||
ud.d = u.val;
|
ud.d = u.val;
|
||||||
|
@ -586,7 +600,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
{
|
{
|
||||||
#if UINTPTR_MAX == UINT32_MAX
|
#if UINTPTR_MAX == UINT32_MAX
|
||||||
if (argv1[k] != 0 && argv1[k] != (uint32)-1)
|
if (argv1[k] != 0 && argv1[k] != (uint32)-1)
|
||||||
os_printf("%p:ref.extern", (void *)argv1[k]);
|
os_printf("0x%" PRIxPTR ":ref.extern", (uintptr_t)argv1[k]);
|
||||||
else
|
else
|
||||||
os_printf("extern:ref.null");
|
os_printf("extern:ref.null");
|
||||||
k++;
|
k++;
|
||||||
|
@ -599,7 +613,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
u.parts[1] = argv1[k + 1];
|
u.parts[1] = argv1[k + 1];
|
||||||
k += 2;
|
k += 2;
|
||||||
if (u.val && u.val != (uintptr_t)-1LL)
|
if (u.val && u.val != (uintptr_t)-1LL)
|
||||||
os_printf("%p:ref.extern", (void *)u.val);
|
os_printf("0x%" PRIxPTR ":ref.extern", u.val);
|
||||||
else
|
else
|
||||||
os_printf("extern:ref.null");
|
os_printf("extern:ref.null");
|
||||||
#endif
|
#endif
|
||||||
|
@ -632,9 +646,7 @@ fail:
|
||||||
if (argv1)
|
if (argv1)
|
||||||
wasm_runtime_free(argv1);
|
wasm_runtime_free(argv1);
|
||||||
|
|
||||||
exception = wasm_runtime_get_exception(module_inst);
|
bh_assert(wasm_runtime_get_exception(module_inst));
|
||||||
bh_assert(exception);
|
|
||||||
os_printf("%s\n", exception);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,13 +292,46 @@ WASM_DEFINE_VEC_OWN(valtype, wasm_valtype_delete)
|
||||||
own wasm_config_t *
|
own wasm_config_t *
|
||||||
wasm_config_new(void)
|
wasm_config_new(void)
|
||||||
{
|
{
|
||||||
|
/* since wasm_runtime_malloc is not ready */
|
||||||
|
wasm_config_t *config = os_malloc(sizeof(wasm_config_t));
|
||||||
|
if (!config)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
memset(config, 0, sizeof(wasm_config_t));
|
||||||
|
config->mem_alloc_type = Alloc_With_System_Allocator;
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_config_delete(own wasm_config_t *config)
|
wasm_config_delete(own wasm_config_t *config)
|
||||||
{
|
{
|
||||||
(void)config;
|
if (config)
|
||||||
|
os_free(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_config_t *
|
||||||
|
wasm_config_set_mem_alloc_opt(wasm_config_t *config,
|
||||||
|
mem_alloc_type_t mem_alloc_type,
|
||||||
|
MemAllocOption *mem_alloc_option)
|
||||||
|
{
|
||||||
|
if (!config)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
config->mem_alloc_type = mem_alloc_type;
|
||||||
|
if (mem_alloc_option)
|
||||||
|
memcpy(&config->mem_alloc_option, mem_alloc_option,
|
||||||
|
sizeof(MemAllocOption));
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_config_t *
|
||||||
|
wasm_config_set_linux_perf_opt(wasm_config_t *config, bool enable)
|
||||||
|
{
|
||||||
|
if (!config)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
config->linux_perf_support = enable;
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -329,12 +362,11 @@ wasm_engine_delete_internal(wasm_engine_t *engine)
|
||||||
}
|
}
|
||||||
|
|
||||||
static wasm_engine_t *
|
static wasm_engine_t *
|
||||||
wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
|
wasm_engine_new_internal(wasm_config_t *config)
|
||||||
{
|
{
|
||||||
wasm_engine_t *engine = NULL;
|
wasm_engine_t *engine = NULL;
|
||||||
/* init runtime */
|
/* init runtime */
|
||||||
RuntimeInitArgs init_args = { 0 };
|
RuntimeInitArgs init_args = { 0 };
|
||||||
init_args.mem_alloc_type = type;
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
bh_log_set_verbose_level(BH_LOG_LEVEL_VERBOSE);
|
bh_log_set_verbose_level(BH_LOG_LEVEL_VERBOSE);
|
||||||
|
@ -344,34 +376,11 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
|
||||||
|
|
||||||
WASM_C_DUMP_PROC_MEM();
|
WASM_C_DUMP_PROC_MEM();
|
||||||
|
|
||||||
if (type == Alloc_With_Pool) {
|
/* wasm_config_t->MemAllocOption -> RuntimeInitArgs->MemAllocOption */
|
||||||
if (!opts) {
|
init_args.mem_alloc_type = config->mem_alloc_type;
|
||||||
return NULL;
|
memcpy(&init_args.mem_alloc_option, &config->mem_alloc_option,
|
||||||
}
|
sizeof(MemAllocOption));
|
||||||
|
init_args.linux_perf_support = config->linux_perf_support;
|
||||||
init_args.mem_alloc_option.pool.heap_buf = opts->pool.heap_buf;
|
|
||||||
init_args.mem_alloc_option.pool.heap_size = opts->pool.heap_size;
|
|
||||||
}
|
|
||||||
else if (type == Alloc_With_Allocator) {
|
|
||||||
if (!opts) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_args.mem_alloc_option.allocator.malloc_func =
|
|
||||||
opts->allocator.malloc_func;
|
|
||||||
init_args.mem_alloc_option.allocator.free_func =
|
|
||||||
opts->allocator.free_func;
|
|
||||||
init_args.mem_alloc_option.allocator.realloc_func =
|
|
||||||
opts->allocator.realloc_func;
|
|
||||||
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
|
||||||
init_args.mem_alloc_option.allocator.user_data =
|
|
||||||
opts->allocator.user_data;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
init_args.mem_alloc_option.pool.heap_buf = NULL;
|
|
||||||
init_args.mem_alloc_option.pool.heap_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wasm_runtime_full_init(&init_args)) {
|
if (!wasm_runtime_full_init(&init_args)) {
|
||||||
LOG_DEBUG("wasm_runtime_full_init failed");
|
LOG_DEBUG("wasm_runtime_full_init failed");
|
||||||
|
@ -418,14 +427,23 @@ static korp_mutex engine_lock = OS_THREAD_MUTEX_INITIALIZER;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
own wasm_engine_t *
|
own wasm_engine_t *
|
||||||
wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts)
|
wasm_engine_new()
|
||||||
|
{
|
||||||
|
wasm_config_t config = { 0 };
|
||||||
|
wasm_config_set_mem_alloc_opt(&config, Alloc_With_System_Allocator, NULL);
|
||||||
|
wasm_engine_t *engine = wasm_engine_new_with_config(&config);
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
own wasm_engine_t *
|
||||||
|
wasm_engine_new_with_config(wasm_config_t *config)
|
||||||
{
|
{
|
||||||
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
#if defined(OS_THREAD_MUTEX_INITIALIZER)
|
||||||
os_mutex_lock(&engine_lock);
|
os_mutex_lock(&engine_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!singleton_engine)
|
if (!singleton_engine)
|
||||||
singleton_engine = wasm_engine_new_internal(type, opts);
|
singleton_engine = wasm_engine_new_internal(config);
|
||||||
else
|
else
|
||||||
singleton_engine->ref_count++;
|
singleton_engine->ref_count++;
|
||||||
|
|
||||||
|
@ -437,16 +455,12 @@ wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
own wasm_engine_t *
|
own wasm_engine_t *
|
||||||
wasm_engine_new()
|
wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts)
|
||||||
{
|
{
|
||||||
return wasm_engine_new_with_args(Alloc_With_System_Allocator, NULL);
|
wasm_config_t config = { 0 };
|
||||||
}
|
config.mem_alloc_type = type;
|
||||||
|
memcpy(&config.mem_alloc_option, opts, sizeof(MemAllocOption));
|
||||||
own wasm_engine_t *
|
return wasm_engine_new_with_config(&config);
|
||||||
wasm_engine_new_with_config(own wasm_config_t *config)
|
|
||||||
{
|
|
||||||
(void)config;
|
|
||||||
return wasm_engine_new_with_args(Alloc_With_System_Allocator, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -53,7 +53,8 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
|
||||||
|
|
||||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||||
if (!(exec_env->exce_check_guard_page =
|
if (!(exec_env->exce_check_guard_page =
|
||||||
os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE)))
|
os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE,
|
||||||
|
os_get_invalid_handle())))
|
||||||
goto fail4;
|
goto fail4;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -187,7 +188,52 @@ void
|
||||||
wasm_exec_env_set_module_inst(WASMExecEnv *exec_env,
|
wasm_exec_env_set_module_inst(WASMExecEnv *exec_env,
|
||||||
WASMModuleInstanceCommon *const module_inst)
|
WASMModuleInstanceCommon *const module_inst)
|
||||||
{
|
{
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
wasm_cluster_traverse_lock(exec_env);
|
||||||
|
#endif
|
||||||
exec_env->module_inst = module_inst;
|
exec_env->module_inst = module_inst;
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
wasm_cluster_traverse_unlock(exec_env);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_exec_env_restore_module_inst(
|
||||||
|
WASMExecEnv *exec_env, WASMModuleInstanceCommon *const module_inst_common)
|
||||||
|
{
|
||||||
|
WASMModuleInstanceCommon *old_module_inst_common = exec_env->module_inst;
|
||||||
|
WASMModuleInstance *old_module_inst =
|
||||||
|
(WASMModuleInstance *)old_module_inst_common;
|
||||||
|
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_common;
|
||||||
|
char cur_exception[EXCEPTION_BUF_LEN];
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
wasm_cluster_traverse_lock(exec_env);
|
||||||
|
#endif
|
||||||
|
exec_env->module_inst = module_inst_common;
|
||||||
|
/*
|
||||||
|
* propagate an exception if any.
|
||||||
|
*/
|
||||||
|
exception_lock(old_module_inst);
|
||||||
|
if (old_module_inst->cur_exception[0] != '\0') {
|
||||||
|
bh_memcpy_s(cur_exception, sizeof(cur_exception),
|
||||||
|
old_module_inst->cur_exception,
|
||||||
|
sizeof(old_module_inst->cur_exception));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cur_exception[0] = '\0';
|
||||||
|
}
|
||||||
|
exception_unlock(old_module_inst);
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
wasm_cluster_traverse_unlock(exec_env);
|
||||||
|
#endif
|
||||||
|
if (cur_exception[0] != '\0') {
|
||||||
|
exception_lock(module_inst);
|
||||||
|
bh_memcpy_s(module_inst->cur_exception,
|
||||||
|
sizeof(module_inst->cur_exception), cur_exception,
|
||||||
|
sizeof(cur_exception));
|
||||||
|
exception_unlock(module_inst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -309,6 +309,10 @@ void
|
||||||
wasm_exec_env_set_module_inst(
|
wasm_exec_env_set_module_inst(
|
||||||
WASMExecEnv *exec_env, struct WASMModuleInstanceCommon *const module_inst);
|
WASMExecEnv *exec_env, struct WASMModuleInstanceCommon *const module_inst);
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_exec_env_restore_module_inst(
|
||||||
|
WASMExecEnv *exec_env, struct WASMModuleInstanceCommon *const module_inst);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_exec_env_set_thread_info(WASMExecEnv *exec_env);
|
wasm_exec_env_set_thread_info(WASMExecEnv *exec_env);
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ wasm_memory_init_with_allocator(void *_malloc_func, void *_realloc_func,
|
||||||
static inline bool
|
static inline bool
|
||||||
is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
|
is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
|
||||||
{
|
{
|
||||||
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
|
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||||
return wasm_runtime_is_bounds_checks_enabled(module_inst);
|
return wasm_runtime_is_bounds_checks_enabled(module_inst);
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
|
@ -298,10 +298,15 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
|
|
||||||
if (app_offset + size <= memory_inst->memory_data_size) {
|
if (app_offset + size <= memory_inst->memory_data_size) {
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
wasm_set_exception(module_inst, "out of bounds memory access");
|
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||||
return false;
|
return false;
|
||||||
|
@ -364,11 +369,16 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
|
|
||||||
if (memory_inst->memory_data <= addr
|
if (memory_inst->memory_data <= addr
|
||||||
&& addr + size <= memory_inst->memory_data_end) {
|
&& addr + size <= memory_inst->memory_data_end) {
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
wasm_set_exception(module_inst, "out of bounds memory access");
|
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||||
return false;
|
return false;
|
||||||
|
@ -393,20 +403,24 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
|
|
||||||
addr = memory_inst->memory_data + app_offset;
|
addr = memory_inst->memory_data + app_offset;
|
||||||
|
|
||||||
if (bounds_checks) {
|
if (bounds_checks) {
|
||||||
if (memory_inst->memory_data <= addr
|
if (memory_inst->memory_data <= addr
|
||||||
&& addr < memory_inst->memory_data_end) {
|
&& addr < memory_inst->memory_data_end) {
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If bounds checks is disabled, return the address directly */
|
/* If bounds checks is disabled, return the address directly */
|
||||||
else if (app_offset != 0) {
|
else if (app_offset != 0) {
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,6 +432,7 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
WASMMemoryInstance *memory_inst;
|
WASMMemoryInstance *memory_inst;
|
||||||
uint8 *addr = (uint8 *)native_ptr;
|
uint8 *addr = (uint8 *)native_ptr;
|
||||||
bool bounds_checks;
|
bool bounds_checks;
|
||||||
|
uint32 ret;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -429,16 +444,24 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
|
|
||||||
if (bounds_checks) {
|
if (bounds_checks) {
|
||||||
if (memory_inst->memory_data <= addr
|
if (memory_inst->memory_data <= addr
|
||||||
&& addr < memory_inst->memory_data_end)
|
&& addr < memory_inst->memory_data_end) {
|
||||||
return (uint32)(addr - memory_inst->memory_data);
|
ret = (uint32)(addr - memory_inst->memory_data);
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* If bounds checks is disabled, return the offset directly */
|
/* If bounds checks is disabled, return the offset directly */
|
||||||
else if (addr != NULL) {
|
else if (addr != NULL) {
|
||||||
return (uint32)(addr - memory_inst->memory_data);
|
ret = (uint32)(addr - memory_inst->memory_data);
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,6 +482,8 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
|
|
||||||
memory_data_size = memory_inst->memory_data_size;
|
memory_data_size = memory_inst->memory_data_size;
|
||||||
|
|
||||||
if (app_offset < memory_data_size) {
|
if (app_offset < memory_data_size) {
|
||||||
|
@ -466,9 +491,11 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
*p_app_start_offset = 0;
|
*p_app_start_offset = 0;
|
||||||
if (p_app_end_offset)
|
if (p_app_end_offset)
|
||||||
*p_app_end_offset = memory_data_size;
|
*p_app_end_offset = memory_data_size;
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,15 +517,19 @@ wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
|
|
||||||
if (memory_inst->memory_data <= addr
|
if (memory_inst->memory_data <= addr
|
||||||
&& addr < memory_inst->memory_data_end) {
|
&& addr < memory_inst->memory_data_end) {
|
||||||
if (p_native_start_addr)
|
if (p_native_start_addr)
|
||||||
*p_native_start_addr = memory_inst->memory_data;
|
*p_native_start_addr = memory_inst->memory_data;
|
||||||
if (p_native_end_addr)
|
if (p_native_end_addr)
|
||||||
*p_native_end_addr = memory_inst->memory_data_end;
|
*p_native_end_addr = memory_inst->memory_data_end;
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +543,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
|
||||||
bool bounds_checks;
|
bool bounds_checks;
|
||||||
|
|
||||||
if (!memory_inst) {
|
if (!memory_inst) {
|
||||||
goto fail;
|
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
native_addr = memory_inst->memory_data + app_buf_addr;
|
native_addr = memory_inst->memory_data + app_buf_addr;
|
||||||
|
@ -529,6 +561,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
|
||||||
/* 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
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
|
|
||||||
if (app_buf_addr >= memory_inst->memory_data_size) {
|
if (app_buf_addr >= memory_inst->memory_data_size) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -549,14 +583,20 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
|
||||||
if (str == str_end)
|
if (str == str_end)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
success:
|
success:
|
||||||
*p_native_addr = (void *)native_addr;
|
*p_native_addr = (void *)native_addr;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
fail:
|
fail:
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
wasm_set_exception(module_inst, "out of bounds memory access");
|
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WASMMemoryInstance *
|
WASMMemoryInstance *
|
||||||
|
@ -568,6 +608,27 @@ wasm_get_default_memory(WASMModuleInstance *module_inst)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
|
||||||
|
uint64 memory_data_size)
|
||||||
|
{
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
memory->mem_bound_check_1byte.u64 = memory_data_size - 1;
|
||||||
|
memory->mem_bound_check_2bytes.u64 = memory_data_size - 2;
|
||||||
|
memory->mem_bound_check_4bytes.u64 = memory_data_size - 4;
|
||||||
|
memory->mem_bound_check_8bytes.u64 = memory_data_size - 8;
|
||||||
|
memory->mem_bound_check_16bytes.u64 = memory_data_size - 16;
|
||||||
|
#else
|
||||||
|
memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1;
|
||||||
|
memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2;
|
||||||
|
memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4;
|
||||||
|
memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8;
|
||||||
|
memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
bool
|
bool
|
||||||
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||||
|
@ -625,9 +686,10 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||||
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;
|
||||||
/* No need to update memory->memory_data_size as it is
|
SET_LINEAR_MEMORY_SIZE(memory, (uint32)total_size_new);
|
||||||
initialized with the maximum memory data size for
|
memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
|
||||||
shared memory */
|
|
||||||
|
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -679,21 +741,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||||
memory->memory_data = memory_data_new;
|
memory->memory_data = memory_data_new;
|
||||||
memory->memory_data_end = memory_data_new + (uint32)total_size_new;
|
memory->memory_data_end = memory_data_new + (uint32)total_size_new;
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
|
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
|
||||||
memory->mem_bound_check_1byte.u64 = total_size_new - 1;
|
|
||||||
memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
|
|
||||||
memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
|
|
||||||
memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
|
|
||||||
memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
|
|
||||||
#else
|
|
||||||
memory->mem_bound_check_1byte.u32[0] = (uint32)total_size_new - 1;
|
|
||||||
memory->mem_bound_check_2bytes.u32[0] = (uint32)total_size_new - 2;
|
|
||||||
memory->mem_bound_check_4bytes.u32[0] = (uint32)total_size_new - 4;
|
|
||||||
memory->mem_bound_check_8bytes.u32[0] = (uint32)total_size_new - 8;
|
|
||||||
memory->mem_bound_check_16bytes.u32[0] = (uint32)total_size_new - 16;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(os_writegsbase)
|
#if defined(os_writegsbase)
|
||||||
/* write base addr of linear memory to GS segment register */
|
/* write base addr of linear memory to GS segment register */
|
||||||
|
@ -786,16 +834,10 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||||
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;
|
||||||
memory->memory_data_size = (uint32)total_size_new;
|
SET_LINEAR_MEMORY_SIZE(memory, (uint32)total_size_new);
|
||||||
memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
|
memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
|
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
|
||||||
memory->mem_bound_check_1byte.u64 = total_size_new - 1;
|
|
||||||
memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
|
|
||||||
memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
|
|
||||||
memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
|
|
||||||
memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return_func:
|
return_func:
|
||||||
if (!ret && enlarge_memory_error_cb) {
|
if (!ret && enlarge_memory_error_cb) {
|
||||||
|
|
|
@ -14,6 +14,16 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
#define GET_LINEAR_MEMORY_SIZE(memory) \
|
||||||
|
BH_ATOMIC_32_LOAD(memory->memory_data_size)
|
||||||
|
#define SET_LINEAR_MEMORY_SIZE(memory, size) \
|
||||||
|
BH_ATOMIC_32_STORE(memory->memory_data_size, size)
|
||||||
|
#else
|
||||||
|
#define GET_LINEAR_MEMORY_SIZE(memory) memory->memory_data_size
|
||||||
|
#define SET_LINEAR_MEMORY_SIZE(memory, size) memory->memory_data_size = size
|
||||||
|
#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);
|
||||||
|
@ -24,6 +34,10 @@ wasm_runtime_memory_destroy();
|
||||||
unsigned
|
unsigned
|
||||||
wasm_runtime_memory_pool_size();
|
wasm_runtime_memory_pool_size();
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
|
||||||
|
uint64 memory_data_size);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_runtime_set_enlarge_mem_error_callback(
|
wasm_runtime_set_enlarge_mem_error_callback(
|
||||||
const enlarge_memory_error_callback_t callback, void *user_data);
|
const enlarge_memory_error_callback_t callback, void *user_data);
|
||||||
|
|
|
@ -542,8 +542,7 @@ void
|
||||||
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
|
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
|
||||||
WASIContext *wasi_ctx)
|
WASIContext *wasi_ctx)
|
||||||
{
|
{
|
||||||
return wasm_native_set_context(module_inst_comm, g_wasi_context_key,
|
wasm_native_set_context(module_inst_comm, g_wasi_context_key, wasi_ctx);
|
||||||
wasi_ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -158,7 +158,7 @@ static JitCompOptions jit_options = { 0 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_JIT != 0
|
#if WASM_ENABLE_JIT != 0
|
||||||
static LLVMJITOptions llvm_jit_options = { 3, 3, 0 };
|
static LLVMJITOptions llvm_jit_options = { 3, 3, 0, false };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static RunningMode runtime_running_mode = Mode_Default;
|
static RunningMode runtime_running_mode = Mode_Default;
|
||||||
|
@ -662,9 +662,14 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_JIT != 0
|
#if WASM_ENABLE_JIT != 0
|
||||||
|
LOG_DEBUG("Start LLVM_JIT, opt_sz=%u, opt_lvl=%u, segue=%s, linux_perf=%s",
|
||||||
|
init_args->llvm_jit_size_level, init_args->llvm_jit_opt_level,
|
||||||
|
init_args->segue_flags ? "Yes" : "No",
|
||||||
|
init_args->linux_perf_support ? "Yes" : "No");
|
||||||
llvm_jit_options.size_level = init_args->llvm_jit_size_level;
|
llvm_jit_options.size_level = init_args->llvm_jit_size_level;
|
||||||
llvm_jit_options.opt_level = init_args->llvm_jit_opt_level;
|
llvm_jit_options.opt_level = init_args->llvm_jit_opt_level;
|
||||||
llvm_jit_options.segue_flags = init_args->segue_flags;
|
llvm_jit_options.segue_flags = init_args->segue_flags;
|
||||||
|
llvm_jit_options.linux_perf_support = init_args->linux_perf_support;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!wasm_runtime_env_init()) {
|
if (!wasm_runtime_env_init()) {
|
||||||
|
@ -2616,7 +2621,7 @@ 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
|
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||||
void
|
void
|
||||||
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
|
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
|
||||||
bool enable)
|
bool enable)
|
||||||
|
@ -2813,7 +2818,7 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
|
||||||
uint32 dir_count, const char *map_dir_list[],
|
uint32 dir_count, const char *map_dir_list[],
|
||||||
uint32 map_dir_count, const char *env_list[],
|
uint32 map_dir_count, const char *env_list[],
|
||||||
uint32 env_count, char *argv[], int argc,
|
uint32 env_count, char *argv[], int argc,
|
||||||
int stdinfd, int stdoutfd, int stderrfd)
|
int64 stdinfd, int64 stdoutfd, int64 stderrfd)
|
||||||
{
|
{
|
||||||
WASIArguments *wasi_args = get_wasi_args_from_module(module);
|
WASIArguments *wasi_args = get_wasi_args_from_module(module);
|
||||||
|
|
||||||
|
@ -2827,9 +2832,9 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
|
||||||
wasi_args->env_count = env_count;
|
wasi_args->env_count = env_count;
|
||||||
wasi_args->argv = argv;
|
wasi_args->argv = argv;
|
||||||
wasi_args->argc = (uint32)argc;
|
wasi_args->argc = (uint32)argc;
|
||||||
wasi_args->stdio[0] = stdinfd;
|
wasi_args->stdio[0] = (os_raw_file_handle)stdinfd;
|
||||||
wasi_args->stdio[1] = stdoutfd;
|
wasi_args->stdio[1] = (os_raw_file_handle)stdoutfd;
|
||||||
wasi_args->stdio[2] = stderrfd;
|
wasi_args->stdio[2] = (os_raw_file_handle)stderrfd;
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
#if WASM_ENABLE_INTERP != 0
|
#if WASM_ENABLE_INTERP != 0
|
||||||
|
@ -2924,8 +2929,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
const char *env[], uint32 env_count,
|
const char *env[], uint32 env_count,
|
||||||
const char *addr_pool[], uint32 addr_pool_size,
|
const char *addr_pool[], uint32 addr_pool_size,
|
||||||
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
||||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
|
||||||
int stderrfd, char *error_buf, uint32 error_buf_size)
|
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
|
||||||
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
WASIContext *wasi_ctx;
|
WASIContext *wasi_ctx;
|
||||||
char *argv_buf = NULL;
|
char *argv_buf = NULL;
|
||||||
|
@ -2943,7 +2949,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
bool argv_environ_inited = false;
|
bool argv_environ_inited = false;
|
||||||
bool addr_pool_inited = false;
|
bool addr_pool_inited = false;
|
||||||
__wasi_fd_t wasm_fd = 3;
|
__wasi_fd_t wasm_fd = 3;
|
||||||
int32 raw_fd;
|
os_file_handle file_handle;
|
||||||
char *path, resolved_path[PATH_MAX];
|
char *path, resolved_path[PATH_MAX];
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
||||||
|
@ -3013,15 +3019,19 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
}
|
}
|
||||||
addr_pool_inited = true;
|
addr_pool_inited = true;
|
||||||
|
|
||||||
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors.
|
os_file_handle stdin_file_handle = os_convert_stdin_handle(stdinfd);
|
||||||
*
|
os_file_handle stdout_file_handle = os_convert_stdout_handle(stdoutfd);
|
||||||
* If -1 is given, use STDIN_FILENO (0), STDOUT_FILENO (1),
|
os_file_handle stderr_file_handle = os_convert_stderr_handle(stderrfd);
|
||||||
* STDERR_FILENO (2) respectively.
|
|
||||||
*/
|
if (!os_is_handle_valid(&stdin_file_handle)
|
||||||
if (!fd_table_insert_existing(curfds, 0, (stdinfd != -1) ? stdinfd : 0)
|
|| !os_is_handle_valid(&stdout_file_handle)
|
||||||
|| !fd_table_insert_existing(curfds, 1, (stdoutfd != -1) ? stdoutfd : 1)
|
|| !os_is_handle_valid(&stderr_file_handle))
|
||||||
|| !fd_table_insert_existing(curfds, 2,
|
goto fail;
|
||||||
(stderrfd != -1) ? stderrfd : 2)) {
|
|
||||||
|
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
|
||||||
|
if (!fd_table_insert_existing(curfds, 0, stdin_file_handle, true)
|
||||||
|
|| !fd_table_insert_existing(curfds, 1, stdout_file_handle, true)
|
||||||
|
|| !fd_table_insert_existing(curfds, 2, stderr_file_handle, true)) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"Init wasi environment failed: init fd table failed");
|
"Init wasi environment failed: init fd table failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -3029,7 +3039,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
|
|
||||||
wasm_fd = 3;
|
wasm_fd = 3;
|
||||||
for (i = 0; i < dir_count; i++, wasm_fd++) {
|
for (i = 0; i < dir_count; i++, wasm_fd++) {
|
||||||
path = realpath(dir_list[i], resolved_path);
|
path = os_realpath(dir_list[i], resolved_path);
|
||||||
if (!path) {
|
if (!path) {
|
||||||
if (error_buf)
|
if (error_buf)
|
||||||
snprintf(error_buf, error_buf_size,
|
snprintf(error_buf, error_buf_size,
|
||||||
|
@ -3038,17 +3048,101 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
|
__wasi_errno_t error = os_open_preopendir(path, &file_handle);
|
||||||
if (raw_fd == -1) {
|
|
||||||
|
if (error != __WASI_ESUCCESS) {
|
||||||
if (error_buf)
|
if (error_buf)
|
||||||
snprintf(error_buf, error_buf_size,
|
snprintf(error_buf, error_buf_size,
|
||||||
"error while pre-opening directory %s: %d\n",
|
"error while pre-opening directory %s: %d\n",
|
||||||
dir_list[i], errno);
|
dir_list[i], error);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_table_insert_existing(curfds, wasm_fd, raw_fd);
|
if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false)) {
|
||||||
fd_prestats_insert(prestats, dir_list[i], wasm_fd);
|
if (error_buf)
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"error inserting preopen fd %u (directory %s) into fd "
|
||||||
|
"table",
|
||||||
|
(unsigned int)wasm_fd, dir_list[i]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fd_prestats_insert(prestats, dir_list[i], wasm_fd)) {
|
||||||
|
if (error_buf)
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"error inserting preopen fd %u (directory %s) into "
|
||||||
|
"prestats table",
|
||||||
|
(unsigned int)wasm_fd, dir_list[i]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < map_dir_count; i++, wasm_fd++) {
|
||||||
|
char mapping_copy_buf[256];
|
||||||
|
char *mapping_copy = mapping_copy_buf;
|
||||||
|
char *map_mapped = NULL, *map_host = NULL;
|
||||||
|
const unsigned long max_len = strlen(map_dir_list[i]) * 2 + 3;
|
||||||
|
|
||||||
|
/* Allocation limit for runtime environments with reduced stack size */
|
||||||
|
if (max_len > 256) {
|
||||||
|
if (!(mapping_copy = wasm_runtime_malloc(max_len))) {
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"error while allocating for directory mapping\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bh_memcpy_s(mapping_copy, max_len, map_dir_list[i],
|
||||||
|
(uint32)(strlen(map_dir_list[i]) + 1));
|
||||||
|
map_mapped = strtok(mapping_copy, "::");
|
||||||
|
map_host = strtok(NULL, "::");
|
||||||
|
|
||||||
|
if (!map_mapped || !map_host) {
|
||||||
|
if (error_buf)
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"error while pre-opening mapped directory: "
|
||||||
|
"invalid map\n");
|
||||||
|
if (mapping_copy != mapping_copy_buf)
|
||||||
|
wasm_runtime_free(mapping_copy);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = os_realpath(map_host, resolved_path);
|
||||||
|
if (!path) {
|
||||||
|
if (error_buf)
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"error while pre-opening mapped directory %s: %d\n",
|
||||||
|
map_host, errno);
|
||||||
|
if (mapping_copy != mapping_copy_buf)
|
||||||
|
wasm_runtime_free(mapping_copy);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t error = os_open_preopendir(path, &file_handle);
|
||||||
|
if (error != __WASI_ESUCCESS) {
|
||||||
|
if (error_buf)
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"error while pre-opening mapped directory %s: %d\n",
|
||||||
|
map_host, errno);
|
||||||
|
if (mapping_copy != mapping_copy_buf)
|
||||||
|
wasm_runtime_free(mapping_copy);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false)
|
||||||
|
|| !fd_prestats_insert(prestats, map_mapped, wasm_fd)) {
|
||||||
|
if (error_buf)
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"error while pre-opening mapped directory %s: "
|
||||||
|
"insertion failed\n",
|
||||||
|
dir_list[i]);
|
||||||
|
if (mapping_copy != mapping_copy_buf)
|
||||||
|
wasm_runtime_free(mapping_copy);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapping_copy != mapping_copy_buf)
|
||||||
|
wasm_runtime_free(mapping_copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* addr_pool(textual) -> apool */
|
/* addr_pool(textual) -> apool */
|
||||||
|
@ -3176,8 +3270,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
const char *env[], uint32 env_count,
|
const char *env[], uint32 env_count,
|
||||||
const char *addr_pool[], uint32 addr_pool_size,
|
const char *addr_pool[], uint32 addr_pool_size,
|
||||||
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
||||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
|
||||||
int stderrfd, char *error_buf, uint32 error_buf_size)
|
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
|
||||||
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
WASIContext *ctx;
|
WASIContext *ctx;
|
||||||
uvwasi_t *uvwasi;
|
uvwasi_t *uvwasi;
|
||||||
|
@ -3963,17 +4058,15 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
if (n_stacks & 1)
|
if (n_stacks & 1)
|
||||||
n_stacks++;
|
n_stacks++;
|
||||||
if (func_type->types[i] == VALUE_TYPE_F32) {
|
if (func_type->types[i] == VALUE_TYPE_F32) {
|
||||||
*(float32 *)&stacks[n_stacks] = *(float32 *)argv_src++;
|
*(float32 *)&stacks[n_stacks++] =
|
||||||
/* NaN boxing, the upper bits of a valid NaN-boxed
|
*(float32 *)argv_src++;
|
||||||
value must be all 1s. */
|
|
||||||
stacks[n_stacks + 1] = 0xFFFFFFFF;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*(float64 *)&stacks[n_stacks] = *(float64 *)argv_src;
|
*(float64 *)&stacks[n_stacks] = *(float64 *)argv_src;
|
||||||
argv_src += 2;
|
argv_src += 2;
|
||||||
}
|
|
||||||
n_stacks += 2;
|
n_stacks += 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* BUILD_TARGET_RISCV32_ILP32D */
|
#endif /* BUILD_TARGET_RISCV32_ILP32D */
|
||||||
|
@ -4374,10 +4467,12 @@ static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative;
|
||||||
|| defined(BUILD_TARGET_RISCV64_LP64) */
|
|| defined(BUILD_TARGET_RISCV64_LP64) */
|
||||||
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
|
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
|
||||||
|
|
||||||
/* ASAN is not designed to work with custom stack unwind or other low-level \
|
/*
|
||||||
things. > Ignore a function that does some low-level magic. (e.g. walking \
|
* ASAN is not designed to work with custom stack unwind or other low-level
|
||||||
through the thread's stack bypassing the frame boundaries) */
|
* things. Ignore a function that does some low-level magic. (e.g. walking
|
||||||
#if defined(__GNUC__)
|
* through the thread's stack bypassing the frame boundaries)
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
__attribute__((no_sanitize_address))
|
__attribute__((no_sanitize_address))
|
||||||
#endif
|
#endif
|
||||||
bool
|
bool
|
||||||
|
@ -5811,7 +5906,7 @@ wasm_runtime_register_sub_module(const WASMModuleCommon *parent_module,
|
||||||
{
|
{
|
||||||
/* register sub_module into its parent sub module list */
|
/* register sub_module into its parent sub module list */
|
||||||
WASMRegisteredModule *node = NULL;
|
WASMRegisteredModule *node = NULL;
|
||||||
bh_list_status ret;
|
bh_list_status ret = BH_LIST_ERROR;
|
||||||
|
|
||||||
if (wasm_runtime_search_sub_module(parent_module, sub_module_name)) {
|
if (wasm_runtime_search_sub_module(parent_module, sub_module_name)) {
|
||||||
LOG_DEBUG("%s has been registered in its parent", sub_module_name);
|
LOG_DEBUG("%s has been registered in its parent", sub_module_name);
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
#include "wasm_native.h"
|
#include "wasm_native.h"
|
||||||
#include "../include/wasm_export.h"
|
#include "../include/wasm_export.h"
|
||||||
#include "../interpreter/wasm.h"
|
#include "../interpreter/wasm.h"
|
||||||
|
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
#if WASM_ENABLE_UVWASI == 0
|
#if WASM_ENABLE_UVWASI == 0
|
||||||
#include "wasmtime_ssp.h"
|
|
||||||
#include "posix.h"
|
#include "posix.h"
|
||||||
#else
|
#else
|
||||||
#include "uvwasi.h"
|
#include "uvwasi.h"
|
||||||
|
@ -44,14 +44,21 @@ extern "C" {
|
||||||
|
|
||||||
/* For STORE opcodes */
|
/* For STORE opcodes */
|
||||||
#define STORE_I64 PUT_I64_TO_ADDR
|
#define STORE_I64 PUT_I64_TO_ADDR
|
||||||
#define STORE_U32(addr, value) \
|
static inline void
|
||||||
do { \
|
STORE_U32(void *addr, uint32_t value)
|
||||||
*(uint32 *)(addr) = (uint32)(value); \
|
{
|
||||||
} while (0)
|
*(uint32_t *)(addr) = (uint32_t)(value);
|
||||||
#define STORE_U16(addr, value) \
|
}
|
||||||
do { \
|
static inline void
|
||||||
*(uint16 *)(addr) = (uint16)(value); \
|
STORE_U16(void *addr, uint16_t value)
|
||||||
} while (0)
|
{
|
||||||
|
*(uint16_t *)(addr) = (uint16_t)(value);
|
||||||
|
}
|
||||||
|
static inline void
|
||||||
|
STORE_U8(void *addr, uint8_t value)
|
||||||
|
{
|
||||||
|
*(uint8 *)addr = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* For LOAD opcodes */
|
/* For LOAD opcodes */
|
||||||
#define LOAD_I64(addr) (*(int64 *)(addr))
|
#define LOAD_I64(addr) (*(int64 *)(addr))
|
||||||
|
@ -147,42 +154,49 @@ GET_F64_FROM_ADDR(uint32 *addr)
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STORE_U32(addr, value) \
|
static inline void
|
||||||
do { \
|
STORE_U32(void *addr, uint32_t value)
|
||||||
uintptr_t addr_ = (uintptr_t)(addr); \
|
{
|
||||||
union { \
|
uintptr_t addr_ = (uintptr_t)(addr);
|
||||||
uint32 val; \
|
union {
|
||||||
uint16 u16[2]; \
|
uint32_t val;
|
||||||
uint8 u8[4]; \
|
uint16_t u16[2];
|
||||||
} u; \
|
uint8_t u8[4];
|
||||||
if ((addr_ & (uintptr_t)3) == 0) \
|
} u;
|
||||||
*(uint32 *)(addr) = (uint32)(value); \
|
if ((addr_ & (uintptr_t)3) == 0)
|
||||||
else { \
|
*(uint32_t *)(addr) = (uint32_t)(value);
|
||||||
u.val = (uint32)(value); \
|
else {
|
||||||
if ((addr_ & (uintptr_t)1) == 0) { \
|
u.val = (uint32_t)(value);
|
||||||
((uint16 *)(addr))[0] = u.u16[0]; \
|
if ((addr_ & (uintptr_t)1) == 0) {
|
||||||
((uint16 *)(addr))[1] = u.u16[1]; \
|
((uint16_t *)(addr))[0] = u.u16[0];
|
||||||
} \
|
((uint16_t *)(addr))[1] = u.u16[1];
|
||||||
else { \
|
}
|
||||||
((uint8 *)(addr))[0] = u.u8[0]; \
|
else {
|
||||||
((uint8 *)(addr))[1] = u.u8[1]; \
|
((uint8_t *)(addr))[0] = u.u8[0];
|
||||||
((uint8 *)(addr))[2] = u.u8[2]; \
|
((uint8_t *)(addr))[1] = u.u8[1];
|
||||||
((uint8 *)(addr))[3] = u.u8[3]; \
|
((uint8_t *)(addr))[2] = u.u8[2];
|
||||||
} \
|
((uint8_t *)(addr))[3] = u.u8[3];
|
||||||
} \
|
}
|
||||||
} while (0)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define STORE_U16(addr, value) \
|
static inline void
|
||||||
do { \
|
STORE_U8(void *addr, uint8_t value)
|
||||||
union { \
|
{
|
||||||
uint16 val; \
|
*(uint8 *)addr = value;
|
||||||
uint8 u8[2]; \
|
}
|
||||||
} u; \
|
|
||||||
u.val = (uint16)(value); \
|
|
||||||
((uint8 *)(addr))[0] = u.u8[0]; \
|
|
||||||
((uint8 *)(addr))[1] = u.u8[1]; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
STORE_U16(void *addr, uint16_t value)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
uint16_t val;
|
||||||
|
uint8_t u8[2];
|
||||||
|
} u;
|
||||||
|
u.val = (uint16_t)(value);
|
||||||
|
((uint8_t *)(addr))[0] = u.u8[0];
|
||||||
|
((uint8_t *)(addr))[1] = u.u8[1];
|
||||||
|
}
|
||||||
/* For LOAD opcodes */
|
/* For LOAD opcodes */
|
||||||
static inline int64
|
static inline int64
|
||||||
LOAD_I64(void *addr)
|
LOAD_I64(void *addr)
|
||||||
|
@ -298,6 +312,14 @@ LOAD_I16(void *addr)
|
||||||
|
|
||||||
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
|
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
|
||||||
|
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
#define SHARED_MEMORY_LOCK(memory) shared_memory_lock(memory)
|
||||||
|
#define SHARED_MEMORY_UNLOCK(memory) shared_memory_unlock(memory)
|
||||||
|
#else
|
||||||
|
#define SHARED_MEMORY_LOCK(memory) (void)0
|
||||||
|
#define SHARED_MEMORY_UNLOCK(memory) (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct WASMModuleCommon {
|
typedef struct WASMModuleCommon {
|
||||||
/* Module type, for module loaded from WASM bytecode binary,
|
/* Module type, for module loaded from WASM bytecode binary,
|
||||||
this field is Wasm_Module_Bytecode, and this structure should
|
this field is Wasm_Module_Bytecode, and this structure should
|
||||||
|
@ -421,6 +443,7 @@ typedef struct LLVMJITOptions {
|
||||||
uint32 opt_level;
|
uint32 opt_level;
|
||||||
uint32 size_level;
|
uint32 size_level;
|
||||||
uint32 segue_flags;
|
uint32 segue_flags;
|
||||||
|
bool linux_perf_support;
|
||||||
} LLVMJITOptions;
|
} LLVMJITOptions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -598,7 +621,7 @@ wasm_runtime_get_user_data(WASMExecEnv *exec_env);
|
||||||
WASMExecEnv *
|
WASMExecEnv *
|
||||||
wasm_runtime_get_cur_exec_env(const WASMModuleInstanceCommon *module_inst);
|
wasm_runtime_get_cur_exec_env(const WASMModuleInstanceCommon *module_inst);
|
||||||
|
|
||||||
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
|
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||||
/* See wasm_export.h for description */
|
/* See wasm_export.h for description */
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
|
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
|
||||||
|
@ -863,7 +886,7 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
|
||||||
uint32 dir_count, const char *map_dir_list[],
|
uint32 dir_count, const char *map_dir_list[],
|
||||||
uint32 map_dir_count, const char *env_list[],
|
uint32 map_dir_count, const char *env_list[],
|
||||||
uint32 env_count, char *argv[], int argc,
|
uint32 env_count, char *argv[], int argc,
|
||||||
int stdinfd, int stdoutfd, int stderrfd);
|
int64 stdinfd, int64 stdoutfd, int64 stderrfd);
|
||||||
|
|
||||||
/* See wasm_export.h for description */
|
/* See wasm_export.h for description */
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
|
@ -891,8 +914,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
const char *env[], uint32 env_count,
|
const char *env[], uint32 env_count,
|
||||||
const char *addr_pool[], uint32 addr_pool_size,
|
const char *addr_pool[], uint32 addr_pool_size,
|
||||||
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
||||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
|
||||||
int stderrfd, char *error_buf, uint32 error_buf_size);
|
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
|
||||||
|
char *error_buf, uint32 error_buf_size);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst);
|
wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* - If you care performance, it's better to make the interpreters
|
* - If you care performance, it's better to make the interpreters
|
||||||
* use atomic ops.
|
* use atomic ops.
|
||||||
*/
|
*/
|
||||||
static korp_mutex _shared_memory_lock;
|
korp_mutex g_shared_memory_lock;
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
enum {
|
enum {
|
||||||
|
@ -55,13 +55,13 @@ destroy_wait_info(void *wait_info);
|
||||||
bool
|
bool
|
||||||
wasm_shared_memory_init()
|
wasm_shared_memory_init()
|
||||||
{
|
{
|
||||||
if (os_mutex_init(&_shared_memory_lock) != 0)
|
if (os_mutex_init(&g_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_lock);
|
os_mutex_destroy(&g_shared_memory_lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -71,79 +71,47 @@ 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_lock);
|
os_mutex_destroy(&g_shared_memory_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint16
|
||||||
shared_memory_inc_reference(WASMMemoryInstance *memory)
|
shared_memory_inc_reference(WASMMemoryInstance *memory)
|
||||||
{
|
{
|
||||||
bh_assert(shared_memory_is_shared(memory));
|
bh_assert(shared_memory_is_shared(memory));
|
||||||
uint32 old;
|
uint16 old;
|
||||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
#if BH_ATOMIC_16_IS_ATOMIC == 0
|
||||||
os_mutex_lock(&_shared_memory_lock);
|
os_mutex_lock(&g_shared_memory_lock);
|
||||||
#endif
|
#endif
|
||||||
old = BH_ATOMIC_32_FETCH_ADD(memory->ref_count, 1);
|
old = BH_ATOMIC_16_FETCH_ADD(memory->ref_count, 1);
|
||||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
#if BH_ATOMIC_16_IS_ATOMIC == 0
|
||||||
os_mutex_unlock(&_shared_memory_lock);
|
os_mutex_unlock(&g_shared_memory_lock);
|
||||||
#endif
|
#endif
|
||||||
bh_assert(old >= 1);
|
bh_assert(old >= 1);
|
||||||
bh_assert(old < UINT32_MAX);
|
bh_assert(old < UINT16_MAX);
|
||||||
return old + 1;
|
return old + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint16
|
||||||
shared_memory_dec_reference(WASMMemoryInstance *memory)
|
shared_memory_dec_reference(WASMMemoryInstance *memory)
|
||||||
{
|
{
|
||||||
bh_assert(shared_memory_is_shared(memory));
|
bh_assert(shared_memory_is_shared(memory));
|
||||||
uint32 old;
|
uint16 old;
|
||||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
#if BH_ATOMIC_16_IS_ATOMIC == 0
|
||||||
os_mutex_lock(&_shared_memory_lock);
|
os_mutex_lock(&g_shared_memory_lock);
|
||||||
#endif
|
#endif
|
||||||
old = BH_ATOMIC_32_FETCH_SUB(memory->ref_count, 1);
|
old = BH_ATOMIC_16_FETCH_SUB(memory->ref_count, 1);
|
||||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
#if BH_ATOMIC_16_IS_ATOMIC == 0
|
||||||
os_mutex_unlock(&_shared_memory_lock);
|
os_mutex_unlock(&g_shared_memory_lock);
|
||||||
#endif
|
#endif
|
||||||
bh_assert(old > 0);
|
bh_assert(old > 0);
|
||||||
return old - 1;
|
return old - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
shared_memory_is_shared(WASMMemoryInstance *memory)
|
|
||||||
{
|
|
||||||
uint32 old;
|
|
||||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
|
||||||
os_mutex_lock(&_shared_memory_lock);
|
|
||||||
#endif
|
|
||||||
old = BH_ATOMIC_32_LOAD(memory->ref_count);
|
|
||||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
|
||||||
os_mutex_unlock(&_shared_memory_lock);
|
|
||||||
#endif
|
|
||||||
return old > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static korp_mutex *
|
static korp_mutex *
|
||||||
shared_memory_get_lock_pointer(WASMMemoryInstance *memory)
|
shared_memory_get_lock_pointer(WASMMemoryInstance *memory)
|
||||||
{
|
{
|
||||||
bh_assert(memory != NULL);
|
bh_assert(memory != NULL);
|
||||||
return &_shared_memory_lock;
|
return &g_shared_memory_lock;
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
shared_memory_lock(WASMMemoryInstance *memory)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
shared_memory_unlock(WASMMemoryInstance *memory)
|
|
||||||
{
|
|
||||||
bh_assert(memory != NULL);
|
|
||||||
os_mutex_unlock(&_shared_memory_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Atomics wait && notify APIs */
|
/* Atomics wait && notify APIs */
|
||||||
|
@ -301,12 +269,15 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_memory_lock(module_inst->memories[0]);
|
||||||
if ((uint8 *)address < module_inst->memories[0]->memory_data
|
if ((uint8 *)address < module_inst->memories[0]->memory_data
|
||||||
|| (uint8 *)address + (wait64 ? 8 : 4)
|
|| (uint8 *)address + (wait64 ? 8 : 4)
|
||||||
> module_inst->memories[0]->memory_data_end) {
|
> module_inst->memories[0]->memory_data_end) {
|
||||||
|
shared_memory_unlock(module_inst->memories[0]);
|
||||||
wasm_runtime_set_exception(module, "out of bounds memory access");
|
wasm_runtime_set_exception(module, "out of bounds memory access");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
shared_memory_unlock(module_inst->memories[0]);
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
exec_env =
|
exec_env =
|
||||||
|
@ -423,9 +394,11 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
|
||||||
bh_assert(module->module_type == Wasm_Module_Bytecode
|
bh_assert(module->module_type == Wasm_Module_Bytecode
|
||||||
|| module->module_type == Wasm_Module_AoT);
|
|| module->module_type == Wasm_Module_AoT);
|
||||||
|
|
||||||
|
shared_memory_lock(module_inst->memories[0]);
|
||||||
out_of_bounds =
|
out_of_bounds =
|
||||||
((uint8 *)address < module_inst->memories[0]->memory_data
|
((uint8 *)address < module_inst->memories[0]->memory_data
|
||||||
|| (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end);
|
|| (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end);
|
||||||
|
shared_memory_unlock(module_inst->memories[0]);
|
||||||
|
|
||||||
if (out_of_bounds) {
|
if (out_of_bounds) {
|
||||||
wasm_runtime_set_exception(module, "out of bounds memory access");
|
wasm_runtime_set_exception(module, "out of bounds memory access");
|
||||||
|
|
|
@ -14,26 +14,39 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern korp_mutex g_shared_memory_lock;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_shared_memory_init();
|
wasm_shared_memory_init();
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_shared_memory_destroy();
|
wasm_shared_memory_destroy();
|
||||||
|
|
||||||
uint32
|
uint16
|
||||||
shared_memory_inc_reference(WASMMemoryInstance *memory);
|
shared_memory_inc_reference(WASMMemoryInstance *memory);
|
||||||
|
|
||||||
uint32
|
uint16
|
||||||
shared_memory_dec_reference(WASMMemoryInstance *memory);
|
shared_memory_dec_reference(WASMMemoryInstance *memory);
|
||||||
|
|
||||||
bool
|
#define shared_memory_is_shared(memory) memory->is_shared_memory
|
||||||
shared_memory_is_shared(WASMMemoryInstance *memory);
|
|
||||||
|
|
||||||
void
|
#define shared_memory_lock(memory) \
|
||||||
shared_memory_lock(WASMMemoryInstance *memory);
|
do { \
|
||||||
|
/* \
|
||||||
|
* Note: exception logic is currently abusing this lock. \
|
||||||
|
* cf. \
|
||||||
|
* https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407 \
|
||||||
|
*/ \
|
||||||
|
bh_assert(memory != NULL); \
|
||||||
|
if (memory->is_shared_memory) \
|
||||||
|
os_mutex_lock(&g_shared_memory_lock); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
void
|
#define shared_memory_unlock(memory) \
|
||||||
shared_memory_unlock(WASMMemoryInstance *memory);
|
do { \
|
||||||
|
if (memory->is_shared_memory) \
|
||||||
|
os_mutex_unlock(&g_shared_memory_lock); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||||
|
|
|
@ -129,7 +129,6 @@ aot_create_table_init_data_list(const WASMModule *module)
|
||||||
data_list[i]->mode = module->table_segments[i].mode;
|
data_list[i]->mode = module->table_segments[i].mode;
|
||||||
data_list[i]->elem_type = module->table_segments[i].elem_type;
|
data_list[i]->elem_type = module->table_segments[i].elem_type;
|
||||||
/* runtime control it */
|
/* runtime control it */
|
||||||
data_list[i]->is_dropped = false;
|
|
||||||
data_list[i]->table_index = module->table_segments[i].table_index;
|
data_list[i]->table_index = module->table_segments[i].table_index;
|
||||||
bh_memcpy_s(&data_list[i]->offset, sizeof(AOTInitExpr),
|
bh_memcpy_s(&data_list[i]->offset, sizeof(AOTInitExpr),
|
||||||
&module->table_segments[i].base_offset,
|
&module->table_segments[i].base_offset,
|
||||||
|
|
|
@ -143,7 +143,6 @@ typedef struct AOTTableInitData {
|
||||||
uint32 mode;
|
uint32 mode;
|
||||||
/* funcref or externref, elemkind will be considered as funcref */
|
/* funcref or externref, elemkind will be considered as funcref */
|
||||||
uint32 elem_type;
|
uint32 elem_type;
|
||||||
bool is_dropped;
|
|
||||||
/* optional, only for active */
|
/* optional, only for active */
|
||||||
uint32 table_index;
|
uint32 table_index;
|
||||||
/* Start address of init data */
|
/* Start address of init data */
|
||||||
|
|
|
@ -269,7 +269,7 @@ static uint32
|
||||||
get_table_init_data_size(AOTTableInitData *table_init_data)
|
get_table_init_data_size(AOTTableInitData *table_init_data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* mode (4 bytes), elem_type (4 bytes), do not need is_dropped field
|
* mode (4 bytes), elem_type (4 bytes)
|
||||||
*
|
*
|
||||||
* table_index(4 bytes) + init expr type (4 bytes) + init expr value (8
|
* table_index(4 bytes) + init expr type (4 bytes) + init expr value (8
|
||||||
* bytes)
|
* bytes)
|
||||||
|
|
|
@ -202,6 +202,9 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
*p_frame_ip = block->wasm_code_else + 1;
|
*p_frame_ip = block->wasm_code_else + 1;
|
||||||
/* Push back the block */
|
/* Push back the block */
|
||||||
aot_block_stack_push(&func_ctx->block_stack, block);
|
aot_block_stack_push(&func_ctx->block_stack, block);
|
||||||
|
/* Recover parameters of else branch */
|
||||||
|
for (i = 0; i < block->param_count; i++)
|
||||||
|
PUSH(block->else_param_phis[i], block->param_types[i]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (block->llvm_end_block) {
|
else if (block->llvm_end_block) {
|
||||||
|
@ -221,6 +224,19 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (block->label_type == LABEL_TYPE_IF && block->llvm_else_block
|
||||||
|
&& !block->skip_wasm_code_else
|
||||||
|
&& *p_frame_ip <= block->wasm_code_else) {
|
||||||
|
/* Clear value stack and start to translate else branch */
|
||||||
|
aot_value_stack_destroy(&block->value_stack);
|
||||||
|
/* Recover parameters of else branch */
|
||||||
|
for (i = 0; i < block->param_count; i++)
|
||||||
|
PUSH(block->else_param_phis[i], block->param_types[i]);
|
||||||
|
SET_BUILDER_POS(block->llvm_else_block);
|
||||||
|
*p_frame_ip = block->wasm_code_else + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
*p_frame_ip = block->wasm_code_end + 1;
|
*p_frame_ip = block->wasm_code_end + 1;
|
||||||
SET_BUILDER_POS(block->llvm_end_block);
|
SET_BUILDER_POS(block->llvm_end_block);
|
||||||
|
|
||||||
|
@ -344,6 +360,8 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
|
||||||
for (i = 0; i < block->param_count; i++) {
|
for (i = 0; i < block->param_count; i++) {
|
||||||
param_index = block->param_count - 1 - i;
|
param_index = block->param_count - 1 - i;
|
||||||
POP(value, block->param_types[param_index]);
|
POP(value, block->param_types[param_index]);
|
||||||
|
if (block->llvm_entry_block)
|
||||||
|
/* Only add incoming phis if the entry block was created */
|
||||||
ADD_TO_PARAM_PHIS(block, value, param_index);
|
ADD_TO_PARAM_PHIS(block, value, param_index);
|
||||||
if (block->label_type == LABEL_TYPE_IF
|
if (block->label_type == LABEL_TYPE_IF
|
||||||
&& !block->skip_wasm_code_else) {
|
&& !block->skip_wasm_code_else) {
|
||||||
|
@ -366,7 +384,17 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
|
||||||
|
|
||||||
/* Push param phis to the new block */
|
/* Push param phis to the new block */
|
||||||
for (i = 0; i < block->param_count; i++) {
|
for (i = 0; i < block->param_count; i++) {
|
||||||
|
if (block->llvm_entry_block)
|
||||||
|
/* Push param phis if the entry basic block was created */
|
||||||
PUSH(block->param_phis[i], block->param_types[i]);
|
PUSH(block->param_phis[i], block->param_types[i]);
|
||||||
|
else {
|
||||||
|
bh_assert(block->label_type == LABEL_TYPE_IF
|
||||||
|
&& block->llvm_else_block && block->else_param_phis
|
||||||
|
&& !block->skip_wasm_code_else);
|
||||||
|
/* Push else param phis if we start to translate the
|
||||||
|
else branch */
|
||||||
|
PUSH(block->else_param_phis[i], block->param_types[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -22,11 +22,14 @@ static bool
|
||||||
is_win_platform(AOTCompContext *comp_ctx)
|
is_win_platform(AOTCompContext *comp_ctx)
|
||||||
{
|
{
|
||||||
char *triple = LLVMGetTargetMachineTriple(comp_ctx->target_machine);
|
char *triple = LLVMGetTargetMachineTriple(comp_ctx->target_machine);
|
||||||
|
bool ret;
|
||||||
|
|
||||||
bh_assert(triple);
|
bh_assert(triple);
|
||||||
if (strstr(triple, "win32") || strstr(triple, "win"))
|
ret = (strstr(triple, "win32") || strstr(triple, "win")) ? true : false;
|
||||||
return true;
|
|
||||||
return false;
|
LLVMDisposeMessage(triple);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
|
@ -157,6 +157,9 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
|
|
||||||
if (mem_offset + bytes <= mem_data_size) {
|
if (mem_offset + bytes <= mem_data_size) {
|
||||||
/* inside memory space */
|
/* inside memory space */
|
||||||
|
if (comp_ctx->pointer_size == sizeof(uint64))
|
||||||
|
offset1 = I64_CONST((uint32)mem_offset);
|
||||||
|
else
|
||||||
offset1 = I32_CONST((uint32)mem_offset);
|
offset1 = I32_CONST((uint32)mem_offset);
|
||||||
CHECK_LLVM_CONST(offset1);
|
CHECK_LLVM_CONST(offset1);
|
||||||
if (!enable_segue) {
|
if (!enable_segue) {
|
||||||
|
|
|
@ -171,15 +171,6 @@
|
||||||
right = shift_count_mask; \
|
right = shift_count_mask; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static bool
|
|
||||||
is_shift_count_mask_needed(AOTCompContext *comp_ctx, LLVMValueRef left,
|
|
||||||
LLVMValueRef right)
|
|
||||||
{
|
|
||||||
return (strcmp(comp_ctx->target_arch, "x86_64") != 0
|
|
||||||
&& strcmp(comp_ctx->target_arch, "i386") != 0)
|
|
||||||
|| (LLVMIsEfficientConstInt(left) && LLVMIsEfficientConstInt(right));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call llvm constrained floating-point intrinsic */
|
/* Call llvm constrained floating-point intrinsic */
|
||||||
static LLVMValueRef
|
static LLVMValueRef
|
||||||
call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
|
call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
|
||||||
|
@ -737,7 +728,6 @@ compile_int_shl(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
|
||||||
{
|
{
|
||||||
LLVMValueRef res;
|
LLVMValueRef res;
|
||||||
|
|
||||||
if (is_shift_count_mask_needed(comp_ctx, left, right))
|
|
||||||
SHIFT_COUNT_MASK;
|
SHIFT_COUNT_MASK;
|
||||||
|
|
||||||
/* Build shl */
|
/* Build shl */
|
||||||
|
@ -752,7 +742,6 @@ compile_int_shr_s(AOTCompContext *comp_ctx, LLVMValueRef left,
|
||||||
{
|
{
|
||||||
LLVMValueRef res;
|
LLVMValueRef res;
|
||||||
|
|
||||||
if (is_shift_count_mask_needed(comp_ctx, left, right))
|
|
||||||
SHIFT_COUNT_MASK;
|
SHIFT_COUNT_MASK;
|
||||||
|
|
||||||
/* Build shl */
|
/* Build shl */
|
||||||
|
@ -767,7 +756,6 @@ compile_int_shr_u(AOTCompContext *comp_ctx, LLVMValueRef left,
|
||||||
{
|
{
|
||||||
LLVMValueRef res;
|
LLVMValueRef res;
|
||||||
|
|
||||||
if (is_shift_count_mask_needed(comp_ctx, left, right))
|
|
||||||
SHIFT_COUNT_MASK;
|
SHIFT_COUNT_MASK;
|
||||||
|
|
||||||
/* Build shl */
|
/* Build shl */
|
||||||
|
@ -789,17 +777,25 @@ compile_int_rot(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
|
||||||
if (IS_CONST_ZERO(right))
|
if (IS_CONST_ZERO(right))
|
||||||
return left;
|
return left;
|
||||||
|
|
||||||
/* Calculate (bits - shif_count) */
|
/* Calculate (bits - shift_count) */
|
||||||
LLVM_BUILD_OP(Sub, is_i32 ? I32_32 : I64_64, right, bits_minus_shift_count,
|
LLVM_BUILD_OP(Sub, is_i32 ? I32_32 : I64_64, right, bits_minus_shift_count,
|
||||||
"bits_minus_shift_count", NULL);
|
"bits_minus_shift_count", NULL);
|
||||||
|
/* Calculate (bits - shift_count) & mask */
|
||||||
|
bits_minus_shift_count =
|
||||||
|
LLVMBuildAnd(comp_ctx->builder, bits_minus_shift_count,
|
||||||
|
is_i32 ? I32_31 : I64_63, "bits_minus_shift_count_and");
|
||||||
|
if (!bits_minus_shift_count) {
|
||||||
|
aot_set_last_error("llvm build and failed.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_rotl) {
|
if (is_rotl) {
|
||||||
/* left<<count | left>>(BITS-count) */
|
/* (left << count) | (left >> ((BITS - count) & mask)) */
|
||||||
LLVM_BUILD_OP(Shl, left, right, tmp_l, "tmp_l", NULL);
|
LLVM_BUILD_OP(Shl, left, right, tmp_l, "tmp_l", NULL);
|
||||||
LLVM_BUILD_OP(LShr, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
|
LLVM_BUILD_OP(LShr, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* left>>count | left<<(BITS-count) */
|
/* (left >> count) | (left << ((BITS - count) & mask)) */
|
||||||
LLVM_BUILD_OP(LShr, left, right, tmp_l, "tmp_l", NULL);
|
LLVM_BUILD_OP(LShr, left, right, tmp_l, "tmp_l", NULL);
|
||||||
LLVM_BUILD_OP(Shl, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
|
LLVM_BUILD_OP(Shl, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,13 @@ aot_target_precheck_can_use_musttail(const AOTCompContext *comp_ctx)
|
||||||
*/
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (strstr(comp_ctx->target_arch, "thumb")) {
|
||||||
|
/*
|
||||||
|
* cf.
|
||||||
|
* https://github.com/bytecodealliance/wasm-micro-runtime/issues/2412
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* x86-64/i386: true
|
* x86-64/i386: true
|
||||||
*
|
*
|
||||||
|
@ -646,6 +653,20 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
|
||||||
attr_no_jump_tables);
|
attr_no_jump_tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* spread fp.all to every function */
|
||||||
|
if (comp_ctx->emit_frame_pointer) {
|
||||||
|
const char *key = "frame-pointer";
|
||||||
|
const char *val = "all";
|
||||||
|
LLVMAttributeRef no_omit_fp = LLVMCreateStringAttribute(
|
||||||
|
comp_ctx->context, key, (unsigned)strlen(key), val,
|
||||||
|
(unsigned)strlen(val));
|
||||||
|
if (!no_omit_fp) {
|
||||||
|
aot_set_last_error("create LLVM attribute (frame-pointer) failed.");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex, no_omit_fp);
|
||||||
|
}
|
||||||
|
|
||||||
if (need_precheck) {
|
if (need_precheck) {
|
||||||
if (!comp_ctx->is_jit_mode)
|
if (!comp_ctx->is_jit_mode)
|
||||||
LLVMSetLinkage(func, LLVMInternalLinkage);
|
LLVMSetLinkage(func, LLVMInternalLinkage);
|
||||||
|
@ -1915,6 +1936,7 @@ static ArchItem valid_archs[] = {
|
||||||
static const char *valid_abis[] = {
|
static const char *valid_abis[] = {
|
||||||
"gnu",
|
"gnu",
|
||||||
"eabi",
|
"eabi",
|
||||||
|
"eabihf",
|
||||||
"gnueabihf",
|
"gnueabihf",
|
||||||
"msvc",
|
"msvc",
|
||||||
"ilp32",
|
"ilp32",
|
||||||
|
@ -1930,13 +1952,33 @@ static void
|
||||||
print_supported_targets()
|
print_supported_targets()
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
const char *target_name;
|
||||||
|
|
||||||
os_printf("Supported targets:\n");
|
os_printf("Supported targets:\n");
|
||||||
|
/* over the list of all available targets */
|
||||||
|
for (LLVMTargetRef target = LLVMGetFirstTarget(); target != NULL;
|
||||||
|
target = LLVMGetNextTarget(target)) {
|
||||||
|
target_name = LLVMGetTargetName(target);
|
||||||
|
/* Skip mipsel, aarch64_be since prefix mips, aarch64 will cover them */
|
||||||
|
if (strcmp(target_name, "mipsel") == 0)
|
||||||
|
continue;
|
||||||
|
else if (strcmp(target_name, "aarch64_be") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(target_name, "x86-64") == 0)
|
||||||
|
os_printf(" x86_64\n");
|
||||||
|
else if (strcmp(target_name, "x86") == 0)
|
||||||
|
os_printf(" i386\n");
|
||||||
|
else {
|
||||||
for (i = 0; i < sizeof(valid_archs) / sizeof(ArchItem); i++) {
|
for (i = 0; i < sizeof(valid_archs) / sizeof(ArchItem); i++) {
|
||||||
os_printf("%s ", valid_archs[i].arch);
|
/* If target_name is prefix for valid_archs[i].arch */
|
||||||
if (valid_archs[i].support_eb)
|
if ((strncmp(target_name, valid_archs[i].arch,
|
||||||
os_printf("%seb ", valid_archs[i].arch);
|
strlen(target_name))
|
||||||
|
== 0))
|
||||||
|
os_printf(" %s\n", valid_archs[i].arch);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
os_printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1992,6 +2034,18 @@ get_target_arch_from_triple(const char *triple, char *arch_buf, uint32 buf_size)
|
||||||
bh_assert(*triple == '-' || *triple == '\0');
|
bh_assert(*triple == '-' || *triple == '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_baremetal_target(const char *target, const char *cpu, const char *abi)
|
||||||
|
{
|
||||||
|
/* TODO: support more baremetal targets */
|
||||||
|
if (target) {
|
||||||
|
/* If target is thumbxxx, then it is baremetal target */
|
||||||
|
if (!strncmp(target, "thumb", strlen("thumb")))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
aot_handle_llvm_errmsg(const char *string, LLVMErrorRef err)
|
aot_handle_llvm_errmsg(const char *string, LLVMErrorRef err)
|
||||||
{
|
{
|
||||||
|
@ -2120,7 +2174,7 @@ jit_stack_size_callback(void *user_data, const char *name, size_t namelen,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
orc_jit_create(AOTCompContext *comp_ctx)
|
orc_jit_create(AOTCompContext *comp_ctx, bool linux_perf_support)
|
||||||
{
|
{
|
||||||
LLVMErrorRef err;
|
LLVMErrorRef err;
|
||||||
LLVMOrcLLLazyJITRef orc_jit = NULL;
|
LLVMOrcLLLazyJITRef orc_jit = NULL;
|
||||||
|
@ -2160,6 +2214,14 @@ orc_jit_create(AOTCompContext *comp_ctx)
|
||||||
/* Ownership transfer: LLVMOrcLLJITBuilderRef -> LLVMOrcLLJITRef */
|
/* Ownership transfer: LLVMOrcLLJITBuilderRef -> LLVMOrcLLJITRef */
|
||||||
builder = NULL;
|
builder = NULL;
|
||||||
|
|
||||||
|
if (linux_perf_support) {
|
||||||
|
LOG_DEBUG("Enable linux perf support");
|
||||||
|
LLVMOrcObjectLayerRef obj_linking_layer =
|
||||||
|
(LLVMOrcObjectLayerRef)LLVMOrcLLLazyJITGetObjLinkingLayer(orc_jit);
|
||||||
|
LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
|
||||||
|
obj_linking_layer, LLVMCreatePerfJITEventListener());
|
||||||
|
}
|
||||||
|
|
||||||
/* Ownership transfer: local -> AOTCompContext */
|
/* Ownership transfer: local -> AOTCompContext */
|
||||||
comp_ctx->orc_jit = orc_jit;
|
comp_ctx->orc_jit = orc_jit;
|
||||||
orc_jit = NULL;
|
orc_jit = NULL;
|
||||||
|
@ -2214,7 +2276,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
char *triple_norm_new = NULL, *cpu_new = NULL;
|
char *triple_norm_new = NULL, *cpu_new = NULL;
|
||||||
char *err = NULL, *fp_round = "round.tonearest",
|
char *err = NULL, *fp_round = "round.tonearest",
|
||||||
*fp_exce = "fpexcept.strict";
|
*fp_exce = "fpexcept.strict";
|
||||||
char triple_buf[32] = { 0 }, features_buf[128] = { 0 };
|
char triple_buf[128] = { 0 }, features_buf[128] = { 0 };
|
||||||
uint32 opt_level, size_level, i;
|
uint32 opt_level, size_level, i;
|
||||||
LLVMCodeModel code_model;
|
LLVMCodeModel code_model;
|
||||||
LLVMTargetDataRef target_data_ref;
|
LLVMTargetDataRef target_data_ref;
|
||||||
|
@ -2258,6 +2320,17 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (option->linux_perf_support) {
|
||||||
|
/* FramePointerKind.All */
|
||||||
|
LLVMMetadataRef val =
|
||||||
|
LLVMValueAsMetadata(LLVMConstInt(LLVMInt32Type(), 2, false));
|
||||||
|
const char *key = "frame-pointer";
|
||||||
|
LLVMAddModuleFlag(comp_ctx->module, LLVMModuleFlagBehaviorWarning, key,
|
||||||
|
strlen(key), val);
|
||||||
|
|
||||||
|
comp_ctx->emit_frame_pointer = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (BH_LIST_ERROR == bh_list_init(&comp_ctx->native_symbols)) {
|
if (BH_LIST_ERROR == bh_list_init(&comp_ctx->native_symbols)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -2361,7 +2434,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Create LLJIT Instance */
|
/* Create LLJIT Instance */
|
||||||
if (!orc_jit_create(comp_ctx))
|
if (!orc_jit_create(comp_ctx, option->linux_perf_support))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2510,6 +2583,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
* for Windows/MacOS under Linux host, or generating AOT file for
|
* for Windows/MacOS under Linux host, or generating AOT file for
|
||||||
* Linux/MacOS under Windows host.
|
* Linux/MacOS under Windows host.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!strcmp(abi, "msvc")) {
|
if (!strcmp(abi, "msvc")) {
|
||||||
if (!strcmp(arch1, "i386"))
|
if (!strcmp(arch1, "i386"))
|
||||||
vendor_sys = "-pc-win32-";
|
vendor_sys = "-pc-win32-";
|
||||||
|
@ -2517,6 +2591,9 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
vendor_sys = "-pc-windows-";
|
vendor_sys = "-pc-windows-";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (is_baremetal_target(arch, cpu, abi))
|
||||||
|
vendor_sys = "-unknown-none-";
|
||||||
|
else
|
||||||
vendor_sys = "-pc-linux-";
|
vendor_sys = "-pc-linux-";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2553,6 +2630,11 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
if (!abi)
|
if (!abi)
|
||||||
abi = "msvc";
|
abi = "msvc";
|
||||||
}
|
}
|
||||||
|
else if (is_baremetal_target(arch, cpu, abi)) {
|
||||||
|
vendor_sys = "-unknown-none-";
|
||||||
|
if (!abi)
|
||||||
|
abi = "gnu";
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
vendor_sys = "-pc-linux-";
|
vendor_sys = "-pc-linux-";
|
||||||
if (!abi)
|
if (!abi)
|
||||||
|
@ -2627,15 +2709,16 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
meta_target_abi);
|
meta_target_abi);
|
||||||
|
|
||||||
if (!strcmp(abi, "lp64d") || !strcmp(abi, "ilp32d")) {
|
if (!strcmp(abi, "lp64d") || !strcmp(abi, "ilp32d")) {
|
||||||
if (features) {
|
if (features && !strstr(features, "+d")) {
|
||||||
snprintf(features_buf, sizeof(features_buf), "%s%s",
|
snprintf(features_buf, sizeof(features_buf), "%s%s",
|
||||||
features, ",+d");
|
features, ",+d");
|
||||||
features = features_buf;
|
features = features_buf;
|
||||||
}
|
}
|
||||||
else
|
else if (!features) {
|
||||||
features = "+d";
|
features = "+d";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!features)
|
if (!features)
|
||||||
features = "";
|
features = "";
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "llvm-c/Target.h"
|
#include "llvm-c/Target.h"
|
||||||
#include "llvm-c/Core.h"
|
#include "llvm-c/Core.h"
|
||||||
#include "llvm-c/Object.h"
|
#include "llvm-c/Object.h"
|
||||||
|
#include "llvm-c/OrcEE.h"
|
||||||
#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"
|
||||||
|
@ -422,6 +423,8 @@ typedef struct AOTCompContext {
|
||||||
char stack_usage_temp_file[64];
|
char stack_usage_temp_file[64];
|
||||||
const char *llvm_passes;
|
const char *llvm_passes;
|
||||||
const char *builtin_intrinsics;
|
const char *builtin_intrinsics;
|
||||||
|
|
||||||
|
bool emit_frame_pointer;
|
||||||
} AOTCompContext;
|
} AOTCompContext;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -431,6 +434,7 @@ enum {
|
||||||
AOT_LLVMIR_OPT_FILE,
|
AOT_LLVMIR_OPT_FILE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* always sync it with AOTCompOption in aot_export.h */
|
||||||
typedef struct AOTCompOption {
|
typedef struct AOTCompOption {
|
||||||
bool is_jit_mode;
|
bool is_jit_mode;
|
||||||
bool is_indirect_mode;
|
bool is_indirect_mode;
|
||||||
|
@ -457,6 +461,7 @@ typedef struct AOTCompOption {
|
||||||
uint32 bounds_checks;
|
uint32 bounds_checks;
|
||||||
uint32 stack_bounds_checks;
|
uint32 stack_bounds_checks;
|
||||||
uint32 segue_flags;
|
uint32 segue_flags;
|
||||||
|
bool linux_perf_support;
|
||||||
char **custom_sections;
|
char **custom_sections;
|
||||||
uint32 custom_sections_count;
|
uint32 custom_sections_count;
|
||||||
const char *stack_usage_file;
|
const char *stack_usage_file;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <llvm/Support/ErrorHandling.h>
|
#include <llvm/Support/ErrorHandling.h>
|
||||||
#if LLVM_VERSION_MAJOR >= 17
|
#if LLVM_VERSION_MAJOR >= 17
|
||||||
#include <llvm/Support/PGOOptions.h>
|
#include <llvm/Support/PGOOptions.h>
|
||||||
|
#include <llvm/Support/VirtualFileSystem.h>
|
||||||
#endif
|
#endif
|
||||||
#include <llvm/Target/CodeGenCWrappers.h>
|
#include <llvm/Target/CodeGenCWrappers.h>
|
||||||
#include <llvm/Target/TargetMachine.h>
|
#include <llvm/Target/TargetMachine.h>
|
||||||
|
@ -203,19 +204,27 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
|
||||||
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 */
|
||||||
const char *argv[] = { "", "-vp-static-alloc=false" };
|
const char *argv[] = { "", "-vp-static-alloc=false" };
|
||||||
cl::ParseCommandLineOptions(2, argv);
|
cl::ParseCommandLineOptions(2, argv);
|
||||||
|
#if LLVM_VERSION_MAJOR < 17
|
||||||
PGO = PGOOptions("", "", "", PGOOptions::IRInstr);
|
PGO = PGOOptions("", "", "", PGOOptions::IRInstr);
|
||||||
|
#else
|
||||||
|
auto FS = vfs::getRealFileSystem();
|
||||||
|
PGO = PGOOptions("", "", "", "", FS, PGOOptions::IRInstr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (comp_ctx->use_prof_file) {
|
else if (comp_ctx->use_prof_file) {
|
||||||
|
#if LLVM_VERSION_MAJOR < 17
|
||||||
PGO = PGOOptions(comp_ctx->use_prof_file, "", "", PGOOptions::IRUse);
|
PGO = PGOOptions(comp_ctx->use_prof_file, "", "", PGOOptions::IRUse);
|
||||||
}
|
#else
|
||||||
|
auto FS = vfs::getRealFileSystem();
|
||||||
|
PGO = PGOOptions(comp_ctx->use_prof_file, "", "", "", FS,
|
||||||
|
PGOOptions::IRUse);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_PASS
|
#ifdef DEBUG_PASS
|
||||||
PassInstrumentationCallbacks PIC;
|
PassInstrumentationCallbacks PIC;
|
||||||
|
@ -343,6 +352,16 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
|
||||||
ExitOnErr(PB.parsePassPipeline(MPM, comp_ctx->llvm_passes));
|
ExitOnErr(PB.parsePassPipeline(MPM, comp_ctx->llvm_passes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
#if LLVM_VERSION_MAJOR <= 13
|
||||||
|
PassBuilder::OptimizationLevel::O0 == OL
|
||||||
|
#else
|
||||||
|
OptimizationLevel::O0 == OL
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
MPM.addPass(PB.buildO0DefaultPipeline(OL));
|
||||||
|
}
|
||||||
|
else {
|
||||||
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
|
||||||
|
@ -356,6 +375,7 @@ 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
|
/* Run specific passes for AOT indirect mode in last since general
|
||||||
optimization may create some intrinsic function calls like
|
optimization may create some intrinsic function calls like
|
||||||
|
|
|
@ -12,11 +12,13 @@
|
||||||
#include "llvm/ADT/None.h"
|
#include "llvm/ADT/None.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "llvm/ExecutionEngine/JITEventListener.h"
|
||||||
|
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
||||||
#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/ObjectLinkingLayer.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
|
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
|
||||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||||
#include "llvm/Support/CBindingWrapping.h"
|
#include "llvm/Support/CBindingWrapping.h"
|
||||||
|
|
||||||
|
@ -108,6 +110,7 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectTransformLayer,
|
||||||
LLVMOrcObjectTransformLayerRef)
|
LLVMOrcObjectTransformLayerRef)
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,
|
||||||
LLVMOrcSymbolStringPoolEntryRef)
|
LLVMOrcSymbolStringPoolEntryRef)
|
||||||
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef)
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef)
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef)
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
|
||||||
|
|
||||||
|
@ -322,3 +325,9 @@ LLVMOrcLLLazyJITGetObjTransformLayer(LLVMOrcLLLazyJITRef J)
|
||||||
{
|
{
|
||||||
return wrap(&unwrap(J)->getObjTransformLayer());
|
return wrap(&unwrap(J)->getObjTransformLayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LLVMOrcObjectLayerRef
|
||||||
|
LLVMOrcLLLazyJITGetObjLinkingLayer(LLVMOrcLLLazyJITRef J)
|
||||||
|
{
|
||||||
|
return wrap(&unwrap(J)->getObjLinkingLayer());
|
||||||
|
}
|
||||||
|
|
|
@ -76,5 +76,8 @@ LLVMOrcLLJITBuilderSetCompileFuncitonCreatorWithStackSizesCallback(
|
||||||
LLVMOrcLLLazyJITBuilderRef Builder,
|
LLVMOrcLLLazyJITBuilderRef Builder,
|
||||||
void (*cb)(void *, const char *, size_t, size_t), void *cb_data);
|
void (*cb)(void *, const char *, size_t, size_t), void *cb_data);
|
||||||
|
|
||||||
|
LLVMOrcObjectLayerRef
|
||||||
|
LLVMOrcLLLazyJITGetObjLinkingLayer(LLVMOrcLLLazyJITRef J);
|
||||||
|
|
||||||
LLVM_C_EXTERN_C_END
|
LLVM_C_EXTERN_C_END
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,11 +30,11 @@ simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
LLVM_CONST(i16x8_vec_zero),
|
LLVM_CONST(i16x8_vec_zero),
|
||||||
LLVM_CONST(i32x4_vec_zero),
|
LLVM_CONST(i32x4_vec_zero),
|
||||||
LLVM_CONST(i64x2_vec_zero) };
|
LLVM_CONST(i64x2_vec_zero) };
|
||||||
LLVMValueRef lane_bits[] = {
|
LLVMValueRef lane_shift_masks[] = {
|
||||||
LLVM_CONST(i32_eight),
|
LLVMConstInt(I32_TYPE, 7, true),
|
||||||
LLVMConstInt(I32_TYPE, 16, true),
|
LLVMConstInt(I32_TYPE, 15, true),
|
||||||
LLVMConstInt(I32_TYPE, 32, true),
|
LLVMConstInt(I32_TYPE, 31, true),
|
||||||
LLVMConstInt(I32_TYPE, 64, true),
|
LLVMConstInt(I32_TYPE, 63, true),
|
||||||
};
|
};
|
||||||
|
|
||||||
POP_I32(offset);
|
POP_I32(offset);
|
||||||
|
@ -44,11 +44,11 @@ simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* offset mod LaneBits */
|
/* offset = offset & shift_mask */
|
||||||
if (!lane_bits[itype]
|
if (!lane_shift_masks[itype]
|
||||||
|| !(offset = LLVMBuildSRem(comp_ctx->builder, offset, lane_bits[itype],
|
|| !(offset = LLVMBuildAnd(comp_ctx->builder, offset,
|
||||||
"offset_fix"))) {
|
lane_shift_masks[itype], "offset_fix"))) {
|
||||||
HANDLE_FAILURE("LLVMBuildSRem");
|
HANDLE_FAILURE("LLVMBuildAnd");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ jit_compile_op_f32_compare(JitCompContext *cc, FloatCond cond)
|
||||||
POP_F32(rhs);
|
POP_F32(rhs);
|
||||||
POP_F32(lhs);
|
POP_F32(lhs);
|
||||||
|
|
||||||
if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) {
|
if (jit_reg_is_const(lhs) && jit_reg_is_const(rhs)) {
|
||||||
float32 lvalue = jit_cc_get_const_F32(cc, lhs);
|
float32 lvalue = jit_cc_get_const_F32(cc, lhs);
|
||||||
float32 rvalue = jit_cc_get_const_F32(cc, rhs);
|
float32 rvalue = jit_cc_get_const_F32(cc, rhs);
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ jit_compile_op_f64_compare(JitCompContext *cc, FloatCond cond)
|
||||||
POP_F64(rhs);
|
POP_F64(rhs);
|
||||||
POP_F64(lhs);
|
POP_F64(lhs);
|
||||||
|
|
||||||
if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) {
|
if (jit_reg_is_const(lhs) && jit_reg_is_const(rhs)) {
|
||||||
float64 lvalue = jit_cc_get_const_F64(cc, lhs);
|
float64 lvalue = jit_cc_get_const_F64(cc, lhs);
|
||||||
float64 rvalue = jit_cc_get_const_F64(cc, rhs);
|
float64 rvalue = jit_cc_get_const_F64(cc, rhs);
|
||||||
|
|
||||||
|
|
|
@ -808,7 +808,7 @@ jit_compile_op_block(JitCompContext *cc, uint8 **p_frame_ip,
|
||||||
else if (label_type == LABEL_TYPE_IF) {
|
else if (label_type == LABEL_TYPE_IF) {
|
||||||
POP_I32(value);
|
POP_I32(value);
|
||||||
|
|
||||||
if (!jit_reg_is_const_val(value)) {
|
if (!jit_reg_is_const(value)) {
|
||||||
/* Compare value is not constant, create condition br IR */
|
/* Compare value is not constant, create condition br IR */
|
||||||
|
|
||||||
/* Create entry block */
|
/* Create entry block */
|
||||||
|
|
|
@ -192,6 +192,55 @@ jit_compile_check_value_range(JitCompContext *cc, JitReg value, JitReg min_fp,
|
||||||
|
|
||||||
bh_assert(JIT_REG_KIND_F32 == kind || JIT_REG_KIND_F64 == kind);
|
bh_assert(JIT_REG_KIND_F32 == kind || JIT_REG_KIND_F64 == kind);
|
||||||
|
|
||||||
|
if (JIT_REG_KIND_F32 == kind && jit_reg_is_const(value)) {
|
||||||
|
/* value is an f32 const */
|
||||||
|
float value_f32_const = jit_cc_get_const_F32(cc, value);
|
||||||
|
float min_fp_f32_const = jit_cc_get_const_F32(cc, min_fp);
|
||||||
|
float max_fp_f32_const = jit_cc_get_const_F32(cc, max_fp);
|
||||||
|
|
||||||
|
if (isnan(value_f32_const)) {
|
||||||
|
/* throw exception if value is nan */
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER,
|
||||||
|
JIT_OP_JMP, 0, NULL))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value_f32_const <= min_fp_f32_const
|
||||||
|
|| value_f32_const >= max_fp_f32_const) {
|
||||||
|
/* throw exception if value is out of range */
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_JMP, 0,
|
||||||
|
NULL))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* value is in range, do nothing */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (JIT_REG_KIND_F64 == kind && jit_reg_is_const(value)) {
|
||||||
|
/* value is an f64 const */
|
||||||
|
double value_f64_const = jit_cc_get_const_F64(cc, value);
|
||||||
|
double min_fp_f64_const = jit_cc_get_const_F64(cc, min_fp);
|
||||||
|
double max_fp_f64_const = jit_cc_get_const_F64(cc, max_fp);
|
||||||
|
|
||||||
|
if (isnan(value_f64_const)) {
|
||||||
|
/* throw exception if value is nan */
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER,
|
||||||
|
JIT_OP_JMP, 0, NULL))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value_f64_const <= min_fp_f64_const
|
||||||
|
|| value_f64_const >= max_fp_f64_const) {
|
||||||
|
/* throw exception if value is out of range */
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_JMP, 0,
|
||||||
|
NULL))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* value is in range, do nothing */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* If value is NaN, throw exception */
|
/* If value is NaN, throw exception */
|
||||||
if (JIT_REG_KIND_F32 == kind)
|
if (JIT_REG_KIND_F32 == kind)
|
||||||
emit_ret = jit_emit_callnative(cc, local_isnanf, nan_ret, &value, 1);
|
emit_ret = jit_emit_callnative(cc, local_isnanf, nan_ret, &value, 1);
|
||||||
|
|
|
@ -827,23 +827,45 @@ emit_callnative(JitCompContext *cc, JitReg native_func_reg, JitReg res,
|
||||||
JitReg *params, uint32 param_count)
|
JitReg *params, uint32 param_count)
|
||||||
{
|
{
|
||||||
JitInsn *insn;
|
JitInsn *insn;
|
||||||
|
char *i32_arg_names[] = { "edi", "esi", "edx", "ecx" };
|
||||||
char *i64_arg_names[] = { "rdi", "rsi", "rdx", "rcx", "r8", "r9" };
|
char *i64_arg_names[] = { "rdi", "rsi", "rdx", "rcx", "r8", "r9" };
|
||||||
char *f32_arg_names[] = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" };
|
char *f32_arg_names[] = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" };
|
||||||
char *f64_arg_names[] = { "xmm0_f64", "xmm1_f64", "xmm2_f64",
|
char *f64_arg_names[] = { "xmm0_f64", "xmm1_f64", "xmm2_f64",
|
||||||
"xmm3_f64", "xmm4_f64", "xmm5_f64" };
|
"xmm3_f64", "xmm4_f64", "xmm5_f64" };
|
||||||
JitReg i64_arg_regs[6], f32_arg_regs[6], f64_arg_regs[6], res_reg = 0;
|
JitReg i32_arg_regs[4], i64_arg_regs[6];
|
||||||
|
JitReg f32_arg_regs[6], f64_arg_regs[6], res_reg = 0;
|
||||||
JitReg eax_hreg = jit_codegen_get_hreg_by_name("eax");
|
JitReg eax_hreg = jit_codegen_get_hreg_by_name("eax");
|
||||||
JitReg xmm0_hreg = jit_codegen_get_hreg_by_name("xmm0");
|
JitReg xmm0_hreg = jit_codegen_get_hreg_by_name("xmm0");
|
||||||
uint32 i, i64_reg_idx, float_reg_idx;
|
uint32 i, i64_reg_idx, float_reg_idx, lock_i32_reg_num;
|
||||||
|
|
||||||
bh_assert(param_count <= 6);
|
bh_assert(param_count <= 6);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
i32_arg_regs[i] = jit_codegen_get_hreg_by_name(i32_arg_names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
i64_arg_regs[i] = jit_codegen_get_hreg_by_name(i64_arg_names[i]);
|
i64_arg_regs[i] = jit_codegen_get_hreg_by_name(i64_arg_names[i]);
|
||||||
f32_arg_regs[i] = jit_codegen_get_hreg_by_name(f32_arg_names[i]);
|
f32_arg_regs[i] = jit_codegen_get_hreg_by_name(f32_arg_names[i]);
|
||||||
f64_arg_regs[i] = jit_codegen_get_hreg_by_name(f64_arg_names[i]);
|
f64_arg_regs[i] = jit_codegen_get_hreg_by_name(f64_arg_names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock_i32_reg_num = param_count < 4 ? param_count : 4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock i32 registers so that they won't be allocated for the operand
|
||||||
|
* of below I32TOI64 insn, which may have been overwritten in the
|
||||||
|
* previous MOV, for example, in the below insns:
|
||||||
|
* MOV I5, I15
|
||||||
|
* I32TOI64 I6, i5
|
||||||
|
* CALLNATIVE VOID, native_func, I5, I6
|
||||||
|
* i5 is used in the second insn, but it has been overwritten in I5
|
||||||
|
* by the first insn
|
||||||
|
*/
|
||||||
|
for (i = 0; i < lock_i32_reg_num; i++) {
|
||||||
|
GEN_INSN(MOV, i32_arg_regs[i], i32_arg_regs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
i64_reg_idx = float_reg_idx = 0;
|
i64_reg_idx = float_reg_idx = 0;
|
||||||
for (i = 0; i < param_count; i++) {
|
for (i = 0; i < param_count; i++) {
|
||||||
switch (jit_reg_kind(params[i])) {
|
switch (jit_reg_kind(params[i])) {
|
||||||
|
@ -865,6 +887,14 @@ emit_callnative(JitCompContext *cc, JitReg native_func_reg, JitReg res,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Announce the locked i32 registers are being used, and do necessary
|
||||||
|
* spill ASAP
|
||||||
|
*/
|
||||||
|
for (i = 0; i < lock_i32_reg_num; i++) {
|
||||||
|
GEN_INSN(MOV, i32_arg_regs[i], i32_arg_regs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
switch (jit_reg_kind(res)) {
|
switch (jit_reg_kind(res)) {
|
||||||
case JIT_REG_KIND_I32:
|
case JIT_REG_KIND_I32:
|
||||||
|
|
|
@ -137,6 +137,7 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
|
||||||
{
|
{
|
||||||
JitReg memory_boundary = 0, offset1;
|
JitReg memory_boundary = 0, offset1;
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
JitReg cur_page_count;
|
||||||
/* the default memory */
|
/* the default memory */
|
||||||
uint32 mem_idx = 0;
|
uint32 mem_idx = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -146,16 +147,10 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
|
||||||
/* 1. shortcut if the memory size is 0 */
|
/* 1. shortcut if the memory size is 0 */
|
||||||
if (cc->cur_wasm_module->memories != NULL
|
if (cc->cur_wasm_module->memories != NULL
|
||||||
&& 0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) {
|
&& 0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) {
|
||||||
JitReg module_inst, cur_page_count;
|
|
||||||
uint32 cur_page_count_offset =
|
cur_page_count = get_cur_page_count_reg(cc->jit_frame, mem_idx);
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
|
|
||||||
|
|
||||||
/* if (cur_mem_page_count == 0) goto EXCEPTION */
|
/* if (cur_mem_page_count == 0) goto EXCEPTION */
|
||||||
module_inst = get_module_inst_reg(cc->jit_frame);
|
|
||||||
cur_page_count = jit_cc_new_reg_I32(cc);
|
|
||||||
GEN_INSN(LDI32, cur_page_count, module_inst,
|
|
||||||
NEW_CONST(I32, cur_page_count_offset));
|
|
||||||
GEN_INSN(CMP, cc->cmp_reg, cur_page_count, NEW_CONST(I32, 0));
|
GEN_INSN(CMP, cc->cmp_reg, cur_page_count, NEW_CONST(I32, 0));
|
||||||
if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
|
if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
|
||||||
JIT_OP_BEQ, cc->cmp_reg, NULL)) {
|
JIT_OP_BEQ, cc->cmp_reg, NULL)) {
|
||||||
|
@ -580,15 +575,9 @@ fail:
|
||||||
bool
|
bool
|
||||||
jit_compile_op_memory_size(JitCompContext *cc, uint32 mem_idx)
|
jit_compile_op_memory_size(JitCompContext *cc, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitReg module_inst, cur_page_count;
|
JitReg cur_page_count;
|
||||||
uint32 cur_page_count_offset =
|
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
|
|
||||||
|
|
||||||
module_inst = get_module_inst_reg(cc->jit_frame);
|
cur_page_count = get_cur_page_count_reg(cc->jit_frame, mem_idx);
|
||||||
cur_page_count = jit_cc_new_reg_I32(cc);
|
|
||||||
GEN_INSN(LDI32, cur_page_count, module_inst,
|
|
||||||
NEW_CONST(I32, cur_page_count_offset));
|
|
||||||
|
|
||||||
PUSH_I32(cur_page_count);
|
PUSH_I32(cur_page_count);
|
||||||
|
|
||||||
|
@ -600,18 +589,11 @@ fail:
|
||||||
bool
|
bool
|
||||||
jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
|
jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitReg module_inst, grow_res, res;
|
JitReg grow_res, res;
|
||||||
JitReg prev_page_count, inc_page_count, args[2];
|
JitReg prev_page_count, inc_page_count, args[2];
|
||||||
|
|
||||||
/* Get current page count */
|
/* Get current page count as prev_page_count */
|
||||||
uint32 cur_page_count_offset =
|
prev_page_count = get_cur_page_count_reg(cc->jit_frame, mem_idx);
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
|
|
||||||
|
|
||||||
module_inst = get_module_inst_reg(cc->jit_frame);
|
|
||||||
prev_page_count = jit_cc_new_reg_I32(cc);
|
|
||||||
GEN_INSN(LDI32, prev_page_count, module_inst,
|
|
||||||
NEW_CONST(I32, cur_page_count_offset));
|
|
||||||
|
|
||||||
/* Call wasm_enlarge_memory */
|
/* Call wasm_enlarge_memory */
|
||||||
POP_I32(inc_page_count);
|
POP_I32(inc_page_count);
|
||||||
|
@ -650,6 +632,7 @@ wasm_init_memory(WASMModuleInstance *inst, uint32 mem_idx, uint32 seg_idx,
|
||||||
WASMDataSeg *data_segment;
|
WASMDataSeg *data_segment;
|
||||||
uint32 mem_size;
|
uint32 mem_size;
|
||||||
uint8 *mem_addr, *data_addr;
|
uint8 *mem_addr, *data_addr;
|
||||||
|
uint32 seg_len;
|
||||||
|
|
||||||
/* if d + n > the length of mem.data */
|
/* if d + n > the length of mem.data */
|
||||||
mem_inst = inst->memories[mem_idx];
|
mem_inst = inst->memories[mem_idx];
|
||||||
|
@ -659,13 +642,19 @@ wasm_init_memory(WASMModuleInstance *inst, uint32 mem_idx, uint32 seg_idx,
|
||||||
|
|
||||||
/* if s + n > the length of data.data */
|
/* if s + n > the length of data.data */
|
||||||
bh_assert(seg_idx < inst->module->data_seg_count);
|
bh_assert(seg_idx < inst->module->data_seg_count);
|
||||||
|
if (bh_bitmap_get_bit(inst->e->common.data_dropped, seg_idx)) {
|
||||||
|
seg_len = 0;
|
||||||
|
data_addr = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
data_segment = inst->module->data_segments[seg_idx];
|
data_segment = inst->module->data_segments[seg_idx];
|
||||||
if (data_segment->data_length < data_offset
|
seg_len = data_segment->data_length;
|
||||||
|| data_segment->data_length - data_offset < len)
|
data_addr = data_segment->data + data_offset;
|
||||||
|
}
|
||||||
|
if (seg_len < data_offset || seg_len - data_offset < len)
|
||||||
goto out_of_bounds;
|
goto out_of_bounds;
|
||||||
|
|
||||||
mem_addr = mem_inst->memory_data + mem_offset;
|
mem_addr = mem_inst->memory_data + mem_offset;
|
||||||
data_addr = data_segment->data + data_offset;
|
|
||||||
bh_memcpy_s(mem_addr, mem_size - mem_offset, data_addr, len);
|
bh_memcpy_s(mem_addr, mem_size - mem_offset, data_addr, len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -706,21 +695,22 @@ fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wasm_data_drop(WASMModuleInstance *inst, uint32 seg_idx)
|
||||||
|
{
|
||||||
|
bh_bitmap_set_bit(inst->e->common.data_dropped, seg_idx);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_data_drop(JitCompContext *cc, uint32 seg_idx)
|
jit_compile_op_data_drop(JitCompContext *cc, uint32 seg_idx)
|
||||||
{
|
{
|
||||||
JitReg module = get_module_reg(cc->jit_frame);
|
JitReg args[2] = { 0 };
|
||||||
JitReg data_segments = jit_cc_new_reg_ptr(cc);
|
|
||||||
JitReg data_segment = jit_cc_new_reg_ptr(cc);
|
|
||||||
|
|
||||||
GEN_INSN(LDPTR, data_segments, module,
|
args[0] = get_module_inst_reg(cc->jit_frame);
|
||||||
NEW_CONST(I32, offsetof(WASMModule, data_segments)));
|
args[1] = NEW_CONST(I32, seg_idx);
|
||||||
GEN_INSN(LDPTR, data_segment, data_segments,
|
|
||||||
NEW_CONST(I32, seg_idx * sizeof(WASMDataSeg *)));
|
|
||||||
GEN_INSN(STI32, NEW_CONST(I32, 0), data_segment,
|
|
||||||
NEW_CONST(I32, offsetof(WASMDataSeg, data_length)));
|
|
||||||
|
|
||||||
return true;
|
return jit_emit_callnative(cc, wasm_data_drop, 0, args,
|
||||||
|
sizeof(args) / sizeof(args[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -10,21 +10,22 @@
|
||||||
#include "../jit_frontend.h"
|
#include "../jit_frontend.h"
|
||||||
|
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
static void
|
||||||
|
wasm_elem_drop(WASMModuleInstance *inst, uint32 tbl_seg_idx)
|
||||||
|
{
|
||||||
|
bh_bitmap_set_bit(inst->e->common.elem_dropped, tbl_seg_idx);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_elem_drop(JitCompContext *cc, uint32 tbl_seg_idx)
|
jit_compile_op_elem_drop(JitCompContext *cc, uint32 tbl_seg_idx)
|
||||||
{
|
{
|
||||||
JitReg module, tbl_segs;
|
JitReg args[2] = { 0 };
|
||||||
|
|
||||||
module = get_module_reg(cc->jit_frame);
|
args[0] = get_module_inst_reg(cc->jit_frame);
|
||||||
|
args[1] = NEW_CONST(I32, tbl_seg_idx);
|
||||||
|
|
||||||
tbl_segs = jit_cc_new_reg_ptr(cc);
|
return jit_emit_callnative(cc, wasm_elem_drop, 0, args,
|
||||||
GEN_INSN(LDPTR, tbl_segs, module,
|
sizeof(args) / sizeof(args[0]));
|
||||||
NEW_CONST(I32, offsetof(WASMModule, table_segments)));
|
|
||||||
|
|
||||||
GEN_INSN(STI32, NEW_CONST(I32, true), tbl_segs,
|
|
||||||
NEW_CONST(I32, tbl_seg_idx * sizeof(WASMTableSeg)
|
|
||||||
+ offsetof(WASMTableSeg, is_dropped)));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -105,6 +106,12 @@ wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx,
|
||||||
if (offset_len_out_of_bounds(dst_offset, len, tbl_sz))
|
if (offset_len_out_of_bounds(dst_offset, len, tbl_sz))
|
||||||
goto out_of_bounds;
|
goto out_of_bounds;
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (bh_bitmap_get_bit(inst->e->common.elem_dropped, elem_idx))
|
||||||
|
goto out_of_bounds;
|
||||||
|
|
||||||
bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems)
|
bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems)
|
||||||
+ dst_offset * sizeof(uint32),
|
+ dst_offset * sizeof(uint32),
|
||||||
(uint32)((tbl_sz - dst_offset) * sizeof(uint32)),
|
(uint32)((tbl_sz - dst_offset) * sizeof(uint32)),
|
||||||
|
|
|
@ -17,8 +17,8 @@ jit_code_cache_init(uint32 code_cache_size)
|
||||||
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
|
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
|
||||||
int map_flags = MMAP_MAP_NONE;
|
int map_flags = MMAP_MAP_NONE;
|
||||||
|
|
||||||
if (!(code_cache_pool =
|
if (!(code_cache_pool = os_mmap(NULL, code_cache_size, map_prot, map_flags,
|
||||||
os_mmap(NULL, code_cache_size, map_prot, map_flags))) {
|
os_get_invalid_handle()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ typedef struct JitInterpSwitchInfo {
|
||||||
typedef struct JitCompOptions {
|
typedef struct JitCompOptions {
|
||||||
uint32 code_cache_size;
|
uint32 code_cache_size;
|
||||||
uint32 opt_level;
|
uint32 opt_level;
|
||||||
|
bool linux_perf_support;
|
||||||
} JitCompOptions;
|
} JitCompOptions;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -218,42 +218,149 @@ get_aux_stack_bottom_reg(JitFrame *frame)
|
||||||
return frame->aux_stack_bottom_reg;
|
return frame->aux_stack_bottom_reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
static bool
|
||||||
|
is_shared_memory(WASMModule *module, uint32 mem_idx)
|
||||||
|
{
|
||||||
|
WASMMemory *memory;
|
||||||
|
WASMMemoryImport *memory_import;
|
||||||
|
bool is_shared;
|
||||||
|
|
||||||
|
if (mem_idx < module->import_memory_count) {
|
||||||
|
memory_import = &(module->import_memories[mem_idx].u.memory);
|
||||||
|
is_shared = memory_import->flags & 0x02 ? true : false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memory = &module->memories[mem_idx - module->import_memory_count];
|
||||||
|
is_shared = memory->flags & 0x02 ? true : false;
|
||||||
|
}
|
||||||
|
return is_shared;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JitReg
|
||||||
|
get_memory_inst_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
|
{
|
||||||
|
JitCompContext *cc = frame->cc;
|
||||||
|
JitReg module_inst_reg = get_module_inst_reg(frame);
|
||||||
|
uint32 memory_inst_offset;
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
JitReg memories_addr;
|
||||||
|
uint32 memories_offset;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame->memory_regs[mem_idx].memory_inst)
|
||||||
|
return frame->memory_regs[mem_idx].memory_inst;
|
||||||
|
|
||||||
|
frame->memory_regs[mem_idx].memory_inst =
|
||||||
|
cc->memory_regs[mem_idx].memory_inst;
|
||||||
|
|
||||||
|
bh_assert(mem_idx == 0);
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
|
if (is_shared) {
|
||||||
|
memories_addr = jit_cc_new_reg_ptr(cc);
|
||||||
|
memories_offset = (uint32)offsetof(WASMModuleInstance, memories);
|
||||||
|
/* module_inst->memories */
|
||||||
|
GEN_INSN(LDPTR, memories_addr, module_inst_reg,
|
||||||
|
NEW_CONST(I32, memories_offset));
|
||||||
|
/* module_inst->memories[mem_idx], mem_idx can only be 0 now */
|
||||||
|
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_inst, memories_addr,
|
||||||
|
NEW_CONST(I32, mem_idx));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
memory_inst_offset =
|
||||||
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes);
|
||||||
|
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_inst,
|
||||||
|
module_inst_reg, NEW_CONST(I32, memory_inst_offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame->memory_regs[mem_idx].memory_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
JitReg
|
||||||
|
get_cur_page_count_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
|
{
|
||||||
|
JitCompContext *cc = frame->cc;
|
||||||
|
JitReg module_inst_reg;
|
||||||
|
uint32 cur_page_count_offset;
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
JitReg memory_inst_reg;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame->memory_regs[mem_idx].cur_page_count)
|
||||||
|
return frame->memory_regs[mem_idx].cur_page_count;
|
||||||
|
|
||||||
|
frame->memory_regs[mem_idx].cur_page_count =
|
||||||
|
cc->memory_regs[mem_idx].cur_page_count;
|
||||||
|
|
||||||
|
/* Get current page count */
|
||||||
|
bh_assert(mem_idx == 0);
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
|
if (is_shared) {
|
||||||
|
memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
|
||||||
|
cur_page_count_offset =
|
||||||
|
(uint32)offsetof(WASMMemoryInstance, cur_page_count);
|
||||||
|
/* memories[mem_idx]->cur_page_count_offset */
|
||||||
|
GEN_INSN(LDI32, frame->memory_regs[mem_idx].cur_page_count,
|
||||||
|
memory_inst_reg, NEW_CONST(I32, cur_page_count_offset));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
module_inst_reg = get_module_inst_reg(frame);
|
||||||
|
cur_page_count_offset =
|
||||||
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||||
|
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
|
||||||
|
GEN_INSN(LDI32, frame->memory_regs[mem_idx].cur_page_count,
|
||||||
|
module_inst_reg, NEW_CONST(I32, cur_page_count_offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame->memory_regs[mem_idx].cur_page_count;
|
||||||
|
}
|
||||||
|
|
||||||
JitReg
|
JitReg
|
||||||
get_memory_data_reg(JitFrame *frame, uint32 mem_idx)
|
get_memory_data_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitCompContext *cc = frame->cc;
|
JitCompContext *cc = frame->cc;
|
||||||
JitReg module_inst_reg = get_module_inst_reg(frame);
|
JitReg module_inst_reg;
|
||||||
uint32 memory_data_offset;
|
uint32 memory_data_offset;
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
JitReg memory_inst_reg;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame->memory_regs[mem_idx].memory_data)
|
||||||
|
return frame->memory_regs[mem_idx].memory_data;
|
||||||
|
|
||||||
|
frame->memory_regs[mem_idx].memory_data =
|
||||||
|
cc->memory_regs[mem_idx].memory_data;
|
||||||
|
|
||||||
bh_assert(mem_idx == 0);
|
bh_assert(mem_idx == 0);
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
uint32 memories_offset = (uint32)offsetof(WASMModuleInstance, memories);
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
JitReg memories_addr = jit_cc_new_reg_ptr(cc);
|
if (is_shared) {
|
||||||
JitReg memories_0_addr = jit_cc_new_reg_ptr(cc);
|
memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
|
||||||
memory_data_offset = (uint32)offsetof(WASMMemoryInstance, memory_data);
|
memory_data_offset = (uint32)offsetof(WASMMemoryInstance, memory_data);
|
||||||
if (!frame->memory_regs[mem_idx].memory_data) {
|
/* memories[mem_idx]->memory_data */
|
||||||
frame->memory_regs[mem_idx].memory_data =
|
|
||||||
cc->memory_regs[mem_idx].memory_data;
|
|
||||||
/* module_inst->memories */
|
|
||||||
GEN_INSN(LDPTR, memories_addr, module_inst_reg,
|
|
||||||
NEW_CONST(I32, memories_offset));
|
|
||||||
/* module_inst->memories[0] */
|
|
||||||
GEN_INSN(LDPTR, memories_0_addr, memories_addr, NEW_CONST(I32, 0));
|
|
||||||
/* memories[0]->memory_data */
|
|
||||||
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data,
|
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data,
|
||||||
memories_0_addr, NEW_CONST(I32, memory_data_offset));
|
memory_inst_reg, NEW_CONST(I32, memory_data_offset));
|
||||||
}
|
}
|
||||||
#else
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
module_inst_reg = get_module_inst_reg(frame);
|
||||||
memory_data_offset =
|
memory_data_offset =
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, memory_data);
|
+ (uint32)offsetof(WASMMemoryInstance, memory_data);
|
||||||
if (!frame->memory_regs[mem_idx].memory_data) {
|
|
||||||
frame->memory_regs[mem_idx].memory_data =
|
|
||||||
cc->memory_regs[mem_idx].memory_data;
|
|
||||||
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data,
|
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data,
|
||||||
module_inst_reg, NEW_CONST(I32, memory_data_offset));
|
module_inst_reg, NEW_CONST(I32, memory_data_offset));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return frame->memory_regs[mem_idx].memory_data;
|
return frame->memory_regs[mem_idx].memory_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,16 +368,37 @@ JitReg
|
||||||
get_memory_data_end_reg(JitFrame *frame, uint32 mem_idx)
|
get_memory_data_end_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitCompContext *cc = frame->cc;
|
JitCompContext *cc = frame->cc;
|
||||||
JitReg module_inst_reg = get_module_inst_reg(frame);
|
JitReg module_inst_reg;
|
||||||
uint32 memory_data_end_offset =
|
uint32 memory_data_end_offset;
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, memory_data_end);
|
JitReg memory_inst_reg;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
bh_assert(mem_idx == 0);
|
if (frame->memory_regs[mem_idx].memory_data_end)
|
||||||
|
return frame->memory_regs[mem_idx].memory_data_end;
|
||||||
|
|
||||||
if (!frame->memory_regs[mem_idx].memory_data_end) {
|
|
||||||
frame->memory_regs[mem_idx].memory_data_end =
|
frame->memory_regs[mem_idx].memory_data_end =
|
||||||
cc->memory_regs[mem_idx].memory_data_end;
|
cc->memory_regs[mem_idx].memory_data_end;
|
||||||
|
|
||||||
|
bh_assert(mem_idx == 0);
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
|
if (is_shared) {
|
||||||
|
memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
|
||||||
|
memory_data_end_offset =
|
||||||
|
(uint32)offsetof(WASMMemoryInstance, memory_data_end);
|
||||||
|
/* memories[mem_idx]->memory_data_end */
|
||||||
|
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data_end,
|
||||||
|
memory_inst_reg, NEW_CONST(I32, memory_data_end_offset));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
module_inst_reg = get_module_inst_reg(frame);
|
||||||
|
memory_data_end_offset =
|
||||||
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||||
|
+ (uint32)offsetof(WASMMemoryInstance, memory_data_end);
|
||||||
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data_end,
|
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data_end,
|
||||||
module_inst_reg, NEW_CONST(I32, memory_data_end_offset));
|
module_inst_reg, NEW_CONST(I32, memory_data_end_offset));
|
||||||
}
|
}
|
||||||
|
@ -281,16 +409,43 @@ JitReg
|
||||||
get_mem_bound_check_1byte_reg(JitFrame *frame, uint32 mem_idx)
|
get_mem_bound_check_1byte_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitCompContext *cc = frame->cc;
|
JitCompContext *cc = frame->cc;
|
||||||
JitReg module_inst_reg = get_module_inst_reg(frame);
|
JitReg module_inst_reg;
|
||||||
uint32 mem_bound_check_1byte_offset =
|
uint32 mem_bound_check_1byte_offset;
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_1byte);
|
JitReg memory_inst_reg;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame->memory_regs[mem_idx].mem_bound_check_1byte)
|
||||||
|
return frame->memory_regs[mem_idx].mem_bound_check_1byte;
|
||||||
|
|
||||||
|
frame->memory_regs[mem_idx].mem_bound_check_1byte =
|
||||||
|
cc->memory_regs[mem_idx].mem_bound_check_1byte;
|
||||||
|
|
||||||
bh_assert(mem_idx == 0);
|
bh_assert(mem_idx == 0);
|
||||||
|
|
||||||
if (!frame->memory_regs[mem_idx].mem_bound_check_1byte) {
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
frame->memory_regs[mem_idx].mem_bound_check_1byte =
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
cc->memory_regs[mem_idx].mem_bound_check_1byte;
|
if (is_shared) {
|
||||||
|
memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
|
||||||
|
mem_bound_check_1byte_offset =
|
||||||
|
(uint32)offsetof(WASMMemoryInstance, mem_bound_check_1byte);
|
||||||
|
/* memories[mem_idx]->mem_bound_check_1byte */
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_1byte,
|
||||||
|
memory_inst_reg, NEW_CONST(I32, mem_bound_check_1byte_offset));
|
||||||
|
#else
|
||||||
|
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_1byte,
|
||||||
|
memory_inst_reg, NEW_CONST(I32, mem_bound_check_1byte_offset));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
module_inst_reg = get_module_inst_reg(frame);
|
||||||
|
mem_bound_check_1byte_offset =
|
||||||
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||||
|
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_1byte);
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_1byte,
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_1byte,
|
||||||
module_inst_reg, NEW_CONST(I32, mem_bound_check_1byte_offset));
|
module_inst_reg, NEW_CONST(I32, mem_bound_check_1byte_offset));
|
||||||
|
@ -306,16 +461,45 @@ JitReg
|
||||||
get_mem_bound_check_2bytes_reg(JitFrame *frame, uint32 mem_idx)
|
get_mem_bound_check_2bytes_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitCompContext *cc = frame->cc;
|
JitCompContext *cc = frame->cc;
|
||||||
JitReg module_inst_reg = get_module_inst_reg(frame);
|
JitReg module_inst_reg;
|
||||||
uint32 mem_bound_check_2bytes_offset =
|
uint32 mem_bound_check_2bytes_offset;
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_2bytes);
|
JitReg memory_inst_reg;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame->memory_regs[mem_idx].mem_bound_check_2bytes)
|
||||||
|
return frame->memory_regs[mem_idx].mem_bound_check_2bytes;
|
||||||
|
|
||||||
|
frame->memory_regs[mem_idx].mem_bound_check_2bytes =
|
||||||
|
cc->memory_regs[mem_idx].mem_bound_check_2bytes;
|
||||||
|
|
||||||
bh_assert(mem_idx == 0);
|
bh_assert(mem_idx == 0);
|
||||||
|
|
||||||
if (!frame->memory_regs[mem_idx].mem_bound_check_2bytes) {
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
frame->memory_regs[mem_idx].mem_bound_check_2bytes =
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
cc->memory_regs[mem_idx].mem_bound_check_2bytes;
|
if (is_shared) {
|
||||||
|
memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
|
||||||
|
mem_bound_check_2bytes_offset =
|
||||||
|
(uint32)offsetof(WASMMemoryInstance, mem_bound_check_2bytes);
|
||||||
|
/* memories[mem_idx]->mem_bound_check_2bytes */
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
|
||||||
|
memory_inst_reg,
|
||||||
|
NEW_CONST(I32, mem_bound_check_2bytes_offset));
|
||||||
|
#else
|
||||||
|
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
|
||||||
|
memory_inst_reg,
|
||||||
|
NEW_CONST(I32, mem_bound_check_2bytes_offset));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
module_inst_reg = get_module_inst_reg(frame);
|
||||||
|
mem_bound_check_2bytes_offset =
|
||||||
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||||
|
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_2bytes);
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
|
||||||
module_inst_reg,
|
module_inst_reg,
|
||||||
|
@ -333,16 +517,45 @@ JitReg
|
||||||
get_mem_bound_check_4bytes_reg(JitFrame *frame, uint32 mem_idx)
|
get_mem_bound_check_4bytes_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitCompContext *cc = frame->cc;
|
JitCompContext *cc = frame->cc;
|
||||||
JitReg module_inst_reg = get_module_inst_reg(frame);
|
JitReg module_inst_reg;
|
||||||
uint32 mem_bound_check_4bytes_offset =
|
uint32 mem_bound_check_4bytes_offset;
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_4bytes);
|
JitReg memory_inst_reg;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame->memory_regs[mem_idx].mem_bound_check_4bytes)
|
||||||
|
return frame->memory_regs[mem_idx].mem_bound_check_4bytes;
|
||||||
|
|
||||||
|
frame->memory_regs[mem_idx].mem_bound_check_4bytes =
|
||||||
|
cc->memory_regs[mem_idx].mem_bound_check_4bytes;
|
||||||
|
|
||||||
bh_assert(mem_idx == 0);
|
bh_assert(mem_idx == 0);
|
||||||
|
|
||||||
if (!frame->memory_regs[mem_idx].mem_bound_check_4bytes) {
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
frame->memory_regs[mem_idx].mem_bound_check_4bytes =
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
cc->memory_regs[mem_idx].mem_bound_check_4bytes;
|
if (is_shared) {
|
||||||
|
memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
|
||||||
|
mem_bound_check_4bytes_offset =
|
||||||
|
(uint32)offsetof(WASMMemoryInstance, mem_bound_check_4bytes);
|
||||||
|
/* memories[mem_idx]->mem_bound_check_4bytes */
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
|
||||||
|
memory_inst_reg,
|
||||||
|
NEW_CONST(I32, mem_bound_check_4bytes_offset));
|
||||||
|
#else
|
||||||
|
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
|
||||||
|
memory_inst_reg,
|
||||||
|
NEW_CONST(I32, mem_bound_check_4bytes_offset));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
module_inst_reg = get_module_inst_reg(frame);
|
||||||
|
mem_bound_check_4bytes_offset =
|
||||||
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||||
|
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_4bytes);
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
|
||||||
module_inst_reg,
|
module_inst_reg,
|
||||||
|
@ -360,16 +573,45 @@ JitReg
|
||||||
get_mem_bound_check_8bytes_reg(JitFrame *frame, uint32 mem_idx)
|
get_mem_bound_check_8bytes_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitCompContext *cc = frame->cc;
|
JitCompContext *cc = frame->cc;
|
||||||
JitReg module_inst_reg = get_module_inst_reg(frame);
|
JitReg module_inst_reg;
|
||||||
uint32 mem_bound_check_8bytes_offset =
|
uint32 mem_bound_check_8bytes_offset;
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_8bytes);
|
JitReg memory_inst_reg;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame->memory_regs[mem_idx].mem_bound_check_8bytes)
|
||||||
|
return frame->memory_regs[mem_idx].mem_bound_check_8bytes;
|
||||||
|
|
||||||
|
frame->memory_regs[mem_idx].mem_bound_check_8bytes =
|
||||||
|
cc->memory_regs[mem_idx].mem_bound_check_8bytes;
|
||||||
|
|
||||||
bh_assert(mem_idx == 0);
|
bh_assert(mem_idx == 0);
|
||||||
|
|
||||||
if (!frame->memory_regs[mem_idx].mem_bound_check_8bytes) {
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
frame->memory_regs[mem_idx].mem_bound_check_8bytes =
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
cc->memory_regs[mem_idx].mem_bound_check_8bytes;
|
if (is_shared) {
|
||||||
|
memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
|
||||||
|
mem_bound_check_8bytes_offset =
|
||||||
|
(uint32)offsetof(WASMMemoryInstance, mem_bound_check_8bytes);
|
||||||
|
/* memories[mem_idx]->mem_bound_check_8bytes */
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
|
||||||
|
memory_inst_reg,
|
||||||
|
NEW_CONST(I32, mem_bound_check_8bytes_offset));
|
||||||
|
#else
|
||||||
|
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
|
||||||
|
memory_inst_reg,
|
||||||
|
NEW_CONST(I32, mem_bound_check_8bytes_offset));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
module_inst_reg = get_module_inst_reg(frame);
|
||||||
|
mem_bound_check_8bytes_offset =
|
||||||
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||||
|
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_8bytes);
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
|
||||||
module_inst_reg,
|
module_inst_reg,
|
||||||
|
@ -387,16 +629,45 @@ JitReg
|
||||||
get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx)
|
get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitCompContext *cc = frame->cc;
|
JitCompContext *cc = frame->cc;
|
||||||
JitReg module_inst_reg = get_module_inst_reg(frame);
|
JitReg module_inst_reg;
|
||||||
uint32 mem_bound_check_16bytes_offset =
|
uint32 mem_bound_check_16bytes_offset;
|
||||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_16bytes);
|
JitReg memory_inst_reg;
|
||||||
|
bool is_shared;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame->memory_regs[mem_idx].mem_bound_check_16bytes)
|
||||||
|
return frame->memory_regs[mem_idx].mem_bound_check_16bytes;
|
||||||
|
|
||||||
|
frame->memory_regs[mem_idx].mem_bound_check_16bytes =
|
||||||
|
cc->memory_regs[mem_idx].mem_bound_check_16bytes;
|
||||||
|
|
||||||
bh_assert(mem_idx == 0);
|
bh_assert(mem_idx == 0);
|
||||||
|
|
||||||
if (!frame->memory_regs[mem_idx].mem_bound_check_16bytes) {
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
frame->memory_regs[mem_idx].mem_bound_check_16bytes =
|
is_shared = is_shared_memory(cc->cur_wasm_module, mem_idx);
|
||||||
cc->memory_regs[mem_idx].mem_bound_check_16bytes;
|
if (is_shared) {
|
||||||
|
memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
|
||||||
|
mem_bound_check_16bytes_offset =
|
||||||
|
(uint32)offsetof(WASMMemoryInstance, mem_bound_check_16bytes);
|
||||||
|
/* memories[mem_idx]->mem_bound_check_16bytes */
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
|
||||||
|
memory_inst_reg,
|
||||||
|
NEW_CONST(I32, mem_bound_check_16bytes_offset));
|
||||||
|
#else
|
||||||
|
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
|
||||||
|
memory_inst_reg,
|
||||||
|
NEW_CONST(I32, mem_bound_check_16bytes_offset));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
module_inst_reg = get_module_inst_reg(frame);
|
||||||
|
mem_bound_check_16bytes_offset =
|
||||||
|
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||||
|
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_16bytes);
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
|
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
|
||||||
module_inst_reg,
|
module_inst_reg,
|
||||||
|
@ -462,6 +733,8 @@ clear_fixed_virtual_regs(JitFrame *frame)
|
||||||
|
|
||||||
count = module->import_memory_count + module->memory_count;
|
count = module->import_memory_count + module->memory_count;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
frame->memory_regs[i].memory_inst = 0;
|
||||||
|
frame->memory_regs[i].cur_page_count = 0;
|
||||||
frame->memory_regs[i].memory_data = 0;
|
frame->memory_regs[i].memory_data = 0;
|
||||||
frame->memory_regs[i].memory_data_end = 0;
|
frame->memory_regs[i].memory_data_end = 0;
|
||||||
frame->memory_regs[i].mem_bound_check_1byte = 0;
|
frame->memory_regs[i].mem_bound_check_1byte = 0;
|
||||||
|
@ -486,6 +759,7 @@ clear_memory_regs(JitFrame *frame)
|
||||||
|
|
||||||
count = module->import_memory_count + module->memory_count;
|
count = module->import_memory_count + module->memory_count;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
frame->memory_regs[i].cur_page_count = 0;
|
||||||
frame->memory_regs[i].memory_data = 0;
|
frame->memory_regs[i].memory_data = 0;
|
||||||
frame->memory_regs[i].memory_data_end = 0;
|
frame->memory_regs[i].memory_data_end = 0;
|
||||||
frame->memory_regs[i].mem_bound_check_1byte = 0;
|
frame->memory_regs[i].mem_bound_check_1byte = 0;
|
||||||
|
@ -654,6 +928,8 @@ create_fixed_virtual_regs(JitCompContext *cc)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
cc->memory_regs[i].memory_inst = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->memory_regs[i].cur_page_count = jit_cc_new_reg_I32(cc);
|
||||||
cc->memory_regs[i].memory_data = jit_cc_new_reg_ptr(cc);
|
cc->memory_regs[i].memory_data = jit_cc_new_reg_ptr(cc);
|
||||||
cc->memory_regs[i].memory_data_end = jit_cc_new_reg_ptr(cc);
|
cc->memory_regs[i].memory_data_end = jit_cc_new_reg_ptr(cc);
|
||||||
cc->memory_regs[i].mem_bound_check_1byte = jit_cc_new_reg_ptr(cc);
|
cc->memory_regs[i].mem_bound_check_1byte = jit_cc_new_reg_ptr(cc);
|
||||||
|
@ -2311,77 +2587,3 @@ jit_frontend_get_jitted_return_addr_offset()
|
||||||
{
|
{
|
||||||
return (uint32)offsetof(WASMInterpFrame, jitted_return_addr);
|
return (uint32)offsetof(WASMInterpFrame, jitted_return_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
|
||||||
bool
|
|
||||||
check_suspend_flags(JitCompContext *cc, JITFuncContext *func_ctx)
|
|
||||||
{
|
|
||||||
LLVMValueRef terminate_addr, terminate_flags, flag, offset, res;
|
|
||||||
JitBasicBlock *terminate_check_block, non_terminate_block;
|
|
||||||
JITFuncType *jit_func_type = func_ctx->jit_func->func_type;
|
|
||||||
JitBasicBlock *terminate_block;
|
|
||||||
|
|
||||||
/* Offset of suspend_flags */
|
|
||||||
offset = I32_FIVE;
|
|
||||||
|
|
||||||
if (!(terminate_addr = LLVMBuildInBoundsGEP(
|
|
||||||
cc->builder, func_ctx->exec_env, &offset, 1, "terminate_addr"))) {
|
|
||||||
jit_set_last_error("llvm build in bounds gep failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(terminate_addr =
|
|
||||||
LLVMBuildBitCast(cc->builder, terminate_addr, INT32_PTR_TYPE,
|
|
||||||
"terminate_addr_ptr"))) {
|
|
||||||
jit_set_last_error("llvm build bit cast failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(terminate_flags =
|
|
||||||
LLVMBuildLoad(cc->builder, terminate_addr, "terminate_flags"))) {
|
|
||||||
jit_set_last_error("llvm build bit cast failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* Set terminate_flags memory accecc to volatile, so that the value
|
|
||||||
will always be loaded from memory rather than register */
|
|
||||||
LLVMSetVolatile(terminate_flags, true);
|
|
||||||
|
|
||||||
CREATE_BASIC_BLOCK(terminate_check_block, "terminate_check");
|
|
||||||
MOVE_BASIC_BLOCK_AFTER_CURR(terminate_check_block);
|
|
||||||
|
|
||||||
CREATE_BASIC_BLOCK(non_terminate_block, "non_terminate");
|
|
||||||
MOVE_BASIC_BLOCK_AFTER_CURR(non_terminate_block);
|
|
||||||
|
|
||||||
BUILD_ICMP(LLVMIntSGT, terminate_flags, I32_ZERO, res, "need_terminate");
|
|
||||||
BUILD_COND_BR(res, terminate_check_block, non_terminate_block);
|
|
||||||
|
|
||||||
/* Move builder to terminate check block */
|
|
||||||
SET_BUILDER_POS(terminate_check_block);
|
|
||||||
|
|
||||||
CREATE_BASIC_BLOCK(terminate_block, "terminate");
|
|
||||||
MOVE_BASIC_BLOCK_AFTER_CURR(terminate_block);
|
|
||||||
|
|
||||||
if (!(flag = LLVMBuildAnd(cc->builder, terminate_flags, I32_ONE,
|
|
||||||
"termination_flag"))) {
|
|
||||||
jit_set_last_error("llvm build AND failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BUILD_ICMP(LLVMIntSGT, flag, I32_ZERO, res, "need_terminate");
|
|
||||||
BUILD_COND_BR(res, terminate_block, non_terminate_block);
|
|
||||||
|
|
||||||
/* Move builder to terminate block */
|
|
||||||
SET_BUILDER_POS(terminate_block);
|
|
||||||
if (!jit_build_zero_function_ret(cc, func_ctx, jit_func_type)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move builder to terminate block */
|
|
||||||
SET_BUILDER_POS(non_terminate_block);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif /* End of WASM_ENABLE_THREAD_MGR */
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -192,6 +192,12 @@ get_aux_stack_bound_reg(JitFrame *frame);
|
||||||
JitReg
|
JitReg
|
||||||
get_aux_stack_bottom_reg(JitFrame *frame);
|
get_aux_stack_bottom_reg(JitFrame *frame);
|
||||||
|
|
||||||
|
JitReg
|
||||||
|
get_memory_inst_reg(JitFrame *frame, uint32 mem_idx);
|
||||||
|
|
||||||
|
JitReg
|
||||||
|
get_cur_page_count_reg(JitFrame *frame, uint32 mem_idx);
|
||||||
|
|
||||||
JitReg
|
JitReg
|
||||||
get_memory_data_reg(JitFrame *frame, uint32 mem_idx);
|
get_memory_data_reg(JitFrame *frame, uint32 mem_idx);
|
||||||
|
|
||||||
|
|
|
@ -866,6 +866,8 @@ typedef struct JitValueSlot {
|
||||||
typedef struct JitMemRegs {
|
typedef struct JitMemRegs {
|
||||||
/* The following registers should be re-loaded after
|
/* The following registers should be re-loaded after
|
||||||
memory.grow, callbc and callnative */
|
memory.grow, callbc and callnative */
|
||||||
|
JitReg memory_inst;
|
||||||
|
JitReg cur_page_count;
|
||||||
JitReg memory_data;
|
JitReg memory_data;
|
||||||
JitReg memory_data_end;
|
JitReg memory_data_end;
|
||||||
JitReg mem_bound_check_1byte;
|
JitReg mem_bound_check_1byte;
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2021 Intel Corporation. All rights reserved.
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "jit_utils.h"
|
|
||||||
|
|
||||||
JitBitmap *
|
|
||||||
jit_bitmap_new(uintptr_t begin_index, unsigned bitnum)
|
|
||||||
{
|
|
||||||
JitBitmap *bitmap;
|
|
||||||
|
|
||||||
if ((bitmap = jit_calloc(offsetof(JitBitmap, map) + (bitnum + 7) / 8))) {
|
|
||||||
bitmap->begin_index = begin_index;
|
|
||||||
bitmap->end_index = begin_index + bitnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
|
@ -12,20 +12,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple fixed size bitmap.
|
|
||||||
*/
|
|
||||||
typedef struct JitBitmap {
|
|
||||||
/* The first valid bit index. */
|
|
||||||
uintptr_t begin_index;
|
|
||||||
|
|
||||||
/* The last valid bit index plus one. */
|
|
||||||
uintptr_t end_index;
|
|
||||||
|
|
||||||
/* The bitmap. */
|
|
||||||
uint8 map[1];
|
|
||||||
} JitBitmap;
|
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
jit_malloc(unsigned int size)
|
jit_malloc(unsigned int size)
|
||||||
{
|
{
|
||||||
|
@ -49,86 +35,6 @@ jit_free(void *ptr)
|
||||||
wasm_runtime_free(ptr);
|
wasm_runtime_free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new bitmap.
|
|
||||||
*
|
|
||||||
* @param begin_index the first valid bit index
|
|
||||||
* @param bitnum maximal bit number of the bitmap.
|
|
||||||
*
|
|
||||||
* @return the new bitmap if succeeds, NULL otherwise.
|
|
||||||
*/
|
|
||||||
JitBitmap *
|
|
||||||
jit_bitmap_new(uintptr_t begin_index, unsigned bitnum);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a bitmap.
|
|
||||||
*
|
|
||||||
* @param bitmap the bitmap to be deleted
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
jit_bitmap_delete(JitBitmap *bitmap)
|
|
||||||
{
|
|
||||||
jit_free(bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether the given index is in the range of the bitmap.
|
|
||||||
*
|
|
||||||
* @param bitmap the bitmap
|
|
||||||
* @param n the bit index
|
|
||||||
*
|
|
||||||
* @return true if the index is in range, false otherwise
|
|
||||||
*/
|
|
||||||
static inline bool
|
|
||||||
jit_bitmap_is_in_range(JitBitmap *bitmap, unsigned n)
|
|
||||||
{
|
|
||||||
return n >= bitmap->begin_index && n < bitmap->end_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a bit in the bitmap
|
|
||||||
*
|
|
||||||
* @param bitmap the bitmap
|
|
||||||
* @param n the n-th bit to be get
|
|
||||||
*
|
|
||||||
* @return value of the bit
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
jit_bitmap_get_bit(JitBitmap *bitmap, unsigned n)
|
|
||||||
{
|
|
||||||
unsigned idx = n - bitmap->begin_index;
|
|
||||||
bh_assert(n >= bitmap->begin_index && n < bitmap->end_index);
|
|
||||||
return (bitmap->map[idx / 8] >> (idx % 8)) & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a bit in the bitmap.
|
|
||||||
*
|
|
||||||
* @param bitmap the bitmap
|
|
||||||
* @param n the n-th bit to be set
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
jit_bitmap_set_bit(JitBitmap *bitmap, unsigned n)
|
|
||||||
{
|
|
||||||
unsigned idx = n - bitmap->begin_index;
|
|
||||||
bh_assert(n >= bitmap->begin_index && n < bitmap->end_index);
|
|
||||||
bitmap->map[idx / 8] |= 1 << (idx % 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear a bit in the bitmap.
|
|
||||||
*
|
|
||||||
* @param bitmap the bitmap
|
|
||||||
* @param n the n-th bit to be cleared
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
jit_bitmap_clear_bit(JitBitmap *bitmap, unsigned n)
|
|
||||||
{
|
|
||||||
unsigned idx = n - bitmap->begin_index;
|
|
||||||
bh_assert(n >= bitmap->begin_index && n < bitmap->end_index);
|
|
||||||
bitmap->map[idx / 8] &= ~(1 << (idx % 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,6 +38,7 @@ enum {
|
||||||
AOT_LLVMIR_OPT_FILE,
|
AOT_LLVMIR_OPT_FILE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* always sync it with AOTCompOption in compilation/aot_llvm.h */
|
||||||
typedef struct AOTCompOption {
|
typedef struct AOTCompOption {
|
||||||
bool is_jit_mode;
|
bool is_jit_mode;
|
||||||
bool is_indirect_mode;
|
bool is_indirect_mode;
|
||||||
|
@ -64,6 +65,7 @@ typedef struct AOTCompOption {
|
||||||
uint32_t bounds_checks;
|
uint32_t bounds_checks;
|
||||||
uint32_t stack_bounds_checks;
|
uint32_t stack_bounds_checks;
|
||||||
uint32_t segue_flags;
|
uint32_t segue_flags;
|
||||||
|
bool linux_perf_support;
|
||||||
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;
|
||||||
|
|
|
@ -21,6 +21,15 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
#define DEPRECATED __attribute__((deprecated))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define DEPRECATED __declspec(deprecated)
|
||||||
|
#else
|
||||||
|
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
|
||||||
|
#define DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -136,31 +145,6 @@ static inline void wasm_name_new_from_string_nt(
|
||||||
|
|
||||||
WASM_DECLARE_OWN(config)
|
WASM_DECLARE_OWN(config)
|
||||||
|
|
||||||
WASM_API_EXTERN own wasm_config_t* wasm_config_new(void);
|
|
||||||
|
|
||||||
// Embedders may provide custom functions for manipulating configs.
|
|
||||||
|
|
||||||
|
|
||||||
// Engine
|
|
||||||
|
|
||||||
WASM_DECLARE_OWN(engine)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new engine
|
|
||||||
*
|
|
||||||
* Note: for the engine new/delete operations, including this,
|
|
||||||
* wasm_engine_new_with_config, wasm_engine_new_with_args, and
|
|
||||||
* wasm_engine_delete, if the platform has mutex initializer,
|
|
||||||
* then they are thread-safe: we use a global lock to lock the
|
|
||||||
* operations of the engine. Otherwise they are not thread-safe:
|
|
||||||
* when there are engine new/delete operations happening
|
|
||||||
* simultaneously in multiple threads, developer must create
|
|
||||||
* the lock by himself, and add the lock when calling these
|
|
||||||
* functions.
|
|
||||||
*/
|
|
||||||
WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(void);
|
|
||||||
WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t*);
|
|
||||||
|
|
||||||
#ifndef MEM_ALLOC_OPTION_DEFINED
|
#ifndef MEM_ALLOC_OPTION_DEFINED
|
||||||
#define MEM_ALLOC_OPTION_DEFINED
|
#define MEM_ALLOC_OPTION_DEFINED
|
||||||
/* same definition from wasm_export.h */
|
/* same definition from wasm_export.h */
|
||||||
|
@ -191,9 +175,51 @@ typedef union MemAllocOption {
|
||||||
void *user_data;
|
void *user_data;
|
||||||
} allocator;
|
} allocator;
|
||||||
} MemAllocOption;
|
} MemAllocOption;
|
||||||
#endif
|
#endif /* MEM_ALLOC_OPTION_DEFINED */
|
||||||
|
|
||||||
WASM_API_EXTERN own wasm_engine_t *
|
/* Runtime configration */
|
||||||
|
struct wasm_config_t {
|
||||||
|
mem_alloc_type_t mem_alloc_type;
|
||||||
|
MemAllocOption mem_alloc_option;
|
||||||
|
bool linux_perf_support;
|
||||||
|
/*TODO: wasi args*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* by default:
|
||||||
|
* - mem_alloc_type is Alloc_With_System_Allocator
|
||||||
|
* - mem_alloc_option is all 0
|
||||||
|
* - linux_perf_support is false
|
||||||
|
*/
|
||||||
|
WASM_API_EXTERN own wasm_config_t* wasm_config_new(void);
|
||||||
|
|
||||||
|
// Embedders may provide custom functions for manipulating configs.
|
||||||
|
WASM_API_EXTERN own wasm_config_t*
|
||||||
|
wasm_config_set_mem_alloc_opt(wasm_config_t *, mem_alloc_type_t, MemAllocOption *);
|
||||||
|
|
||||||
|
WASM_API_EXTERN own wasm_config_t*
|
||||||
|
wasm_config_set_linux_perf_opt(wasm_config_t *, bool);
|
||||||
|
|
||||||
|
// Engine
|
||||||
|
|
||||||
|
WASM_DECLARE_OWN(engine)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new engine
|
||||||
|
*
|
||||||
|
* Note: for the engine new/delete operations, including this,
|
||||||
|
* wasm_engine_new_with_config, wasm_engine_new_with_args, and
|
||||||
|
* wasm_engine_delete, if the platform has mutex initializer,
|
||||||
|
* then they are thread-safe: we use a global lock to lock the
|
||||||
|
* operations of the engine. Otherwise they are not thread-safe:
|
||||||
|
* when there are engine new/delete operations happening
|
||||||
|
* simultaneously in multiple threads, developer must create
|
||||||
|
* the lock by himself, and add the lock when calling these
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(void);
|
||||||
|
WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(wasm_config_t*);
|
||||||
|
DEPRECATED WASM_API_EXTERN own wasm_engine_t *
|
||||||
wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts);
|
wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts);
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
|
|
|
@ -169,6 +169,15 @@ typedef struct RuntimeInitArgs {
|
||||||
uint32_t llvm_jit_size_level;
|
uint32_t llvm_jit_size_level;
|
||||||
/* Segue optimization flags for LLVM JIT */
|
/* Segue optimization flags for LLVM JIT */
|
||||||
uint32_t segue_flags;
|
uint32_t segue_flags;
|
||||||
|
/**
|
||||||
|
* If enabled
|
||||||
|
* - llvm-jit will output a jitdump file for `perf inject`
|
||||||
|
* - aot. TBD
|
||||||
|
* - fast-jit. TBD
|
||||||
|
* - multi-tier-jit. TBD
|
||||||
|
* - interpreter. TBD
|
||||||
|
*/
|
||||||
|
bool linux_perf_support;
|
||||||
} RuntimeInitArgs;
|
} RuntimeInitArgs;
|
||||||
|
|
||||||
#ifndef WASM_VALKIND_T_DEFINED
|
#ifndef WASM_VALKIND_T_DEFINED
|
||||||
|
@ -311,7 +320,8 @@ wasm_runtime_is_xip_file(const uint8_t *buf, uint32_t size);
|
||||||
/**
|
/**
|
||||||
* Callback to load a module file into a buffer in multi-module feature
|
* Callback to load a module file into a buffer in multi-module feature
|
||||||
*/
|
*/
|
||||||
typedef bool (*module_reader)(package_type_t module_type,const char *module_name,
|
typedef bool (*module_reader)(package_type_t module_type,
|
||||||
|
const char *module_name,
|
||||||
uint8_t **p_buffer, uint32_t *p_size);
|
uint8_t **p_buffer, uint32_t *p_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -423,6 +433,7 @@ wasm_runtime_get_module_hash(wasm_module_t module);
|
||||||
* @param dir_list The list of directories to preopen. (real path)
|
* @param dir_list The list of directories to preopen. (real path)
|
||||||
* @param dir_count The number of elements in dir_list.
|
* @param dir_count The number of elements in dir_list.
|
||||||
* @param map_dir_list The list of directories to preopen. (mapped path)
|
* @param map_dir_list The list of directories to preopen. (mapped path)
|
||||||
|
* Format for each map entry: <guest-path>::<host-path>
|
||||||
* @param map_dir_count The number of elements in map_dir_list.
|
* @param map_dir_count The number of elements in map_dir_list.
|
||||||
* If map_dir_count is smaller than dir_count,
|
* If map_dir_count is smaller than dir_count,
|
||||||
* mapped path is assumed to be same as the
|
* mapped path is assumed to be same as the
|
||||||
|
@ -431,26 +442,31 @@ wasm_runtime_get_module_hash(wasm_module_t module);
|
||||||
* @param env_count The number of elements in env.
|
* @param env_count The number of elements in env.
|
||||||
* @param argv The list of command line arguments.
|
* @param argv The list of command line arguments.
|
||||||
* @param argc The number of elements in argv.
|
* @param argc The number of elements in argv.
|
||||||
* @param stdinfd The host file descriptor to back WASI STDIN_FILENO.
|
* @param stdin_handle The raw host handle to back WASI STDIN_FILENO.
|
||||||
* If -1 is specified, STDIN_FILENO is used.
|
* If an invalid handle is specified (e.g. -1 on POSIX,
|
||||||
* @param stdoutfd The host file descriptor to back WASI STDOUT_FILENO.
|
* INVALID_HANDLE_VALUE on Windows), the platform default
|
||||||
* If -1 is specified, STDOUT_FILENO is used.
|
* for STDIN is used.
|
||||||
* @param stderrfd The host file descriptor to back WASI STDERR_FILENO.
|
* @param stdoutfd The raw host handle to back WASI STDOUT_FILENO.
|
||||||
* If -1 is specified, STDERR_FILENO is used.
|
* If an invalid handle is specified (e.g. -1 on POSIX,
|
||||||
|
* INVALID_HANDLE_VALUE on Windows), the platform default
|
||||||
|
* for STDOUT is used.
|
||||||
|
* @param stderrfd The raw host handle to back WASI STDERR_FILENO.
|
||||||
|
* If an invalid handle is specified (e.g. -1 on POSIX,
|
||||||
|
* INVALID_HANDLE_VALUE on Windows), the platform default
|
||||||
|
* for STDERR is used.
|
||||||
*/
|
*/
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_wasi_args_ex(wasm_module_t module,
|
wasm_runtime_set_wasi_args_ex(wasm_module_t module,
|
||||||
const char *dir_list[], uint32_t dir_count,
|
const char *dir_list[], uint32_t dir_count,
|
||||||
const char *map_dir_list[], uint32_t map_dir_count,
|
const char *map_dir_list[], uint32_t map_dir_count,
|
||||||
const char *env[], uint32_t env_count,
|
const char *env[], uint32_t env_count,
|
||||||
char *argv[], int argc,
|
char *argv[], int argc, int64_t stdinfd,
|
||||||
int stdinfd, int stdoutfd, int stderrfd);
|
int64_t stdoutfd, int64_t stderrfd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set WASI parameters.
|
* Set WASI parameters.
|
||||||
*
|
*
|
||||||
* Same as wasm_runtime_set_wasi_args_ex with stdinfd = -1, stdoutfd = -1,
|
* Same as wasm_runtime_set_wasi_args_ex but with default stdio handles
|
||||||
* stderrfd = -1.
|
|
||||||
*/
|
*/
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_wasi_args(wasm_module_t module,
|
wasm_runtime_set_wasi_args(wasm_module_t module,
|
||||||
|
@ -865,6 +881,7 @@ wasm_application_execute_main(wasm_module_inst_t module_inst,
|
||||||
WASM_RUNTIME_API_EXTERN bool
|
WASM_RUNTIME_API_EXTERN bool
|
||||||
wasm_application_execute_func(wasm_module_inst_t module_inst,
|
wasm_application_execute_func(wasm_module_inst_t module_inst,
|
||||||
const char *name, int32_t argc, char *argv[]);
|
const char *name, int32_t argc, char *argv[]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get exception info of the WASM module instance.
|
* Get exception info of the WASM module instance.
|
||||||
*
|
*
|
||||||
|
@ -927,6 +944,7 @@ wasm_runtime_terminate(wasm_module_inst_t module_inst);
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_custom_data(wasm_module_inst_t module_inst,
|
wasm_runtime_set_custom_data(wasm_module_inst_t module_inst,
|
||||||
void *custom_data);
|
void *custom_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the custom data within a WASM module instance.
|
* Get the custom data within a WASM module instance.
|
||||||
*
|
*
|
||||||
|
@ -946,16 +964,17 @@ wasm_runtime_get_custom_data(wasm_module_inst_t module_inst);
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
|
wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
|
||||||
bool enable);
|
bool enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the memory bounds checks flag is enabled for a WASM module instance.
|
* Check if the memory bounds checks flag is enabled for a WASM module instance.
|
||||||
*
|
*
|
||||||
* @param module_inst the WASM module instance
|
* @param module_inst the WASM module instance
|
||||||
*
|
|
||||||
* @return true if the memory bounds checks flag is enabled, false otherwise
|
* @return true if the memory bounds checks flag is enabled, false otherwise
|
||||||
*/
|
*/
|
||||||
WASM_RUNTIME_API_EXTERN bool
|
WASM_RUNTIME_API_EXTERN bool
|
||||||
wasm_runtime_is_bounds_checks_enabled(
|
wasm_runtime_is_bounds_checks_enabled(
|
||||||
wasm_module_inst_t module_inst);
|
wasm_module_inst_t module_inst);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate memory from the heap of WASM module instance
|
* Allocate memory from the heap of WASM module instance
|
||||||
*
|
*
|
||||||
|
@ -1330,7 +1349,8 @@ wasm_externref_objdel(wasm_module_inst_t module_inst, void *extern_obj);
|
||||||
*
|
*
|
||||||
* @param module_inst the WASM module instance that the extern object
|
* @param module_inst the WASM module instance that the extern object
|
||||||
* belongs to
|
* belongs to
|
||||||
* @param extern_obj the external object to which to set the `extern_obj_cleanup` cleanup callback.
|
* @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`
|
* @param extern_obj_cleanup a callback to release `extern_obj`
|
||||||
*
|
*
|
||||||
* @return true if success, false otherwise
|
* @return true if success, false otherwise
|
||||||
|
@ -1538,11 +1558,11 @@ WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_destroy_context_key(void *key);
|
wasm_runtime_destroy_context_key(void *key);
|
||||||
|
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_context(wasm_module_inst_t inst, void *key,
|
wasm_runtime_set_context(wasm_module_inst_t inst, void *key, void *ctx);
|
||||||
void *ctx);
|
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key,
|
wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key, void *ctx);
|
||||||
void *ctx);
|
|
||||||
WASM_RUNTIME_API_EXTERN void *
|
WASM_RUNTIME_API_EXTERN void *
|
||||||
wasm_runtime_get_context(wasm_module_inst_t inst, void *key);
|
wasm_runtime_get_context(wasm_module_inst_t inst, void *key);
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,6 @@ typedef struct WASMTableSeg {
|
||||||
uint32 mode;
|
uint32 mode;
|
||||||
/* funcref or externref, elemkind will be considered as funcref */
|
/* funcref or externref, elemkind will be considered as funcref */
|
||||||
uint32 elem_type;
|
uint32 elem_type;
|
||||||
bool is_dropped;
|
|
||||||
/* optional, only for active */
|
/* optional, only for active */
|
||||||
uint32 table_index;
|
uint32 table_index;
|
||||||
InitializerExpression base_offset;
|
InitializerExpression base_offset;
|
||||||
|
@ -350,7 +349,7 @@ typedef struct WASIArguments {
|
||||||
uint32 ns_lookup_count;
|
uint32 ns_lookup_count;
|
||||||
char **argv;
|
char **argv;
|
||||||
uint32 argc;
|
uint32 argc;
|
||||||
int stdio[3];
|
os_raw_file_handle stdio[3];
|
||||||
} WASIArguments;
|
} WASIArguments;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ typedef float64 CellType_F64;
|
||||||
* multi-threading mode since it may be changed by other
|
* multi-threading mode since it may be changed by other
|
||||||
* threads in memory.grow
|
* threads in memory.grow
|
||||||
*/
|
*/
|
||||||
#define get_linear_mem_size() memory->memory_data_size
|
#define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||||
|
@ -1015,7 +1015,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* - module_inst */
|
/* - module_inst */
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)sub_module_inst;
|
wasm_exec_env_set_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)sub_module_inst);
|
||||||
/* - aux_stack_boundary */
|
/* - aux_stack_boundary */
|
||||||
aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
|
aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
|
||||||
exec_env->aux_stack_boundary.boundary =
|
exec_env->aux_stack_boundary.boundary =
|
||||||
|
@ -1037,15 +1038,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||||
prev_frame->ip = ip;
|
prev_frame->ip = ip;
|
||||||
exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
|
exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
|
||||||
exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
|
exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_restore_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
/* transfer exception if it is thrown */
|
|
||||||
if (wasm_copy_exception(sub_module_inst, NULL)) {
|
|
||||||
bh_memcpy_s(module_inst->cur_exception,
|
|
||||||
sizeof(module_inst->cur_exception),
|
|
||||||
sub_module_inst->cur_exception,
|
|
||||||
sizeof(sub_module_inst->cur_exception));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1158,7 +1152,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *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 \
|
||||||
|| WASM_ENABLE_BULK_MEMORY != 0
|
|| WASM_ENABLE_BULK_MEMORY != 0
|
||||||
uint32 linear_mem_size = memory ? memory->memory_data_size : 0;
|
uint32 linear_mem_size = 0;
|
||||||
|
if (memory)
|
||||||
|
#if WASM_ENABLE_THREAD_MGR == 0
|
||||||
|
linear_mem_size = memory->memory_data_size;
|
||||||
|
#else
|
||||||
|
linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
WASMType **wasm_types = module->module->types;
|
WASMType **wasm_types = module->module->types;
|
||||||
WASMGlobalInstance *globals = module->e->globals, *global;
|
WASMGlobalInstance *globals = module->e->globals, *global;
|
||||||
|
@ -1184,7 +1184,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
uint8 value_type;
|
uint8 value_type;
|
||||||
#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
|
||||||
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
|
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||||
bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
|
bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
|
||||||
(WASMModuleInstanceCommon *)module);
|
(WASMModuleInstanceCommon *)module);
|
||||||
#else
|
#else
|
||||||
|
@ -2146,7 +2146,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *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 \
|
||||||
|| WASM_ENABLE_BULK_MEMORY != 0
|
|| WASM_ENABLE_BULK_MEMORY != 0
|
||||||
|
#if WASM_ENABLE_THREAD_MGR == 0
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = memory->memory_data_size;
|
||||||
|
#else
|
||||||
|
linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3151,7 +3155,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = (uint32)POP_I32();
|
addr = (uint32)POP_I32();
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = get_linear_mem_size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
@ -3163,9 +3167,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
maddr = memory->memory_data + (uint32)addr;
|
maddr = memory->memory_data + (uint32)addr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
seg_len = (uint64)module->module->data_segments[segment]
|
if (bh_bitmap_get_bit(module->e->common.data_dropped,
|
||||||
|
segment)) {
|
||||||
|
seg_len = 0;
|
||||||
|
data = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
seg_len =
|
||||||
|
(uint64)module->module->data_segments[segment]
|
||||||
->data_length;
|
->data_length;
|
||||||
data = module->module->data_segments[segment]->data;
|
data = module->module->data_segments[segment]->data;
|
||||||
|
}
|
||||||
if (offset + bytes > seg_len)
|
if (offset + bytes > seg_len)
|
||||||
goto out_of_bounds;
|
goto out_of_bounds;
|
||||||
|
|
||||||
|
@ -3178,7 +3190,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
uint32 segment;
|
uint32 segment;
|
||||||
|
|
||||||
read_leb_uint32(frame_ip, frame_ip_end, segment);
|
read_leb_uint32(frame_ip, frame_ip_end, segment);
|
||||||
module->module->data_segments[segment]->data_length = 0;
|
bh_bitmap_set_bit(module->e->common.data_dropped,
|
||||||
|
segment);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WASM_OP_MEMORY_COPY:
|
case WASM_OP_MEMORY_COPY:
|
||||||
|
@ -3193,7 +3206,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
dst = POP_I32();
|
dst = POP_I32();
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = get_linear_mem_size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
@ -3224,7 +3237,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
dst = POP_I32();
|
dst = POP_I32();
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = get_linear_mem_size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
@ -3273,8 +3286,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module->module->table_segments[elem_idx]
|
if (bh_bitmap_get_bit(module->e->common.elem_dropped,
|
||||||
.is_dropped) {
|
elem_idx)) {
|
||||||
wasm_set_exception(module,
|
wasm_set_exception(module,
|
||||||
"out of bounds table access");
|
"out of bounds table access");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
@ -3306,8 +3319,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
|
read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
|
||||||
bh_assert(elem_idx < module->module->table_seg_count);
|
bh_assert(elem_idx < module->module->table_seg_count);
|
||||||
|
|
||||||
module->module->table_segments[elem_idx].is_dropped =
|
bh_bitmap_set_bit(module->e->common.elem_dropped,
|
||||||
true;
|
elem_idx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WASM_OP_TABLE_COPY:
|
case WASM_OP_TABLE_COPY:
|
||||||
|
@ -3901,7 +3914,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|
||||||
|| WASM_ENABLE_BULK_MEMORY != 0
|
|| WASM_ENABLE_BULK_MEMORY != 0
|
||||||
if (memory)
|
if (memory)
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = get_linear_mem_size();
|
||||||
#endif
|
#endif
|
||||||
if (wasm_copy_exception(module, NULL))
|
if (wasm_copy_exception(module, NULL))
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
@ -4006,10 +4019,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_JIT != 0
|
#if WASM_ENABLE_FAST_JIT != 0
|
||||||
/* ASAN is not designed to work with custom stack unwind or other low-level \
|
/*
|
||||||
things. > Ignore a function that does some low-level magic. (e.g. walking \
|
* ASAN is not designed to work with custom stack unwind or other low-level
|
||||||
through the thread's stack bypassing the frame boundaries) */
|
* things. Ignore a function that does some low-level magic. (e.g. walking
|
||||||
#if defined(__GNUC__)
|
* through the thread's stack bypassing the frame boundaries)
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
__attribute__((no_sanitize_address))
|
__attribute__((no_sanitize_address))
|
||||||
#endif
|
#endif
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -30,7 +30,7 @@ typedef float64 CellType_F64;
|
||||||
* multi-threading mode since it may be changed by other
|
* multi-threading mode since it may be changed by other
|
||||||
* threads in memory.grow
|
* threads in memory.grow
|
||||||
*/
|
*/
|
||||||
#define get_linear_mem_size() memory->memory_data_size
|
#define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||||
|
@ -1034,7 +1034,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* - module_inst */
|
/* - module_inst */
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)sub_module_inst;
|
wasm_exec_env_set_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)sub_module_inst);
|
||||||
/* - aux_stack_boundary */
|
/* - aux_stack_boundary */
|
||||||
aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
|
aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
|
||||||
exec_env->aux_stack_boundary.boundary =
|
exec_env->aux_stack_boundary.boundary =
|
||||||
|
@ -1056,15 +1057,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||||
prev_frame->ip = ip;
|
prev_frame->ip = ip;
|
||||||
exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
|
exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
|
||||||
exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
|
exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_restore_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
/* transfer exception if it is thrown */
|
|
||||||
if (wasm_copy_exception(sub_module_inst, NULL)) {
|
|
||||||
bh_memcpy_s(module_inst->cur_exception,
|
|
||||||
sizeof(module_inst->cur_exception),
|
|
||||||
sub_module_inst->cur_exception,
|
|
||||||
sizeof(sub_module_inst->cur_exception));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1142,12 +1136,27 @@ wasm_interp_dump_op_count()
|
||||||
goto *p_label_addr; \
|
goto *p_label_addr; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
#define FETCH_OPCODE_AND_DISPATCH() \
|
#define FETCH_OPCODE_AND_DISPATCH() \
|
||||||
do { \
|
do { \
|
||||||
const void *p_label_addr = label_base + *(int16 *)frame_ip; \
|
const void *p_label_addr; \
|
||||||
frame_ip += sizeof(int16); \
|
bh_assert(((uintptr_t)frame_ip & 1) == 0); \
|
||||||
|
/* int32 relative offset was emitted in 64-bit target */ \
|
||||||
|
p_label_addr = label_base + (int32)LOAD_U32_WITH_2U16S(frame_ip); \
|
||||||
|
frame_ip += sizeof(int32); \
|
||||||
goto *p_label_addr; \
|
goto *p_label_addr; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define FETCH_OPCODE_AND_DISPATCH() \
|
||||||
|
do { \
|
||||||
|
const void *p_label_addr; \
|
||||||
|
bh_assert(((uintptr_t)frame_ip & 1) == 0); \
|
||||||
|
/* uint32 label address was emitted in 32-bit target */ \
|
||||||
|
p_label_addr = (void *)(uintptr_t)LOAD_U32_WITH_2U16S(frame_ip); \
|
||||||
|
frame_ip += sizeof(int32); \
|
||||||
|
goto *p_label_addr; \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
#define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
|
#define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
|
||||||
|
|
||||||
|
@ -1185,7 +1194,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *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 \
|
||||||
|| WASM_ENABLE_BULK_MEMORY != 0
|
|| WASM_ENABLE_BULK_MEMORY != 0
|
||||||
uint32 linear_mem_size = memory ? memory->memory_data_size : 0;
|
uint32 linear_mem_size = 0;
|
||||||
|
if (memory)
|
||||||
|
#if WASM_ENABLE_THREAD_MGR == 0
|
||||||
|
linear_mem_size = memory->memory_data_size;
|
||||||
|
#else
|
||||||
|
linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
WASMGlobalInstance *globals = module->e ? module->e->globals : NULL;
|
WASMGlobalInstance *globals = module->e ? module->e->globals : NULL;
|
||||||
WASMGlobalInstance *global;
|
WASMGlobalInstance *global;
|
||||||
|
@ -1197,7 +1212,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
|
register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
|
||||||
register uint32 *frame_lp = NULL; /* cache of frame->lp */
|
register uint32 *frame_lp = NULL; /* cache of frame->lp */
|
||||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
|
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 && UINTPTR_MAX == UINT64_MAX
|
||||||
/* cache of label base addr */
|
/* cache of label base addr */
|
||||||
register uint8 *label_base = &&HANDLE_WASM_OP_UNREACHABLE;
|
register uint8 *label_base = &&HANDLE_WASM_OP_UNREACHABLE;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1212,7 +1227,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
uint8 opcode, local_type, *global_addr;
|
uint8 opcode, local_type, *global_addr;
|
||||||
#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
|
||||||
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
|
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||||
bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
|
bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
|
||||||
(WASMModuleInstanceCommon *)module);
|
(WASMModuleInstanceCommon *)module);
|
||||||
#else
|
#else
|
||||||
|
@ -1691,7 +1706,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
frame_ip += 2;
|
frame_ip += 2;
|
||||||
addr_ret = GET_OFFSET();
|
addr_ret = GET_OFFSET();
|
||||||
CHECK_MEMORY_OVERFLOW(1);
|
CHECK_MEMORY_OVERFLOW(1);
|
||||||
frame_lp[addr_ret] = (uint32)(*(uint8 *)maddr);
|
frame_lp[addr_ret] = (uint32)(*(uint8 *)(maddr));
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1816,7 +1831,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = GET_OPERAND(uint32, I32, 2);
|
addr = GET_OPERAND(uint32, I32, 2);
|
||||||
frame_ip += 4;
|
frame_ip += 4;
|
||||||
CHECK_MEMORY_OVERFLOW(1);
|
CHECK_MEMORY_OVERFLOW(1);
|
||||||
*(uint8 *)maddr = (uint8)sval;
|
STORE_U8(maddr, (uint8_t)sval);
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1916,7 +1931,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *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 \
|
||||||
|| WASM_ENABLE_BULK_MEMORY != 0
|
|| WASM_ENABLE_BULK_MEMORY != 0
|
||||||
|
#if WASM_ENABLE_THREAD_MGR == 0
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = memory->memory_data_size;
|
||||||
|
#else
|
||||||
|
linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2994,12 +3013,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
|
|
||||||
segment = read_uint32(frame_ip);
|
segment = read_uint32(frame_ip);
|
||||||
|
|
||||||
bytes = (uint64)POP_I32();
|
bytes = (uint64)(uint32)POP_I32();
|
||||||
offset = (uint64)POP_I32();
|
offset = (uint64)(uint32)POP_I32();
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR
|
#if WASM_ENABLE_THREAD_MGR
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = get_linear_mem_size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
@ -3010,10 +3029,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
goto out_of_bounds;
|
goto out_of_bounds;
|
||||||
maddr = memory->memory_data + (uint32)addr;
|
maddr = memory->memory_data + (uint32)addr;
|
||||||
#endif
|
#endif
|
||||||
|
if (bh_bitmap_get_bit(module->e->common.data_dropped,
|
||||||
|
segment)) {
|
||||||
|
seg_len = 0;
|
||||||
|
data = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
seg_len = (uint64)module->module->data_segments[segment]
|
seg_len =
|
||||||
|
(uint64)module->module->data_segments[segment]
|
||||||
->data_length;
|
->data_length;
|
||||||
data = module->module->data_segments[segment]->data;
|
data = module->module->data_segments[segment]->data;
|
||||||
|
}
|
||||||
if (offset + bytes > seg_len)
|
if (offset + bytes > seg_len)
|
||||||
goto out_of_bounds;
|
goto out_of_bounds;
|
||||||
|
|
||||||
|
@ -3026,8 +3053,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
uint32 segment;
|
uint32 segment;
|
||||||
|
|
||||||
segment = read_uint32(frame_ip);
|
segment = read_uint32(frame_ip);
|
||||||
|
bh_bitmap_set_bit(module->e->common.data_dropped,
|
||||||
module->module->data_segments[segment]->data_length = 0;
|
segment);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WASM_OP_MEMORY_COPY:
|
case WASM_OP_MEMORY_COPY:
|
||||||
|
@ -3040,7 +3067,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
dst = POP_I32();
|
dst = POP_I32();
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR
|
#if WASM_ENABLE_THREAD_MGR
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = get_linear_mem_size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
@ -3070,7 +3097,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
dst = POP_I32();
|
dst = POP_I32();
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR
|
#if WASM_ENABLE_THREAD_MGR
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = get_linear_mem_size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
@ -3119,8 +3146,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module->module->table_segments[elem_idx]
|
if (bh_bitmap_get_bit(module->e->common.elem_dropped,
|
||||||
.is_dropped) {
|
elem_idx)) {
|
||||||
wasm_set_exception(module,
|
wasm_set_exception(module,
|
||||||
"out of bounds table access");
|
"out of bounds table access");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
@ -3149,9 +3176,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
{
|
{
|
||||||
uint32 elem_idx = read_uint32(frame_ip);
|
uint32 elem_idx = read_uint32(frame_ip);
|
||||||
bh_assert(elem_idx < module->module->table_seg_count);
|
bh_assert(elem_idx < module->module->table_seg_count);
|
||||||
|
bh_bitmap_set_bit(module->e->common.elem_dropped,
|
||||||
module->module->table_segments[elem_idx].is_dropped =
|
elem_idx);
|
||||||
true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WASM_OP_TABLE_COPY:
|
case WASM_OP_TABLE_COPY:
|
||||||
|
@ -3846,7 +3872,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|
||||||
|| WASM_ENABLE_BULK_MEMORY != 0
|
|| WASM_ENABLE_BULK_MEMORY != 0
|
||||||
if (memory)
|
if (memory)
|
||||||
linear_mem_size = memory->memory_data_size;
|
linear_mem_size = get_linear_mem_size();
|
||||||
#endif
|
#endif
|
||||||
if (wasm_copy_exception(module, NULL))
|
if (wasm_copy_exception(module, NULL))
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
|
|
@ -173,7 +173,6 @@ fail:
|
||||||
|
|
||||||
#define read_uint8(p) TEMPLATE_READ_VALUE(uint8, p)
|
#define read_uint8(p) TEMPLATE_READ_VALUE(uint8, p)
|
||||||
#define read_uint32(p) TEMPLATE_READ_VALUE(uint32, p)
|
#define read_uint32(p) TEMPLATE_READ_VALUE(uint32, p)
|
||||||
#define read_bool(p) TEMPLATE_READ_VALUE(bool, p)
|
|
||||||
|
|
||||||
#define read_leb_int64(p, p_end, res) \
|
#define read_leb_int64(p, p_end, res) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -302,7 +301,13 @@ check_utf8_str(const uint8 *str, uint32 len)
|
||||||
|
|
||||||
while (p < p_end) {
|
while (p < p_end) {
|
||||||
chr = *p;
|
chr = *p;
|
||||||
if (chr < 0x80) {
|
|
||||||
|
if (chr == 0) {
|
||||||
|
LOG_WARNING(
|
||||||
|
"LIMITATION: a string which contains '\\00' is unsupported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (chr < 0x80) {
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
|
else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
|
||||||
|
@ -490,6 +495,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
if (type != VALUE_TYPE_V128)
|
if (type != VALUE_TYPE_V128)
|
||||||
goto fail_type_mismatch;
|
goto fail_type_mismatch;
|
||||||
|
|
||||||
|
CHECK_BUF(p, p_end, 1);
|
||||||
flag = read_uint8(p);
|
flag = read_uint8(p);
|
||||||
(void)flag;
|
(void)flag;
|
||||||
|
|
||||||
|
@ -1163,9 +1169,16 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
|
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
|
||||||
error_buf_size);
|
error_buf_size);
|
||||||
if (!sub_module) {
|
if (!sub_module) {
|
||||||
|
#if WASM_ENABLE_LIB_WASI_THREADS != 0
|
||||||
|
/* Avoid memory import failure when wasi-threads is enabled
|
||||||
|
and the memory is shared */
|
||||||
|
if (!(declare_max_page_count_flag & 2))
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif /* WASM_ENABLE_LIB_WASI_THREADS */
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
linked_memory = wasm_loader_resolve_memory(
|
linked_memory = wasm_loader_resolve_memory(
|
||||||
sub_module_name, memory_name, declare_init_page_count,
|
sub_module_name, memory_name, declare_init_page_count,
|
||||||
declare_max_page_count, error_buf, error_buf_size);
|
declare_max_page_count, error_buf, error_buf_size);
|
||||||
|
@ -1181,6 +1194,7 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
declare_init_page_count = linked_memory->init_page_count;
|
declare_init_page_count = linked_memory->init_page_count;
|
||||||
declare_max_page_count = linked_memory->max_page_count;
|
declare_max_page_count = linked_memory->max_page_count;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* (memory (export "memory") 1 2) */
|
/* (memory (export "memory") 1 2) */
|
||||||
|
@ -1375,7 +1389,15 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (memory->flags > 1) {
|
if (memory->flags > 1) {
|
||||||
set_error_buf(error_buf, error_buf_size, "integer too large");
|
if (memory->flags & 2) {
|
||||||
|
set_error_buf(error_buf, error_buf_size,
|
||||||
|
"shared memory flag was found, "
|
||||||
|
"please enable shared memory, lib-pthread "
|
||||||
|
"or lib-wasi-threads");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set_error_buf(error_buf, error_buf_size, "invalid memory flags");
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -2694,7 +2716,7 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
|
|
||||||
read_leb_uint32(p, p_end, name_len);
|
read_leb_uint32(p, p_end, name_len);
|
||||||
|
|
||||||
if (name_len == 0 || p + name_len > p_end) {
|
if (p + name_len > p_end) {
|
||||||
set_error_buf(error_buf, error_buf_size, "unexpected end");
|
set_error_buf(error_buf, error_buf_size, "unexpected end");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2870,6 +2892,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
|
||||||
option.opt_level = llvm_jit_options.opt_level;
|
option.opt_level = llvm_jit_options.opt_level;
|
||||||
option.size_level = llvm_jit_options.size_level;
|
option.size_level = llvm_jit_options.size_level;
|
||||||
option.segue_flags = llvm_jit_options.segue_flags;
|
option.segue_flags = llvm_jit_options.segue_flags;
|
||||||
|
option.linux_perf_support = llvm_jit_options.linux_perf_support;
|
||||||
|
|
||||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
option.enable_bulk_memory = true;
|
option.enable_bulk_memory = true;
|
||||||
|
@ -3979,13 +4002,16 @@ check_wasi_abi_compatibility(const WASMModule *module,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
/* (func (export "_initialize") (...) */
|
/* (func (export "_initialize") (...) */
|
||||||
initialize = wasm_loader_find_export(
|
initialize =
|
||||||
module, "", "_initialize", EXPORT_KIND_FUNC, error_buf, error_buf_size);
|
wasm_loader_find_export(module, "", "_initialize", EXPORT_KIND_FUNC,
|
||||||
|
error_buf, error_buf_size);
|
||||||
if (initialize) {
|
if (initialize) {
|
||||||
WASMType *func_type =
|
WASMType *func_type =
|
||||||
module->functions[initialize->index - module->import_function_count]
|
module
|
||||||
|
->functions[initialize->index
|
||||||
|
- module->import_function_count]
|
||||||
->func_type;
|
->func_type;
|
||||||
if (func_type->param_count || func_type->result_count) {
|
if (func_type->param_count || func_type->result_count) {
|
||||||
set_error_buf(
|
set_error_buf(
|
||||||
|
@ -3994,6 +4020,7 @@ check_wasi_abi_compatibility(const WASMModule *module,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* filter out non-wasi compatiable modules */
|
/* filter out non-wasi compatiable modules */
|
||||||
if (!module->import_wasi_api && !start && !initialize) {
|
if (!module->import_wasi_api && !start && !initialize) {
|
||||||
|
@ -5389,21 +5416,27 @@ fail:
|
||||||
LOG_OP("\ndelete last op\n"); \
|
LOG_OP("\ndelete last op\n"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
#define emit_label(opcode) \
|
#define emit_label(opcode) \
|
||||||
do { \
|
do { \
|
||||||
int32 offset = \
|
int32 offset = \
|
||||||
(int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \
|
(int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \
|
||||||
if (!(offset >= INT16_MIN && offset < INT16_MAX)) { \
|
/* emit int32 relative offset in 64-bit target */ \
|
||||||
set_error_buf(error_buf, error_buf_size, \
|
wasm_loader_emit_uint32(loader_ctx, offset); \
|
||||||
"pre-compiled label offset out of range"); \
|
|
||||||
goto fail; \
|
|
||||||
} \
|
|
||||||
wasm_loader_emit_int16(loader_ctx, offset); \
|
|
||||||
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define emit_label(opcode) \
|
||||||
|
do { \
|
||||||
|
uint32 label_addr = (uint32)(uintptr_t)handle_table[opcode]; \
|
||||||
|
/* emit uint32 label address in 32-bit target */ \
|
||||||
|
wasm_loader_emit_uint32(loader_ctx, label_addr); \
|
||||||
|
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
#define skip_label() \
|
#define skip_label() \
|
||||||
do { \
|
do { \
|
||||||
wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); \
|
wasm_loader_emit_backspace(loader_ctx, sizeof(int32)); \
|
||||||
LOG_OP("\ndelete last op\n"); \
|
LOG_OP("\ndelete last op\n"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
|
@ -5733,12 +5766,6 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
||||||
(void)error_buf;
|
(void)error_buf;
|
||||||
(void)error_buf_size;
|
(void)error_buf_size;
|
||||||
return true;
|
return true;
|
||||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
|
|
||||||
fail:
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -7018,7 +7045,7 @@ wasm_loader_get_custom_section(WASMModule *module, const char *name,
|
||||||
section = section->next;
|
section = section->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -7130,6 +7157,7 @@ re_scan:
|
||||||
BlockType block_type;
|
BlockType block_type;
|
||||||
|
|
||||||
p_org = p - 1;
|
p_org = p - 1;
|
||||||
|
CHECK_BUF(p, p_end, 1);
|
||||||
value_type = read_uint8(p);
|
value_type = read_uint8(p);
|
||||||
if (is_byte_a_type(value_type)) {
|
if (is_byte_a_type(value_type)) {
|
||||||
/* If the first byte is one of these special values:
|
/* If the first byte is one of these special values:
|
||||||
|
@ -7183,10 +7211,7 @@ re_scan:
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
if (opcode == WASM_OP_BLOCK) {
|
if (opcode == WASM_OP_BLOCK || opcode == WASM_OP_LOOP) {
|
||||||
skip_label();
|
|
||||||
}
|
|
||||||
else if (opcode == WASM_OP_LOOP) {
|
|
||||||
skip_label();
|
skip_label();
|
||||||
if (BLOCK_HAS_PARAM(block_type)) {
|
if (BLOCK_HAS_PARAM(block_type)) {
|
||||||
/* Make sure params are in dynamic space */
|
/* Make sure params are in dynamic space */
|
||||||
|
@ -7194,9 +7219,11 @@ re_scan:
|
||||||
loader_ctx, false, error_buf, error_buf_size))
|
loader_ctx, false, error_buf, error_buf_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (opcode == WASM_OP_LOOP) {
|
||||||
(loader_ctx->frame_csp - 1)->code_compiled =
|
(loader_ctx->frame_csp - 1)->code_compiled =
|
||||||
loader_ctx->p_code_compiled;
|
loader_ctx->p_code_compiled;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (opcode == WASM_OP_IF) {
|
else if (opcode == WASM_OP_IF) {
|
||||||
/* If block has parameters, we should make sure they are in
|
/* If block has parameters, we should make sure they are in
|
||||||
* dynamic space. Otherwise, when else branch is missing,
|
* dynamic space. Otherwise, when else branch is missing,
|
||||||
|
@ -7435,6 +7462,9 @@ re_scan:
|
||||||
if (frame_csp_tmp->label_type != LABEL_TYPE_LOOP)
|
if (frame_csp_tmp->label_type != LABEL_TYPE_LOOP)
|
||||||
ret_count = block_type_get_result_types(
|
ret_count = block_type_get_result_types(
|
||||||
&frame_csp_tmp->block_type, &ret_types);
|
&frame_csp_tmp->block_type, &ret_types);
|
||||||
|
else
|
||||||
|
ret_count = block_type_get_param_types(
|
||||||
|
&frame_csp_tmp->block_type, &ret_types);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint8 *tmp_ret_types = NULL;
|
uint8 *tmp_ret_types = NULL;
|
||||||
|
@ -7445,6 +7475,9 @@ re_scan:
|
||||||
if (frame_csp_tmp->label_type != LABEL_TYPE_LOOP)
|
if (frame_csp_tmp->label_type != LABEL_TYPE_LOOP)
|
||||||
tmp_ret_count = block_type_get_result_types(
|
tmp_ret_count = block_type_get_result_types(
|
||||||
&frame_csp_tmp->block_type, &tmp_ret_types);
|
&frame_csp_tmp->block_type, &tmp_ret_types);
|
||||||
|
else
|
||||||
|
tmp_ret_count = block_type_get_param_types(
|
||||||
|
&frame_csp_tmp->block_type, &tmp_ret_types);
|
||||||
|
|
||||||
if (ret_count != tmp_ret_count
|
if (ret_count != tmp_ret_count
|
||||||
|| (ret_count
|
|| (ret_count
|
||||||
|
@ -7737,7 +7770,8 @@ re_scan:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (available_stack_cell > 0) {
|
if (available_stack_cell > 0) {
|
||||||
if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
|
if (is_32bit_type(*(loader_ctx->frame_ref - 1))
|
||||||
|
|| *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
|
||||||
loader_ctx->frame_ref--;
|
loader_ctx->frame_ref--;
|
||||||
loader_ctx->stack_cell_num--;
|
loader_ctx->stack_cell_num--;
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
@ -7793,6 +7827,9 @@ re_scan:
|
||||||
uint8 ref_type;
|
uint8 ref_type;
|
||||||
BranchBlock *cur_block = loader_ctx->frame_csp - 1;
|
BranchBlock *cur_block = loader_ctx->frame_csp - 1;
|
||||||
int32 available_stack_cell;
|
int32 available_stack_cell;
|
||||||
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
|
||||||
|
#endif
|
||||||
|
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
|
||||||
|
@ -7821,26 +7858,26 @@ 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_64;
|
uint8 opcode_tmp = WASM_OP_SELECT_64;
|
||||||
uint8 *p_code_compiled_tmp =
|
|
||||||
loader_ctx->p_code_compiled - 2;
|
|
||||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||||
*(void **)(p_code_compiled_tmp
|
*(void **)(p_code_compiled_tmp
|
||||||
- sizeof(void *)) =
|
- sizeof(void *)) =
|
||||||
handle_table[opcode_tmp];
|
handle_table[opcode_tmp];
|
||||||
#else
|
#else
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
/* emit int32 relative offset in 64-bit target
|
||||||
|
*/
|
||||||
int32 offset =
|
int32 offset =
|
||||||
(int32)((uint8 *)handle_table[opcode_tmp]
|
(int32)((uint8 *)handle_table[opcode_tmp]
|
||||||
- (uint8 *)handle_table[0]);
|
- (uint8 *)handle_table[0]);
|
||||||
if (!(offset >= INT16_MIN
|
*(int32 *)(p_code_compiled_tmp
|
||||||
&& offset < INT16_MAX)) {
|
- sizeof(int32)) = offset;
|
||||||
set_error_buf(error_buf, error_buf_size,
|
#else
|
||||||
"pre-compiled label offset "
|
/* emit uint32 label address in 32-bit target */
|
||||||
"out of range");
|
*(uint32 *)(p_code_compiled_tmp
|
||||||
goto fail;
|
- sizeof(uint32)) =
|
||||||
}
|
(uint32)(uintptr_t)handle_table[opcode_tmp];
|
||||||
*(int16 *)(p_code_compiled_tmp
|
#endif
|
||||||
- sizeof(int16)) = (int16)offset;
|
|
||||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||||
|
@ -7934,16 +7971,17 @@ re_scan:
|
||||||
*(void **)(p_code_compiled_tmp - sizeof(void *)) =
|
*(void **)(p_code_compiled_tmp - sizeof(void *)) =
|
||||||
handle_table[opcode_tmp];
|
handle_table[opcode_tmp];
|
||||||
#else
|
#else
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
/* emit int32 relative offset in 64-bit target */
|
||||||
int32 offset = (int32)((uint8 *)handle_table[opcode_tmp]
|
int32 offset = (int32)((uint8 *)handle_table[opcode_tmp]
|
||||||
- (uint8 *)handle_table[0]);
|
- (uint8 *)handle_table[0]);
|
||||||
if (!(offset >= INT16_MIN && offset < INT16_MAX)) {
|
*(int32 *)(p_code_compiled_tmp - sizeof(int32)) =
|
||||||
set_error_buf(
|
offset;
|
||||||
error_buf, error_buf_size,
|
#else
|
||||||
"pre-compiled label offset out of range");
|
/* emit uint32 label address in 32-bit target */
|
||||||
goto fail;
|
*(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) =
|
||||||
}
|
(uint32)(uintptr_t)handle_table[opcode_tmp];
|
||||||
*(int16 *)(p_code_compiled_tmp - sizeof(int16)) =
|
#endif
|
||||||
(int16)offset;
|
|
||||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||||
|
@ -9087,6 +9125,7 @@ re_scan:
|
||||||
{
|
{
|
||||||
uint32 opcode1;
|
uint32 opcode1;
|
||||||
|
|
||||||
|
CHECK_BUF(p, p_end, 1);
|
||||||
opcode1 = read_uint8(p);
|
opcode1 = read_uint8(p);
|
||||||
/* follow the order of enum WASMSimdEXTOpcode in wasm_opcode.h
|
/* follow the order of enum WASMSimdEXTOpcode in wasm_opcode.h
|
||||||
*/
|
*/
|
||||||
|
@ -9748,6 +9787,7 @@ re_scan:
|
||||||
{
|
{
|
||||||
uint32 opcode1;
|
uint32 opcode1;
|
||||||
|
|
||||||
|
CHECK_BUF(p, p_end, 1);
|
||||||
opcode1 = read_uint8(p);
|
opcode1 = read_uint8(p);
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
emit_byte(loader_ctx, opcode1);
|
emit_byte(loader_ctx, opcode1);
|
||||||
|
|
|
@ -1877,6 +1877,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
|
||||||
option.opt_level = llvm_jit_options.opt_level;
|
option.opt_level = llvm_jit_options.opt_level;
|
||||||
option.size_level = llvm_jit_options.size_level;
|
option.size_level = llvm_jit_options.size_level;
|
||||||
option.segue_flags = llvm_jit_options.segue_flags;
|
option.segue_flags = llvm_jit_options.segue_flags;
|
||||||
|
option.linux_perf_support = llvm_jit_options.linux_perf_support;
|
||||||
|
|
||||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
option.enable_bulk_memory = true;
|
option.enable_bulk_memory = true;
|
||||||
|
@ -4009,21 +4010,27 @@ wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf,
|
||||||
LOG_OP("\ndelete last op\n"); \
|
LOG_OP("\ndelete last op\n"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
#define emit_label(opcode) \
|
#define emit_label(opcode) \
|
||||||
do { \
|
do { \
|
||||||
int32 offset = \
|
int32 offset = \
|
||||||
(int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \
|
(int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \
|
||||||
if (!(offset >= INT16_MIN && offset < INT16_MAX)) { \
|
/* emit int32 relative offset in 64-bit target */ \
|
||||||
set_error_buf(error_buf, error_buf_size, \
|
wasm_loader_emit_uint32(loader_ctx, offset); \
|
||||||
"pre-compiled label offset out of range"); \
|
|
||||||
goto fail; \
|
|
||||||
} \
|
|
||||||
wasm_loader_emit_int16(loader_ctx, offset); \
|
|
||||||
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define emit_label(opcode) \
|
||||||
|
do { \
|
||||||
|
uint32 label_addr = (uint32)(uintptr_t)handle_table[opcode]; \
|
||||||
|
/* emit uint32 label address in 32-bit target */ \
|
||||||
|
wasm_loader_emit_uint32(loader_ctx, label_addr); \
|
||||||
|
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
#define skip_label() \
|
#define skip_label() \
|
||||||
do { \
|
do { \
|
||||||
wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); \
|
wasm_loader_emit_backspace(loader_ctx, sizeof(int32)); \
|
||||||
LOG_OP("\ndelete last op\n"); \
|
LOG_OP("\ndelete last op\n"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
|
@ -4351,13 +4358,6 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
|
|
||||||
fail:
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -5627,10 +5627,7 @@ re_scan:
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
if (opcode == WASM_OP_BLOCK) {
|
if (opcode == WASM_OP_BLOCK || opcode == WASM_OP_LOOP) {
|
||||||
skip_label();
|
|
||||||
}
|
|
||||||
else if (opcode == WASM_OP_LOOP) {
|
|
||||||
skip_label();
|
skip_label();
|
||||||
if (BLOCK_HAS_PARAM(block_type)) {
|
if (BLOCK_HAS_PARAM(block_type)) {
|
||||||
/* Make sure params are in dynamic space */
|
/* Make sure params are in dynamic space */
|
||||||
|
@ -5638,9 +5635,11 @@ re_scan:
|
||||||
loader_ctx, false, error_buf, error_buf_size))
|
loader_ctx, false, error_buf, error_buf_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (opcode == WASM_OP_LOOP) {
|
||||||
(loader_ctx->frame_csp - 1)->code_compiled =
|
(loader_ctx->frame_csp - 1)->code_compiled =
|
||||||
loader_ctx->p_code_compiled;
|
loader_ctx->p_code_compiled;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (opcode == WASM_OP_IF) {
|
else if (opcode == WASM_OP_IF) {
|
||||||
/* If block has parameters, we should make sure they are in
|
/* If block has parameters, we should make sure they are in
|
||||||
* dynamic space. Otherwise, when else branch is missing,
|
* dynamic space. Otherwise, when else branch is missing,
|
||||||
|
@ -6100,7 +6099,8 @@ re_scan:
|
||||||
&& !cur_block->is_stack_polymorphic));
|
&& !cur_block->is_stack_polymorphic));
|
||||||
|
|
||||||
if (available_stack_cell > 0) {
|
if (available_stack_cell > 0) {
|
||||||
if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
|
if (is_32bit_type(*(loader_ctx->frame_ref - 1))
|
||||||
|
|| *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
|
||||||
loader_ctx->frame_ref--;
|
loader_ctx->frame_ref--;
|
||||||
loader_ctx->stack_cell_num--;
|
loader_ctx->stack_cell_num--;
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
@ -6146,6 +6146,9 @@ re_scan:
|
||||||
uint8 ref_type;
|
uint8 ref_type;
|
||||||
BranchBlock *cur_block = loader_ctx->frame_csp - 1;
|
BranchBlock *cur_block = loader_ctx->frame_csp - 1;
|
||||||
int32 available_stack_cell;
|
int32 available_stack_cell;
|
||||||
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
|
||||||
|
#endif
|
||||||
|
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
|
||||||
|
@ -6168,26 +6171,26 @@ 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_64;
|
uint8 opcode_tmp = WASM_OP_SELECT_64;
|
||||||
uint8 *p_code_compiled_tmp =
|
|
||||||
loader_ctx->p_code_compiled - 2;
|
|
||||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||||
*(void **)(p_code_compiled_tmp
|
*(void **)(p_code_compiled_tmp
|
||||||
- sizeof(void *)) =
|
- sizeof(void *)) =
|
||||||
handle_table[opcode_tmp];
|
handle_table[opcode_tmp];
|
||||||
#else
|
#else
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
/* emit int32 relative offset in 64-bit target
|
||||||
|
*/
|
||||||
int32 offset =
|
int32 offset =
|
||||||
(int32)((uint8 *)handle_table[opcode_tmp]
|
(int32)((uint8 *)handle_table[opcode_tmp]
|
||||||
- (uint8 *)handle_table[0]);
|
- (uint8 *)handle_table[0]);
|
||||||
if (!(offset >= INT16_MIN
|
*(int32 *)(p_code_compiled_tmp
|
||||||
&& offset < INT16_MAX)) {
|
- sizeof(int32)) = offset;
|
||||||
set_error_buf(error_buf, error_buf_size,
|
#else
|
||||||
"pre-compiled label offset "
|
/* emit uint32 label address in 32-bit target */
|
||||||
"out of range");
|
*(uint32 *)(p_code_compiled_tmp
|
||||||
goto fail;
|
- sizeof(uint32)) =
|
||||||
}
|
(uint32)(uintptr_t)handle_table[opcode_tmp];
|
||||||
*(int16 *)(p_code_compiled_tmp
|
#endif
|
||||||
- sizeof(int16)) = (int16)offset;
|
|
||||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||||
|
@ -6263,15 +6266,16 @@ re_scan:
|
||||||
*(void **)(p_code_compiled_tmp - sizeof(void *)) =
|
*(void **)(p_code_compiled_tmp - sizeof(void *)) =
|
||||||
handle_table[opcode_tmp];
|
handle_table[opcode_tmp];
|
||||||
#else
|
#else
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
/* emit int32 relative offset in 64-bit target */
|
||||||
int32 offset = (int32)((uint8 *)handle_table[opcode_tmp]
|
int32 offset = (int32)((uint8 *)handle_table[opcode_tmp]
|
||||||
- (uint8 *)handle_table[0]);
|
- (uint8 *)handle_table[0]);
|
||||||
if (!(offset >= INT16_MIN && offset < INT16_MAX)) {
|
*(int32 *)(p_code_compiled_tmp - sizeof(int32)) = offset;
|
||||||
set_error_buf(error_buf, error_buf_size,
|
#else
|
||||||
"pre-compiled label offset out of range");
|
/* emit uint32 label address in 32-bit target */
|
||||||
goto fail;
|
*(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) =
|
||||||
}
|
(uint32)(uintptr_t)handle_table[opcode_tmp];
|
||||||
*(int16 *)(p_code_compiled_tmp - sizeof(int16)) =
|
#endif
|
||||||
(int16)offset;
|
|
||||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "bh_log.h"
|
#include "bh_log.h"
|
||||||
#include "mem_alloc.h"
|
#include "mem_alloc.h"
|
||||||
#include "../common/wasm_runtime_common.h"
|
#include "../common/wasm_runtime_common.h"
|
||||||
|
#include "../common/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"
|
||||||
#endif
|
#endif
|
||||||
|
@ -167,7 +168,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
char *error_buf, uint32 error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
WASMModule *module = module_inst->module;
|
WASMModule *module = module_inst->module;
|
||||||
uint64 memory_data_size;
|
uint64 memory_data_size, max_memory_data_size;
|
||||||
uint32 heap_offset = num_bytes_per_page * init_page_count;
|
uint32 heap_offset = num_bytes_per_page * init_page_count;
|
||||||
uint32 inc_page_count, aux_heap_base, global_idx;
|
uint32 inc_page_count, aux_heap_base, global_idx;
|
||||||
uint32 bytes_of_last_page, bytes_to_page_end;
|
uint32 bytes_of_last_page, bytes_to_page_end;
|
||||||
|
@ -275,6 +276,12 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
if (max_page_count > DEFAULT_MAX_PAGES)
|
if (max_page_count > DEFAULT_MAX_PAGES)
|
||||||
max_page_count = DEFAULT_MAX_PAGES;
|
max_page_count = DEFAULT_MAX_PAGES;
|
||||||
}
|
}
|
||||||
|
else { /* heap_size == 0 */
|
||||||
|
if (init_page_count == DEFAULT_MAX_PAGES) {
|
||||||
|
num_bytes_per_page = UINT32_MAX;
|
||||||
|
init_page_count = max_page_count = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG_VERBOSE("Memory instantiate:");
|
LOG_VERBOSE("Memory instantiate:");
|
||||||
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
||||||
|
@ -282,22 +289,33 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size);
|
LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size);
|
||||||
|
|
||||||
memory_data_size = (uint64)num_bytes_per_page * init_page_count;
|
memory_data_size = (uint64)num_bytes_per_page * init_page_count;
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
|
||||||
if (is_shared_memory) {
|
bh_assert(memory_data_size <= UINT32_MAX);
|
||||||
/* Allocate max page for shared memory */
|
bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB);
|
||||||
memory_data_size = (uint64)num_bytes_per_page * max_page_count;
|
(void)max_memory_data_size;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bh_assert(memory_data_size <= 4 * (uint64)BH_GB);
|
|
||||||
|
|
||||||
bh_assert(memory != NULL);
|
bh_assert(memory != NULL);
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
if (memory_data_size > 0
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
&& !(memory->memory_data =
|
if (is_shared_memory) {
|
||||||
runtime_malloc(memory_data_size, error_buf, error_buf_size))) {
|
/* Allocate maximum memory size when memory is shared */
|
||||||
|
if (max_memory_data_size > 0
|
||||||
|
&& !(memory->memory_data = runtime_malloc(
|
||||||
|
max_memory_data_size, error_buf, error_buf_size))) {
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Allocate initial memory size when memory is not shared */
|
||||||
|
if (memory_data_size > 0
|
||||||
|
&& !(memory->memory_data = runtime_malloc(
|
||||||
|
memory_data_size, error_buf, error_buf_size))) {
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* else of OS_ENABLE_HW_BOUND_CHECK */
|
||||||
memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1);
|
memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1);
|
||||||
|
|
||||||
/* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
|
/* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
|
||||||
|
@ -306,13 +324,15 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
* so the range of ea is 0 to 8G
|
* so the range of ea is 0 to 8G
|
||||||
*/
|
*/
|
||||||
if (!(memory->memory_data = mapped_mem =
|
if (!(memory->memory_data = mapped_mem =
|
||||||
os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
|
os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BH_PLATFORM_WINDOWS
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
if (!os_mem_commit(mapped_mem, memory_data_size,
|
if (memory_data_size > 0
|
||||||
|
&& !os_mem_commit(mapped_mem, memory_data_size,
|
||||||
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
||||||
set_error_buf(error_buf, error_buf_size, "commit memory failed");
|
set_error_buf(error_buf, error_buf_size, "commit memory failed");
|
||||||
os_munmap(mapped_mem, map_size);
|
os_munmap(mapped_mem, map_size);
|
||||||
|
@ -326,12 +346,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
|
set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Newly allocated pages are filled with zero by the OS, we don't fill it
|
/* Newly allocated pages are filled with zero by the OS, we don't fill it
|
||||||
* again here */
|
* again here */
|
||||||
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
|
||||||
|
|
||||||
if (memory_data_size > UINT32_MAX)
|
if (memory_data_size > UINT32_MAX)
|
||||||
memory_data_size = (uint32)memory_data_size;
|
memory_data_size = UINT32_MAX;
|
||||||
|
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
||||||
|
|
||||||
memory->module_type = Wasm_Module_Bytecode;
|
memory->module_type = Wasm_Module_Bytecode;
|
||||||
memory->num_bytes_per_page = num_bytes_per_page;
|
memory->num_bytes_per_page = num_bytes_per_page;
|
||||||
|
@ -359,26 +380,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0
|
|
||||||
if (memory_data_size > 0) {
|
if (memory_data_size > 0) {
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
wasm_runtime_set_mem_bound_check_bytes(memory, memory_data_size);
|
||||||
memory->mem_bound_check_1byte.u64 = memory_data_size - 1;
|
|
||||||
memory->mem_bound_check_2bytes.u64 = memory_data_size - 2;
|
|
||||||
memory->mem_bound_check_4bytes.u64 = memory_data_size - 4;
|
|
||||||
memory->mem_bound_check_8bytes.u64 = memory_data_size - 8;
|
|
||||||
memory->mem_bound_check_16bytes.u64 = memory_data_size - 16;
|
|
||||||
#else
|
|
||||||
memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1;
|
|
||||||
memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2;
|
|
||||||
memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4;
|
|
||||||
memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8;
|
|
||||||
memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
if (is_shared_memory) {
|
if (is_shared_memory) {
|
||||||
|
memory->is_shared_memory = 1;
|
||||||
memory->ref_count = 1;
|
memory->ref_count = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1054,7 +1062,8 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
|
||||||
wasm functions, and ensure that the exec_env's module inst
|
wasm functions, and ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_main = exec_env_main->module_inst;
|
module_inst_main = exec_env_main->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Try using the existing exec_env */
|
/* Try using the existing exec_env */
|
||||||
|
@ -1079,7 +1088,8 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_main = exec_env->module_inst;
|
module_inst_main = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1112,12 +1122,12 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
|
||||||
fail:
|
fail:
|
||||||
if (is_sub_inst) {
|
if (is_sub_inst) {
|
||||||
/* Restore the parent exec_env's module inst */
|
/* Restore the parent exec_env's module inst */
|
||||||
exec_env_main->module_inst = module_inst_main;
|
wasm_exec_env_restore_module_inst(exec_env_main, module_inst_main);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (module_inst_main)
|
if (module_inst_main)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_main;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_main);
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
}
|
}
|
||||||
|
@ -1186,7 +1196,8 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_old = exec_env->module_inst;
|
module_inst_old = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,7 +1208,7 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (module_inst_old)
|
if (module_inst_old)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_old;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
|
||||||
|
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
|
@ -1253,7 +1264,8 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_old = exec_env->module_inst;
|
module_inst_old = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1261,7 +1273,7 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (module_inst_old)
|
if (module_inst_old)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_old;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
|
||||||
|
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
|
@ -1654,6 +1666,31 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
|
if (module->data_seg_count > 0) {
|
||||||
|
module_inst->e->common.data_dropped =
|
||||||
|
bh_bitmap_new(0, module->data_seg_count);
|
||||||
|
if (module_inst->e->common.data_dropped == NULL) {
|
||||||
|
LOG_DEBUG("failed to allocate bitmaps");
|
||||||
|
set_error_buf(error_buf, error_buf_size,
|
||||||
|
"failed to allocate bitmaps");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
if (module->table_seg_count > 0) {
|
||||||
|
module_inst->e->common.elem_dropped =
|
||||||
|
bh_bitmap_new(0, module->table_seg_count);
|
||||||
|
if (module_inst->e->common.elem_dropped == NULL) {
|
||||||
|
LOG_DEBUG("failed to allocate bitmaps");
|
||||||
|
set_error_buf(error_buf, error_buf_size,
|
||||||
|
"failed to allocate bitmaps");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||||
if (!(module_inst->frames = runtime_malloc((uint64)sizeof(Vector),
|
if (!(module_inst->frames = runtime_malloc((uint64)sizeof(Vector),
|
||||||
error_buf, error_buf_size))) {
|
error_buf, error_buf_size))) {
|
||||||
|
@ -1779,6 +1816,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||||
if (data_seg->is_passive)
|
if (data_seg->is_passive)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
if (is_sub_inst)
|
||||||
|
/* Ignore setting memory init data if the memory has been
|
||||||
|
initialized */
|
||||||
|
continue;
|
||||||
|
|
||||||
/* has check it in loader */
|
/* has check it in loader */
|
||||||
memory = module_inst->memories[data_seg->memory_index];
|
memory = module_inst->memories[data_seg->memory_index];
|
||||||
|
@ -2173,6 +2214,13 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
||||||
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
|
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
|
bh_bitmap_delete(module_inst->e->common.data_dropped);
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
bh_bitmap_delete(module_inst->e->common.elem_dropped);
|
||||||
|
#endif
|
||||||
|
|
||||||
wasm_runtime_free(module_inst);
|
wasm_runtime_free(module_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2371,14 +2419,16 @@ wasm_dump_perf_profiling(const WASMModuleInstance *module_inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func_name)
|
if (func_name)
|
||||||
os_printf(" func %s, execution time: %.3f ms, execution count: %d "
|
os_printf(
|
||||||
"times\n",
|
" func %s, execution time: %.3f ms, execution count: %" PRIu32
|
||||||
|
" times\n",
|
||||||
func_name,
|
func_name,
|
||||||
module_inst->e->functions[i].total_exec_time / 1000.0f,
|
module_inst->e->functions[i].total_exec_time / 1000.0f,
|
||||||
module_inst->e->functions[i].total_exec_cnt);
|
module_inst->e->functions[i].total_exec_cnt);
|
||||||
else
|
else
|
||||||
os_printf(" func %d, execution time: %.3f ms, execution count: %d "
|
os_printf(" func %" PRIu32
|
||||||
"times\n",
|
", execution time: %.3f ms, execution count: %" PRIu32
|
||||||
|
" times\n",
|
||||||
i, module_inst->e->functions[i].total_exec_time / 1000.0f,
|
i, module_inst->e->functions[i].total_exec_time / 1000.0f,
|
||||||
module_inst->e->functions[i].total_exec_cnt);
|
module_inst->e->functions[i].total_exec_cnt);
|
||||||
}
|
}
|
||||||
|
@ -2472,15 +2522,20 @@ void
|
||||||
wasm_module_free_internal(WASMModuleInstance *module_inst,
|
wasm_module_free_internal(WASMModuleInstance *module_inst,
|
||||||
WASMExecEnv *exec_env, uint32 ptr)
|
WASMExecEnv *exec_env, uint32 ptr)
|
||||||
{
|
{
|
||||||
if (ptr) {
|
|
||||||
WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
|
WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
|
||||||
uint8 *addr;
|
|
||||||
|
|
||||||
if (!memory) {
|
if (!memory) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = memory->memory_data + ptr;
|
if (ptr) {
|
||||||
|
uint8 *addr = memory->memory_data + ptr;
|
||||||
|
uint8 *memory_data_end;
|
||||||
|
|
||||||
|
/* memory->memory_data_end may be changed in memory grow */
|
||||||
|
SHARED_MEMORY_LOCK(memory);
|
||||||
|
memory_data_end = memory->memory_data_end;
|
||||||
|
SHARED_MEMORY_UNLOCK(memory);
|
||||||
|
|
||||||
if (memory->heap_handle && memory->heap_data <= addr
|
if (memory->heap_handle && memory->heap_data <= addr
|
||||||
&& addr < memory->heap_data_end) {
|
&& addr < memory->heap_data_end) {
|
||||||
|
@ -2488,7 +2543,7 @@ wasm_module_free_internal(WASMModuleInstance *module_inst,
|
||||||
}
|
}
|
||||||
else if (module_inst->e->malloc_function
|
else if (module_inst->e->malloc_function
|
||||||
&& module_inst->e->free_function && memory->memory_data <= addr
|
&& module_inst->e->free_function && memory->memory_data <= addr
|
||||||
&& addr < memory->memory_data_end) {
|
&& addr < memory_data_end) {
|
||||||
execute_free_function(module_inst, exec_env,
|
execute_free_function(module_inst, exec_env,
|
||||||
module_inst->e->free_function, ptr);
|
module_inst->e->free_function, ptr);
|
||||||
}
|
}
|
||||||
|
@ -3127,16 +3182,23 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
|
||||||
{
|
{
|
||||||
WASMMemoryInstance *memory_inst;
|
WASMMemoryInstance *memory_inst;
|
||||||
WASMModule *module;
|
WASMModule *module;
|
||||||
uint8 *data = NULL;
|
uint8 *data;
|
||||||
uint8 *maddr;
|
uint8 *maddr;
|
||||||
uint64 seg_len = 0;
|
uint64 seg_len;
|
||||||
|
|
||||||
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
|
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
|
||||||
|
|
||||||
memory_inst = wasm_get_default_memory(module_inst);
|
memory_inst = wasm_get_default_memory(module_inst);
|
||||||
|
|
||||||
|
if (bh_bitmap_get_bit(module_inst->e->common.data_dropped, seg_index)) {
|
||||||
|
seg_len = 0;
|
||||||
|
data = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
module = module_inst->module;
|
module = module_inst->module;
|
||||||
seg_len = module->data_segments[seg_index]->data_length;
|
seg_len = module->data_segments[seg_index]->data_length;
|
||||||
data = module->data_segments[seg_index]->data;
|
data = module->data_segments[seg_index]->data;
|
||||||
|
}
|
||||||
|
|
||||||
if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
|
if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
|
||||||
dst, len))
|
dst, len))
|
||||||
|
@ -3150,7 +3212,9 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
|
||||||
maddr = wasm_runtime_addr_app_to_native(
|
maddr = wasm_runtime_addr_app_to_native(
|
||||||
(WASMModuleInstanceCommon *)module_inst, dst);
|
(WASMModuleInstanceCommon *)module_inst, dst);
|
||||||
|
|
||||||
|
SHARED_MEMORY_LOCK(memory_inst);
|
||||||
bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
|
bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
|
||||||
|
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3159,7 +3223,7 @@ llvm_jit_data_drop(WASMModuleInstance *module_inst, uint32 seg_index)
|
||||||
{
|
{
|
||||||
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
|
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
|
||||||
|
|
||||||
module_inst->module->data_segments[seg_index]->data_length = 0;
|
bh_bitmap_set_bit(module_inst->e->common.data_dropped, seg_index);
|
||||||
/* Currently we can't free the dropped data segment
|
/* Currently we can't free the dropped data segment
|
||||||
as they are stored in wasm bytecode */
|
as they are stored in wasm bytecode */
|
||||||
return true;
|
return true;
|
||||||
|
@ -3170,12 +3234,8 @@ llvm_jit_data_drop(WASMModuleInstance *module_inst, uint32 seg_index)
|
||||||
void
|
void
|
||||||
llvm_jit_drop_table_seg(WASMModuleInstance *module_inst, uint32 tbl_seg_idx)
|
llvm_jit_drop_table_seg(WASMModuleInstance *module_inst, uint32 tbl_seg_idx)
|
||||||
{
|
{
|
||||||
WASMTableSeg *tbl_segs;
|
|
||||||
|
|
||||||
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
|
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
|
||||||
|
bh_bitmap_set_bit(module_inst->e->common.elem_dropped, tbl_seg_idx);
|
||||||
tbl_segs = module_inst->module->table_segments;
|
|
||||||
tbl_segs[tbl_seg_idx].is_dropped = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -3204,7 +3264,7 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tbl_seg->is_dropped) {
|
if (bh_bitmap_get_bit(module_inst->e->common.elem_dropped, tbl_seg_idx)) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "wasm.h"
|
#include "wasm.h"
|
||||||
#include "bh_atomic.h"
|
#include "bh_atomic.h"
|
||||||
|
#include "bh_bitmap.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,8 +80,16 @@ typedef union {
|
||||||
struct WASMMemoryInstance {
|
struct WASMMemoryInstance {
|
||||||
/* Module type */
|
/* Module type */
|
||||||
uint32 module_type;
|
uint32 module_type;
|
||||||
/* Shared memory flag */
|
|
||||||
bh_atomic_32_t ref_count; /* 0: non-shared, > 0: reference count */
|
/* Whether the memory is shared */
|
||||||
|
uint8 is_shared_memory;
|
||||||
|
|
||||||
|
/* One byte padding */
|
||||||
|
uint8 __padding__;
|
||||||
|
|
||||||
|
/* Reference count of the memory instance:
|
||||||
|
0: non-shared memory, > 0: shared memory */
|
||||||
|
bh_atomic_16_t ref_count;
|
||||||
|
|
||||||
/* Number bytes per page */
|
/* Number bytes per page */
|
||||||
uint32 num_bytes_per_page;
|
uint32 num_bytes_per_page;
|
||||||
|
@ -216,10 +225,16 @@ typedef struct WASMModuleInstanceExtraCommon {
|
||||||
CApiFuncImport *c_api_func_imports;
|
CApiFuncImport *c_api_func_imports;
|
||||||
/* pointer to the exec env currently used */
|
/* pointer to the exec env currently used */
|
||||||
WASMExecEnv *cur_exec_env;
|
WASMExecEnv *cur_exec_env;
|
||||||
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
|
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||||
/* Disable bounds checks or not */
|
/* Disable bounds checks or not */
|
||||||
bool disable_bounds_checks;
|
bool disable_bounds_checks;
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
|
bh_bitmap *data_dropped;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
bh_bitmap *elem_dropped;
|
||||||
|
#endif
|
||||||
} WASMModuleInstanceExtraCommon;
|
} WASMModuleInstanceExtraCommon;
|
||||||
|
|
||||||
/* Extra info of WASM module instance for interpreter/jit mode */
|
/* Extra info of WASM module instance for interpreter/jit mode */
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "lib_rats_common.h"
|
#include "lib_rats_common.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
librats_collect_wrapper(wasm_exec_env_t exec_env, char **evidence_json,
|
librats_collect_wrapper(wasm_exec_env_t exec_env, uint32_t *evidence_json,
|
||||||
const char *buffer, uint32_t buffer_size)
|
const char *buffer, uint32_t buffer_size)
|
||||||
{
|
{
|
||||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||||
|
@ -47,7 +47,7 @@ librats_collect_wrapper(wasm_exec_env_t exec_env, char **evidence_json,
|
||||||
return (int)RATS_ATTESTER_ERR_NO_MEM;
|
return (int)RATS_ATTESTER_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
bh_memcpy_s(str_ret, json_size, json, json_size);
|
bh_memcpy_s(str_ret, json_size, json, json_size);
|
||||||
*((int *)evidence_json) = str_ret_offset;
|
*evidence_json = str_ret_offset;
|
||||||
free(json);
|
free(json);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -96,6 +96,15 @@ librats_parse_evidence_wrapper(wasm_exec_env_t exec_env,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
librats_dispose_evidence_json_wrapper(wasm_exec_env_t exec_env,
|
||||||
|
uint32_t evidence_json)
|
||||||
|
{
|
||||||
|
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||||
|
|
||||||
|
module_free(evidence_json);
|
||||||
|
}
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||||
{ #func_name, func_name##_wrapper, signature, NULL }
|
{ #func_name, func_name##_wrapper, signature, NULL }
|
||||||
|
@ -104,7 +113,8 @@ librats_parse_evidence_wrapper(wasm_exec_env_t exec_env,
|
||||||
static NativeSymbol native_symbols_lib_rats[] = {
|
static NativeSymbol native_symbols_lib_rats[] = {
|
||||||
REG_NATIVE_FUNC(librats_collect, "(**~)i"),
|
REG_NATIVE_FUNC(librats_collect, "(**~)i"),
|
||||||
REG_NATIVE_FUNC(librats_verify, "(*~*~)i"),
|
REG_NATIVE_FUNC(librats_verify, "(*~*~)i"),
|
||||||
REG_NATIVE_FUNC(librats_parse_evidence, "(*~*~)i")
|
REG_NATIVE_FUNC(librats_parse_evidence, "(*~*~)i"),
|
||||||
|
REG_NATIVE_FUNC(librats_dispose_evidence_json, "(i)")
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
|
|
@ -41,6 +41,9 @@ librats_parse_evidence(const char *evidence_json, uint32_t json_size,
|
||||||
evidence_json ? strlen(evidence_json) + 1 : 0, \
|
evidence_json ? strlen(evidence_json) + 1 : 0, \
|
||||||
evidence, sizeof(rats_sgx_evidence_t))
|
evidence, sizeof(rats_sgx_evidence_t))
|
||||||
|
|
||||||
|
void
|
||||||
|
librats_dispose_evidence_json(char *evidence_json);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
3
core/iwasm/libraries/lib-socket/test/manifest.json
Normal file
3
core/iwasm/libraries/lib-socket/test/manifest.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"name": "WAMR lib-socket tests"
|
||||||
|
}
|
|
@ -30,7 +30,16 @@
|
||||||
wasm_runtime_module_free(module_inst, offset)
|
wasm_runtime_module_free(module_inst, offset)
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
#define wasi_errno_t uvwasi_errno_t
|
// uvwasi_errno_t is typedef'd to uint16 which is correct according to the ABI
|
||||||
|
// specification. However, in WASM, the smallest integer type is int32. If we
|
||||||
|
// return uint16, we would rely on language SDKs to implement the correct
|
||||||
|
// behaviour of casting to uint16 before checking the value or using it any way.
|
||||||
|
// Failure to do so can cause tricky bugs as the upper 16 bits of the error
|
||||||
|
// result are not guaranteed to be zero'ed by us so the result essentially
|
||||||
|
// contains garbage from the WASM app perspective. To prevent this, we return
|
||||||
|
// uint32 directly instead so as not to be reliant on the correct behaviour of
|
||||||
|
// any current/future SDK implementations.
|
||||||
|
#define wasi_errno_t uint32_t
|
||||||
#define wasi_fd_t uvwasi_fd_t
|
#define wasi_fd_t uvwasi_fd_t
|
||||||
#define wasi_clockid_t uvwasi_clockid_t
|
#define wasi_clockid_t uvwasi_clockid_t
|
||||||
#define wasi_timestamp_t uvwasi_timestamp_t
|
#define wasi_timestamp_t uvwasi_timestamp_t
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "bh_platform.h"
|
#include "bh_platform.h"
|
||||||
#include "wasm_export.h"
|
#include "wasm_export.h"
|
||||||
#include "wasm_runtime_common.h"
|
#include "wasm_runtime_common.h"
|
||||||
|
#include "wasmtime_ssp.h"
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
#include "../../../thread-mgr/thread_manager.h"
|
#include "../../../thread-mgr/thread_manager.h"
|
||||||
|
@ -192,7 +193,7 @@ wasi_clock_res_get(wasm_exec_env_t exec_env,
|
||||||
if (!validate_native_addr(resolution, sizeof(wasi_timestamp_t)))
|
if (!validate_native_addr(resolution, sizeof(wasi_timestamp_t)))
|
||||||
return (wasi_errno_t)-1;
|
return (wasi_errno_t)-1;
|
||||||
|
|
||||||
return wasmtime_ssp_clock_res_get(clock_id, resolution);
|
return os_clock_res_get(clock_id, resolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
static wasi_errno_t
|
static wasi_errno_t
|
||||||
|
@ -206,7 +207,7 @@ wasi_clock_time_get(wasm_exec_env_t exec_env,
|
||||||
if (!validate_native_addr(time, sizeof(wasi_timestamp_t)))
|
if (!validate_native_addr(time, sizeof(wasi_timestamp_t)))
|
||||||
return (wasi_errno_t)-1;
|
return (wasi_errno_t)-1;
|
||||||
|
|
||||||
return wasmtime_ssp_clock_time_get(clock_id, precision, time);
|
return os_clock_time_get(clock_id, precision, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static wasi_errno_t
|
static wasi_errno_t
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#ifndef _LIBC_WASI_WRAPPER_H
|
#ifndef _LIBC_WASI_WRAPPER_H
|
||||||
#define _LIBC_WASI_WRAPPER_H
|
#define _LIBC_WASI_WRAPPER_H
|
||||||
|
|
||||||
#include "wasmtime_ssp.h"
|
|
||||||
#include "posix.h"
|
#include "posix.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -19,7 +18,16 @@ typedef __wasi_advice_t wasi_advice_t;
|
||||||
typedef __wasi_ciovec_t wasi_ciovec_t;
|
typedef __wasi_ciovec_t wasi_ciovec_t;
|
||||||
typedef __wasi_clockid_t wasi_clockid_t;
|
typedef __wasi_clockid_t wasi_clockid_t;
|
||||||
typedef __wasi_dircookie_t wasi_dircookie_t;
|
typedef __wasi_dircookie_t wasi_dircookie_t;
|
||||||
typedef __wasi_errno_t wasi_errno_t;
|
// __wasi_errno_t is typedef'd to uint16 which is correct according to the ABI
|
||||||
|
// specification. However, in WASM, the smallest integer type is int32. If we
|
||||||
|
// return uint16, we would rely on language SDKs to implement the correct
|
||||||
|
// behaviour of casting to uint16 before checking the value or using it any way.
|
||||||
|
// Failure to do so can cause tricky bugs as the upper 16 bits of the error
|
||||||
|
// result are not guaranteed to be zero'ed by us so the result essentially
|
||||||
|
// contains garbage from the WASM app perspective. To prevent this, we return
|
||||||
|
// uint32 directly instead so as not to be reliant on the correct behaviour of
|
||||||
|
// any current/future WASI SDK implemenations.
|
||||||
|
typedef uint32_t wasi_errno_t;
|
||||||
typedef __wasi_event_t wasi_event_t;
|
typedef __wasi_event_t wasi_event_t;
|
||||||
typedef __wasi_exitcode_t wasi_exitcode_t;
|
typedef __wasi_exitcode_t wasi_exitcode_t;
|
||||||
typedef __wasi_fdflags_t wasi_fdflags_t;
|
typedef __wasi_fdflags_t wasi_fdflags_t;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,99 +8,68 @@
|
||||||
#include "ssp_config.h"
|
#include "ssp_config.h"
|
||||||
#include "blocking_op.h"
|
#include "blocking_op.h"
|
||||||
|
|
||||||
int
|
__wasi_errno_t
|
||||||
blocking_op_close(wasm_exec_env_t exec_env, int fd)
|
blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
|
bool is_stdio)
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
errno = EINTR;
|
return __WASI_EINTR;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
int ret = close(fd);
|
__wasi_errno_t error = os_close(handle, is_stdio);
|
||||||
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
blocking_op_readv(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
|
const struct __wasi_iovec_t *iov, int iovcnt, size_t *nread)
|
||||||
|
{
|
||||||
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
|
return __WASI_EINTR;
|
||||||
|
}
|
||||||
|
__wasi_errno_t error = os_readv(handle, iov, iovcnt, nread);
|
||||||
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
blocking_op_preadv(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
|
const struct __wasi_iovec_t *iov, int iovcnt,
|
||||||
|
__wasi_filesize_t offset, size_t *nread)
|
||||||
|
{
|
||||||
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
|
return __WASI_EINTR;
|
||||||
|
}
|
||||||
|
__wasi_errno_t ret = os_preadv(handle, iov, iovcnt, offset, nread);
|
||||||
wasm_runtime_end_blocking_op(exec_env);
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
__wasi_errno_t
|
||||||
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
blocking_op_writev(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
int iovcnt)
|
const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
|
size_t *nwritten)
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
errno = EINTR;
|
return __WASI_EINTR;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
ssize_t ret = readv(fd, iov, iovcnt);
|
__wasi_errno_t error = os_writev(handle, iov, iovcnt, nwritten);
|
||||||
wasm_runtime_end_blocking_op(exec_env);
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
return ret;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_HAS_PREADV
|
__wasi_errno_t
|
||||||
ssize_t
|
blocking_op_pwritev(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
int iovcnt, off_t offset)
|
__wasi_filesize_t offset, size_t *nwritten)
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
errno = EINTR;
|
return __WASI_EINTR;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
ssize_t ret = preadv(fd, iov, iovcnt, offset);
|
__wasi_errno_t error = os_pwritev(handle, iov, iovcnt, offset, nwritten);
|
||||||
wasm_runtime_end_blocking_op(exec_env);
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
return ret;
|
return error;
|
||||||
}
|
}
|
||||||
#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
|
int
|
||||||
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
|
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
|
||||||
|
@ -187,15 +156,17 @@ blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
__wasi_errno_t
|
||||||
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
|
blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
int oflags, mode_t mode)
|
const char *path, __wasi_oflags_t oflags,
|
||||||
|
__wasi_fdflags_t fd_flags, __wasi_lookupflags_t lookup_flags,
|
||||||
|
wasi_libc_file_access_mode access_mode, os_file_handle *out)
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
errno = EINTR;
|
return __WASI_EINTR;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
int ret = openat(fd, path, oflags, mode);
|
__wasi_errno_t error = os_openat(handle, path, oflags, fd_flags,
|
||||||
|
lookup_flags, access_mode, out);
|
||||||
wasm_runtime_end_blocking_op(exec_env);
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
return ret;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,24 @@
|
||||||
#include "bh_platform.h"
|
#include "bh_platform.h"
|
||||||
#include "wasm_export.h"
|
#include "wasm_export.h"
|
||||||
|
|
||||||
int
|
__wasi_errno_t
|
||||||
blocking_op_close(wasm_exec_env_t exec_env, int fd);
|
blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
ssize_t
|
bool is_stdio);
|
||||||
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
__wasi_errno_t
|
||||||
int iovcnt);
|
blocking_op_readv(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
ssize_t
|
const struct __wasi_iovec_t *iov, int iovcnt, size_t *nread);
|
||||||
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
__wasi_errno_t
|
||||||
int iovcnt, off_t offset);
|
blocking_op_preadv(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
ssize_t
|
const struct __wasi_iovec_t *iov, int iovcnt,
|
||||||
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
|
__wasi_filesize_t offset, size_t *nread);
|
||||||
off_t offset);
|
__wasi_errno_t
|
||||||
ssize_t
|
blocking_op_writev(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
int iovcnt);
|
size_t *nwritten);
|
||||||
ssize_t
|
__wasi_errno_t
|
||||||
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
blocking_op_pwritev(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
int iovcnt, off_t offset);
|
const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
ssize_t
|
__wasi_filesize_t offset, size_t *nwritten);
|
||||||
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
|
|
||||||
off_t offset);
|
|
||||||
int
|
int
|
||||||
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
|
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
|
||||||
bh_socket_t *sockp, void *addr,
|
bh_socket_t *sockp, void *addr,
|
||||||
|
@ -47,6 +45,9 @@ blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
|
||||||
uint8_t *hint_is_ipv4,
|
uint8_t *hint_is_ipv4,
|
||||||
bh_addr_info_t *addr_info,
|
bh_addr_info_t *addr_info,
|
||||||
size_t addr_info_size, size_t *max_info_size);
|
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,
|
__wasi_errno_t
|
||||||
int oflags, mode_t mode);
|
blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
|
const char *path, __wasi_oflags_t oflags,
|
||||||
|
__wasi_fdflags_t fd_flags, __wasi_lookupflags_t lookup_flags,
|
||||||
|
wasi_libc_file_access_mode access_mode, os_file_handle *out);
|
|
@ -49,7 +49,7 @@
|
||||||
/* Mutex that uses the lock annotations. */
|
/* Mutex that uses the lock annotations. */
|
||||||
|
|
||||||
struct LOCKABLE mutex {
|
struct LOCKABLE mutex {
|
||||||
pthread_mutex_t object;
|
korp_mutex object;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
@ -60,69 +60,71 @@ struct LOCKABLE mutex {
|
||||||
static inline bool
|
static inline bool
|
||||||
mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
|
mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
|
||||||
{
|
{
|
||||||
return pthread_mutex_init(&lock->object, NULL) == 0 ? true : false;
|
return os_mutex_init(&lock->object) == BHT_OK ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mutex_destroy(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
|
mutex_destroy(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&lock->object);
|
os_mutex_destroy(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mutex_lock(struct mutex *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
mutex_lock(struct mutex *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&lock->object);
|
os_mutex_lock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mutex_unlock(struct mutex *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
mutex_unlock(struct mutex *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&lock->object);
|
os_mutex_unlock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read-write lock that uses the lock annotations. */
|
/* Read-write lock that uses the lock annotations. */
|
||||||
|
|
||||||
struct LOCKABLE rwlock {
|
struct LOCKABLE rwlock {
|
||||||
pthread_rwlock_t object;
|
korp_rwlock object;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock)
|
rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock)
|
||||||
{
|
{
|
||||||
return pthread_rwlock_init(&lock->object, NULL) == 0 ? true : false;
|
return os_rwlock_init(&lock->object) == 0 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rwlock_rdlock(struct rwlock *lock) LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS
|
rwlock_rdlock(struct rwlock *lock) LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_rwlock_rdlock(&lock->object);
|
os_rwlock_rdlock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rwlock_wrlock(struct rwlock *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
rwlock_wrlock(struct rwlock *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_rwlock_wrlock(&lock->object);
|
os_rwlock_wrlock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rwlock_unlock(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
rwlock_unlock(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_rwlock_unlock(&lock->object);
|
os_rwlock_unlock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rwlock_destroy(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
rwlock_destroy(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_rwlock_destroy(&lock->object);
|
os_rwlock_destroy(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Condition variable that uses the lock annotations. */
|
/* Condition variable that uses the lock annotations. */
|
||||||
|
|
||||||
struct LOCKABLE cond {
|
struct LOCKABLE cond {
|
||||||
pthread_cond_t object;
|
korp_cond object;
|
||||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
|
||||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
#if !CONFIG_HAS_CLOCK_NANOSLEEP \
|
||||||
|
&& (!CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||||
|
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
|
||||||
clockid_t clock;
|
clockid_t clock;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -147,43 +149,49 @@ cond_init_monotonic(struct cond *cond)
|
||||||
fail:
|
fail:
|
||||||
pthread_condattr_destroy(&attr);
|
pthread_condattr_destroy(&attr);
|
||||||
#else
|
#else
|
||||||
if (pthread_cond_init(&cond->object, NULL) != 0)
|
if (os_cond_init(&cond->object) != 0)
|
||||||
return false;
|
return false;
|
||||||
ret = true;
|
ret = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
#if !CONFIG_HAS_CLOCK_NANOSLEEP \
|
||||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
&& (!CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||||
|
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
|
||||||
cond->clock = CLOCK_MONOTONIC;
|
cond->clock = CLOCK_MONOTONIC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
cond_init_realtime(struct cond *cond)
|
cond_init_realtime(struct cond *cond)
|
||||||
{
|
{
|
||||||
if (pthread_cond_init(&cond->object, NULL) != 0)
|
if (os_cond_init(&cond->object) != 0)
|
||||||
return false;
|
return false;
|
||||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
|
||||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
#if !CONFIG_HAS_CLOCK_NANOSLEEP \
|
||||||
|
&& (!CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||||
|
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
|
||||||
cond->clock = CLOCK_REALTIME;
|
cond->clock = CLOCK_REALTIME;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
cond_destroy(struct cond *cond)
|
cond_destroy(struct cond *cond)
|
||||||
{
|
{
|
||||||
pthread_cond_destroy(&cond->object);
|
os_cond_destroy(&cond->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
cond_signal(struct cond *cond)
|
cond_signal(struct cond *cond)
|
||||||
{
|
{
|
||||||
pthread_cond_signal(&cond->object);
|
os_cond_signal(&cond->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !CONFIG_HAS_CLOCK_NANOSLEEP
|
#if !CONFIG_HAS_CLOCK_NANOSLEEP
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
|
cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
|
||||||
bool abstime) REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
bool abstime) REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||||
|
@ -259,7 +267,7 @@ static inline void
|
||||||
cond_wait(struct cond *cond, struct mutex *lock)
|
cond_wait(struct cond *cond, struct mutex *lock)
|
||||||
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_cond_wait(&cond->object, &lock->object);
|
os_cond_wait(&cond->object, &lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -60,7 +60,8 @@ struct addr_pool {
|
||||||
bool
|
bool
|
||||||
fd_table_init(struct fd_table *);
|
fd_table_init(struct fd_table *);
|
||||||
bool
|
bool
|
||||||
fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
|
fd_table_insert_existing(struct fd_table *, __wasi_fd_t, os_file_handle,
|
||||||
|
bool is_stdio);
|
||||||
bool
|
bool
|
||||||
fd_prestats_init(struct fd_prestats *);
|
fd_prestats_init(struct fd_prestats *);
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -13,14 +13,16 @@
|
||||||
|
|
||||||
#include "ssp_config.h"
|
#include "ssp_config.h"
|
||||||
#include "bh_platform.h"
|
#include "bh_platform.h"
|
||||||
|
#include "libc_errno.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
#if CONFIG_HAS_ARC4RANDOM_BUF
|
#if CONFIG_HAS_ARC4RANDOM_BUF
|
||||||
|
|
||||||
void
|
__wasi_errno_t
|
||||||
random_buf(void *buf, size_t len)
|
random_buf(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
arc4random_buf(buf, len);
|
arc4random_buf(buf, len);
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif CONFIG_HAS_GETRANDOM
|
#elif CONFIG_HAS_GETRANDOM
|
||||||
|
@ -29,7 +31,7 @@ random_buf(void *buf, size_t len)
|
||||||
#include <sys/random.h>
|
#include <sys/random.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
__wasi_errno_t
|
||||||
random_buf(void *buf, size_t len)
|
random_buf(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -37,40 +39,71 @@ random_buf(void *buf, size_t len)
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
os_printf("getrandom failed: %s", strerror(errno));
|
return convert_errno(errno);
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
if ((size_t)x == len)
|
if ((size_t)x == len)
|
||||||
return;
|
break;
|
||||||
buf = (void *)((unsigned char *)buf + x);
|
buf = (void *)((unsigned char *)buf + x);
|
||||||
len -= (size_t)x;
|
len -= (size_t)x;
|
||||||
}
|
}
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(BH_PLATFORM_WINDOWS)
|
||||||
|
|
||||||
|
#include <bcrypt.h>
|
||||||
|
#pragma comment(lib, "Bcrypt.lib")
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
random_buf(void *buf, size_t len)
|
||||||
|
{
|
||||||
|
NTSTATUS ret =
|
||||||
|
BCryptGenRandom(NULL, buf, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||||
|
|
||||||
|
// Since we pass NULL for the algorithm handle, the only way BCryptGenRandom
|
||||||
|
// can fail is if one of the parameters is invalid
|
||||||
|
// (STATUS_INVALID_PARAMETER).
|
||||||
|
return ret ? __WASI_EINVAL : __WASI_ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static int urandom;
|
static int urandom = -1;
|
||||||
|
static __wasi_errno_t urandom_error = __WASI_ESUCCESS;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
open_urandom(void)
|
open_urandom(void)
|
||||||
{
|
{
|
||||||
urandom = open("/dev/urandom", O_RDONLY);
|
urandom = open("/dev/urandom", O_RDONLY);
|
||||||
if (urandom < 0) {
|
if (urandom < 0)
|
||||||
os_printf("Failed to open /dev/urandom\n");
|
urandom_error = convert_errno(errno);
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
__wasi_errno_t
|
||||||
random_buf(void *buf, size_t len)
|
random_buf(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
|
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
|
||||||
pthread_once(&open_once, open_urandom);
|
int pthread_ret = pthread_once(&open_once, open_urandom);
|
||||||
|
|
||||||
if ((size_t)read(urandom, buf, len) != len) {
|
if (pthread_ret != 0)
|
||||||
os_printf("Short read on /dev/urandom\n");
|
return convert_errno(pthread_ret);
|
||||||
abort();
|
|
||||||
|
if (urandom < 0)
|
||||||
|
return urandom_error;
|
||||||
|
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
|
||||||
|
while (bytes_read < len) {
|
||||||
|
ssize_t bytes_read_now =
|
||||||
|
read(urandom, buf + bytes_read, len - bytes_read);
|
||||||
|
|
||||||
|
if (bytes_read_now < 0)
|
||||||
|
return convert_errno(errno);
|
||||||
|
|
||||||
|
bytes_read += (size_t)bytes_read_now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,8 +115,8 @@ random_buf(void *buf, size_t len)
|
||||||
// arc4random() until it lies within the range [2^k % upper, 2^k). As
|
// arc4random() until it lies within the range [2^k % upper, 2^k). As
|
||||||
// this range has length k * upper, we can safely obtain a number
|
// this range has length k * upper, we can safely obtain a number
|
||||||
// without any modulo bias.
|
// without any modulo bias.
|
||||||
uintmax_t
|
__wasi_errno_t
|
||||||
random_uniform(uintmax_t upper)
|
random_uniform(uintmax_t upper, uintmax_t *out)
|
||||||
{
|
{
|
||||||
// Compute 2^k % upper
|
// Compute 2^k % upper
|
||||||
// == (2^k - upper) % upper
|
// == (2^k - upper) % upper
|
||||||
|
@ -91,8 +124,14 @@ random_uniform(uintmax_t upper)
|
||||||
uintmax_t lower = -upper % upper;
|
uintmax_t lower = -upper % upper;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
uintmax_t value;
|
uintmax_t value;
|
||||||
random_buf(&value, sizeof(value));
|
__wasi_errno_t error = random_buf(&value, sizeof(value));
|
||||||
if (value >= lower)
|
|
||||||
return value % upper;
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (value >= lower) {
|
||||||
|
*out = value % upper;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,12 @@
|
||||||
#ifndef RANDOM_H
|
#ifndef RANDOM_H
|
||||||
#define RANDOM_H
|
#define RANDOM_H
|
||||||
|
|
||||||
void
|
#include "bh_platform.h"
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
random_buf(void *, size_t);
|
random_buf(void *, size_t);
|
||||||
uintmax_t random_uniform(uintmax_t);
|
|
||||||
|
__wasi_errno_t
|
||||||
|
random_uniform(uintmax_t upper, uintmax_t *out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
// On Linux, prefer to use getrandom, though it isn't available in
|
// On Linux, prefer to use getrandom, though it isn't available in
|
||||||
// GLIBC before 2.25.
|
// GLIBC before 2.25.
|
||||||
#if (defined(__linux__) || defined(ESP_PLATFORM)) \
|
#if (defined(__linux__) || defined(ESP_PLATFORM) || defined(__COSMOPOLITAN__)) \
|
||||||
&& (!defined(__GLIBC__) || __GLIBC__ > 2 \
|
&& (!defined(__GLIBC__) || __GLIBC__ > 2 \
|
||||||
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
|
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
|
||||||
#define CONFIG_HAS_GETRANDOM 1
|
#define CONFIG_HAS_GETRANDOM 1
|
||||||
|
@ -47,75 +47,19 @@
|
||||||
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
|
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(ESP_PLATFORM)
|
|
||||||
#define CONFIG_HAS_FDATASYNC 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_FDATASYNC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For NuttX, CONFIG_HAS_ISATTY is provided by its platform header.
|
|
||||||
* (platform_internal.h)
|
|
||||||
*/
|
|
||||||
#ifndef __NuttX__
|
|
||||||
#ifndef __CloudABI__
|
|
||||||
#define CONFIG_HAS_ISATTY 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_ISATTY 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(__COSMOPOLITAN__)
|
|
||||||
#define CONFIG_HAS_POSIX_FALLOCATE 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_POSIX_FALLOCATE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(ESP_PLATFORM)
|
|
||||||
#define CONFIG_HAS_PREADV 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_PREADV 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__CloudABI__)
|
#if defined(__APPLE__) || defined(__CloudABI__)
|
||||||
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
|
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
|
||||||
#else
|
#else
|
||||||
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
|
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) \
|
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) && !defined(_WIN32) \
|
||||||
&& !defined(__COSMOPOLITAN__)
|
&& !defined(__COSMOPOLITAN__)
|
||||||
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
|
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
|
||||||
#else
|
#else
|
||||||
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
|
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(ESP_PLATFORM)
|
|
||||||
#define CONFIG_HAS_PWRITEV 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_PWRITEV 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#define st_atim st_atimespec
|
|
||||||
#define st_ctim st_ctimespec
|
|
||||||
#define st_mtim st_mtimespec
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(O_DSYNC)
|
|
||||||
#define CONFIG_HAS_O_DSYNC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// POSIX requires O_RSYNC to be defined, but Linux explicitly doesn't support
|
|
||||||
// it.
|
|
||||||
#if defined(O_RSYNC) && !defined(__linux__)
|
|
||||||
#define CONFIG_HAS_O_RSYNC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(O_SYNC)
|
|
||||||
#define CONFIG_HAS_O_SYNC
|
|
||||||
#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 */
|
||||||
|
@ -143,10 +87,4 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58016 */
|
||||||
#define CONFIG_HAS_STD_ATOMIC 0
|
#define CONFIG_HAS_STD_ATOMIC 0
|
||||||
#endif /* end of !defined(BH_PLATFORM_LINUX_SGX) */
|
#endif /* end of !defined(BH_PLATFORM_LINUX_SGX) */
|
||||||
|
|
||||||
#if !defined(__NuttX__)
|
|
||||||
#define CONFIG_HAS_D_INO 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_D_INO 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -798,10 +798,25 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||||
|
module, module_inst, exec_env, stack_size, 0, NULL, 0))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set custom_data to new module instance */
|
||||||
|
wasm_runtime_set_custom_data_internal(
|
||||||
|
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
||||||
|
|
||||||
|
wasm_native_inherit_contexts(new_module_inst, module_inst);
|
||||||
|
|
||||||
|
if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst))) {
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
cluster_lock_thread_list(cluster, exec_env);
|
cluster_lock_thread_list(cluster, exec_env);
|
||||||
|
|
||||||
if (cluster->has_exception || cluster->processing) {
|
if (cluster->has_exception || cluster->processing) {
|
||||||
goto fail1;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_INTERP != 0
|
#if WASM_ENABLE_INTERP != 0
|
||||||
|
@ -818,21 +833,11 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
|
||||||
module, module_inst, exec_env, stack_size, 0, NULL, 0))) {
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set custom_data to new module instance */
|
|
||||||
wasm_runtime_set_custom_data_internal(
|
|
||||||
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
|
||||||
|
|
||||||
wasm_native_inherit_contexts(new_module_inst, module_inst);
|
|
||||||
|
|
||||||
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);
|
||||||
if (!new_exec_env)
|
if (!new_exec_env) {
|
||||||
goto fail2;
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
if (!allocate_aux_stack(exec_env, &aux_stack_start, &aux_stack_size)) {
|
if (!allocate_aux_stack(exec_env, &aux_stack_start, &aux_stack_size)) {
|
||||||
LOG_ERROR("thread manager error: "
|
LOG_ERROR("thread manager error: "
|
||||||
|
@ -850,8 +855,9 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
||||||
thread_state_lock as the thread list has been locked */
|
thread_state_lock as the thread list has been locked */
|
||||||
new_exec_env->suspend_flags.flags = exec_env->suspend_flags.flags;
|
new_exec_env->suspend_flags.flags = exec_env->suspend_flags.flags;
|
||||||
|
|
||||||
if (!wasm_cluster_add_exec_env(cluster, new_exec_env))
|
if (!wasm_cluster_add_exec_env(cluster, new_exec_env)) {
|
||||||
goto fail4;
|
goto fail4;
|
||||||
|
}
|
||||||
|
|
||||||
cluster_unlock_thread_list(cluster);
|
cluster_unlock_thread_list(cluster);
|
||||||
|
|
||||||
|
@ -863,9 +869,9 @@ fail4:
|
||||||
fail3:
|
fail3:
|
||||||
wasm_exec_env_destroy_internal(new_exec_env);
|
wasm_exec_env_destroy_internal(new_exec_env);
|
||||||
fail2:
|
fail2:
|
||||||
wasm_runtime_deinstantiate_internal(new_module_inst, true);
|
|
||||||
fail1:
|
|
||||||
cluster_unlock_thread_list(cluster);
|
cluster_unlock_thread_list(cluster);
|
||||||
|
fail1:
|
||||||
|
wasm_runtime_deinstantiate_internal(new_module_inst, true);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1801,3 +1807,19 @@ exception_unlock(WASMModuleInstance *module_inst)
|
||||||
{
|
{
|
||||||
os_mutex_unlock(&_exception_lock);
|
os_mutex_unlock(&_exception_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_cluster_traverse_lock(WASMExecEnv *exec_env)
|
||||||
|
{
|
||||||
|
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||||
|
bh_assert(cluster);
|
||||||
|
cluster_lock_thread_list(cluster, exec_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_cluster_traverse_unlock(WASMExecEnv *exec_env)
|
||||||
|
{
|
||||||
|
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||||
|
bh_assert(cluster);
|
||||||
|
cluster_unlock_thread_list(cluster);
|
||||||
|
}
|
||||||
|
|
|
@ -240,6 +240,12 @@ wasm_cluster_set_debug_inst(WASMCluster *cluster, WASMDebugInstance *inst);
|
||||||
|
|
||||||
#endif /* end of WASM_ENABLE_DEBUG_INTERP != 0 */
|
#endif /* end of WASM_ENABLE_DEBUG_INTERP != 0 */
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_cluster_traverse_lock(WASMExecEnv *exec_env);
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_cluster_traverse_unlock(WASMExecEnv *exec_env);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,19 +24,23 @@ hmu_is_in_heap(void *hmu, gc_uint8 *heap_base_addr, gc_uint8 *heap_end_addr)
|
||||||
static bool
|
static bool
|
||||||
remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
{
|
{
|
||||||
hmu_tree_node_t *q = NULL, **slot = NULL, *parent;
|
hmu_tree_node_t *q = NULL, **slot = NULL;
|
||||||
hmu_tree_node_t *root = heap->kfc_tree_root;
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
|
hmu_tree_node_t *root = heap->kfc_tree_root, *parent;
|
||||||
gc_uint8 *base_addr = heap->base_addr;
|
gc_uint8 *base_addr = heap->base_addr;
|
||||||
gc_uint8 *end_addr = base_addr + heap->current_size;
|
gc_uint8 *end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
bh_assert(p);
|
bh_assert(p);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
parent = p->parent;
|
parent = p->parent;
|
||||||
if (!parent || p == root /* p can not be the ROOT node */
|
if (!parent || p == root /* p can not be the ROOT node */
|
||||||
|| !hmu_is_in_heap(p, base_addr, end_addr)
|
|| !hmu_is_in_heap(p, base_addr, end_addr)
|
||||||
|| (parent != root && !hmu_is_in_heap(parent, base_addr, end_addr))) {
|
|| (parent != root && !hmu_is_in_heap(parent, base_addr, end_addr))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get the slot which holds pointer to node p */
|
/* get the slot which holds pointer to node p */
|
||||||
if (p == p->parent->right) {
|
if (p == p->parent->right) {
|
||||||
|
@ -67,9 +71,11 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
/* move right child up*/
|
/* move right child up*/
|
||||||
*slot = p->right;
|
*slot = p->right;
|
||||||
if (p->right) {
|
if (p->right) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p->right, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p->right, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
p->right->parent = p->parent;
|
p->right->parent = p->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +86,11 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
if (!p->right) {
|
if (!p->right) {
|
||||||
/* move left child up*/
|
/* move left child up*/
|
||||||
*slot = p->left;
|
*slot = p->left;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p->left, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p->left, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* p->left can never be NULL unless it is corrupted. */
|
/* p->left can never be NULL unless it is corrupted. */
|
||||||
p->left->parent = p->parent;
|
p->left->parent = p->parent;
|
||||||
|
|
||||||
|
@ -92,14 +100,18 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
|
|
||||||
/* both left & right exist, find p's predecessor at first*/
|
/* both left & right exist, find p's predecessor at first*/
|
||||||
q = p->left;
|
q = p->left;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
while (q->right) {
|
while (q->right) {
|
||||||
q = q->right;
|
q = q->right;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove from the tree*/
|
/* remove from the tree*/
|
||||||
|
@ -111,15 +123,19 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
q->left = p->left;
|
q->left = p->left;
|
||||||
q->right = p->right;
|
q->right = p->right;
|
||||||
if (q->left) {
|
if (q->left) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q->left, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q->left, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
q->left->parent = q;
|
q->left->parent = q;
|
||||||
}
|
}
|
||||||
if (q->right) {
|
if (q->right) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q->right, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q->right, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
q->right->parent = q;
|
q->right->parent = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,27 +143,35 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_uint8 *base_addr, *end_addr;
|
gc_uint8 *base_addr, *end_addr;
|
||||||
|
#endif
|
||||||
gc_size_t size;
|
gc_size_t size;
|
||||||
|
|
||||||
bh_assert(gci_is_heap_valid(heap));
|
bh_assert(gci_is_heap_valid(heap));
|
||||||
bh_assert(hmu && (gc_uint8 *)hmu >= heap->base_addr
|
bh_assert(hmu && (gc_uint8 *)hmu >= heap->base_addr
|
||||||
&& (gc_uint8 *)hmu < heap->base_addr + heap->current_size);
|
&& (gc_uint8 *)hmu < heap->base_addr + heap->current_size);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (hmu_get_ut(hmu) != HMU_FC) {
|
if (hmu_get_ut(hmu) != HMU_FC) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
base_addr = heap->base_addr;
|
base_addr = heap->base_addr;
|
||||||
end_addr = base_addr + heap->current_size;
|
end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
size = hmu_get_size(hmu);
|
size = hmu_get_size(hmu);
|
||||||
|
|
||||||
if (HMU_IS_FC_NORMAL(size)) {
|
if (HMU_IS_FC_NORMAL(size)) {
|
||||||
|
@ -156,10 +180,12 @@ unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
||||||
hmu_normal_node_t *node = heap->kfc_normal_list[node_idx].next;
|
hmu_normal_node_t *node = heap->kfc_normal_list[node_idx].next;
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(node, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(node, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
node_next = get_hmu_normal_node_next(node);
|
node_next = get_hmu_normal_node_next(node);
|
||||||
if ((hmu_t *)node == hmu) {
|
if ((hmu_t *)node == hmu) {
|
||||||
if (!node_prev) /* list head */
|
if (!node_prev) /* list head */
|
||||||
|
@ -205,7 +231,9 @@ hmu_set_free_size(hmu_t *hmu)
|
||||||
bool
|
bool
|
||||||
gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_uint8 *base_addr, *end_addr;
|
gc_uint8 *base_addr, *end_addr;
|
||||||
|
#endif
|
||||||
hmu_normal_node_t *np = NULL;
|
hmu_normal_node_t *np = NULL;
|
||||||
hmu_tree_node_t *root = NULL, *tp = NULL, *node = NULL;
|
hmu_tree_node_t *root = NULL, *tp = NULL, *node = NULL;
|
||||||
uint32 node_idx;
|
uint32 node_idx;
|
||||||
|
@ -219,8 +247,10 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
<= heap->base_addr + heap->current_size);
|
<= heap->base_addr + heap->current_size);
|
||||||
bh_assert(!(size & 7));
|
bh_assert(!(size & 7));
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
base_addr = heap->base_addr;
|
base_addr = heap->base_addr;
|
||||||
end_addr = base_addr + heap->current_size;
|
end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
hmu_set_ut(hmu, HMU_FC);
|
hmu_set_ut(hmu, HMU_FC);
|
||||||
hmu_set_size(hmu, size);
|
hmu_set_size(hmu, size);
|
||||||
|
@ -228,10 +258,12 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
|
|
||||||
if (HMU_IS_FC_NORMAL(size)) {
|
if (HMU_IS_FC_NORMAL(size)) {
|
||||||
np = (hmu_normal_node_t *)hmu;
|
np = (hmu_normal_node_t *)hmu;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(np, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(np, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
node_idx = size >> 3;
|
node_idx = size >> 3;
|
||||||
set_hmu_normal_node_next(np, heap->kfc_normal_list[node_idx].next);
|
set_hmu_normal_node_next(np, heap->kfc_normal_list[node_idx].next);
|
||||||
|
@ -265,10 +297,12 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
}
|
}
|
||||||
tp = tp->left;
|
tp = tp->left;
|
||||||
}
|
}
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -321,15 +355,19 @@ alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||||
bh_assert(node_idx >= init_node_idx);
|
bh_assert(node_idx >= init_node_idx);
|
||||||
|
|
||||||
p = normal_head->next;
|
p = normal_head->next;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
normal_head->next = get_hmu_normal_node_next(p);
|
normal_head->next = get_hmu_normal_node_next(p);
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) != 0) {
|
if (((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) != 0) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((gc_size_t)node_idx != (uint32)init_node_idx
|
if ((gc_size_t)node_idx != (uint32)init_node_idx
|
||||||
/* with bigger size*/
|
/* with bigger size*/
|
||||||
|
@ -365,10 +403,12 @@ alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||||
bh_assert(root);
|
bh_assert(root);
|
||||||
tp = root->right;
|
tp = root->right;
|
||||||
while (tp) {
|
while (tp) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tp->size < size) {
|
if (tp->size < size) {
|
||||||
tp = tp->right;
|
tp = tp->right;
|
||||||
|
@ -462,10 +502,12 @@ gc_alloc_vo_internal(void *vheap, gc_size_t size, const char *file, int line)
|
||||||
/* integer overflow */
|
/* integer overflow */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
os_mutex_lock(&heap->lock);
|
os_mutex_lock(&heap->lock);
|
||||||
|
|
||||||
|
@ -522,10 +564,12 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size, const char *file,
|
||||||
/* integer overflow */
|
/* integer overflow */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (obj_old) {
|
if (obj_old) {
|
||||||
hmu_old = obj_to_hmu(obj_old);
|
hmu_old = obj_to_hmu(obj_old);
|
||||||
|
@ -647,10 +691,12 @@ gc_free_vo_internal(void *vheap, gc_object_t obj, const char *file, int line)
|
||||||
return GC_SUCCESS;
|
return GC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, free memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, free memory failed.\n");
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
hmu = obj_to_hmu(obj);
|
hmu = obj_to_hmu(obj);
|
||||||
|
|
||||||
|
@ -767,11 +813,13 @@ gci_dump(gc_heap_t *heap)
|
||||||
else if (ut == HMU_FC)
|
else if (ut == HMU_FC)
|
||||||
inuse = 'F';
|
inuse = 'F';
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (size == 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
if (size == 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
os_printf("#%d %08" PRIx32 " %" PRIx32 " %d %d"
|
os_printf("#%d %08" PRIx32 " %" PRIx32 " %d %d"
|
||||||
" %c %" PRId32 "\n",
|
" %c %" PRId32 "\n",
|
||||||
|
@ -788,8 +836,12 @@ gci_dump(gc_heap_t *heap)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (cur != end) {
|
if (cur != end) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bh_assert(cur == end);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,9 +271,11 @@ typedef struct gc_heap_struct {
|
||||||
size[left] <= size[cur] < size[right] */
|
size[left] <= size[cur] < size[right] */
|
||||||
hmu_tree_node_t *kfc_tree_root;
|
hmu_tree_node_t *kfc_tree_root;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
/* whether heap is corrupted, e.g. the hmu nodes are modified
|
/* whether heap is corrupted, e.g. the hmu nodes are modified
|
||||||
by user */
|
by user */
|
||||||
bool is_heap_corrupted;
|
bool is_heap_corrupted;
|
||||||
|
#endif
|
||||||
|
|
||||||
gc_size_t init_size;
|
gc_size_t init_size;
|
||||||
gc_size_t highmark_size;
|
gc_size_t highmark_size;
|
||||||
|
|
|
@ -83,7 +83,9 @@ hmu_verify(void *vheap, hmu_t *hmu)
|
||||||
os_printf("Invalid padding for object created at %s:%d\n",
|
os_printf("Invalid padding for object created at %s:%d\n",
|
||||||
(prefix->file_name ? prefix->file_name : ""),
|
(prefix->file_name ? prefix->file_name : ""),
|
||||||
prefix->line_no);
|
prefix->line_no);
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,8 +133,11 @@ gc_destroy_with_pool(gc_handle_t handle)
|
||||||
hmu_t *cur = (hmu_t *)heap->base_addr;
|
hmu_t *cur = (hmu_t *)heap->base_addr;
|
||||||
hmu_t *end = (hmu_t *)((char *)heap->base_addr + heap->current_size);
|
hmu_t *end = (hmu_t *)((char *)heap->base_addr + heap->current_size);
|
||||||
|
|
||||||
if (!heap->is_heap_corrupted
|
if (
|
||||||
&& (hmu_t *)((char *)cur + hmu_get_size(cur)) != end) {
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
|
!heap->is_heap_corrupted &&
|
||||||
|
#endif
|
||||||
|
(hmu_t *)((char *)cur + hmu_get_size(cur)) != end) {
|
||||||
os_printf("Memory leak detected:\n");
|
os_printf("Memory leak detected:\n");
|
||||||
gci_dump(heap);
|
gci_dump(heap);
|
||||||
ret = GC_ERROR;
|
ret = GC_ERROR;
|
||||||
|
@ -186,10 +189,12 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
heap->base_addr = (uint8 *)base_addr_new;
|
heap->base_addr = (uint8 *)base_addr_new;
|
||||||
|
|
||||||
|
@ -211,11 +216,13 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
while (cur < end) {
|
while (cur < end) {
|
||||||
size = hmu_get_size(cur);
|
size = hmu_get_size(cur);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (size <= 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
if (size <= 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (hmu_get_ut(cur) == HMU_FC && !HMU_IS_FC_NORMAL(size)) {
|
if (hmu_get_ut(cur) == HMU_FC && !HMU_IS_FC_NORMAL(size)) {
|
||||||
tree_node = (hmu_tree_node_t *)cur;
|
tree_node = (hmu_tree_node_t *)cur;
|
||||||
|
@ -238,11 +245,15 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
cur = (hmu_t *)((char *)cur + size);
|
cur = (hmu_t *)((char *)cur + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (cur != end) {
|
if (cur != end) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bh_assert(cur == end);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -250,9 +261,13 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
bool
|
bool
|
||||||
gc_is_heap_corrupted(gc_handle_t handle)
|
gc_is_heap_corrupted(gc_handle_t handle)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_heap_t *heap = (gc_heap_t *)handle;
|
gc_heap_t *heap = (gc_heap_t *)handle;
|
||||||
|
|
||||||
return heap->is_heap_corrupted ? true : false;
|
return heap->is_heap_corrupted ? true : false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BH_ENABLE_GC_VERIFY != 0
|
#if BH_ENABLE_GC_VERIFY != 0
|
||||||
|
|
|
@ -10,6 +10,14 @@ if (WAMR_BUILD_GC_VERIFY EQUAL 1)
|
||||||
add_definitions (-DBH_ENABLE_GC_VERIFY=1)
|
add_definitions (-DBH_ENABLE_GC_VERIFY=1)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (NOT DEFINED WAMR_BUILD_GC_CORRUPTION_CHECK)
|
||||||
|
set (WAMR_BUILD_GC_CORRUPTION_CHECK 1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (WAMR_BUILD_GC_CORRUPTION_CHECK EQUAL 0)
|
||||||
|
add_definitions (-DBH_ENABLE_GC_CORRUPTION_CHECK=0)
|
||||||
|
endif ()
|
||||||
|
|
||||||
file (GLOB_RECURSE source_all
|
file (GLOB_RECURSE source_all
|
||||||
${MEM_ALLOC_DIR}/ems/*.c
|
${MEM_ALLOC_DIR}/ems/*.c
|
||||||
${MEM_ALLOC_DIR}/tlsf/*.c
|
${MEM_ALLOC_DIR}/tlsf/*.c
|
||||||
|
|
|
@ -47,7 +47,7 @@ os_dumps_proc_mem_info(char *out, unsigned int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
if ((uint64)size >= UINT32_MAX)
|
if ((uint64)size >= UINT32_MAX)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -32,6 +32,12 @@ typedef aos_task_t *aos_tid_t;
|
||||||
typedef aos_mutex_t korp_mutex;
|
typedef aos_mutex_t korp_mutex;
|
||||||
typedef aos_sem_t korp_sem;
|
typedef aos_sem_t korp_sem;
|
||||||
|
|
||||||
|
/* korp_rwlock is used in platform_api_extension.h,
|
||||||
|
we just define the type to make the compiler happy */
|
||||||
|
typedef struct {
|
||||||
|
int dummy;
|
||||||
|
} korp_rwlock;
|
||||||
|
|
||||||
struct os_thread_wait_node;
|
struct os_thread_wait_node;
|
||||||
typedef struct os_thread_wait_node *os_thread_wait_list;
|
typedef struct os_thread_wait_node *os_thread_wait_list;
|
||||||
typedef struct korp_cond {
|
typedef struct korp_cond {
|
||||||
|
@ -64,4 +70,16 @@ int signbit(double x);
|
||||||
int isnan(double x);
|
int isnan(double x);
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
/* The below types are used in platform_api_extension.h,
|
||||||
|
we just define them to make the compiler happy */
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef void *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* end of _BH_PLATFORM_H */
|
#endif /* end of _BH_PLATFORM_H */
|
||||||
|
|
|
@ -56,6 +56,7 @@ typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
typedef pthread_t korp_thread;
|
typedef pthread_t korp_thread;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef sem_t korp_sem;
|
typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
@ -145,6 +146,16 @@ preadv(int __fd, const struct iovec *__iov, int __count, off_t __offset);
|
||||||
ssize_t
|
ssize_t
|
||||||
pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset);
|
pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset);
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
256
core/shared/platform/common/libc-util/libc_errno.c
Normal file
256
core/shared/platform/common/libc-util/libc_errno.c
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "errno.h"
|
||||||
|
#include "libc_errno.h"
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
convert_errno(int error)
|
||||||
|
{
|
||||||
|
// The C standard library only requires EDOM, EILSEQ and ERANGE to be
|
||||||
|
// defined. Other error codes are POSIX-specific and hence may or may
|
||||||
|
// not be available on non-POSIX platforms.
|
||||||
|
__wasi_errno_t code = __WASI_ENOSYS;
|
||||||
|
#define X(v) \
|
||||||
|
case v: \
|
||||||
|
code = __WASI_##v; \
|
||||||
|
break;
|
||||||
|
switch (error) {
|
||||||
|
X(EDOM)
|
||||||
|
X(EILSEQ)
|
||||||
|
X(ERANGE)
|
||||||
|
#ifdef E2BIG
|
||||||
|
X(E2BIG)
|
||||||
|
#endif
|
||||||
|
#ifdef EACCES
|
||||||
|
X(EACCES)
|
||||||
|
#endif
|
||||||
|
#ifdef EADDRINUSE
|
||||||
|
X(EADDRINUSE)
|
||||||
|
#endif
|
||||||
|
#ifdef EADDRNOTAVAIL
|
||||||
|
X(EADDRNOTAVAIL)
|
||||||
|
#endif
|
||||||
|
#ifdef EAFNOSUPPORT
|
||||||
|
X(EAFNOSUPPORT)
|
||||||
|
#endif
|
||||||
|
#ifdef EAGAIN
|
||||||
|
X(EAGAIN)
|
||||||
|
#endif
|
||||||
|
#ifdef EALREADY
|
||||||
|
X(EALREADY)
|
||||||
|
#endif
|
||||||
|
#ifdef EBADF
|
||||||
|
X(EBADF)
|
||||||
|
#endif
|
||||||
|
#ifdef EBADMSG
|
||||||
|
X(EBADMSG)
|
||||||
|
#endif
|
||||||
|
#ifdef EBUSY
|
||||||
|
X(EBUSY)
|
||||||
|
#endif
|
||||||
|
#ifdef ECANCELED
|
||||||
|
X(ECANCELED)
|
||||||
|
#endif
|
||||||
|
#ifdef ECHILD
|
||||||
|
X(ECHILD)
|
||||||
|
#endif
|
||||||
|
#ifdef ECONNABORTED
|
||||||
|
X(ECONNABORTED)
|
||||||
|
#endif
|
||||||
|
#ifdef ECONNREFUSED
|
||||||
|
X(ECONNREFUSED)
|
||||||
|
#endif
|
||||||
|
#ifdef ECONNRESET
|
||||||
|
X(ECONNRESET)
|
||||||
|
#endif
|
||||||
|
#ifdef EDEADLK
|
||||||
|
X(EDEADLK)
|
||||||
|
#endif
|
||||||
|
#ifdef EDESTADDRREQ
|
||||||
|
X(EDESTADDRREQ)
|
||||||
|
#endif
|
||||||
|
#ifdef EDQUOT
|
||||||
|
X(EDQUOT)
|
||||||
|
#endif
|
||||||
|
#ifdef EEXIST
|
||||||
|
X(EEXIST)
|
||||||
|
#endif
|
||||||
|
#ifdef EFAULT
|
||||||
|
X(EFAULT)
|
||||||
|
#endif
|
||||||
|
#ifdef EFBIG
|
||||||
|
X(EFBIG)
|
||||||
|
#endif
|
||||||
|
#ifdef EHOSTUNREACH
|
||||||
|
X(EHOSTUNREACH)
|
||||||
|
#endif
|
||||||
|
#ifdef EIDRM
|
||||||
|
X(EIDRM)
|
||||||
|
#endif
|
||||||
|
#ifdef EINPROGRESS
|
||||||
|
X(EINPROGRESS)
|
||||||
|
#endif
|
||||||
|
#ifdef EINTR
|
||||||
|
X(EINTR)
|
||||||
|
#endif
|
||||||
|
#ifdef EINVAL
|
||||||
|
X(EINVAL)
|
||||||
|
#endif
|
||||||
|
#ifdef EIO
|
||||||
|
X(EIO)
|
||||||
|
#endif
|
||||||
|
#ifdef EISCONN
|
||||||
|
X(EISCONN)
|
||||||
|
#endif
|
||||||
|
#ifdef EISDIR
|
||||||
|
X(EISDIR)
|
||||||
|
#endif
|
||||||
|
#ifdef ELOOP
|
||||||
|
X(ELOOP)
|
||||||
|
#endif
|
||||||
|
#ifdef EMFILE
|
||||||
|
X(EMFILE)
|
||||||
|
#endif
|
||||||
|
#ifdef EMLINK
|
||||||
|
X(EMLINK)
|
||||||
|
#endif
|
||||||
|
#ifdef EMSGSIZE
|
||||||
|
X(EMSGSIZE)
|
||||||
|
#endif
|
||||||
|
#ifdef EMULTIHOP
|
||||||
|
X(EMULTIHOP)
|
||||||
|
#endif
|
||||||
|
#ifdef ENAMETOOLONG
|
||||||
|
X(ENAMETOOLONG)
|
||||||
|
#endif
|
||||||
|
#ifdef ENETDOWN
|
||||||
|
X(ENETDOWN)
|
||||||
|
#endif
|
||||||
|
#ifdef ENETRESET
|
||||||
|
X(ENETRESET)
|
||||||
|
#endif
|
||||||
|
#ifdef ENETUNREACH
|
||||||
|
X(ENETUNREACH)
|
||||||
|
#endif
|
||||||
|
#ifdef ENFILE
|
||||||
|
X(ENFILE)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOBUFS
|
||||||
|
X(ENOBUFS)
|
||||||
|
#endif
|
||||||
|
#ifdef ENODEV
|
||||||
|
X(ENODEV)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOENT
|
||||||
|
X(ENOENT)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOEXEC
|
||||||
|
X(ENOEXEC)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOLCK
|
||||||
|
X(ENOLCK)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOLINK
|
||||||
|
X(ENOLINK)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOMEM
|
||||||
|
X(ENOMEM)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOMSG
|
||||||
|
X(ENOMSG)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOPROTOOPT
|
||||||
|
X(ENOPROTOOPT)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOSPC
|
||||||
|
X(ENOSPC)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOSYS
|
||||||
|
X(ENOSYS)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTCAPABLE
|
||||||
|
X(ENOTCAPABLE)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTCONN
|
||||||
|
X(ENOTCONN)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTDIR
|
||||||
|
X(ENOTDIR)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTEMPTY
|
||||||
|
X(ENOTEMPTY)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTRECOVERABLE
|
||||||
|
X(ENOTRECOVERABLE)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTSOCK
|
||||||
|
X(ENOTSOCK)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTSUP
|
||||||
|
X(ENOTSUP)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTTY
|
||||||
|
X(ENOTTY)
|
||||||
|
#endif
|
||||||
|
#ifdef ENXIO
|
||||||
|
X(ENXIO)
|
||||||
|
#endif
|
||||||
|
#ifdef EOVERFLOW
|
||||||
|
X(EOVERFLOW)
|
||||||
|
#endif
|
||||||
|
#ifdef EOWNERDEAD
|
||||||
|
X(EOWNERDEAD)
|
||||||
|
#endif
|
||||||
|
#ifdef EPERM
|
||||||
|
X(EPERM)
|
||||||
|
#endif
|
||||||
|
#ifdef EPIPE
|
||||||
|
X(EPIPE)
|
||||||
|
#endif
|
||||||
|
#ifdef EPROTO
|
||||||
|
X(EPROTO)
|
||||||
|
#endif
|
||||||
|
#ifdef EPROTONOSUPPORT
|
||||||
|
X(EPROTONOSUPPORT)
|
||||||
|
#endif
|
||||||
|
#ifdef EPROTOTYPE
|
||||||
|
X(EPROTOTYPE)
|
||||||
|
#endif
|
||||||
|
#ifdef EROFS
|
||||||
|
X(EROFS)
|
||||||
|
#endif
|
||||||
|
#ifdef ESPIPE
|
||||||
|
X(ESPIPE)
|
||||||
|
#endif
|
||||||
|
#ifdef ESRCH
|
||||||
|
X(ESRCH)
|
||||||
|
#endif
|
||||||
|
#ifdef ESTALE
|
||||||
|
X(ESTALE)
|
||||||
|
#endif
|
||||||
|
#ifdef ETIMEDOUT
|
||||||
|
X(ETIMEDOUT)
|
||||||
|
#endif
|
||||||
|
#ifdef ETXTBSY
|
||||||
|
X(ETXTBSY)
|
||||||
|
#endif
|
||||||
|
#ifdef EXDEV
|
||||||
|
X(EXDEV)
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
#ifdef EOPNOTSUPP
|
||||||
|
if (error == EOPNOTSUPP)
|
||||||
|
code = __WASI_ENOTSUP;
|
||||||
|
#endif
|
||||||
|
#ifdef EWOULDBLOCK
|
||||||
|
if (error == EWOULDBLOCK)
|
||||||
|
code = __WASI_EAGAIN;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#undef X
|
||||||
|
return code;
|
||||||
|
}
|
15
core/shared/platform/common/libc-util/libc_errno.h
Normal file
15
core/shared/platform/common/libc-util/libc_errno.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WASI_ERRNO_H
|
||||||
|
#define WASI_ERRNO_H
|
||||||
|
|
||||||
|
#include "platform_wasi_types.h"
|
||||||
|
|
||||||
|
// Converts an errno error code to a WASI error code.
|
||||||
|
__wasi_errno_t
|
||||||
|
convert_errno(int error);
|
||||||
|
|
||||||
|
#endif /* end of WASI_ERRNO_H */
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
set (PLATFORM_COMMON_LIBC_UTIL_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
include_directories(${PLATFORM_COMMON_LIBC_UTIL_DIR})
|
||||||
|
|
||||||
|
file (GLOB_RECURSE PLATFORM_COMMON_LIBC_UTIL_SOURCE ${PLATFORM_COMMON_LIBC_UTIL_DIR}/*.c)
|
|
@ -5,4 +5,15 @@ set (PLATFORM_COMMON_POSIX_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
file (GLOB_RECURSE source_all ${PLATFORM_COMMON_POSIX_DIR}/*.c)
|
file (GLOB_RECURSE source_all ${PLATFORM_COMMON_POSIX_DIR}/*.c)
|
||||||
|
|
||||||
|
if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1)
|
||||||
|
list(REMOVE_ITEM source_all
|
||||||
|
${PLATFORM_COMMON_POSIX_DIR}/posix_file.c
|
||||||
|
${PLATFORM_COMMON_POSIX_DIR}/posix_clock.c
|
||||||
|
${PLATFORM_COMMON_POSIX_DIR}/posix_socket.c
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
include (${CMAKE_CURRENT_LIST_DIR}/../libc-util/platform_common_libc_util.cmake)
|
||||||
|
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||||
|
endif()
|
||||||
|
|
||||||
set (PLATFORM_COMMON_POSIX_SOURCE ${source_all} )
|
set (PLATFORM_COMMON_POSIX_SOURCE ${source_all} )
|
||||||
|
|
86
core/shared/platform/common/posix/posix_clock.c
Normal file
86
core/shared/platform/common/posix/posix_clock.c
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libc_errno.h"
|
||||||
|
#include "platform_api_extension.h"
|
||||||
|
|
||||||
|
#define NANOSECONDS_PER_SECOND 1000000000ULL
|
||||||
|
|
||||||
|
static __wasi_errno_t
|
||||||
|
wasi_clockid_to_clockid(__wasi_clockid_t in, clockid_t *out)
|
||||||
|
{
|
||||||
|
switch (in) {
|
||||||
|
case __WASI_CLOCK_MONOTONIC:
|
||||||
|
*out = CLOCK_MONOTONIC;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
case __WASI_CLOCK_REALTIME:
|
||||||
|
*out = CLOCK_REALTIME;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
|
||||||
|
#if defined(CLOCK_PROCESS_CPUTIME_ID)
|
||||||
|
*out = CLOCK_PROCESS_CPUTIME_ID;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
#else
|
||||||
|
return __WASI_ENOTSUP;
|
||||||
|
#endif
|
||||||
|
case __WASI_CLOCK_THREAD_CPUTIME_ID:
|
||||||
|
#if defined(CLOCK_THREAD_CPUTIME_ID)
|
||||||
|
*out = CLOCK_THREAD_CPUTIME_ID;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
#else
|
||||||
|
return __WASI_ENOTSUP;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return __WASI_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __wasi_timestamp_t
|
||||||
|
timespec_to_nanoseconds(const struct timespec *ts)
|
||||||
|
{
|
||||||
|
if (ts->tv_sec < 0)
|
||||||
|
return 0;
|
||||||
|
if ((__wasi_timestamp_t)ts->tv_sec >= UINT64_MAX / NANOSECONDS_PER_SECOND)
|
||||||
|
return UINT64_MAX;
|
||||||
|
return (__wasi_timestamp_t)ts->tv_sec * NANOSECONDS_PER_SECOND
|
||||||
|
+ (__wasi_timestamp_t)ts->tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution)
|
||||||
|
{
|
||||||
|
clockid_t nclock_id;
|
||||||
|
__wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
|
||||||
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
struct timespec ts;
|
||||||
|
if (clock_getres(nclock_id, &ts) < 0)
|
||||||
|
return convert_errno(errno);
|
||||||
|
|
||||||
|
*resolution = timespec_to_nanoseconds(&ts);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
|
||||||
|
__wasi_timestamp_t *time)
|
||||||
|
{
|
||||||
|
clockid_t nclock_id;
|
||||||
|
__wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
|
||||||
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
struct timespec ts;
|
||||||
|
if (clock_gettime(nclock_id, &ts) < 0)
|
||||||
|
return convert_errno(errno);
|
||||||
|
|
||||||
|
*time = timespec_to_nanoseconds(&ts);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
1007
core/shared/platform/common/posix/posix_file.c
Normal file
1007
core/shared/platform/common/posix/posix_file.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -37,7 +37,7 @@ round_down(uintptr_t v, uintptr_t b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
int map_prot = PROT_NONE;
|
int map_prot = PROT_NONE;
|
||||||
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
|
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
|
||||||
|
@ -114,7 +114,7 @@ os_mmap(void *hint, size_t size, int prot, int flags)
|
||||||
/* try 10 times, step with 1MB each time */
|
/* try 10 times, step with 1MB each time */
|
||||||
for (i = 0; i < 10 && hint_addr < (uint8 *)(uintptr_t)(2ULL * BH_GB);
|
for (i = 0; i < 10 && hint_addr < (uint8 *)(uintptr_t)(2ULL * BH_GB);
|
||||||
i++) {
|
i++) {
|
||||||
addr = mmap(hint_addr, request_size, map_prot, map_flags, -1, 0);
|
addr = mmap(hint_addr, request_size, map_prot, map_flags, file, 0);
|
||||||
if (addr != MAP_FAILED) {
|
if (addr != MAP_FAILED) {
|
||||||
if (addr > (uint8 *)(uintptr_t)(2ULL * BH_GB)) {
|
if (addr > (uint8 *)(uintptr_t)(2ULL * BH_GB)) {
|
||||||
/* unmap and try again if the mapped address doesn't
|
/* unmap and try again if the mapped address doesn't
|
||||||
|
@ -136,7 +136,7 @@ os_mmap(void *hint, size_t size, int prot, int flags)
|
||||||
if (addr == MAP_FAILED) {
|
if (addr == MAP_FAILED) {
|
||||||
/* try 5 times */
|
/* try 5 times */
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
addr = mmap(hint, request_size, map_prot, map_flags, -1, 0);
|
addr = mmap(hint, request_size, map_prot, map_flags, file, 0);
|
||||||
if (addr != MAP_FAILED)
|
if (addr != MAP_FAILED)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user