Merge branch main into dev/exce_handling

This commit is contained in:
Wenyong Huang 2023-12-12 15:25:19 +08:00
commit 0f25b19c25
122 changed files with 2705 additions and 1490 deletions

View File

@ -11,6 +11,9 @@ on:
arch:
required: true
type: string
container_image:
required: false
type: string
outputs:
cache_key:
description: "A cached key of LLVM libraries"
@ -19,6 +22,10 @@ on:
jobs:
build_llvm_libraries:
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:
key: ${{ steps.create_lib_cache_key.outputs.key}}
@ -71,8 +78,9 @@ jobs:
0-ccache-${{ inputs.os }}
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
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
with:

View File

@ -444,6 +444,12 @@ jobs:
cmake --build . --config Release --parallel 4
./iwasm wasm-apps/no_pthread.wasm
- name: Build Sample [shared-module]
run: |
cd samples/shared-module
./build.sh
./run.sh
test:
needs:
[

View File

@ -327,3 +327,9 @@ jobs:
cmake ..
cmake --build . --config Release --parallel 4
./iwasm wasm-apps/no_pthread.wasm
- name: Build Sample [shared-module]
run: |
cd samples/shared-module
./build.sh
./run.sh

View File

@ -50,7 +50,10 @@ env:
jobs:
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:
matrix:
nuttx_board_config: [
@ -60,12 +63,14 @@ jobs:
"boards/arm/rp2040/raspberrypi-pico/configs/nsh",
# cortex-m7
"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",
# riscv64imac
"boards/risc-v/qemu-rv/rv-virt/configs/nsh64",
# 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: [
"CONFIG_INTERPRETERS_WAMR=y\\nCONFIG_INTERPRETERS_WAMR_AOT=y\\nCONFIG_INTERPRETERS_WAMR_FAST=y\\n",
@ -81,39 +86,18 @@ jobs:
]
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 https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v12.3.0-1/xpack-riscv-none-elf-gcc-12.3.0-1-linux-x64.tar.gz > riscv.tar.gz
tar xvf riscv.tar.gz
echo "$PWD/xpack-riscv-none-elf-gcc-12.3.0-1/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
uses: actions/checkout@v3
with:
repository: apache/incubator-nuttx
ref: releases/12.3
path: nuttx
- name: Checkout NuttX Apps
uses: actions/checkout@v3
with:
repository: apache/incubator-nuttx-apps
ref: releases/12.3
path: apps
- name: Checkout WAMR
@ -124,7 +108,7 @@ jobs:
- name: Enable WAMR for NuttX
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'
- name: Build

View File

@ -501,6 +501,12 @@ jobs:
cmake ..
cmake --build . --config Release --parallel 4
./iwasm wasm-apps/no_pthread.wasm
- name: Build Sample [shared-module]
run: |
cd samples/shared-module
./build.sh
./run.sh
test:
needs:
[
@ -660,7 +666,7 @@ jobs:
- name: run tests
timeout-minutes: 40
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} -T %{{matrix.sanitizer}}
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} -T "${{ matrix.sanitizer }}"
working-directory: ./tests/wamr-test-suites
#only install x32 support libraries when to run x86_32 cases

View File

@ -56,21 +56,21 @@ jobs:
uses: ./.github/workflows/build_llvm_libraries.yml
with:
os: "ubuntu-20.04"
arch: "X86"
arch: "AArch64 ARM Mips RISCV X86"
build_llvm_libraries_on_ubuntu_2204:
needs: [create_tag, create_release]
uses: ./.github/workflows/build_llvm_libraries.yml
with:
os: "ubuntu-22.04"
arch: "X86"
arch: "AArch64 ARM Mips RISCV X86"
build_llvm_libraries_on_macos:
needs: [create_tag, create_release]
uses: ./.github/workflows/build_llvm_libraries.yml
with:
os: "macos-latest"
arch: "X86"
arch: "AArch64 ARM Mips RISCV X86"
#
# WAMRC

View File

@ -4,6 +4,13 @@
name: spec test on nuttx
on:
pull_request:
types:
- opened
- synchronize
paths:
- ".github/workflows/spec_test_on_nuttx.yml"
schedule:
- cron: '0 0 * * *'
@ -12,6 +19,8 @@ on:
env:
LLVM_CACHE_SUFFIX: "build-llvm_libraries_ex"
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:
build_llvm_libraries:
@ -19,59 +28,85 @@ jobs:
with:
os: "ubuntu-22.04"
arch: "ARM RISCV AArch64"
container_image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:4b4cbf0b70512e61ada9cdcb76b97e90ad478b85e4d0774d05a95fa32caa8c39
spec_test_on_qemu:
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
needs: [build_llvm_libraries]
container:
image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:4b4cbf0b70512e61ada9cdcb76b97e90ad478b85e4d0774d05a95fa32caa8c39
strategy:
matrix:
os: [ubuntu-22.04]
nuttx_board_config: [
# cortex-a9
"boards/arm/imx6/sabre-6quad/configs/nsh",
# riscv32imac
"boards/risc-v/qemu-rv/rv-virt/configs/nsh",
# riscv64imac
# "boards/risc-v/qemu-rv/rv-virt/configs/nsh64",
target_config: [
# {
# config: "boards/arm64/qemu/qemu-armv8a/configs/nsh",
# target: "aarch64_vfp",
# fpu_type: "fp"
# },
# {
# 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: [
# "-t fast-interp",
"-t aot",
"-t aot -X"
{
mode: "-t aot",
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:
- 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 https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v12.3.0-1/xpack-riscv-none-elf-gcc-12.3.0-1-linux-x64.tar.gz > riscv.tar.gz
tar xvf riscv.tar.gz
echo "$PWD/xpack-riscv-none-elf-gcc-12.3.0-1/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
uses: actions/checkout@v3
with:
repository: apache/incubator-nuttx
ref: releases/12.3
path: nuttx
- name: Checkout NuttX Apps
uses: actions/checkout@v3
with:
repository: apache/incubator-nuttx-apps
ref: releases/12.3
path: apps
- name: Checkout WAMR
@ -81,6 +116,7 @@ jobs:
path: apps/interpreters/wamr/wamr
- name: Get LLVM libraries
if: contains(matrix.wamr_test_option.mode, 'aot')
id: retrieve_llvm_libs
uses: actions/cache@v3
with:
@ -90,56 +126,50 @@ jobs:
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
key: ${{ needs.build_llvm_libraries.outputs.cache_key }}
- 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
- name: Copy LLVM
if: contains(matrix.wamr_test_option.mode, 'aot')
run: cp -r core/deps/llvm apps/interpreters/wamr/wamr/core/deps/llvm
- name: Enable WAMR for NuttX
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\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'
find nuttx/boards -name defconfig | xargs sed -i '$a\${{ env.WAMR_COMMON_OPTION }}'
- 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
if: contains(matrix.wamr_test_option.mode, 'aot')
working-directory: apps/interpreters/wamr/wamr/wamr-compiler
run: |
cmake -Bbuild .
cmake --build build
- name: Build
id: build_firmware
run: |
cd nuttx
tools/configure.sh ${{ matrix.nuttx_board_config }}
tools/configure.sh ${{ matrix.target_config.config }}
make -j$(nproc)
echo "firmware=$PWD/nuttx" >> $GITHUB_ENV
echo "firmware=$PWD/nuttx" >> $GITHUB_OUTPUT
- name: Test on ARM
if: endsWith(matrix.nuttx_board_config, 'sabre-6quad/configs/nsh')
- name: Test
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
./test_wamr.sh -s spec ${{ matrix.wamr_test_option }} -m thumbv7_vfp -b -Q -P -F ${{ env.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 }}
./test_wamr.sh -s spec ${{ matrix.wamr_test_option.mode }} -m ${{ matrix.target_config.target }} -b -Q -P -F ${{ steps.build_firmware.outputs.firmware }}

View File

@ -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
### Breaking Changes

View File

@ -55,8 +55,6 @@ def build_llvm(llvm_dir, platform, backends, projects, use_clang=False, extra_fl
"-DLLVM_APPEND_VC_REV:BOOL=ON",
"-DLLVM_BUILD_EXAMPLES: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_IDE:BOOL=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_UTILS:BOOL=OFF",
"-DLLVM_INCLUDE_TESTS:BOOL=OFF",
"-DLLVM_BUILD_TESTS:BOOL=OFF",
"-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
if not sys.platform.startswith("darwin") and use_clang:
if shutil.which("clang") and shutil.which("clang++") and shutil.which("lld"):

View File

@ -122,6 +122,11 @@ if (WAMR_BUILD_JIT EQUAL 1)
if (CXX_SUPPORTS_REDUNDANT_MOVE_FLAG)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-redundant-move")
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 ()
else ()
unset (LLVM_AVAILABLE_LIBS)

View File

@ -1,8 +1,8 @@
# 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%">

View File

@ -6,8 +6,14 @@
#include "app_manager.h"
#include "bh_platform.h"
#include <autoconf.h>
#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */
#include <zephyr.h>
#include <kernel.h>
#else
#include <zephyr/kernel.h>
#endif
#if 0
#include <sigverify.h>
#endif

View File

@ -485,7 +485,7 @@
/* Some chip cannot support external ram with rwx attr at the same time,
it has to map it into 2 spaces of idbus and dbus, code in dbus can be
read/written and read/executed in ibus. so there are 2 steps to execute
the code, first, copy&do relocaiton in dbus space, and second execute
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,
so we call it bus mirror.
*/

View File

@ -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]->elem_type = elem_type;
data_list[i]->is_dropped = false;
data_list[i]->table_index = table_index;
data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
data_list[i]->offset.u.i64 = (int64)init_expr_value;

View File

@ -605,7 +605,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
#if WASM_ENABLE_SHARED_MEMORY != 0
if (is_shared_memory) {
memory_inst->is_shared_memory = true;
memory_inst->is_shared_memory = 1;
memory_inst->ref_count = 1;
}
#endif
@ -1098,6 +1098,9 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
char *error_buf, uint32 error_buf_size)
{
AOTModuleInstance *module_inst;
#if WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_REF_TYPES != 0
WASMModuleInstanceExtraCommon *common;
#endif
const uint32 module_inst_struct_size =
offsetof(AOTModuleInstance, global_table_data.bytes);
const uint64 module_inst_mem_inst_size =
@ -1164,6 +1167,32 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
}
#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 */
p = (uint8 *)module_inst + module_inst_struct_size
+ module_inst_mem_inst_size;
@ -1264,6 +1293,8 @@ fail:
void
aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
{
WASMModuleInstanceExtraCommon *common =
&((AOTModuleInstanceExtra *)module_inst->e)->common;
if (module_inst->exec_env_singleton) {
/* wasm_exec_env_destroy will call
wasm_cluster_wait_for_all_except_self to wait for other
@ -1306,7 +1337,7 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
if (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)
->common.c_api_func_imports);
@ -1317,6 +1348,13 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_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);
}
@ -2302,13 +2340,21 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
{
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
AOTModule *aot_module;
uint8 *data = NULL;
uint8 *data;
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;
seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
data = aot_module->mem_init_data_list[seg_index]->bytes;
}
if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
dst, len))
@ -2331,9 +2377,9 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
bool
aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
{
AOTModule *aot_module = (AOTModule *)module_inst->module;
aot_module->mem_init_data_list[seg_index]->byte_count = 0;
bh_bitmap_set_bit(
((AOTModuleInstanceExtra *)module_inst->e)->common.data_dropped,
seg_index);
/* Currently we can't free the dropped data segment
as the mem_init_data_count is a continuous array */
return true;
@ -2546,9 +2592,9 @@ aot_get_module_inst_mem_consumption(const AOTModuleInstance *module_inst,
void
aot_drop_table_seg(AOTModuleInstance *module_inst, uint32 tbl_seg_idx)
{
AOTModule *module = (AOTModule *)module_inst->module;
AOTTableInitData *tbl_seg = module->table_init_data_list[tbl_seg_idx];
tbl_seg->is_dropped = true;
bh_bitmap_set_bit(
((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
tbl_seg_idx);
}
void
@ -2576,7 +2622,9 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
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);
return;
}
@ -2917,13 +2965,15 @@ aot_dump_perf_profiling(const AOTModuleInstance *module_inst)
func_name = get_func_name_from_index(module_inst, i);
if (func_name)
os_printf(" func %s, execution time: %.3f ms, execution count: %d "
"times\n",
os_printf(
" func %s, execution time: %.3f ms, execution count: %" PRIu32
" times\n",
func_name, perf_prof->total_exec_time / 1000.0f,
perf_prof->total_exec_cnt);
else
os_printf(" func %d, execution time: %.3f ms, execution count: %d "
"times\n",
os_printf(" func %" PRIu32
", execution time: %.3f ms, execution count: %" PRIu32
" times\n",
i, perf_prof->total_exec_time / 1000.0f,
perf_prof->total_exec_cnt);
}

View File

@ -11,21 +11,52 @@
#define R_RISCV_CALL_PLT 19
#define R_RISCV_PCREL_HI20 23
#define R_RISCV_PCREL_LO12_I 24
#define R_RISCV_PCREL_LO12_S 25
#define R_RISCV_HI20 26
#define R_RISCV_LO12_I 27
#define R_RISCV_LO12_S 28
#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 */
void __adddf3();
void __addsf3();
void __divdi3();
void __divsi3();
void __divdf3();
void __divdi3();
void __divsf3();
void __eqsf2();
void __divsi3();
void __eqdf2();
void __eqsf2();
void __extendsfdf2();
void __fixdfdi();
void __fixdfsi();
@ -37,12 +68,12 @@ void __fixunssfdi();
void __fixunssfsi();
void __floatdidf();
void __floatdisf();
void __floatsisf();
void __floatsidf();
void __floatsisf();
void __floatundidf();
void __floatundisf();
void __floatunsisf();
void __floatunsidf();
void __floatunsisf();
void __gedf2();
void __gesf2();
void __gtdf2();
@ -58,6 +89,8 @@ void __muldi3();
void __mulsf3();
void __mulsi3();
void __nedf2();
void __negdf2();
void __negsf2();
void __nesf2();
void __subdf3();
void __subsf3();
@ -73,60 +106,74 @@ void __unordsf2();
static SymbolMap target_sym_map[] = {
/* clang-format off */
REG_COMMON_SYMBOLS
#ifndef __riscv_flen
REG_SYM(__adddf3),
#ifdef NEED_SOFT_FP
REG_SYM(__addsf3),
REG_SYM(__divdf3),
REG_SYM(__divsf3),
REG_SYM(__eqdf2),
REG_SYM(__eqsf2),
REG_SYM(__extendsfdf2),
REG_SYM(__fixunsdfdi),
REG_SYM(__fixunsdfsi),
REG_SYM(__fixsfdi),
REG_SYM(__fixunssfdi),
REG_SYM(__fixunssfsi),
REG_SYM(__gedf2),
REG_SYM(__floatsidf),
REG_SYM(__gesf2),
REG_SYM(__gtdf2),
REG_SYM(__gtsf2),
REG_SYM(__ledf2),
REG_SYM(__lesf2),
REG_SYM(__ltdf2),
REG_SYM(__ltsf2),
REG_SYM(__mulsf3),
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(__nedf2),
REG_SYM(__nesf2),
REG_SYM(__negdf2),
REG_SYM(__subdf3),
REG_SYM(__subsf3),
REG_SYM(__truncdfsf2),
REG_SYM(__unorddf2),
REG_SYM(__unordsf2),
#if __riscv_xlen == 32
#elif __riscv_xlen == 32
/* rv32d, support DP instruction but need soft routines
* to convert double and long long
*/
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(__floatundisf),
REG_SYM(__floatunsidf),
REG_SYM(__floatunsisf),
REG_SYM(__mulsf3),
#endif
#ifdef NEED_SOFT_I32_MUL
REG_SYM(__mulsi3),
#endif
#endif
REG_SYM(__divdi3),
#ifdef NEED_SOFT_I32_DIV
REG_SYM(__divsi3),
REG_SYM(__moddi3),
REG_SYM(__modsi3),
REG_SYM(__muldi3),
REG_SYM(__udivdi3),
REG_SYM(__udivsi3),
REG_SYM(__umoddi3),
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 */
};
@ -177,7 +224,11 @@ rv_set_val(uint16 *addr, uint32 val)
*addr = (val & 0xffff);
*(addr + 1) = (val >> 16);
#ifdef __riscv_zifencei
__asm__ volatile("fence.i");
#else
__asm__ volatile("fence");
#endif
}
/* Add a val to given address */
@ -265,9 +316,10 @@ typedef struct RelocTypeStrMap {
}
static RelocTypeStrMap reloc_type_str_maps[] = {
RELOC_TYPE_MAP(R_RISCV_32), RELOC_TYPE_MAP(R_RISCV_CALL),
RELOC_TYPE_MAP(R_RISCV_CALL_PLT), RELOC_TYPE_MAP(R_RISCV_PCREL_HI20),
RELOC_TYPE_MAP(R_RISCV_PCREL_LO12_I), RELOC_TYPE_MAP(R_RISCV_HI20),
RELOC_TYPE_MAP(R_RISCV_32), RELOC_TYPE_MAP(R_RISCV_64),
RELOC_TYPE_MAP(R_RISCV_CALL), RELOC_TYPE_MAP(R_RISCV_CALL_PLT),
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),
};
@ -323,21 +375,37 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
rv_set_val((uint16 *)addr, val_32);
break;
}
#if __riscv_xlen == 64
case R_RISCV_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));
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);
#ifdef __riscv_zifencei
__asm__ volatile("fence.i");
#else
__asm__ volatile("fence");
#endif
break;
}
#endif
case R_RISCV_CALL:
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));
if (val != (intptr_t)((uint8 *)symbol_addr - addr)) {
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend - addr)) {
if (symbol_index >= 0) {
/* Call runtime function by plt code */
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;
}
@ -369,31 +437,14 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
}
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);
}
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)) {
goto fail_addr_out_of_range;
}
}
addr = target_section_addr + reloc_offset;
insn = rv_get_val((uint16 *)addr);
rv_calc_imm(val, &imm_hi, &imm_lo);
insn = (insn & 0x00000fff) | (imm_hi << 12);
@ -401,28 +452,45 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
break;
}
case R_RISCV_LO12_I: /* S + A */
case R_RISCV_PCREL_LO12_I: /* S - P */
case R_RISCV_PCREL_LO12_S: /* S - P */
{
if (reloc_type == R_RISCV_PCREL_LO12_I) {
/* A = 0 */
val = (int32)((intptr_t)symbol_addr - (intptr_t)addr);
/* Already handled in R_RISCV_PCREL_HI20, it should be skipped for
* most cases. But it is still needed for some special cases, e.g.
* ```
* 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 {
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
break;
}
case R_RISCV_LO12_I: /* S + A */
{
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
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) {
goto fail_addr_out_of_range;
}
}
addr = target_section_addr + reloc_offset;
insn = rv_get_val((uint16 *)addr);

View File

@ -600,7 +600,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
{
#if UINTPTR_MAX == UINT32_MAX
if (argv1[k] != 0 && argv1[k] != (uint32)-1)
os_printf("0x%" PRIxPTR ":ref.extern", (void *)argv1[k]);
os_printf("0x%" PRIxPTR ":ref.extern", (uintptr_t)argv1[k]);
else
os_printf("extern:ref.null");
k++;
@ -613,7 +613,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
u.parts[1] = argv1[k + 1];
k += 2;
if (u.val && u.val != (uintptr_t)-1LL)
os_printf("0x%" PRIxPTR ":ref.extern", (void *)u.val);
os_printf("0x%" PRIxPTR ":ref.extern", u.val);
else
os_printf("extern:ref.null");
#endif

View File

@ -292,13 +292,46 @@ WASM_DEFINE_VEC_OWN(valtype, wasm_valtype_delete)
own wasm_config_t *
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;
memset(config, 0, sizeof(wasm_config_t));
config->mem_alloc_type = Alloc_With_System_Allocator;
return config;
}
void
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
@ -329,12 +362,11 @@ wasm_engine_delete_internal(wasm_engine_t *engine)
}
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;
/* init runtime */
RuntimeInitArgs init_args = { 0 };
init_args.mem_alloc_type = type;
#ifndef NDEBUG
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();
if (type == Alloc_With_Pool) {
if (!opts) {
return NULL;
}
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;
}
/* wasm_config_t->MemAllocOption -> RuntimeInitArgs->MemAllocOption */
init_args.mem_alloc_type = config->mem_alloc_type;
memcpy(&init_args.mem_alloc_option, &config->mem_alloc_option,
sizeof(MemAllocOption));
init_args.linux_perf_support = config->linux_perf_support;
if (!wasm_runtime_full_init(&init_args)) {
LOG_DEBUG("wasm_runtime_full_init failed");
@ -418,14 +427,23 @@ static korp_mutex engine_lock = OS_THREAD_MUTEX_INITIALIZER;
#endif
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)
os_mutex_lock(&engine_lock);
#endif
if (!singleton_engine)
singleton_engine = wasm_engine_new_internal(type, opts);
singleton_engine = wasm_engine_new_internal(config);
else
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 *
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);
}
own wasm_engine_t *
wasm_engine_new_with_config(own wasm_config_t *config)
{
(void)config;
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));
return wasm_engine_new_with_config(&config);
}
void

View File

@ -95,7 +95,7 @@ wasm_memory_init_with_allocator(void *_malloc_func, void *_realloc_func,
static inline bool
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);
#else
return true;
@ -686,7 +686,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
memory->num_bytes_per_page = num_bytes_per_page;
memory->cur_page_count = total_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;
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
@ -844,7 +844,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
memory->num_bytes_per_page = num_bytes_per_page;
memory->cur_page_count = total_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;
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);

View File

@ -14,6 +14,16 @@
extern "C" {
#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
wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
const MemAllocOption *alloc_option);

View File

@ -158,7 +158,7 @@ static JitCompOptions jit_options = { 0 };
#endif
#if WASM_ENABLE_JIT != 0
static LLVMJITOptions llvm_jit_options = { 3, 3, 0 };
static LLVMJITOptions llvm_jit_options = { 3, 3, 0, false };
#endif
static RunningMode runtime_running_mode = Mode_Default;
@ -662,9 +662,14 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
#endif
#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.opt_level = init_args->llvm_jit_opt_level;
llvm_jit_options.segue_flags = init_args->segue_flags;
llvm_jit_options.linux_perf_support = init_args->linux_perf_support;
#endif
if (!wasm_runtime_env_init()) {
@ -2581,7 +2586,7 @@ wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst_comm)
return module_inst->custom_data;
}
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
void
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
bool enable)
@ -4018,17 +4023,15 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
if (n_stacks & 1)
n_stacks++;
if (func_type->types[i] == VALUE_TYPE_F32) {
*(float32 *)&stacks[n_stacks] = *(float32 *)argv_src++;
/* NaN boxing, the upper bits of a valid NaN-boxed
value must be all 1s. */
stacks[n_stacks + 1] = 0xFFFFFFFF;
*(float32 *)&stacks[n_stacks++] =
*(float32 *)argv_src++;
}
else {
*(float64 *)&stacks[n_stacks] = *(float64 *)argv_src;
argv_src += 2;
}
n_stacks += 2;
}
}
break;
}
#endif /* BUILD_TARGET_RISCV32_ILP32D */
@ -5868,7 +5871,7 @@ wasm_runtime_register_sub_module(const WASMModuleCommon *parent_module,
{
/* register sub_module into its parent sub module list */
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)) {
LOG_DEBUG("%s has been registered in its parent", sub_module_name);

View File

@ -54,6 +54,12 @@ STORE_U16(void *addr, uint16_t value)
{
*(uint16_t *)(addr) = (uint16_t)(value);
}
static inline void
STORE_U8(void *addr, uint8_t value)
{
*(uint8 *)addr = value;
}
/* For LOAD opcodes */
#define LOAD_I64(addr) (*(int64 *)(addr))
#define LOAD_F64(addr) (*(float64 *)(addr))
@ -173,6 +179,13 @@ STORE_U32(void *addr, uint32_t value)
}
}
}
static inline void
STORE_U8(void *addr, uint8_t value)
{
*(uint8 *)addr = value;
}
static inline void
STORE_U16(void *addr, uint16_t value)
{
@ -430,6 +443,7 @@ typedef struct LLVMJITOptions {
uint32 opt_level;
uint32 size_level;
uint32 segue_flags;
bool linux_perf_support;
} LLVMJITOptions;
#endif
@ -603,7 +617,7 @@ wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data);
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_user_data(WASMExecEnv *exec_env);
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,

View File

@ -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]->elem_type = module->table_segments[i].elem_type;
/* runtime control it */
data_list[i]->is_dropped = false;
data_list[i]->table_index = module->table_segments[i].table_index;
bh_memcpy_s(&data_list[i]->offset, sizeof(AOTInitExpr),
&module->table_segments[i].base_offset,

View File

@ -143,7 +143,6 @@ typedef struct AOTTableInitData {
uint32 mode;
/* funcref or externref, elemkind will be considered as funcref */
uint32 elem_type;
bool is_dropped;
/* optional, only for active */
uint32 table_index;
/* Start address of init data */

View File

@ -269,7 +269,7 @@ static uint32
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
* bytes)

View File

@ -202,6 +202,9 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
*p_frame_ip = block->wasm_code_else + 1;
/* Push back the 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;
}
else if (block->llvm_end_block) {
@ -221,6 +224,19 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
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;
SET_BUILDER_POS(block->llvm_end_block);

View File

@ -22,11 +22,14 @@ static bool
is_win_platform(AOTCompContext *comp_ctx)
{
char *triple = LLVMGetTargetMachineTriple(comp_ctx->target_machine);
bool ret;
bh_assert(triple);
if (strstr(triple, "win32") || strstr(triple, "win"))
return true;
return false;
ret = (strstr(triple, "win32") || strstr(triple, "win")) ? true : false;
LLVMDisposeMessage(triple);
return ret;
}
static bool

View File

@ -653,6 +653,20 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
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 (!comp_ctx->is_jit_mode)
LLVMSetLinkage(func, LLVMInternalLinkage);
@ -1938,13 +1952,33 @@ static void
print_supported_targets()
{
uint32 i;
const char *target_name;
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++) {
os_printf("%s ", valid_archs[i].arch);
if (valid_archs[i].support_eb)
os_printf("%seb ", valid_archs[i].arch);
/* If target_name is prefix for valid_archs[i].arch */
if ((strncmp(target_name, valid_archs[i].arch,
strlen(target_name))
== 0))
os_printf(" %s\n", valid_archs[i].arch);
}
}
}
os_printf("\n");
}
static void
@ -2140,7 +2174,7 @@ jit_stack_size_callback(void *user_data, const char *name, size_t namelen,
}
static bool
orc_jit_create(AOTCompContext *comp_ctx)
orc_jit_create(AOTCompContext *comp_ctx, bool linux_perf_support)
{
LLVMErrorRef err;
LLVMOrcLLLazyJITRef orc_jit = NULL;
@ -2180,6 +2214,14 @@ orc_jit_create(AOTCompContext *comp_ctx)
/* Ownership transfer: LLVMOrcLLJITBuilderRef -> LLVMOrcLLJITRef */
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 */
comp_ctx->orc_jit = orc_jit;
orc_jit = NULL;
@ -2278,6 +2320,17 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
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)) {
goto fail;
}
@ -2381,7 +2434,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
goto fail;
/* Create LLJIT Instance */
if (!orc_jit_create(comp_ctx))
if (!orc_jit_create(comp_ctx, option->linux_perf_support))
goto fail;
}
else {
@ -2656,15 +2709,16 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
meta_target_abi);
if (!strcmp(abi, "lp64d") || !strcmp(abi, "ilp32d")) {
if (features) {
if (features && !strstr(features, "+d")) {
snprintf(features_buf, sizeof(features_buf), "%s%s",
features, ",+d");
features = features_buf;
}
else
else if (!features) {
features = "+d";
}
}
}
if (!features)
features = "";

View File

@ -12,6 +12,7 @@
#include "llvm-c/Target.h"
#include "llvm-c/Core.h"
#include "llvm-c/Object.h"
#include "llvm-c/OrcEE.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Analysis.h"
#include "llvm-c/BitWriter.h"
@ -422,6 +423,8 @@ typedef struct AOTCompContext {
char stack_usage_temp_file[64];
const char *llvm_passes;
const char *builtin_intrinsics;
bool emit_frame_pointer;
} AOTCompContext;
enum {
@ -431,6 +434,7 @@ enum {
AOT_LLVMIR_OPT_FILE,
};
/* always sync it with AOTCompOption in aot_export.h */
typedef struct AOTCompOption {
bool is_jit_mode;
bool is_indirect_mode;
@ -457,6 +461,7 @@ typedef struct AOTCompOption {
uint32 bounds_checks;
uint32 stack_bounds_checks;
uint32 segue_flags;
bool linux_perf_support;
char **custom_sections;
uint32 custom_sections_count;
const char *stack_usage_file;

View File

@ -36,6 +36,7 @@
#include <llvm/Support/ErrorHandling.h>
#if LLVM_VERSION_MAJOR >= 17
#include <llvm/Support/PGOOptions.h>
#include <llvm/Support/VirtualFileSystem.h>
#endif
#include <llvm/Target/CodeGenCWrappers.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;
#endif
// TODO
#if LLVM_VERSION_MAJOR < 17
if (comp_ctx->enable_llvm_pgo) {
/* Disable static counter allocation for value profiler,
it will be allocated by runtime */
const char *argv[] = { "", "-vp-static-alloc=false" };
cl::ParseCommandLineOptions(2, argv);
#if LLVM_VERSION_MAJOR < 17
PGO = PGOOptions("", "", "", PGOOptions::IRInstr);
#else
auto FS = vfs::getRealFileSystem();
PGO = PGOOptions("", "", "", "", FS, PGOOptions::IRInstr);
#endif
}
else if (comp_ctx->use_prof_file) {
#if LLVM_VERSION_MAJOR < 17
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
}
#ifdef DEBUG_PASS
PassInstrumentationCallbacks PIC;
@ -343,7 +352,13 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
ExitOnErr(PB.parsePassPipeline(MPM, comp_ctx->llvm_passes));
}
if (OptimizationLevel::O0 == OL) {
if (
#if LLVM_VERSION_MAJOR <= 13
PassBuilder::OptimizationLevel::O0 == OL
#else
OptimizationLevel::O0 == OL
#endif
) {
MPM.addPass(PB.buildO0DefaultPipeline(OL));
}
else {

View File

@ -12,11 +12,13 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#endif
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Support/CBindingWrapping.h"
@ -108,6 +110,7 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectTransformLayer,
LLVMOrcObjectTransformLayerRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,
LLVMOrcSymbolStringPoolEntryRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
@ -322,3 +325,9 @@ LLVMOrcLLLazyJITGetObjTransformLayer(LLVMOrcLLLazyJITRef J)
{
return wrap(&unwrap(J)->getObjTransformLayer());
}
LLVMOrcObjectLayerRef
LLVMOrcLLLazyJITGetObjLinkingLayer(LLVMOrcLLLazyJITRef J)
{
return wrap(&unwrap(J)->getObjLinkingLayer());
}

View File

@ -76,5 +76,8 @@ LLVMOrcLLJITBuilderSetCompileFuncitonCreatorWithStackSizesCallback(
LLVMOrcLLLazyJITBuilderRef Builder,
void (*cb)(void *, const char *, size_t, size_t), void *cb_data);
LLVMOrcObjectLayerRef
LLVMOrcLLLazyJITGetObjLinkingLayer(LLVMOrcLLLazyJITRef J);
LLVM_C_EXTERN_C_END
#endif

View File

@ -137,6 +137,7 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
{
JitReg memory_boundary = 0, offset1;
#ifndef OS_ENABLE_HW_BOUND_CHECK
JitReg cur_page_count;
/* the default memory */
uint32 mem_idx = 0;
#endif
@ -146,16 +147,10 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
/* 1. shortcut if the memory size is 0 */
if (cc->cur_wasm_module->memories != NULL
&& 0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) {
JitReg module_inst, cur_page_count;
uint32 cur_page_count_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
cur_page_count = get_cur_page_count_reg(cc->jit_frame, mem_idx);
/* 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));
if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
JIT_OP_BEQ, cc->cmp_reg, NULL)) {
@ -580,15 +575,9 @@ fail:
bool
jit_compile_op_memory_size(JitCompContext *cc, uint32 mem_idx)
{
JitReg module_inst, cur_page_count;
uint32 cur_page_count_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
JitReg cur_page_count;
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));
cur_page_count = get_cur_page_count_reg(cc->jit_frame, mem_idx);
PUSH_I32(cur_page_count);
@ -600,18 +589,11 @@ fail:
bool
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];
/* Get current 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);
prev_page_count = jit_cc_new_reg_I32(cc);
GEN_INSN(LDI32, prev_page_count, module_inst,
NEW_CONST(I32, cur_page_count_offset));
/* Get current page count as prev_page_count */
prev_page_count = get_cur_page_count_reg(cc->jit_frame, mem_idx);
/* Call wasm_enlarge_memory */
POP_I32(inc_page_count);
@ -650,6 +632,7 @@ wasm_init_memory(WASMModuleInstance *inst, uint32 mem_idx, uint32 seg_idx,
WASMDataSeg *data_segment;
uint32 mem_size;
uint8 *mem_addr, *data_addr;
uint32 seg_len;
/* if d + n > the length of mem.data */
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 */
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];
if (data_segment->data_length < data_offset
|| data_segment->data_length - data_offset < len)
seg_len = data_segment->data_length;
data_addr = data_segment->data + data_offset;
}
if (seg_len < data_offset || seg_len - data_offset < len)
goto out_of_bounds;
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);
return 0;
@ -706,21 +695,22 @@ fail:
return false;
}
static void
wasm_data_drop(WASMModuleInstance *inst, uint32 seg_idx)
{
bh_bitmap_set_bit(inst->e->common.data_dropped, seg_idx);
}
bool
jit_compile_op_data_drop(JitCompContext *cc, uint32 seg_idx)
{
JitReg module = get_module_reg(cc->jit_frame);
JitReg data_segments = jit_cc_new_reg_ptr(cc);
JitReg data_segment = jit_cc_new_reg_ptr(cc);
JitReg args[2] = { 0 };
GEN_INSN(LDPTR, data_segments, module,
NEW_CONST(I32, offsetof(WASMModule, data_segments)));
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)));
args[0] = get_module_inst_reg(cc->jit_frame);
args[1] = NEW_CONST(I32, seg_idx);
return true;
return jit_emit_callnative(cc, wasm_data_drop, 0, args,
sizeof(args) / sizeof(args[0]));
}
static int

View File

@ -10,21 +10,22 @@
#include "../jit_frontend.h"
#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
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);
GEN_INSN(LDPTR, tbl_segs, module,
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;
return jit_emit_callnative(cc, wasm_elem_drop, 0, args,
sizeof(args) / sizeof(args[0]));
}
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))
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)
+ dst_offset * sizeof(uint32),
(uint32)((tbl_sz - dst_offset) * sizeof(uint32)),

View File

@ -70,6 +70,7 @@ typedef struct JitInterpSwitchInfo {
typedef struct JitCompOptions {
uint32 code_cache_size;
uint32 opt_level;
bool linux_perf_support;
} JitCompOptions;
bool

View File

@ -218,42 +218,149 @@ get_aux_stack_bottom_reg(JitFrame *frame)
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
get_memory_data_reg(JitFrame *frame, uint32 mem_idx)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
JitReg module_inst_reg;
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);
#if WASM_ENABLE_SHARED_MEMORY != 0
uint32 memories_offset = (uint32)offsetof(WASMModuleInstance, memories);
JitReg memories_addr = jit_cc_new_reg_ptr(cc);
JitReg memories_0_addr = jit_cc_new_reg_ptr(cc);
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_offset = (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;
/* 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 */
/* memories[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 =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (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,
module_inst_reg, NEW_CONST(I32, memory_data_offset));
}
#endif
return frame->memory_regs[mem_idx].memory_data;
}
@ -261,16 +368,37 @@ JitReg
get_memory_data_end_reg(JitFrame *frame, uint32 mem_idx)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 memory_data_end_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, memory_data_end);
JitReg module_inst_reg;
uint32 memory_data_end_offset;
#if WASM_ENABLE_SHARED_MEMORY != 0
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 =
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,
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)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_1byte_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_1byte);
JitReg module_inst_reg;
uint32 mem_bound_check_1byte_offset;
#if WASM_ENABLE_SHARED_MEMORY != 0
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);
if (!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;
#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);
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
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_1byte,
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)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_2bytes_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_2bytes);
JitReg module_inst_reg;
uint32 mem_bound_check_2bytes_offset;
#if WASM_ENABLE_SHARED_MEMORY != 0
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);
if (!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;
#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);
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
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
module_inst_reg,
@ -333,16 +517,45 @@ JitReg
get_mem_bound_check_4bytes_reg(JitFrame *frame, uint32 mem_idx)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_4bytes_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_4bytes);
JitReg module_inst_reg;
uint32 mem_bound_check_4bytes_offset;
#if WASM_ENABLE_SHARED_MEMORY != 0
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);
if (!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;
#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);
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
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
module_inst_reg,
@ -360,16 +573,45 @@ JitReg
get_mem_bound_check_8bytes_reg(JitFrame *frame, uint32 mem_idx)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_8bytes_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_8bytes);
JitReg module_inst_reg;
uint32 mem_bound_check_8bytes_offset;
#if WASM_ENABLE_SHARED_MEMORY != 0
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);
if (!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;
#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);
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
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
module_inst_reg,
@ -387,16 +629,45 @@ JitReg
get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_16bytes_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_16bytes);
JitReg module_inst_reg;
uint32 mem_bound_check_16bytes_offset;
#if WASM_ENABLE_SHARED_MEMORY != 0
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);
if (!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;
#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);
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
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
module_inst_reg,
@ -462,6 +733,8 @@ clear_fixed_virtual_regs(JitFrame *frame)
count = module->import_memory_count + module->memory_count;
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_end = 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;
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_end = 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++) {
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_end = jit_cc_new_reg_ptr(cc);
cc->memory_regs[i].mem_bound_check_1byte = jit_cc_new_reg_ptr(cc);

View File

@ -192,6 +192,12 @@ get_aux_stack_bound_reg(JitFrame *frame);
JitReg
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
get_memory_data_reg(JitFrame *frame, uint32 mem_idx);

View File

@ -866,6 +866,8 @@ typedef struct JitValueSlot {
typedef struct JitMemRegs {
/* The following registers should be re-loaded after
memory.grow, callbc and callnative */
JitReg memory_inst;
JitReg cur_page_count;
JitReg memory_data;
JitReg memory_data_end;
JitReg mem_bound_check_1byte;

View File

@ -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;
}

View File

@ -12,20 +12,6 @@
extern "C" {
#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 *
jit_malloc(unsigned int size)
{
@ -49,86 +35,6 @@ jit_free(void *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
}
#endif

View File

@ -38,6 +38,7 @@ enum {
AOT_LLVMIR_OPT_FILE,
};
/* always sync it with AOTCompOption in compilation/aot_llvm.h */
typedef struct AOTCompOption {
bool is_jit_mode;
bool is_indirect_mode;
@ -64,6 +65,7 @@ typedef struct AOTCompOption {
uint32_t bounds_checks;
uint32_t stack_bounds_checks;
uint32_t segue_flags;
bool linux_perf_support;
char **custom_sections;
uint32_t custom_sections_count;
const char *stack_usage_file;

View File

@ -21,6 +21,15 @@
#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
extern "C" {
#endif
@ -136,31 +145,6 @@ static inline void wasm_name_new_from_string_nt(
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
#define MEM_ALLOC_OPTION_DEFINED
/* same definition from wasm_export.h */
@ -191,9 +175,51 @@ typedef union MemAllocOption {
void *user_data;
} allocator;
} 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);
// Store

View File

@ -169,6 +169,15 @@ typedef struct RuntimeInitArgs {
uint32_t llvm_jit_size_level;
/* Segue optimization flags for LLVM JIT */
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;
#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
*/
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);
/**
@ -871,6 +881,7 @@ wasm_application_execute_main(wasm_module_inst_t module_inst,
WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_func(wasm_module_inst_t module_inst,
const char *name, int32_t argc, char *argv[]);
/**
* Get exception info of the WASM module instance.
*
@ -933,6 +944,7 @@ wasm_runtime_terminate(wasm_module_inst_t module_inst);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_custom_data(wasm_module_inst_t module_inst,
void *custom_data);
/**
* Get the custom data within a WASM module instance.
*
@ -952,16 +964,17 @@ wasm_runtime_get_custom_data(wasm_module_inst_t module_inst);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
bool enable);
/**
* Check if the memory bounds checks flag is enabled for a WASM module instance.
*
* @param module_inst the WASM module instance
*
* @return true if the memory bounds checks flag is enabled, false otherwise
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_bounds_checks_enabled(
wasm_module_inst_t module_inst);
/**
* Allocate memory from the heap of WASM module instance
*
@ -1336,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
* 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`
*
* @return true if success, false otherwise
@ -1544,11 +1558,11 @@ WASM_RUNTIME_API_EXTERN void
wasm_runtime_destroy_context_key(void *key);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_context(wasm_module_inst_t inst, void *key,
void *ctx);
wasm_runtime_set_context(wasm_module_inst_t inst, void *key, void *ctx);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key,
void *ctx);
wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key, void *ctx);
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_context(wasm_module_inst_t inst, void *key);

View File

@ -361,7 +361,6 @@ typedef struct WASMTableSeg {
uint32 mode;
/* funcref or externref, elemkind will be considered as funcref */
uint32 elem_type;
bool is_dropped;
/* optional, only for active */
uint32 table_index;
InitializerExpression base_offset;

View File

@ -36,7 +36,7 @@ typedef float64 CellType_F64;
* multi-threading mode since it may be changed by other
* threads in memory.grow
*/
#define get_linear_mem_size() memory->memory_data_size
#define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
#endif
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
@ -1176,7 +1176,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 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
WASMType **wasm_types = module->module->types;
WASMGlobalInstance *globals = module->e->globals, *global;
@ -1205,7 +1211,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 value_type;
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| 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(
(WASMModuleInstanceCommon *)module);
#else
@ -2540,7 +2546,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0
#if WASM_ENABLE_THREAD_MGR == 0
linear_mem_size = memory->memory_data_size;
#else
linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
#endif
#endif
}
@ -3545,7 +3555,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
addr = (uint32)POP_I32();
#if WASM_ENABLE_THREAD_MGR != 0
linear_mem_size = memory->memory_data_size;
linear_mem_size = get_linear_mem_size();
#endif
#ifndef OS_ENABLE_HW_BOUND_CHECK
@ -3557,9 +3567,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
maddr = memory->memory_data + (uint32)addr;
#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 = module->module->data_segments[segment]->data;
}
if (offset + bytes > seg_len)
goto out_of_bounds;
@ -3572,7 +3590,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 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;
}
case WASM_OP_MEMORY_COPY:
@ -3587,7 +3606,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
dst = POP_I32();
#if WASM_ENABLE_THREAD_MGR != 0
linear_mem_size = memory->memory_data_size;
linear_mem_size = get_linear_mem_size();
#endif
#ifndef OS_ENABLE_HW_BOUND_CHECK
@ -3618,7 +3637,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
dst = POP_I32();
#if WASM_ENABLE_THREAD_MGR != 0
linear_mem_size = memory->memory_data_size;
linear_mem_size = get_linear_mem_size();
#endif
#ifndef OS_ENABLE_HW_BOUND_CHECK
@ -3667,8 +3686,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
break;
}
if (module->module->table_segments[elem_idx]
.is_dropped) {
if (bh_bitmap_get_bit(module->e->common.elem_dropped,
elem_idx)) {
wasm_set_exception(module,
"out of bounds table access");
goto got_exception;
@ -3700,8 +3719,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
bh_assert(elem_idx < module->module->table_seg_count);
module->module->table_segments[elem_idx].is_dropped =
true;
bh_bitmap_set_bit(module->e->common.elem_dropped,
elem_idx);
break;
}
case WASM_OP_TABLE_COPY:
@ -4342,7 +4361,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0
if (memory)
linear_mem_size = memory->memory_data_size;
linear_mem_size = get_linear_mem_size();
#endif
if (wasm_copy_exception(module, NULL)) {
#if WASM_ENABLE_EXCE_HANDLING != 0

View File

@ -27,7 +27,7 @@ typedef float64 CellType_F64;
* multi-threading mode since it may be changed by other
* threads in memory.grow
*/
#define get_linear_mem_size() memory->memory_data_size
#define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
#endif
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
@ -1180,7 +1180,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 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
WASMGlobalInstance *globals = module->e ? module->e->globals : NULL;
WASMGlobalInstance *global;
@ -1207,7 +1213,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 opcode, local_type, *global_addr;
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
(WASMModuleInstanceCommon *)module);
#else
@ -1700,7 +1706,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame_ip += 2;
addr_ret = GET_OFFSET();
CHECK_MEMORY_OVERFLOW(1);
frame_lp[addr_ret] = (uint32)(*(uint8 *)maddr);
frame_lp[addr_ret] = (uint32)(*(uint8 *)(maddr));
HANDLE_OP_END();
}
@ -1825,7 +1831,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
addr = GET_OPERAND(uint32, I32, 2);
frame_ip += 4;
CHECK_MEMORY_OVERFLOW(1);
*(uint8 *)maddr = (uint8)sval;
STORE_U8(maddr, (uint8_t)sval);
HANDLE_OP_END();
}
@ -1925,7 +1931,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0
#if WASM_ENABLE_THREAD_MGR == 0
linear_mem_size = memory->memory_data_size;
#else
linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
#endif
#endif
}
@ -3003,12 +3013,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
segment = read_uint32(frame_ip);
bytes = (uint64)POP_I32();
offset = (uint64)POP_I32();
bytes = (uint64)(uint32)POP_I32();
offset = (uint64)(uint32)POP_I32();
addr = POP_I32();
#if WASM_ENABLE_THREAD_MGR
linear_mem_size = memory->memory_data_size;
linear_mem_size = get_linear_mem_size();
#endif
#ifndef OS_ENABLE_HW_BOUND_CHECK
@ -3019,10 +3029,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto out_of_bounds;
maddr = memory->memory_data + (uint32)addr;
#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 = module->module->data_segments[segment]->data;
}
if (offset + bytes > seg_len)
goto out_of_bounds;
@ -3035,8 +3053,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 segment;
segment = read_uint32(frame_ip);
module->module->data_segments[segment]->data_length = 0;
bh_bitmap_set_bit(module->e->common.data_dropped,
segment);
break;
}
case WASM_OP_MEMORY_COPY:
@ -3049,7 +3067,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
dst = POP_I32();
#if WASM_ENABLE_THREAD_MGR
linear_mem_size = memory->memory_data_size;
linear_mem_size = get_linear_mem_size();
#endif
#ifndef OS_ENABLE_HW_BOUND_CHECK
@ -3079,7 +3097,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
dst = POP_I32();
#if WASM_ENABLE_THREAD_MGR
linear_mem_size = memory->memory_data_size;
linear_mem_size = get_linear_mem_size();
#endif
#ifndef OS_ENABLE_HW_BOUND_CHECK
@ -3128,8 +3146,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
break;
}
if (module->module->table_segments[elem_idx]
.is_dropped) {
if (bh_bitmap_get_bit(module->e->common.elem_dropped,
elem_idx)) {
wasm_set_exception(module,
"out of bounds table access");
goto got_exception;
@ -3158,9 +3176,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
uint32 elem_idx = read_uint32(frame_ip);
bh_assert(elem_idx < module->module->table_seg_count);
module->module->table_segments[elem_idx].is_dropped =
true;
bh_bitmap_set_bit(module->e->common.elem_dropped,
elem_idx);
break;
}
case WASM_OP_TABLE_COPY:
@ -3859,7 +3876,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0
if (memory)
linear_mem_size = memory->memory_data_size;
linear_mem_size = get_linear_mem_size();
#endif
if (wasm_copy_exception(module, NULL))
goto got_exception;

View File

@ -301,7 +301,13 @@ check_utf8_str(const uint8 *str, uint32 len)
while (p < p_end) {
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++;
}
else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
@ -1214,9 +1220,16 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
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;
#else
return false;
#endif /* WASM_ENABLE_LIB_WASI_THREADS */
}
else {
linked_memory = wasm_loader_resolve_memory(
sub_module_name, memory_name, declare_init_page_count,
declare_max_page_count, error_buf, error_buf_size);
@ -1232,6 +1245,7 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
declare_init_page_count = linked_memory->init_page_count;
declare_max_page_count = linked_memory->max_page_count;
}
}
#endif
/* (memory (export "memory") 1 2) */
@ -2962,7 +2976,7 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
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");
return false;
}
@ -3138,6 +3152,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
option.opt_level = llvm_jit_options.opt_level;
option.size_level = llvm_jit_options.size_level;
option.segue_flags = llvm_jit_options.segue_flags;
option.linux_perf_support = llvm_jit_options.linux_perf_support;
#if WASM_ENABLE_BULK_MEMORY != 0
option.enable_bulk_memory = true;
@ -4258,13 +4273,16 @@ check_wasi_abi_compatibility(const WASMModule *module,
return false;
}
}
else {
/* (func (export "_initialize") (...) */
initialize = wasm_loader_find_export(
module, "", "_initialize", EXPORT_KIND_FUNC, error_buf, error_buf_size);
initialize =
wasm_loader_find_export(module, "", "_initialize", EXPORT_KIND_FUNC,
error_buf, error_buf_size);
if (initialize) {
WASMType *func_type =
module->functions[initialize->index - module->import_function_count]
module
->functions[initialize->index
- module->import_function_count]
->func_type;
if (func_type->param_count || func_type->result_count) {
set_error_buf(
@ -4273,6 +4291,7 @@ check_wasi_abi_compatibility(const WASMModule *module,
return false;
}
}
}
/* filter out non-wasi compatiable modules */
if (!module->import_wasi_api && !start && !initialize) {
@ -7384,7 +7403,7 @@ wasm_loader_get_custom_section(WASMModule *module, const char *name,
section = section->next;
}
return false;
return NULL;
}
#endif
@ -7567,15 +7586,7 @@ re_scan:
}
#if WASM_ENABLE_FAST_INTERP != 0
if (opcode == WASM_OP_BLOCK) {
skip_label();
}
#if WASM_ENABLE_EXCE_HANDLING != 0
else if (opcode == WASM_OP_TRY) {
skip_label();
}
#endif
else if (opcode == WASM_OP_LOOP) {
if (opcode == WASM_OP_BLOCK || opcode == WASM_OP_LOOP) {
skip_label();
if (BLOCK_HAS_PARAM(block_type)) {
/* Make sure params are in dynamic space */
@ -7583,9 +7594,16 @@ re_scan:
loader_ctx, false, error_buf, error_buf_size))
goto fail;
}
if (opcode == WASM_OP_LOOP) {
(loader_ctx->frame_csp - 1)->code_compiled =
loader_ctx->p_code_compiled;
}
}
#if WASM_ENABLE_EXCE_HANDLING != 0
else if (opcode == WASM_OP_TRY) {
skip_label();
}
#endif
else if (opcode == WASM_OP_IF) {
/* If block has parameters, we should make sure they are in
* dynamic space. Otherwise, when else branch is missing,
@ -8029,6 +8047,9 @@ re_scan:
if (frame_csp_tmp->label_type != LABEL_TYPE_LOOP)
ret_count = block_type_get_result_types(
&frame_csp_tmp->block_type, &ret_types);
else
ret_count = block_type_get_param_types(
&frame_csp_tmp->block_type, &ret_types);
}
else {
uint8 *tmp_ret_types = NULL;
@ -8039,6 +8060,9 @@ re_scan:
if (frame_csp_tmp->label_type != LABEL_TYPE_LOOP)
tmp_ret_count = block_type_get_result_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
|| (ret_count
@ -8331,7 +8355,8 @@ re_scan:
}
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->stack_cell_num--;
#if WASM_ENABLE_FAST_INTERP != 0

View File

@ -1877,6 +1877,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
option.opt_level = llvm_jit_options.opt_level;
option.size_level = llvm_jit_options.size_level;
option.segue_flags = llvm_jit_options.segue_flags;
option.linux_perf_support = llvm_jit_options.linux_perf_support;
#if WASM_ENABLE_BULK_MEMORY != 0
option.enable_bulk_memory = true;
@ -5637,10 +5638,7 @@ re_scan:
}
#if WASM_ENABLE_FAST_INTERP != 0
if (opcode == WASM_OP_BLOCK) {
skip_label();
}
else if (opcode == WASM_OP_LOOP) {
if (opcode == WASM_OP_BLOCK || opcode == WASM_OP_LOOP) {
skip_label();
if (BLOCK_HAS_PARAM(block_type)) {
/* Make sure params are in dynamic space */
@ -5648,9 +5646,11 @@ re_scan:
loader_ctx, false, error_buf, error_buf_size))
goto fail;
}
if (opcode == WASM_OP_LOOP) {
(loader_ctx->frame_csp - 1)->code_compiled =
loader_ctx->p_code_compiled;
}
}
else if (opcode == WASM_OP_IF) {
/* If block has parameters, we should make sure they are in
* dynamic space. Otherwise, when else branch is missing,
@ -6122,7 +6122,8 @@ re_scan:
&& !cur_block->is_stack_polymorphic));
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->stack_cell_num--;
#if WASM_ENABLE_FAST_INTERP != 0

View File

@ -386,7 +386,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
#if WASM_ENABLE_SHARED_MEMORY != 0
if (is_shared_memory) {
memory->is_shared_memory = true;
memory->is_shared_memory = 1;
memory->ref_count = 1;
}
#endif
@ -1807,6 +1807,31 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
}
#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 (!(module_inst->frames = runtime_malloc((uint64)sizeof(Vector),
error_buf, error_buf_size))) {
@ -2353,6 +2378,13 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_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);
}
@ -2566,14 +2598,16 @@ wasm_dump_perf_profiling(const WASMModuleInstance *module_inst)
}
if (func_name)
os_printf(" func %s, execution time: %.3f ms, execution count: %d "
"times\n",
os_printf(
" func %s, execution time: %.3f ms, execution count: %" PRIu32
" times\n",
func_name,
module_inst->e->functions[i].total_exec_time / 1000.0f,
module_inst->e->functions[i].total_exec_cnt);
else
os_printf(" func %d, execution time: %.3f ms, execution count: %d "
"times\n",
os_printf(" func %" PRIu32
", execution time: %.3f ms, execution count: %" PRIu32
" times\n",
i, module_inst->e->functions[i].total_exec_time / 1000.0f,
module_inst->e->functions[i].total_exec_cnt);
}
@ -3327,16 +3361,23 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index,
{
WASMMemoryInstance *memory_inst;
WASMModule *module;
uint8 *data = NULL;
uint8 *data;
uint8 *maddr;
uint64 seg_len = 0;
uint64 seg_len;
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
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;
seg_len = module->data_segments[seg_index]->data_length;
data = module->data_segments[seg_index]->data;
}
if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
dst, len))
@ -3361,7 +3402,7 @@ llvm_jit_data_drop(WASMModuleInstance *module_inst, uint32 seg_index)
{
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
as they are stored in wasm bytecode */
return true;
@ -3372,12 +3413,8 @@ llvm_jit_data_drop(WASMModuleInstance *module_inst, uint32 seg_index)
void
llvm_jit_drop_table_seg(WASMModuleInstance *module_inst, uint32 tbl_seg_idx)
{
WASMTableSeg *tbl_segs;
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
tbl_segs = module_inst->module->table_segments;
tbl_segs[tbl_seg_idx].is_dropped = true;
bh_bitmap_set_bit(module_inst->e->common.elem_dropped, tbl_seg_idx);
}
void
@ -3406,7 +3443,7 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
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);
return;
}

View File

@ -8,6 +8,7 @@
#include "wasm.h"
#include "bh_atomic.h"
#include "bh_bitmap.h"
#include "bh_hashmap.h"
#include "../common/wasm_runtime_common.h"
#include "../common/wasm_exec_env.h"
@ -83,10 +84,15 @@ struct WASMMemoryInstance {
/* Module type */
uint32 module_type;
bool is_shared_memory;
/* Whether the memory is shared */
uint8 is_shared_memory;
/* Shared memory flag */
bh_atomic_16_t ref_count; /* 0: non-shared, > 0: reference count */
/* 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 */
uint32 num_bytes_per_page;
@ -253,10 +259,16 @@ typedef struct WASMModuleInstanceExtraCommon {
CApiFuncImport *c_api_func_imports;
/* pointer to the exec env currently used */
WASMExecEnv *cur_exec_env;
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
/* Disable bounds checks or not */
bool disable_bounds_checks;
#endif
#if WASM_ENABLE_BULK_MEMORY != 0
bh_bitmap *data_dropped;
#endif
#if WASM_ENABLE_REF_TYPES != 0
bh_bitmap *elem_dropped;
#endif
} WASMModuleInstanceExtraCommon;
/* Extra info of WASM module instance for interpreter/jit mode */

View File

@ -17,7 +17,7 @@
#include "lib_rats_common.h"
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)
{
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;
}
bh_memcpy_s(str_ret, json_size, json, json_size);
*((int *)evidence_json) = str_ret_offset;
*evidence_json = str_ret_offset;
free(json);
return 0;
@ -96,6 +96,15 @@ librats_parse_evidence_wrapper(wasm_exec_env_t exec_env,
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 */
#define REG_NATIVE_FUNC(func_name, signature) \
{ #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[] = {
REG_NATIVE_FUNC(librats_collect, "(**~)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

View File

@ -41,6 +41,9 @@ librats_parse_evidence(const char *evidence_json, uint32_t json_size,
evidence_json ? strlen(evidence_json) + 1 : 0, \
evidence, sizeof(rats_sgx_evidence_t))
void
librats_dispose_evidence_json(char *evidence_json);
#ifdef __cplusplus
}
#endif

View File

@ -614,14 +614,21 @@ fd_table_insert_existing(struct fd_table *ft, __wasi_fd_t in,
}
// Picks an unused slot from the file descriptor table.
static __wasi_fd_t
fd_table_unused(struct fd_table *ft) REQUIRES_SHARED(ft->lock)
static __wasi_errno_t
fd_table_unused(struct fd_table *ft, __wasi_fd_t *out) REQUIRES_SHARED(ft->lock)
{
assert(ft->size > ft->used && "File descriptor table has no free slots");
for (;;) {
__wasi_fd_t fd = (__wasi_fd_t)random_uniform(ft->size);
if (ft->entries[fd].object == NULL)
return fd;
uintmax_t random_fd = 0;
__wasi_errno_t error = random_uniform(ft->size, &random_fd);
if (error != __WASI_ESUCCESS)
return error;
if (ft->entries[(__wasi_fd_t)random_fd].object == NULL) {
*out = (__wasi_fd_t)random_fd;
return error;
}
}
}
@ -641,10 +648,14 @@ fd_table_insert(wasm_exec_env_t exec_env, struct fd_table *ft,
return convert_errno(errno);
}
*out = fd_table_unused(ft);
__wasi_errno_t error = fd_table_unused(ft, out);
if (error != __WASI_ESUCCESS)
return error;
fd_table_attach(ft, *out, fo, rights_base, rights_inheriting);
rwlock_unlock(&ft->lock);
return 0;
return error;
}
// Inserts a numerical file descriptor into the file descriptor table.
@ -1144,6 +1155,11 @@ wasmtime_ssp_fd_advise(wasm_exec_env_t exec_env, struct fd_table *curfds,
if (error != 0)
return error;
if (fo->type == __WASI_FILETYPE_DIRECTORY) {
fd_object_release(exec_env, fo);
return __WASI_EBADF;
}
error = os_fadvise(fo->file_handle, offset, len, advice);
fd_object_release(exec_env, fo);
@ -1875,7 +1891,13 @@ wasmtime_ssp_fd_filestat_set_times(wasm_exec_env_t exec_env,
if ((fstflags
& ~(__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW
| __WASI_FILESTAT_SET_MTIM | __WASI_FILESTAT_SET_MTIM_NOW))
!= 0)
!= 0
|| (fstflags
& (__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW))
== (__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW)
|| (fstflags
& (__WASI_FILESTAT_SET_MTIM | __WASI_FILESTAT_SET_MTIM_NOW))
== (__WASI_FILESTAT_SET_MTIM | __WASI_FILESTAT_SET_MTIM_NOW))
return __WASI_EINVAL;
struct fd_object *fo;
@ -2282,8 +2304,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
__wasi_errno_t
wasmtime_ssp_random_get(void *buf, size_t nbyte)
{
random_buf(buf, nbyte);
return 0;
return random_buf(buf, nbyte);
}
__wasi_errno_t
@ -2867,18 +2888,15 @@ wasmtime_ssp_sock_shutdown(wasm_exec_env_t exec_env, struct fd_table *curfds,
{
struct fd_object *fo;
__wasi_errno_t error;
int ret;
error = fd_object_get(curfds, &fo, sock, 0, 0);
if (error != 0)
return error;
ret = os_socket_shutdown(fo->file_handle);
error = os_socket_shutdown(fo->file_handle);
fd_object_release(exec_env, fo);
if (BHT_OK != ret)
return convert_errno(errno);
return __WASI_ESUCCESS;
return error;
}
__wasi_errno_t

View File

@ -13,14 +13,16 @@
#include "ssp_config.h"
#include "bh_platform.h"
#include "libc_errno.h"
#include "random.h"
#if CONFIG_HAS_ARC4RANDOM_BUF
void
__wasi_errno_t
random_buf(void *buf, size_t len)
{
arc4random_buf(buf, len);
return __WASI_ESUCCESS;
}
#elif CONFIG_HAS_GETRANDOM
@ -29,7 +31,7 @@ random_buf(void *buf, size_t len)
#include <sys/random.h>
#endif
void
__wasi_errno_t
random_buf(void *buf, size_t len)
{
for (;;) {
@ -37,57 +39,71 @@ random_buf(void *buf, size_t len)
if (x < 0) {
if (errno == EINTR)
continue;
os_printf("getrandom failed: %s", strerror(errno));
abort();
return convert_errno(errno);
}
if ((size_t)x == len)
return;
break;
buf = (void *)((unsigned char *)buf + x);
len -= (size_t)x;
}
return __WASI_ESUCCESS;
}
#elif defined(BH_PLATFORM_WINDOWS)
#include <wincrypt.h>
#include <bcrypt.h>
#pragma comment(lib, "Bcrypt.lib")
void
__wasi_errno_t
random_buf(void *buf, size_t len)
{
static int crypt_initialized = 0;
static HCRYPTPROV provider;
if (!crypt_initialized) {
CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT);
crypt_initialized = 1;
}
CryptGenRandom(provider, len, buf);
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
static int urandom;
static int urandom = -1;
static __wasi_errno_t urandom_error = __WASI_ESUCCESS;
static void
open_urandom(void)
{
urandom = open("/dev/urandom", O_RDONLY);
if (urandom < 0) {
os_printf("Failed to open /dev/urandom\n");
abort();
}
if (urandom < 0)
urandom_error = convert_errno(errno);
}
void
__wasi_errno_t
random_buf(void *buf, size_t len)
{
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) {
os_printf("Short read on /dev/urandom\n");
abort();
if (pthread_ret != 0)
return convert_errno(pthread_ret);
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
@ -99,8 +115,8 @@ random_buf(void *buf, size_t len)
// 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
// without any modulo bias.
uintmax_t
random_uniform(uintmax_t upper)
__wasi_errno_t
random_uniform(uintmax_t upper, uintmax_t *out)
{
// Compute 2^k % upper
// == (2^k - upper) % upper
@ -108,8 +124,14 @@ random_uniform(uintmax_t upper)
uintmax_t lower = -upper % upper;
for (;;) {
uintmax_t value;
random_buf(&value, sizeof(value));
if (value >= lower)
return value % upper;
__wasi_errno_t error = random_buf(&value, sizeof(value));
if (error != __WASI_ESUCCESS)
return error;
if (value >= lower) {
*out = value % upper;
return error;
}
}
}

View File

@ -14,8 +14,12 @@
#ifndef RANDOM_H
#define RANDOM_H
void
#include "bh_platform.h"
__wasi_errno_t
random_buf(void *, size_t);
uintmax_t random_uniform(uintmax_t);
__wasi_errno_t
random_uniform(uintmax_t upper, uintmax_t *out);
#endif

View File

@ -488,10 +488,25 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
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;
}
os_mutex_lock(&cluster->lock);
if (cluster->has_exception || cluster->processing) {
goto fail1;
goto fail2;
}
#if WASM_ENABLE_INTERP != 0
@ -508,21 +523,11 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
}
#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,
exec_env->wasm_stack_size);
if (!new_exec_env)
if (!new_exec_env) {
goto fail2;
}
if (!allocate_aux_stack(exec_env, &aux_stack_start, &aux_stack_size)) {
LOG_ERROR("thread manager error: "
@ -539,8 +544,9 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
/* Inherit suspend_flags of parent thread */
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;
}
os_mutex_unlock(&cluster->lock);
@ -552,9 +558,9 @@ fail4:
fail3:
wasm_exec_env_destroy_internal(new_exec_env);
fail2:
wasm_runtime_deinstantiate_internal(new_module_inst, true);
fail1:
os_mutex_unlock(&cluster->lock);
fail1:
wasm_runtime_deinstantiate_internal(new_module_inst, true);
return NULL;
}

View File

@ -32,6 +32,12 @@ typedef aos_task_t *aos_tid_t;
typedef aos_mutex_t korp_mutex;
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;
typedef struct os_thread_wait_node *os_thread_wait_list;
typedef struct korp_cond {
@ -64,8 +70,10 @@ int signbit(double x);
int isnan(double x);
/* 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 DIR *os_dir_stream;
typedef void *os_dir_stream;
typedef int os_raw_file_handle;
static inline os_file_handle

View File

@ -9,6 +9,7 @@ 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)

View File

@ -479,7 +479,7 @@ os_preadv(os_file_handle handle, const struct __wasi_iovec_t *iov, int iovcnt,
// Allocate a single buffer to fit all data.
size_t totalsize = 0;
for (size_t i = 0; i < iovcnt; ++i)
for (int i = 0; i < iovcnt; ++i)
totalsize += iov[i].buf_len;
char *buf = BH_MALLOC(totalsize);
@ -498,7 +498,7 @@ os_preadv(os_file_handle handle, const struct __wasi_iovec_t *iov, int iovcnt,
// Copy data back to vectors.
size_t bufoff = 0;
for (size_t i = 0; i < iovcnt; ++i) {
for (int i = 0; i < iovcnt; ++i) {
if (bufoff + iov[i].buf_len < (size_t)len) {
memcpy(iov[i].buf, buf + bufoff, iov[i].buf_len);
bufoff += iov[i].buf_len;
@ -533,14 +533,14 @@ os_pwritev(os_file_handle handle, const struct __wasi_ciovec_t *iov, int iovcnt,
else {
// Allocate a single buffer to fit all data.
size_t totalsize = 0;
for (size_t i = 0; i < iovcnt; ++i)
for (int i = 0; i < iovcnt; ++i)
totalsize += iov[i].buf_len;
char *buf = BH_MALLOC(totalsize);
if (buf == NULL) {
return __WASI_ENOMEM;
}
size_t bufoff = 0;
for (size_t i = 0; i < iovcnt; ++i) {
for (int i = 0; i < iovcnt; ++i) {
memcpy(buf + bufoff, iov[i].buf, iov[i].buf_len);
bufoff += iov[i].buf_len;
}

View File

@ -5,6 +5,7 @@
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
#include "libc_errno.h"
#include <arpa/inet.h>
#include <netdb.h>
@ -308,11 +309,13 @@ os_socket_close(bh_socket_t socket)
return BHT_OK;
}
int
__wasi_errno_t
os_socket_shutdown(bh_socket_t socket)
{
shutdown(socket, O_RDWR);
return BHT_OK;
if (shutdown(socket, O_RDWR) != 0) {
return convert_errno(errno);
}
return __WASI_ESUCCESS;
}
int

View File

@ -5,6 +5,7 @@
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
#include "libc_errno.h"
#include <arpa/inet.h>
@ -167,11 +168,13 @@ os_socket_close(bh_socket_t socket)
return BHT_OK;
}
int
__wasi_errno_t
os_socket_shutdown(bh_socket_t socket)
{
shutdown(socket, O_RDWR);
return BHT_OK;
if (shutdown(socket, O_RDWR) != 0) {
return convert_errno(errno);
}
return __WASI_ESUCCESS;
}
int

View File

@ -573,9 +573,9 @@ os_socket_close(bh_socket_t socket);
*
* @param socket the socket to be shutdown
*
* @return always return 0
* @return returns corresponding error code
*/
int
__wasi_errno_t
os_socket_shutdown(bh_socket_t socket);
/**

View File

@ -5,6 +5,7 @@
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
#include "libc_errno.h"
#ifndef SGX_DISABLE_WASI
@ -855,10 +856,13 @@ os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
return ret;
}
int
__wasi_errno_t
os_socket_shutdown(bh_socket_t socket)
{
return shutdown(socket, O_RDWR);
if (shutdown(socket, O_RDWR) != 0) {
return convert_errno(errno);
}
return __WASI_ESUCCESS;
}
int

View File

@ -40,6 +40,12 @@ typedef kernel_pid_t korp_tid;
typedef mutex_t korp_mutex;
typedef unsigned int 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;
/* typedef sema_t korp_sem; */
struct os_thread_wait_node;
@ -52,8 +58,10 @@ typedef struct korp_cond {
#define os_printf printf
#define os_vprintf vprintf
/* 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 DIR *os_dir_stream;
typedef void *os_dir_stream;
typedef int os_raw_file_handle;
#if WA_MATH

View File

@ -38,6 +38,12 @@ typedef struct rt_thread korp_cond;
typedef struct rt_thread korp_thread;
typedef unsigned int 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;
typedef rt_uint8_t uint8_t;
typedef rt_int8_t int8_t;
typedef rt_uint16_t uint16_t;
@ -45,8 +51,10 @@ typedef rt_int16_t int16_t;
typedef rt_uint64_t uint64_t;
typedef rt_int64_t int64_t;
/* 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 DIR *os_dir_stream;
typedef void *os_dir_stream;
typedef int os_raw_file_handle;
static inline os_file_handle

View File

@ -46,50 +46,6 @@
CHECK_VALID_FILE_HANDLE((win_dir_stream)->handle); \
} while (0)
static __wasi_errno_t
convert_winsock_error_code(int error_code)
{
switch (error_code) {
case WSASYSNOTREADY:
case WSAEWOULDBLOCK:
return __WASI_EAGAIN;
case WSAVERNOTSUPPORTED:
return __WASI_ENOTSUP;
case WSAEINPROGRESS:
return __WASI_EINPROGRESS;
case WSAEPROCLIM:
return __WASI_EBUSY;
case WSAEFAULT:
return __WASI_EFAULT;
case WSAENETDOWN:
return __WASI_ENETDOWN;
case WSAENOTSOCK:
return __WASI_ENOTSOCK;
case WSAEINTR:
return __WASI_EINTR;
case WSAEAFNOSUPPORT:
return __WASI_EAFNOSUPPORT;
case WSAEMFILE:
return __WASI_ENFILE;
case WSAEINVAL:
return __WASI_EINVAL;
case WSAENOBUFS:
return __WASI_ENOBUFS;
case WSAEPROTONOSUPPORT:
return __WASI_EPROTONOSUPPORT;
case WSAEPROTOTYPE:
return __WASI_EPROTOTYPE;
case WSAESOCKTNOSUPPORT:
return __WASI_ENOTSUP;
case WSAEINVALIDPROCTABLE:
case WSAEINVALIDPROVIDER:
case WSAEPROVIDERFAILEDINIT:
case WSANOTINITIALISED:
default:
return __WASI_EINVAL;
}
}
static __wasi_filetype_t
get_disk_filetype(DWORD attribute)
{

View File

@ -5,6 +5,8 @@
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
#include "platform_wasi_types.h"
#include "win_util.h"
/* link with Ws2_32.lib */
#pragma comment(lib, "ws2_32.lib")
@ -238,13 +240,15 @@ os_socket_close(bh_socket_t socket)
return BHT_OK;
}
int
__wasi_errno_t
os_socket_shutdown(bh_socket_t socket)
{
CHECK_VALID_SOCKET_HANDLE(socket);
shutdown(socket->raw.socket, SD_BOTH);
return BHT_OK;
if (shutdown(socket->raw.socket, SD_BOTH) != 0) {
return convert_winsock_error_code(WSAGetLastError());
}
return __WASI_ESUCCESS;
}
int

View File

@ -94,3 +94,53 @@ uwp_print_to_debugger(const char *format, va_list ap)
return ret;
}
#endif
__wasi_errno_t
convert_winsock_error_code(int error_code)
{
switch (error_code) {
case WSASYSNOTREADY:
case WSAEWOULDBLOCK:
return __WASI_EAGAIN;
case WSAVERNOTSUPPORTED:
return __WASI_ENOTSUP;
case WSAEINPROGRESS:
return __WASI_EINPROGRESS;
case WSAEPROCLIM:
return __WASI_EBUSY;
case WSAEFAULT:
return __WASI_EFAULT;
case WSAENETDOWN:
return __WASI_ENETDOWN;
case WSAENOTSOCK:
return __WASI_ENOTSOCK;
case WSAEINTR:
return __WASI_EINTR;
case WSAEAFNOSUPPORT:
return __WASI_EAFNOSUPPORT;
case WSAEMFILE:
return __WASI_ENFILE;
case WSAEINVAL:
return __WASI_EINVAL;
case WSAENOBUFS:
return __WASI_ENOBUFS;
case WSAEPROTONOSUPPORT:
return __WASI_EPROTONOSUPPORT;
case WSAEPROTOTYPE:
return __WASI_EPROTOTYPE;
case WSAESOCKTNOSUPPORT:
return __WASI_ENOTSUP;
case WSAECONNABORTED:
return __WASI_ECONNABORTED;
case WSAECONNRESET:
return __WASI_ECONNRESET;
case WSAENOTCONN:
return __WASI_ENOTCONN;
case WSAEINVALIDPROCTABLE:
case WSAEINVALIDPROVIDER:
case WSAEPROVIDERFAILEDINIT:
case WSANOTINITIALISED:
default:
return __WASI_EINVAL;
}
}

View File

@ -12,8 +12,12 @@
__wasi_timestamp_t
convert_filetime_to_wasi_timestamp(LPFILETIME filetime);
// Convert a Windows error code to a WASI error code
/* Convert a Windows error code to a WASI error code */
__wasi_errno_t
convert_windows_error_code(DWORD windows_error_code);
/* Convert a Winsock error code to a WASI error code */
__wasi_errno_t
convert_winsock_error_code(int error_code);
#endif /* end of _WIN_UTIL_H */

View File

@ -74,6 +74,12 @@ typedef korp_thread *korp_tid;
typedef struct k_mutex korp_mutex;
typedef unsigned int 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;
typedef struct os_thread_wait_node *os_thread_wait_list;
typedef struct korp_cond {
@ -125,7 +131,7 @@ float strtof(const char *nptr, char **endptr);
#endif
/**
* @brief Allocate executable memroy
* @brief Allocate executable memory
*
* @param size size of the memory to be allocated
*
@ -134,7 +140,7 @@ float strtof(const char *nptr, char **endptr);
typedef void *(*exec_mem_alloc_func_t)(unsigned int size);
/**
* @brief Release executable memroy
* @brief Release executable memory
*
* @param the address of the executable memory to be released
*/
@ -148,8 +154,10 @@ void
set_exec_mem_alloc_func(exec_mem_alloc_func_t alloc_func,
exec_mem_free_func_t free_func);
/* 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 DIR *os_dir_stream;
typedef void *os_dir_stream;
typedef int os_raw_file_handle;
static inline os_file_handle

View File

@ -47,6 +47,19 @@ extern "C" {
typedef uint32 bh_atomic_32_t;
typedef uint16 bh_atomic_16_t;
/* The flag can be defined by the user if the platform
* supports atomic 32-bit operations.
* If left undefined, it will be automatically defined
* according to the platform.
*/
#ifdef WASM_UINT32_IS_ATOMIC
#define BH_ATOMIC_32_IS_ATOMIC WASM_UINT32_IS_ATOMIC
#endif /* WASM_UINT32_IS_ATOMIC */
#ifdef WASM_UINT16_IS_ATOMIC
#define BH_ATOMIC_16_IS_ATOMIC WASM_UINT16_IS_ATOMIC
#endif /* WASM_UINT16_IS_ATOMIC */
#if defined(__GNUC_PREREQ)
#if __GNUC_PREREQ(4, 7)
#define CLANG_GCC_HAS_ATOMIC_BUILTIN
@ -58,7 +71,38 @@ typedef uint16 bh_atomic_16_t;
#endif
#if defined(CLANG_GCC_HAS_ATOMIC_BUILTIN)
#ifndef BH_ATOMIC_32_IS_ATOMIC
#define BH_ATOMIC_32_IS_ATOMIC 1
#endif
#ifndef BH_ATOMIC_16_IS_ATOMIC
#define BH_ATOMIC_16_IS_ATOMIC 1
#endif
#else
#ifndef BH_ATOMIC_32_IS_ATOMIC
#define BH_ATOMIC_32_IS_ATOMIC 0
#endif
#ifndef BH_ATOMIC_16_IS_ATOMIC
#define BH_ATOMIC_16_IS_ATOMIC 0
#endif
#endif
/* Force disable atomic 16-bit operations on bare-metal RISC-V
* because the 16-bit atomic operations is emulated by 32-bit
* atomic operations, which has linkage problem on current toolchain:
* in function `shared_memory_inc_reference':
* wasm_shared_memory.c:85:(.text.shared_memory_inc_reference+0x10): undefined
* reference to `__atomic_fetch_add_2'
*/
#ifndef WASM_UINT16_IS_ATOMIC
#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) \
&& !defined(__OpenBSD__) && defined(__riscv)
#undef BH_ATOMIC_16_IS_ATOMIC
#define BH_ATOMIC_16_IS_ATOMIC 0
#endif
#endif
#if BH_ATOMIC_32_IS_ATOMIC != 0
#define BH_ATOMIC_32_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_32_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST)
#define BH_ATOMIC_32_FETCH_OR(v, val) \
@ -70,18 +114,8 @@ typedef uint16 bh_atomic_16_t;
#define BH_ATOMIC_32_FETCH_SUB(v, val) \
__atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_IS_ATOMIC 1
#define BH_ATOMIC_16_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_FETCH_OR(v, val) \
__atomic_fetch_or(&(v), (val), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_FETCH_AND(v, val) \
__atomic_fetch_and(&(v), (val), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_FETCH_ADD(v, val) \
__atomic_fetch_add(&(v), (val), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_FETCH_SUB(v, val) \
__atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST)
#else /* else of defined(CLANG_GCC_HAS_ATOMIC_BUILTIN) */
#else /* else of BH_ATOMIC_32_IS_ATOMIC != 0 */
#define BH_ATOMIC_32_LOAD(v) (v)
#define BH_ATOMIC_32_STORE(v, val) (v) = val
#define BH_ATOMIC_32_FETCH_OR(v, val) nonatomic_32_fetch_or(&(v), val)
@ -89,13 +123,6 @@ typedef uint16 bh_atomic_16_t;
#define BH_ATOMIC_32_FETCH_ADD(v, val) nonatomic_32_fetch_add(&(v), val)
#define BH_ATOMIC_32_FETCH_SUB(v, val) nonatomic_32_fetch_sub(&(v), val)
#define BH_ATOMIC_16_LOAD(v) (v)
#define BH_ATOMIC_16_STORE(v) (v) = val
#define BH_ATOMIC_16_FETCH_OR(v, val) nonatomic_16_fetch_or(&(v), val)
#define BH_ATOMIC_16_FETCH_AND(v, val) nonatomic_16_fetch_and(&(v), val)
#define BH_ATOMIC_16_FETCH_ADD(v, val) nonatomic_16_fetch_add(&(v), val)
#define BH_ATOMIC_16_FETCH_SUB(v, val) nonatomic_16_fetch_sub(&(v), val)
static inline uint32
nonatomic_32_fetch_or(bh_atomic_32_t *p, uint32 val)
{
@ -128,6 +155,31 @@ nonatomic_32_fetch_sub(bh_atomic_32_t *p, uint32 val)
return old;
}
#endif
#if BH_ATOMIC_16_IS_ATOMIC != 0
#define BH_ATOMIC_16_IS_ATOMIC 1
#define BH_ATOMIC_16_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_FETCH_OR(v, val) \
__atomic_fetch_or(&(v), (val), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_FETCH_AND(v, val) \
__atomic_fetch_and(&(v), (val), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_FETCH_ADD(v, val) \
__atomic_fetch_add(&(v), (val), __ATOMIC_SEQ_CST)
#define BH_ATOMIC_16_FETCH_SUB(v, val) \
__atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST)
#else /* else of BH_ATOMIC_16_IS_ATOMIC != 0 */
#define BH_ATOMIC_16_LOAD(v) (v)
#define BH_ATOMIC_16_STORE(v) (v) = val
#define BH_ATOMIC_16_FETCH_OR(v, val) nonatomic_16_fetch_or(&(v), val)
#define BH_ATOMIC_16_FETCH_AND(v, val) nonatomic_16_fetch_and(&(v), val)
#define BH_ATOMIC_16_FETCH_ADD(v, val) nonatomic_16_fetch_add(&(v), val)
#define BH_ATOMIC_16_FETCH_SUB(v, val) nonatomic_16_fetch_sub(&(v), val)
static inline uint16
nonatomic_16_fetch_or(bh_atomic_16_t *p, uint16 val)
{
@ -160,20 +212,6 @@ nonatomic_16_fetch_sub(bh_atomic_16_t *p, uint16 val)
return old;
}
/* The flag can be defined by the user if the platform
supports atomic access to uint32 aligned memory. */
#ifdef WASM_UINT32_IS_ATOMIC
#define BH_ATOMIC_32_IS_ATOMIC 1
#else /* else of WASM_UINT32_IS_ATOMIC */
#define BH_ATOMIC_32_IS_ATOMIC 0
#endif /* WASM_UINT32_IS_ATOMIC */
#ifdef WASM_UINT16_IS_ATOMIC
#define BH_ATOMIC_16_IS_ATOMIC 1
#else /* else of WASM_UINT16_IS_ATOMIC */
#define BH_ATOMIC_16_IS_ATOMIC 0
#endif /* WASM_UINT16_IS_ATOMIC */
#endif
#ifdef __cplusplus

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2021 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_bitmap.h"
bh_bitmap *
bh_bitmap_new(uintptr_t begin_index, unsigned bitnum)
{
bh_bitmap *bitmap;
uint32 bitmap_size = (bitnum + 7) / 8;
uint32 total_size = offsetof(bh_bitmap, map) + bitmap_size;
if (bitnum > UINT32_MAX - 7 || total_size < offsetof(bh_bitmap, map)
|| (total_size - offsetof(bh_bitmap, map)) != bitmap_size) {
return NULL; /* integer overflow */
}
if ((bitmap = BH_MALLOC(total_size)) != NULL) {
memset(bitmap, 0, total_size);
bitmap->begin_index = begin_index;
bitmap->end_index = begin_index + bitnum;
}
return bitmap;
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (C) 2021 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_BITMAP_H
#define _BH_BITMAP_H
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* A simple fixed size bitmap.
*/
typedef struct bh_bitmap {
/* 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];
} bh_bitmap;
/**
* 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.
*/
bh_bitmap *
bh_bitmap_new(uintptr_t begin_index, unsigned bitnum);
/**
* Delete a bitmap.
*
* @param bitmap the bitmap to be deleted
*/
static inline void
bh_bitmap_delete(bh_bitmap *bitmap)
{
if (bitmap != NULL)
BH_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
bh_bitmap_is_in_range(bh_bitmap *bitmap, uintptr_t 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
bh_bitmap_get_bit(bh_bitmap *bitmap, uintptr_t n)
{
uintptr_t 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
bh_bitmap_set_bit(bh_bitmap *bitmap, uintptr_t n)
{
uintptr_t 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
bh_bitmap_clear_bit(bh_bitmap *bitmap, uintptr_t n)
{
uintptr_t idx = n - bitmap->begin_index;
bh_assert(n >= bitmap->begin_index && n < bitmap->end_index);
bitmap->map[idx / 8] &= ~(1 << (idx % 8));
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -6,6 +6,6 @@
#ifndef _WAMR_VERSION_H_
#define _WAMR_VERSION_H_
#define WAMR_VERSION_MAJOR 1
#define WAMR_VERSION_MINOR 2
#define WAMR_VERSION_PATCH 3
#define WAMR_VERSION_MINOR 3
#define WAMR_VERSION_PATCH 0
#endif

View File

@ -27,8 +27,8 @@ The script `runtime_lib.cmake` defines a number of variables for configuring the
- **WAMR_BUILD_TARGET**: set the target CPU architecture. Current supported targets are: X86_64, X86_32, AARCH64, ARM, THUMB, XTENSA, ARC, RISCV32, RISCV64 and MIPS.
- For ARM and THUMB, the format is \<arch>\[\<sub-arch>]\[_VFP], where \<sub-arch> is the ARM sub-architecture and the "_VFP" suffix means using VFP coprocessor registers s0-s15 (d0-d7) for passing arguments or returning results in standard procedure-call. Both \<sub-arch> and "_VFP" are optional, e.g. ARMV7, ARMV7_VFP, THUMBV7, THUMBV7_VFP and so on.
- For AARCH64, the format is\<arch>[\<sub-arch>], VFP is enabled by default. \<sub-arch> is optional, e.g. AARCH64, AARCH64V8, AARCH64V8.1 and so on.
- For RISCV64, the format is \<arch\>[_abi], where "_abi" is optional, currently the supported formats are RISCV64, RISCV64_LP64D and RISCV64_LP64: RISCV64 and RISCV64_LP64D are identical, using [LP64D](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-named-abis) as abi (LP64 with hardware floating-point calling convention for FLEN=64). And RISCV64_LP64 uses [LP64](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-named-abis) as abi (Integer calling-convention only, and hardware floating-point calling convention is not used).
- For RISCV32, the format is \<arch\>[_abi], where "_abi" is optional, currently the supported formats are RISCV32, RISCV32_ILP32D and RISCV32_ILP32: RISCV32 and RISCV32_ILP32D are identical, using [ILP32D](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-named-abis) as abi (ILP32 with hardware floating-point calling convention for FLEN=64). And RISCV32_ILP32 uses [ILP32](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-named-abis) as abi (Integer calling-convention only, and hardware floating-point calling convention is not used).
- For RISCV64, the format is \<arch\>[_abi], where "_abi" is optional, currently the supported formats are RISCV64, RISCV64_LP64D and RISCV64_LP64: RISCV64 and RISCV64_LP64D are identical, using [LP64D](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#named-abis) as abi (LP64 with hardware floating-point calling convention for FLEN=64). And RISCV64_LP64 uses [LP64](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#named-abis) as abi (Integer calling-convention only, and hardware floating-point calling convention is not used).
- For RISCV32, the format is \<arch\>[_abi], where "_abi" is optional, currently the supported formats are RISCV32, RISCV32_ILP32D and RISCV32_ILP32: RISCV32 and RISCV32_ILP32D are identical, using [ILP32D](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#named-abis) as abi (ILP32 with hardware floating-point calling convention for FLEN=64). And RISCV32_ILP32 uses [ILP32](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#named-abis) as abi (Integer calling-convention only, and hardware floating-point calling convention is not used).
```bash
cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM

View File

@ -23,16 +23,19 @@ emcc -msimd128 -O3 -o <wasm_file> <c/c++ source files>
## 3. Enable segue optimization for wamrc when generating the aot file
[Segue](https://plas2022.github.io/files/pdf/SegueColorGuard.pdf) is an optimization technology which uses x86 segment register to store the WebAssembly linear memory base address, so as to remove most of the cost of SFI (Software-based Fault Isolation) base addition and free up a general purpose register, by this way it may:
- Improve the performance of JIT/AOT
- Reduce the footprint of JIT/AOT, the JIT/AOT code generated is smaller
- Reduce the compilation time of JIT/AOT
Currently it is supported on linux x86-64, developer can use `--enable-segue=[<flags>]` for wamrc:
```bash
wamrc --enable-segue -o aot_file wasm_file
# or
wamrc --enable-segue=[<flags>] -o aot_file wasm_file
```
`flags` can be: i32.load, i64.load, f32.load, f64.load, v128.load, i32.store, i64.store, f32.store, f64.store and v128.store, use comma to separate them, e.g. `--enable-segue=i32.load,i64.store`, and `--enable-segue` means all flags are added.
> Note: Normally for most cases, using `--enable-segue` is enough, but for some cases, using `--enable-segue=<flags>` may be better, for example for CoreMark benchmark, `--enable-segue=i32.store` may lead to better performance than `--enable-segue`.
@ -40,7 +43,8 @@ wamrc --enable-segue=[<flags>] -o aot_file wasm_file
## 4. Enable segue optimization for iwasm when running wasm file
Similar to segue optimization for wamrc, run:
``` bash
```bash
iwasm --enable-segue wasm_file (iwasm is built with llvm-jit enabled)
# or
iwasm --enable-segue=[<flags>] wasm_file
@ -55,6 +59,7 @@ LLVM PGO (Profile-Guided Optimization) allows the compiler to better optimize co
2. Compile iwasm with `cmake -DWAMR_BUILD_STATIC_PGO=1` and run `iwasm --gen-prof-file=<raw_profile_file> <aot_file_of_pgo>` to generate the raw profile file.
> Note: Directly dumping raw profile data to file system may be unsupported in some environments, developer can dump the profile data into memory buffer instead and try outputting it through network (e.g. uart or socket):
```C
uint32_t
wasm_runtime_get_pgo_prof_data_size(wasm_module_inst_t module_inst);
@ -84,6 +89,91 @@ Please notice that this method is not a general solution since it may lead to se
3. Run the AOT module by iwasm with `--disable-bounds-checks` option.
> Note: The size of AOT file will be much smaller than the default, and some tricks are possible such as let the wasm application access the memory of host os directly.
Please notice that if this option is enabled, the wasm spec test will fail since it requires the memory boundary check. For example, the runtime will crash when accessing the memory out of the boundary in some cases instead of throwing an exception as the spec requires.
> Please notice that if this option is enabled, the wasm spec test will fail since it requires the memory boundary check. For example, the runtime will crash when accessing the memory out of the boundary in some cases instead of throwing an exception as the spec requires.
You should only use this method for well tested wasm applications and make sure the memory access is safe.
## 7. Use linux-perf
Linux perf is a powerful tool to analyze the performance of a program, developer can use it to find the hot functions and optimize them. It is one profiler supported by WAMR. In order to use it, you need to add `--perf-profile` while running _iwasm_. By default, it is disabled.
> [!CAUTION]
> For now, only llvm-jit mode supports linux-perf.
Here is a basic example, if there is a Wasm application _foo.wasm_, you'll execute.
```
$ perf record --output=perf.data.raw -- iwasm --perf-profile foo.wasm
```
This will create a _perf.data_ and a _jit-xxx.dump_ under _~/.debug.jit/_ folder. This extra file is WAMR generated at runtime, and it contains the mapping between the JIT code and the original Wasm function names.
The next thing need to do is to merge _jit-xxx.dump_ file into the _perf.data_.
```
$ perf inject --jit --input=perf.data.raw --output=perf.data
```
This step will create a lot of _jitted-xxxx-N.so_ which are ELF images for all JIT functions created at runtime.
> [!TIP]
> add `-v` and check if there is output likes _write ELF image ..._. If yes, it means above merge is successful.
Finally, you can use _perf report_ to analyze the performance.
```
$ perf report --input=perf.data
```
> [!CAUTION]
> Using release builds of llvm and iwasm will produce "[unknown]" functions in the call graph. It is not only because
> of the missing debug information, but also because of removing frame pointers. To get the complete result, please
> use debug builds of both llvm and iwasm.
>
> Wasm functions names are stored in _the custom name section_. Toolchains always generate the custom name section in both debug and release builds. However, the custom name section is stripped to pursue smallest size in release build. So, if you want to get a understandable result, please search the manual of toolchain to look for a way to keep the custom name section.
>
> For example, with EMCC, you can add `-g2`.
>
> If not able to get the context of the custom name section, WAMR will use `aot_func#N` to represent the function name. `N` is from 0. `aot_func#0` represents the first *not imported wasm function*.
### 7.1 Flamegraph
[Flamegraph](https://www.brendangregg.com/flamegraphs.html) is a powerful tool to visualize stack traces of profiled software so that the most frequent code-paths can be identified quickly and accurately. In order to use it, you need to [capture graphs](https://github.com/brendangregg/FlameGraph#1-capture-stacks) when running `perf record`
```
$ perf record -k mono --call-graph=fp --output=perf.data.raw -- iwasm --perf-profile foo.wasm
```
merge the _jit-xxx.dump_ file into the _perf.data.raw_.
```
$ perf inject --jit --input=perf.data.raw --output=perf.data
```
generate the stack trace file.
```
$ perf script > out.perf
```
[fold stacks](https://github.com/brendangregg/FlameGraph#2-fold-stacks).
```
$ ./FlameGraph/stackcollapse-perf.pl out.perf > out.folded
```
[render a flamegraph](https://github.com/brendangregg/FlameGraph#3-flamegraphpl)
```
$ ./FlameGraph/flamegraph.pl out.folded > perf.foo.wasm.svg
```
> [!TIP]
> use `grep` to pick up folded stacks you are interested in or filter out something.
>
> For example, if just want to see stacks of wasm functions, you can use
>
> ```bash
> # only jitted functions
> $ grep "wasm_runtime_invoke_native" out.folded | ./FlameGraph/flamegraph.pl > perf.foo.wasm.only.svg
> ```

View File

@ -58,7 +58,7 @@ enabled.
_iwasm_ accepts address ranges via an option, `--addr-pool`, to implement
the capability control. All IP address the WebAssembly application may need to `bind()` or `connect()`
should be announced first. Every IP address should be in CIRD notation.
should be announced first. Every IP address should be in CIDR notation.
```bash
$ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm

View File

@ -98,6 +98,7 @@ $(NAME)_SOURCES := ${SHARED_ROOT}/platform/alios/alios_platform.c \
${SHARED_ROOT}/mem-alloc/ems/ems_alloc.c \
${SHARED_ROOT}/mem-alloc/ems/ems_hmu.c \
${SHARED_ROOT}/utils/bh_assert.c \
${SHARED_ROOT}/utils/bh_bitmap.c \
${SHARED_ROOT}/utils/bh_common.c \
${SHARED_ROOT}/utils/bh_hashmap.c \
${SHARED_ROOT}/utils/bh_list.c \

View File

@ -47,7 +47,7 @@ libc_wasi_print_help()
"--map-dir=<guest-path2::host-path2>\n");
printf(" --addr-pool=<addrs> Grant wasi access to the given network "
"addresses in\n");
printf(" CIRD notation to the program, seperated "
printf(" CIDR notation to the program, seperated "
"with ',',\n");
printf(" for example:\n");
printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
@ -156,6 +156,9 @@ libc_wasi_parse(char *arg, libc_wasi_parse_context_t *ctx)
}
ctx->ns_lookup_pool[ctx->ns_lookup_pool_size++] = arg + 16;
}
else {
return LIBC_WASI_PARSE_RESULT_NEED_HELP;
}
return LIBC_WASI_PARSE_RESULT_OK;
}

View File

@ -228,7 +228,7 @@ print_help()
printf(" to the program, for example:\n");
printf(" --dir=<dir1> --dir=<dir2>\n");
printf(" --addr-pool= Grant wasi access to the given network addresses in\n");
printf(" CIRD notation to the program, seperated with ',',\n");
printf(" CIDR notation to the program, seperated with ',',\n");
printf(" for example:\n");
printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
printf(" --max-threads=n Set maximum thread number per cluster, default is 4\n");

View File

@ -13,6 +13,8 @@ else ifeq ($(CONFIG_ARCH_ARMV7M),y)
WAMR_BUILD_TARGET := THUMBV7EM
else ifeq ($(CONFIG_ARCH_ARMV8M),y)
WAMR_BUILD_TARGET := THUMBV8M
else ifeq ($(CONFIG_ARCH_ARM64),y)
WAMR_BUILD_TARGET := AARCH64
else ifeq ($(CONFIG_ARCH_X86),y)
WAMR_BUILD_TARGET := X86_32
else ifeq ($(CONFIG_ARCH_X86_64),y)
@ -236,10 +238,10 @@ else
CFLAGS += -DWASM_ENABLE_LIBC_BUILTIN=0
endif
ifeq ($(CONFIG_INTERPRETERS_WAMR_CONFIGUABLE_BOUNDS_CHECKS),y)
CFLAGS += -DWASM_CONFIGUABLE_BOUNDS_CHECKS=1
ifeq ($(CONFIG_INTERPRETERS_WAMR_CONFIGURABLE_BOUNDS_CHECKS),y)
CFLAGS += -DWASM_CONFIGURABLE_BOUNDS_CHECKS=1
else
CFLAGS += -DWASM_CONFIGUABLE_BOUNDS_CHECKS=0
CFLAGS += -DWASM_CONFIGURABLE_BOUNDS_CHECKS=0
endif
ifeq ($(CONFIG_INTERPRETERS_WAMR_LIBC_WASI),y)
@ -317,6 +319,12 @@ endif
# REVISIT: is this worth to have a Kconfig?
CFLAGS += -DWASM_DISABLE_WAKEUP_BLOCKING_OP=0
ifeq ($(CONFIG_INTERPRETERS_WAMR_LOAD_CUSTOM_SECTIONS),y)
CFLAGS += -DWASM_ENABLE_LOAD_CUSTOM_SECTION=1
else
CFLAGS += -DWASM_ENABLE_LOAD_CUSTOM_SECTION=0
endif
ifeq ($(CONFIG_INTERPRETERS_WAMR_CUSTOM_NAME_SECTIONS),y)
CFLAGS += -DWASM_ENABLE_CUSTOM_NAME_SECTION=1
else
@ -379,6 +387,7 @@ CSRCS += nuttx_platform.c \
ems_alloc.c \
ems_hmu.c \
bh_assert.c \
bh_bitmap.c \
bh_common.c \
bh_hashmap.c \
bh_list.c \

View File

@ -58,6 +58,7 @@ print_help()
#if WASM_ENABLE_JIT != 0
printf(" --llvm-jit-size-level=n Set LLVM JIT size level, default is 3\n");
printf(" --llvm-jit-opt-level=n Set LLVM JIT optimization level, default is 3\n");
printf(" --perf-profile Enable linux perf support. For now, it only works in llvm-jit.\n");
#if defined(os_writegsbase)
printf(" --enable-segue[=<flags>] Enable using segment register GS as the base address of\n");
printf(" linear memory, which may improve performance, flags can be:\n");
@ -69,7 +70,7 @@ print_help()
#endif
printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
" that runs commands in the form of \"FUNC ARG...\"\n");
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
printf(" --disable-bounds-checks Disable bounds checks for memory accesses\n");
#endif
#if WASM_ENABLE_LIBC_WASI != 0
@ -560,6 +561,7 @@ main(int argc, char *argv[])
uint32 llvm_jit_size_level = 3;
uint32 llvm_jit_opt_level = 3;
uint32 segue_flags = 0;
bool enable_linux_perf_support = false;
#endif
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
@ -571,7 +573,7 @@ main(int argc, char *argv[])
#endif
bool is_repl_mode = false;
bool is_xip_file = false;
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
bool disable_bounds_checks = false;
#endif
#if WASM_ENABLE_LIBC_WASI != 0
@ -638,7 +640,7 @@ main(int argc, char *argv[])
else if (!strcmp(argv[0], "--repl")) {
is_repl_mode = true;
}
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
else if (!strcmp(argv[0], "--disable-bounds-checks")) {
disable_bounds_checks = true;
}
@ -700,6 +702,9 @@ main(int argc, char *argv[])
if (segue_flags == (uint32)-1)
return print_help();
}
else if (!strncmp(argv[0], "--perf-profile", 14)) {
enable_linux_perf_support = true;
}
#endif /* end of WASM_ENABLE_JIT != 0 */
#if BH_HAS_DLFCN
else if (!strncmp(argv[0], "--native-lib=", 13)) {
@ -814,6 +819,7 @@ main(int argc, char *argv[])
init_args.llvm_jit_size_level = llvm_jit_size_level;
init_args.llvm_jit_opt_level = llvm_jit_opt_level;
init_args.segue_flags = segue_flags;
init_args.linux_perf_support = enable_linux_perf_support;
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
@ -886,7 +892,7 @@ main(int argc, char *argv[])
goto fail3;
}
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
if (disable_bounds_checks) {
wasm_runtime_set_bounds_checks(wasm_module_inst, false);
}

View File

@ -1,49 +1,32 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
FROM ubuntu:20.04
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asian/Shanghai
# Install dependencies for Zephyr and ESPRESSIF
# Install dependencies for Zephyr
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv\
python3-dev python3-setuptools python3-tk python3-wheel xz-utils file libpython3.8-dev \
ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 device-tree-compiler \
make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 qemu udev --no-install-recommends \
RUN apt-get update && apt-get install -y --no-install-recommends git cmake ninja-build gperf \
ccache dfu-util device-tree-compiler wget \
python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \
make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
# Install recent CMake version
WORKDIR /tmp
RUN mkdir /opt/cmake \
&& wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1-linux-x86_64.sh \
&& sh cmake-3.22.1-linux-x86_64.sh --skip-license --prefix=/opt/cmake && rm cmake-3.22.1-linux-x86_64.sh
ENV PATH="/opt/cmake/bin:$PATH"
# Install the Zephyr Software Development Kit (SDK)
WORKDIR /opt
# hadolint ignore=DL4006
RUN wget --progress=dot:giga https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64.tar.xz \
&& wget --progress=dot:giga -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing \
&& tar xvf zephyr-sdk-0.16.1_linux-x86_64.tar.xz && rm zephyr-sdk-0.16.1_linux-x86_64.tar.xz
RUN wget --progress=dot:giga https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64.tar.xz \
&& wget --progress=dot:giga -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/sha256.sum | shasum --check --ignore-missing \
&& tar xvf zephyr-sdk-0.16.3_linux-x86_64.tar.xz && rm zephyr-sdk-0.16.3_linux-x86_64.tar.xz
WORKDIR /opt/zephyr-sdk-0.16.1
WORKDIR /opt/zephyr-sdk-0.16.3
# hadolint ignore=DL4006
RUN yes | ./setup.sh
# Get ESP-IDF
RUN ln -s /usr/bin/python3 /usr/bin/python && mkdir -p ~/esp
WORKDIR /root/esp
RUN git clone https://github.com/espressif/esp-idf.git
WORKDIR /root/esp/esp-idf
RUN git checkout 03d4fa28694ee15ccfd5a97447575de2d1655026 \
&& git submodule update --init --recursive
# Set up the sep-idf tools
RUN ./install.sh esp32 esp32c3
# Get Zephyr
# hadolint ignore=DL3013
RUN pip3 install --no-cache-dir west && west init -m https://github.com/zephyrproject-rtos/zephyr --mr v3.4.0 /root/zephyrproject
RUN pip3 install --no-cache-dir west && west init -m https://github.com/zephyrproject-rtos/zephyr --mr v3.5.0 /root/zephyrproject
WORKDIR /root/zephyrproject
RUN west update

View File

@ -1,58 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asian/Shanghai
# Install dependencies for Zephyr and ESPRESSIF
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv\
python3-dev python3-setuptools python3-tk python3-wheel xz-utils file libpython3.8-dev \
ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 device-tree-compiler \
make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 qemu udev --no-install-recommends \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
# Install recent CMake version
WORKDIR /tmp
RUN mkdir /opt/cmake \
&& wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1-linux-x86_64.sh \
&& sh cmake-3.22.1-linux-x86_64.sh --skip-license --prefix=/opt/cmake && rm cmake-3.22.1-linux-x86_64.sh
ENV PATH="/opt/cmake/bin:$PATH"
# Install the Zephyr Software Development Kit (SDK)
WORKDIR /opt
# hadolint ignore=DL4006
RUN wget --progress=dot:giga https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.3/zephyr-sdk-0.11.3-setup.run \
&& chmod +x ./zephyr-sdk-0.11.3-setup.run \
&& ./zephyr-sdk-0.11.3-setup.run -- -d /opt/zephyr-sdk-0.11.3
ENV ZEPHYR_TOOLCHAIN_VARIANT=zephyr
ENV ZEPHYR_SDK_INSTALL_DIR=/opt/zephyr-sdk-0.11.3
# Get ESP-IDF
RUN ln -s /usr/bin/python3 /usr/bin/python && mkdir -p ~/esp
WORKDIR /root/esp
RUN git clone https://github.com/espressif/esp-idf.git
WORKDIR /root/esp/esp-idf
RUN git checkout v4.0 \
&& pip install --no-cache-dir virtualenv==16.7.12 \
&& git submodule update --init --recursive \
&& ./install.sh esp32 esp32c3
# Get Zephyr
# hadolint ignore=DL3013
RUN pip3 install --no-cache-dir west && west init -m https://github.com/zephyrproject-rtos/zephyr --mr v2.3.0 /root/zephyrproject
WORKDIR /root/zephyrproject
RUN west update
WORKDIR /root/zephyrproject/zephyr
RUN west zephyr-export && pip install --no-cache-dir -r ~/zephyrproject/zephyr/scripts/requirements.txt
# Git clone wamr
WORKDIR /root
RUN git clone https://github.com/bytecodealliance/wasm-micro-runtime.git
WORKDIR /root/wasm-micro-runtime/product-mini/platforms/zephyr/simple
ENV ZEPHYR_BASE="/root/zephyrproject/zephyr"

View File

@ -1,106 +1,108 @@
# How to use WAMR with Zephyr
## Build with Docker(recommend approach)
[Zephyr](https://www.zephyrproject.org/) is an open source real-time operating
system (RTOS) with a focus on security and broad hardware support. WAMR is
compatible with Zephyr via the [Zephyr WAMR
port](../../../../core/shared/platform/zephyr).
To have a quicker start, a Docker container of the Zephyr setup can be generated. The current docker image would be considerably large(~15GB), it would take some time to build it and enough disk space to store it.
## Setup
### Build Docker images
Using WAMR with Zephyr can be accomplished by either using the provided Docker
image, or by installing Zephyr locally. Both approaches are described below.
### Docker
The provided Docker image sets up Zephyr and its dependencies for all
architectures, meaning that you are ready to build for any [supported
board](https://docs.zephyrproject.org/latest/boards/index.html). This comes at
the expense of building a rather large image, which both can take a long time to
build and uses up a large amount of storage (~15 GB).
Execute the following command to build the Docker image. This may take an
extended period of time to complete.
```shell
docker build -t wamr-zephyr .
```
> PS: currently, the esp32 custom linker script only works with a lower version of Zephyr, if you want to use an esp32 board, you can build the Dockerfile with a lower version of Zephyr, Zephyr SDE, ESP-IDF. The old version of Docker image can also build other targets, but probably it's a better choice to use the new Dockerfile for other boards
Execute the following command to run the image built in the previous step. If
you are planning to flash a device after building, make sure to specify it with
[`--device`](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities).
```shell
# If you want to build on esp32 platform
docker build -f Dockerfile.old -t wamr-zephyr .
docker run -it --rm --device=/dev/ttyUSB0 wamr-zephyr
```
### Run Docker images
### Local Environment
Adopt the device or remove if not needed.
Zephyr can also be setup locally to enable building this sample application.
This allows you have have more control over what modules and tools are
installed, which can drastically reduce the storage required compared to the
Docker image.
Follow the steps provided in the [Zephyr Getting Started
guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html)
to setup for local development.
## Building for a Specific Board
With an environment setup either locally or in a Docker container, you can build
for a Zephyr suppported board using
[`west`](https://docs.zephyrproject.org/latest/develop/west/index.html). There
are already [configuaration files](./boards) for a few boards in this sample.
However, if you are using a new board, you will need to add your own file for
the board, or define configuration in the [`prj.conf](./prj.conf). After doing
so, use the following command with your board identifier to build the sample
application.
```shell
docker run -ti --device=/dev/ttyUSB0 wamr-zephyr
west build . -b <board-identifier> --pristine -- -DWAMR_BUILD_TARGET=<wamr-arch>
```
And then inside the docker container:
The `<board-identifier>` can be found in the Zephyr supported boards
documentation. It must also be used as the name of the board configuration file.
You must define the architecture for WAMR to target with `WAMR_BUILD_TARGET`.
The list of supported architectures can be found in the main project
[README.md](../../../../README.md#supported-architectures-and-platforms).
It may be necessary to define additional symbols for some boards. For example,
WAMR AOT execution may not be supported on all architectures. It and other
options can be disabled by modifying the [CMakeLists.txt](./CMakeLists.txt)
file, or by passing additional arguments at build (e.g. `-DWAMR_BUILD_AOT=0`).
### Example Targets
[ESP32-C3](https://docs.zephyrproject.org/latest/boards/riscv/esp32c3_devkitm/doc/index.html)
is a 32-bit RISC-V target that does not currently support AOT.
```shell
# copy the corresponding board conf file to current directory
cp boards/qemu_x86_nommu.conf prj.conf
# then build
./build_and_run.sh x86
west build . -b esp32c3_devkitm -p always -- -DWAMR_BUILD_TARGET=RISCV32_ILP32 -DWAMR_BUILD_AOT=0
```
> PS: for boards esp32, need to configure some environment first
[ARM Cortex-A53 QEMU
(ARM)](https://docs.zephyrproject.org/latest/boards/arm64/qemu_cortex_a53/doc/index.html)
is a 64-bit ARM target for emulating the Cortex-A53 platform.
```shell
# configure zephyr with espressif
export ZEPHYR_TOOLCHAIN_VARIANT="espressif"
export ESPRESSIF_TOOLCHAIN_PATH="/root/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-elf/"
export ESP_IDF_PATH="/root/esp/esp-idf"
# copy the corresponding board conf file to current directory
cp boards/esp32.conf prj.conf
# then build
./build_and_run.sh esp32
west build . -b qemu_cortex_a53 -p always -- -DWAMR_BUILD_TARGET=AARCH64
```
## Build on local environment
### Dependencies installation
## Flashing or Running Image
Following the Zephyr and Espressif official document:
1. Zephyr installation:
<https://docs.zephyrproject.org/latest/develop/getting_started/index.html>
2. ESP32 installation:
<https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-macos-setup.html>
And setup the Zephyr for esp32:
<https://wiki.amarulasolutions.com/zephyr/esp32/esp32-setup.html>
Then Installing QEMU, for example, on Linux:
The board can be flashed with the built image with the following command.
```shell
sudo apt-get install qemu
west flash
```
### Run the build script
`west` will automatically identify the board if it is connected to the host
machine.
Make sure you have the environment variable ready, you can use the command `env` to check:
When using emulated targets, such as those that utilize QEMU, there is no
physical device to flash, but `west` can be used to run the image under
emulation.
```shell
env
```
```shell
# export ZEPHYR_BASE if it's not present
export ZEPHYR_BASE=~/zephyrproject/zephyr
# and if you install zephyr in virtual environment rather than global
source ~/zephyrproject/.venv/bin/activate
```
For boards esp32, need to configure some extra environment first, check the following env variable whether in the env list, if not, add them like:
> Noted: The esp32 custom linker script doesn't work with the recent version of Zephyr, if you want to use it in the local environment, please install Zephyr 2.3.0 with the corresponding SDK, and ESP-IDF 4.0
```shell
export ZEPHYR_TOOLCHAIN_VARIANT="espressif"
export ESPRESSIF_TOOLCHAIN_PATH="~/.espressif/tools/xtensa-esp32-elf/esp-{the version you installed}/xtensa-esp32-elf/"
export ESP_IDF_PATH="~/esp/esp-idf"
```
Then you can run the build script:
```shell
# copy the corresponding board conf file to current directory
cp boards/qemu_x86_nommu.conf prj.conf
# then build
./build_and_run.sh x86
west build -t run
```

View File

@ -1,8 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
CONFIG_STACK_SENTINEL=y
CONFIG_PRINTK=y
CONFIG_LOG=y
CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y
CONFIG_CUSTOM_LINKER_SCRIPT="esp32_custom_linker.ld"

View File

@ -2,6 +2,3 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
CONFIG_ARM_MPU=y
CONFIG_STACK_SENTINEL=y
CONFIG_PRINTK=y
CONFIG_LOG=y

View File

@ -2,6 +2,3 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
CONFIG_ARM_MMU=n
CONFIG_STACK_SENTINEL=y
CONFIG_PRINTK=y
CONFIG_LOG=y

View File

@ -1,6 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
CONFIG_STACK_SENTINEL=y
CONFIG_PRINTK=y
CONFIG_LOG=n

View File

@ -1,6 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
CONFIG_STACK_SENTINEL=y
CONFIG_PRINTK=y
CONFIG_LOG=n

View File

@ -1,6 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
CONFIG_STACK_SENTINEL=y
CONFIG_PRINTK=y
CONFIG_LOG=y

View File

@ -1,6 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
CONFIG_STACK_SENTINEL=y
CONFIG_PRINTK=y
CONFIG_LOG=y

View File

@ -5,7 +5,6 @@
X86_TARGET="x86"
STM32_TARGET="stm32"
ESP32_TARGET="esp32"
ESP32C3_TARGET="esp32c3"
PARTICLE_ARGON_TARGET="particle_argon"
QEMU_CORTEX_A53="qemu_cortex_a53"
@ -17,11 +16,10 @@ QEMU_ARC_TARGET="qemu_arc"
usage ()
{
echo "USAGE:"
echo "$0 $X86_TARGET|$STM32_TARGET|$ESP32_TARGET|$ESP32C3_TARGET|$PARTICLE_ARGON_TARGET|$QEMU_CORTEX_A53|$QEMU_XTENSA_TARGET|$QEMU_RISCV64_TARGET|$QEMU_RISCV32_TARGET|$QEMU_ARC_TARGET"
echo "$0 $X86_TARGET|$STM32_TARGET|$ESP32C3_TARGET|$PARTICLE_ARGON_TARGET|$QEMU_CORTEX_A53|$QEMU_XTENSA_TARGET|$QEMU_RISCV64_TARGET|$QEMU_RISCV32_TARGET|$QEMU_ARC_TARGET"
echo "Example:"
echo " $0 $X86_TARGET"
echo " $0 $STM32_TARGET"
echo " $0 $ESP32_TARGET"
echo " $0 $ESP32C3_TARGET"
echo " $0 $PARTICLE_ARGON_TARGET"
echo " $0 $QEMU_CORTEX_A53"
@ -51,27 +49,11 @@ case $TARGET in
-DWAMR_BUILD_TARGET=THUMBV7
west flash
;;
$ESP32_TARGET)
export ZEPHYR_TOOLCHAIN_VARIANT="espressif"
if [[ -z "${ESPRESSIF_TOOLCHAIN_PATH}" ]]; then
echo "Set ESPRESSIF_TOOLCHAIN_PATH to your espressif toolchain"
exit 1
fi
west build -b esp32 \
. -p always -- \
-DWAMR_BUILD_TARGET=XTENSA
# west flash will discover the device
west flash
;;
$ESP32C3_TARGET)
export ZEPHYR_TOOLCHAIN_VARIANT="espressif"
if [[ -z "${ESPRESSIF_TOOLCHAIN_PATH}" ]]; then
echo "Set ESPRESSIF_TOOLCHAIN_PATH to your espressif toolchain"
exit 1
fi
west build -b esp32c3_devkitm \
. -p always -- \
-DWAMR_BUILD_TARGET=RISCV32_ILP32
-DWAMR_BUILD_TARGET=RISCV32_ILP32 \
-DWAMR_BUILD_AOT=0
# west flash will discover the device
west flash
;;

View File

@ -1,274 +0,0 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* Copyright (c) 2017 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
#include <devicetree.h>
#include <autoconf.h>
#include <linker/sections.h>
#include <linker/linker-defs.h>
#include <linker/linker-tool.h>
#define RAMABLE_REGION dram0_0_seg :dram0_0_phdr
#define RAMABLE_REGION1 dram0_1_seg :dram0_0_phdr
#define ROMABLE_REGION iram0_0_seg :iram0_0_phdr
PROVIDE ( __stack = 0x3ffe3f20 );
PROVIDE ( esp32_rom_uart_tx_one_char = 0x40009200 );
PROVIDE ( esp32_rom_uart_rx_one_char = 0x400092d0 );
PROVIDE ( esp32_rom_uart_attach = 0x40008fd0 );
PROVIDE ( esp32_rom_intr_matrix_set = 0x4000681c );
PROVIDE ( esp32_rom_gpio_matrix_in = 0x40009edc );
PROVIDE ( esp32_rom_gpio_matrix_out = 0x40009f0c );
PROVIDE ( esp32_rom_Cache_Flush = 0x40009a14 );
PROVIDE ( esp32_rom_Cache_Read_Enable = 0x40009a84 );
PROVIDE ( esp32_rom_ets_set_appcpu_boot_addr = 0x4000689c );
MEMORY
{
iram0_0_seg(RX): org = 0x40080000, len = 0x20000
iram0_2_seg(RX): org = 0x400D0018, len = 0x330000
dram0_0_seg(RW): org = 0x3FFB0000, len = 0x30000
dram0_1_seg(RWX):org = 0x400A0000, len = 0x20000
drom0_0_seg(R): org = 0x3F400010, len = 0x800000
rtc_iram_seg(RWX): org = 0x400C0000, len = 0x2000
rtc_slow_seg(RW): org = 0x50000000, len = 0x1000
#ifdef CONFIG_GEN_ISR_TABLES
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
#endif
}
PHDRS
{
iram0_0_phdr PT_LOAD;
dram0_0_phdr PT_LOAD;
}
/* Default entry point: */
PROVIDE ( _ResetVector = 0x40000400 );
ENTRY(CONFIG_KERNEL_ENTRY)
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x40000450);
PROVIDE(_memmap_reset_vector = 0x40000400);
SECTIONS
{
#include <linker/rel-sections.ld>
/* RTC fast memory holds RTC wake stub code,
including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
. = ALIGN(4);
*(.rtc.literal .rtc.text)
*rtc_wake_stub*.o(.literal .text .literal.* .text.*)
} >rtc_iram_seg
/* RTC slow memory holds RTC wake stub
data/rodata, including from any source file
named rtc_wake_stub*.c
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*)
_rtc_data_end = ABSOLUTE(.);
} > rtc_slow_seg
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.o(.bss .bss.*)
*rtc_wake_stub*.o(COMMON)
_rtc_bss_end = ABSOLUTE(.);
} > rtc_slow_seg
/* Send .iram0 code to iram */
.iram0.vectors : ALIGN(4)
{
/* Vectors go to IRAM */
_init_start = ABSOLUTE(.);
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
. = 0x0;
KEEP(*(.WindowVectors.text));
. = 0x180;
KEEP(*(.Level2InterruptVector.text));
. = 0x1c0;
KEEP(*(.Level3InterruptVector.text));
. = 0x200;
KEEP(*(.Level4InterruptVector.text));
. = 0x240;
KEEP(*(.Level5InterruptVector.text));
. = 0x280;
KEEP(*(.DebugExceptionVector.text));
. = 0x2c0;
KEEP(*(.NMIExceptionVector.text));
. = 0x300;
KEEP(*(.KernelExceptionVector.text));
. = 0x340;
KEEP(*(.UserExceptionVector.text));
. = 0x3C0;
KEEP(*(.DoubleExceptionVector.text));
. = 0x400;
*(.*Vector.literal)
*(.UserEnter.literal);
*(.UserEnter.text);
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
_init_end = ABSOLUTE(.);
/* This goes here, not at top of linker script, so addr2line finds it last,
and uses it in preference to the first symbol in IRAM */
_iram_start = ABSOLUTE(0);
} GROUP_LINK_IN(ROMABLE_REGION)
#include <linker/common-ram.ld>
#include <linker/common-rom.ld>
SECTION_PROLOGUE(_TEXT_SECTION_NAME, , ALIGN(4))
{
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
*(.iram1 .iram1.*)
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
*(.literal .text .literal.* .text.*)
_iram_text_end = ABSOLUTE(.);
} GROUP_LINK_IN(ROMABLE_REGION)
.dram0.text :
{
_data_start = ABSOLUTE(.);
*(.aot_code_buf)
_data_end = ABSOLUTE(.);
. = ALIGN(4);
} GROUP_LINK_IN(RAMABLE_REGION1)
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
*(.dram1 .dram1.*)
_data_end = ABSOLUTE(.);
. = ALIGN(4);
} GROUP_LINK_IN(RAMABLE_REGION)
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(4))
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
KEEP (*(.xt_except_table))
KEEP (*(.gcc_except_table .gcc_except_table.*))
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
KEEP (*(.eh_frame))
/* C++ constructor and destructor tables, properly ordered: */
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
. = ALIGN(4); /* this table MUST be 4-byte aligned */
_rodata_end = ABSOLUTE(.);
} GROUP_LINK_IN(RAMABLE_REGION)
/* Shared RAM */
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
. = ALIGN (8);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.share.mem)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} GROUP_LINK_IN(RAMABLE_REGION)
SECTION_DATA_PROLOGUE(_APP_NOINIT_SECTION_NAME, (NOLOAD),)
{
. = ALIGN (8);
*(.app_noinit)
*("app_noinit.*")
. = ALIGN (8);
_app_end = ABSOLUTE(.);
} GROUP_LINK_IN(RAMABLE_REGION)
SECTION_DATA_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD),)
{
. = ALIGN (8);
*(.noinit)
*(".noinit.*")
. = ALIGN (8);
_heap_start = ABSOLUTE(.);
} GROUP_LINK_IN(RAMABLE_REGION)
#ifdef CONFIG_GEN_ISR_TABLES
#include <linker/intlist.ld>
#endif
#include <linker/debug-sections.ld>
SECTION_PROLOGUE(.xtensa.info, 0,)
{
*(.xtensa.info)
}
}

View File

@ -104,56 +104,6 @@ app_instance_main(wasm_module_inst_t module_inst)
static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 };
#endif
#ifdef CONFIG_BOARD_ESP32
#include "mem_alloc.h"
/*
esp32_technical_reference_manual:
"
The capacity of Internal SRAM 1 is 128 KB. Either CPU can read and write this
memory at addresses 0x3FFE_0000 ~ 0x3FFF_FFFF of the data bus, and also at
addresses 0x400A_0000 ~ 0x400B_FFFF of the instruction bus.
"
The custom linker script defines dram0_1_seg and map it to 0x400A_0000 ~
0x400B_FFFF for instruction bus access. Here we define the buffer that will be
placed to dram0_1_seg.
*/
static char esp32_executable_memory_buf[100 * 1024]
__attribute__((section(".aot_code_buf"))) = { 0 };
/* the poll allocator for executable memory */
static mem_allocator_t esp32_exec_mem_pool_allocator;
static int
esp32_exec_mem_init()
{
if (!(esp32_exec_mem_pool_allocator =
mem_allocator_create(esp32_executable_memory_buf,
sizeof(esp32_executable_memory_buf))))
return -1;
return 0;
}
static void
esp32_exec_mem_destroy()
{
mem_allocator_destroy(esp32_exec_mem_pool_allocator);
}
static void *
esp32_exec_mem_alloc(unsigned int size)
{
return mem_allocator_malloc(esp32_exec_mem_pool_allocator, size);
}
static void
esp32_exec_mem_free(void *addr)
{
mem_allocator_free(esp32_exec_mem_pool_allocator, addr);
}
#endif /* end of #ifdef CONFIG_BOARD_ESP32 */
void
iwasm_main(void *arg1, void *arg2, void *arg3)
{
@ -189,16 +139,6 @@ iwasm_main(void *arg1, void *arg2, void *arg3)
return;
}
#ifdef CONFIG_BOARD_ESP32
/* Initialize executable memory */
if (esp32_exec_mem_init() != 0) {
printf("Init executable memory failed.\n");
goto fail1;
}
/* Set hook functions for executable memory management */
set_exec_mem_alloc_func(esp32_exec_mem_alloc, esp32_exec_mem_free);
#endif
#if WASM_ENABLE_LOG != 0
bh_log_set_verbose_level(log_verbose_level);
#endif
@ -211,11 +151,7 @@ iwasm_main(void *arg1, void *arg2, void *arg3)
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
error_buf, sizeof(error_buf)))) {
printf("%s\n", error_buf);
#ifdef CONFIG_BOARD_ESP32
goto fail1_1;
#else
goto fail1;
#endif
}
/* instantiate the module */
@ -236,12 +172,6 @@ fail2:
/* unload the module */
wasm_runtime_unload(wasm_module);
#ifdef CONFIG_BOARD_ESP32
fail1_1:
/* destroy executable memory */
esp32_exec_mem_destroy();
#endif
fail1:
/* destroy runtime environment */
wasm_runtime_destroy();
@ -265,8 +195,18 @@ iwasm_init(void)
iwasm_main, NULL, NULL, NULL, MAIN_THREAD_PRIORITY, 0, K_NO_WAIT);
return tid ? true : false;
}
#if KERNEL_VERSION_NUMBER < 0x030400 /* version 3.4.0 */
void
main(void)
{
iwasm_init();
}
#else
int
main(void)
{
iwasm_init();
return 0;
}
#endif

View File

@ -58,7 +58,7 @@ float_to_string(float n, char *res, int res_size, int afterpoint)
// is needed to handle cases like 233.007
fpart = fpart * get_pow(10, afterpoint);
intToStr((int)fpart, res + i + 1, sizeof(res + i + 1), afterpoint);
intToStr((int)fpart, res + i + 1, res_size - i - 1, afterpoint);
}
}

View File

@ -10,8 +10,12 @@
#include <string.h>
#include "drivers/spi.h"
#include "zephyr.h"
#include "kernel.h"
#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */
#include <zephyr.h>
#include <kernel.h>
#else
#include <zephyr/kernel.h>
#endif
#if USE_XPT2046

View File

@ -7,7 +7,12 @@
#define ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_
#include "board_config.h"
#include <autoconf.h>
#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */
#include <zephyr.h>
#else
#include <zephyr/kernel.h>
#endif
#define ILI9340_CMD_ENTER_SLEEP 0x10
#define ILI9340_CMD_EXIT_SLEEP 0x11

View File

@ -31,7 +31,12 @@ xpt2046_init(void);
extern void
wgl_init();
#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */
#include <zephyr.h>
#else
#include <zephyr/kernel.h>
#endif
#include <drivers/uart.h>
#include <device.h>

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