diff --git a/.github/scripts/codeql_buildscript.sh b/.github/scripts/codeql_buildscript.sh index 3e523775f8..388f3680d3 100755 --- a/.github/scripts/codeql_buildscript.sh +++ b/.github/scripts/codeql_buildscript.sh @@ -126,6 +126,16 @@ if [[ $? != 0 ]]; then exit 1; fi +# build iwasm with multi-memory enabled +cd ${WAMR_DIR}/product-mini/platforms/linux +rm -rf build && mkdir build && cd build +cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_MULTI_MEMORY=1 +make -j +if [[ $? != 0 ]]; then + echo "Failed to build iwasm with multi-memory enabled!" + exit 1; +fi + # build iwasm with hardware boundary check disabled cd ${WAMR_DIR}/product-mini/platforms/linux rm -rf build && mkdir build && cd build @@ -280,3 +290,23 @@ if [[ $? != 0 ]]; then echo "Failed to build iwasm with linux perf support enabled!" exit 1; fi + +# build iwasm with shared heap enabled +cd ${WAMR_DIR}/product-mini/platforms/linux +rm -rf build && mkdir build && cd build +cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_SHARED_HEAP=1 +make -j +if [[ $? != 0 ]]; then + echo "Failed to build iwasm with shared heap enabled!" + exit 1; +fi + +# build iwasm with dynamic aot debug enabled +cd ${WAMR_DIR}/product-mini/platforms/linux +rm -rf build && mkdir build && cd build +cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_DYNAMIC_AOT_DEBUG=1 +make -j +if [[ $? != 0 ]]; then + echo "Failed to build iwasm dynamic aot debug enabled!" + exit 1; +fi diff --git a/.github/workflows/build_docker_images.yml b/.github/workflows/build_docker_images.yml index d5bf682c4e..f7643af3fd 100644 --- a/.github/workflows/build_docker_images.yml +++ b/.github/workflows/build_docker_images.yml @@ -15,9 +15,14 @@ on: type: string required: true +permissions: + contents: read + jobs: build-and-push-images: runs-on: ubuntu-22.04 + permissions: + contents: write # for uploading release artifacts steps: - name: Checkout repository diff --git a/.github/workflows/build_iwasm_release.yml b/.github/workflows/build_iwasm_release.yml index 8870208534..74c2340af9 100644 --- a/.github/workflows/build_iwasm_release.yml +++ b/.github/workflows/build_iwasm_release.yml @@ -31,9 +31,78 @@ on: type: string required: false +env: + DEFAULT_BUILD_OPTIONS: + "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=1 \ + -DWAMR_BUILD_CUSTOM_NAME_SECTION=0 \ + -DWAMR_BUILD_DEBUG_INTERP=0 \ + -DWAMR_BUILD_DEBUG_AOT=0 \ + -DWAMR_BUILD_DUMP_CALL_STACK=0 \ + -DWAMR_BUILD_LIBC_UVWASI=0 \ + -DWAMR_BUILD_LIBC_EMCC=0 \ + -DWAMR_BUILD_LIB_RATS=0 \ + -DWAMR_BUILD_LOAD_CUSTOM_SECTION=0 \ + -DWAMR_BUILD_MEMORY_PROFILING=0 \ + -DWAMR_BUILD_MINI_LOADER=0 \ + -DWAMR_BUILD_MULTI_MODULE=0 \ + -DWAMR_BUILD_PERF_PROFILING=0 \ + -DWAMR_BUILD_SPEC_TEST=0 \ + -DWAMR_BUILD_BULK_MEMORY=1 \ + -DWAMR_BUILD_LIB_PTHREAD=1 \ + -DWAMR_BUILD_LIB_PTHREAD_SEMAPHORE=1 \ + -DWAMR_BUILD_LIB_WASI_THREADS=1 \ + -DWAMR_BUILD_LIBC_BUILTIN=1 \ + -DWAMR_BUILD_LIBC_WASI=1 \ + -DWAMR_BUILD_REF_TYPES=1 \ + -DWAMR_BUILD_SIMD=1 \ + -DWAMR_BUILD_SHARED_MEMORY=1 \ + -DWAMR_BUILD_TAIL_CALL=1 \ + -DWAMR_BUILD_THREAD_MGR=1" + GC_EH_BUILD_OPTIONS: + "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_FAST_JIT=0 -DWAMR_BUILD_JIT=0 \ + -DWAMR_BUILD_CUSTOM_NAME_SECTION=0 \ + -DWAMR_BUILD_DEBUG_INTERP=0 \ + -DWAMR_BUILD_DEBUG_AOT=0 \ + -DWAMR_BUILD_DUMP_CALL_STACK=0 \ + -DWAMR_BUILD_LIBC_UVWASI=0 \ + -DWAMR_BUILD_LIBC_EMCC=0 \ + -DWAMR_BUILD_LIB_RATS=0 \ + -DWAMR_BUILD_LOAD_CUSTOM_SECTION=0 \ + -DWAMR_BUILD_MEMORY_PROFILING=0 \ + -DWAMR_BUILD_MINI_LOADER=0 \ + -DWAMR_BUILD_MULTI_MODULE=0 \ + -DWAMR_BUILD_PERF_PROFILING=0 \ + -DWAMR_BUILD_SPEC_TEST=0 \ + -DWAMR_BUILD_BULK_MEMORY=1 \ + -DWAMR_BUILD_LIB_PTHREAD=1 \ + -DWAMR_BUILD_LIB_PTHREAD_SEMAPHORE=1 \ + -DWAMR_BUILD_LIB_WASI_THREADS=1 \ + -DWAMR_BUILD_LIBC_BUILTIN=1 \ + -DWAMR_BUILD_LIBC_WASI=1 \ + -DWAMR_BUILD_REF_TYPES=1 \ + -DWAMR_BUILD_SIMD=1 \ + -DWAMR_BUILD_SHARED_MEMORY=1 \ + -DWAMR_BUILD_TAIL_CALL=1 \ + -DWAMR_BUILD_THREAD_MGR=1 \ + -DWAMR_BUILD_EXCE_HANDLING=1 \ + -DWAMR_BUILD_GC=1" + +permissions: + contents: read + jobs: build: runs-on: ${{ inputs.runner }} + strategy: + matrix: + include: + - build_options: $DEFAULT_BUILD_OPTIONS + suffix: '' + - build_options: $GC_EH_BUILD_OPTIONS + suffix: '-gc-eh' + permissions: + contents: write # for uploading release artifacts + steps: - uses: actions/checkout@v4 @@ -51,40 +120,25 @@ jobs: fail-on-cache-miss: true - name: generate iwasm binary release + shell: bash run: | - cmake -S . -B build \ - -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=1 \ - -DWAMR_BUILD_CUSTOM_NAME_SECTION=0 \ - -DWAMR_BUILD_DEBUG_INTERP=0 \ - -DWAMR_BUILD_DEBUG_AOT=0 \ - -DWAMR_BUILD_DUMP_CALL_STACK=0 \ - -DWAMR_BUILD_LIBC_UVWASI=0 \ - -DWAMR_BUILD_LIBC_EMCC=0 \ - -DWAMR_BUILD_LIB_RATS=0 \ - -DWAMR_BUILD_LOAD_CUSTOM_SECTION=0 \ - -DWAMR_BUILD_MEMORY_PROFILING=0 \ - -DWAMR_BUILD_MINI_LOADER=0 \ - -DWAMR_BUILD_MULTI_MODULE=0 \ - -DWAMR_BUILD_PERF_PROFILING=0 \ - -DWAMR_BUILD_SPEC_TEST=0 \ - -DWAMR_BUILD_BULK_MEMORY=1 \ - -DWAMR_BUILD_LIB_PTHREAD=1 \ - -DWAMR_BUILD_LIB_PTHREAD_SEMAPHORE=1 \ - -DWAMR_BUILD_LIB_WASI_THREADS=1 \ - -DWAMR_BUILD_LIBC_BUILTIN=1 \ - -DWAMR_BUILD_LIBC_WASI=1 \ - -DWAMR_BUILD_REF_TYPES=1 \ - -DWAMR_BUILD_SIMD=1 \ - -DWAMR_BUILD_SHARED_MEMORY=1 \ - -DWAMR_BUILD_TAIL_CALL=1 \ - -DWAMR_BUILD_THREAD_MGR=1 + cmake -S . -B build ${{ matrix.build_options }} cmake --build build --config Release --parallel 4 working-directory: ${{ inputs.cwd }} - - name: compress the binary + - name: Compress the binary on Windows + if: inputs.runner == 'windows-latest' + run: | + tar -czf iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz iwasm.exe + Compress-Archive -Path iwasm.exe -DestinationPath iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.runner }}.zip + mv iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.runner }}.* ../ + working-directory: ${{ inputs.cwd }}/build/Release + + - name: compress the binary on non-Windows + if: inputs.runner != 'windows-latest' run: | - tar czf iwasm-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz iwasm - zip iwasm-${{ inputs.ver_num }}-${{ inputs.runner }}.zip iwasm + tar czf iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz iwasm + zip iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.runner }}.zip iwasm working-directory: ${{ inputs.cwd }}/build - name: upload release tar.gz @@ -93,8 +147,8 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ inputs.upload_url }} - asset_path: ${{ inputs.cwd }}/build/iwasm-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz - asset_name: iwasm-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}.tar.gz + asset_path: ${{ inputs.cwd }}/build/iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz + asset_name: iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}.tar.gz asset_content_type: application/x-gzip - name: upload release zip @@ -103,6 +157,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ inputs.upload_url }} - asset_path: ${{ inputs.cwd }}/build/iwasm-${{ inputs.ver_num }}-${{ inputs.runner }}.zip - asset_name: iwasm-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}.zip + asset_path: ${{ inputs.cwd }}/build/iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.runner }}.zip + asset_name: iwasm${{ matrix.suffix }}-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}.zip asset_content_type: application/zip diff --git a/.github/workflows/build_llvm_libraries.yml b/.github/workflows/build_llvm_libraries.yml index 5cde572097..bdfd4fcb2c 100644 --- a/.github/workflows/build_llvm_libraries.yml +++ b/.github/workflows/build_llvm_libraries.yml @@ -27,6 +27,9 @@ on: description: "A cached key of LLVM libraries" value: ${{ jobs.build_llvm_libraries.outputs.key}} +permissions: + contents: read + jobs: build_llvm_libraries: runs-on: ${{ inputs.os }} @@ -36,6 +39,9 @@ jobs: image: ${{ inputs.container_image }} outputs: key: ${{ steps.create_lib_cache_key.outputs.key}} + permissions: + contents: read + actions: write # for uploading cached artifact steps: - name: checkout @@ -43,6 +49,7 @@ jobs: - name: install dependencies for non macos-14 if: inputs.os != 'macos-14' + shell: bash run: /usr/bin/env python3 -m pip install -r requirements.txt working-directory: build-scripts @@ -51,10 +58,13 @@ jobs: run: /usr/bin/env python3 -m pip install -r requirements.txt --break-system-packages working-directory: build-scripts - - name: retrieve the last commit ID + - name: Retrieve the last commit ID id: get_last_commit - run: echo "last_commit=$(GH_TOKEN=${{ secrets.GITHUB_TOKEN }} /usr/bin/env python3 ./build_llvm.py ${{ inputs.extra_build_llvm_options }} --llvm-ver)" >> $GITHUB_OUTPUT - working-directory: build-scripts + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: bash + run: | + echo "last_commit=$(GH_TOKEN=${{ secrets.GITHUB_TOKEN }} /usr/bin/env python3 ./build_llvm.py ${{ inputs.extra_build_llvm_options }} --llvm-ver)" >> $GITHUB_OUTPUT # Bump the prefix number to evict all previous caches and # enforce a clean build, in the unlikely case that some @@ -62,7 +72,9 @@ jobs: # suspect. - name: form the cache key of libraries id: create_lib_cache_key - run: echo "key=0-llvm-libraries-${{ inputs.os }}-${{ inputs.arch }}-${{ steps.get_last_commit.outputs.last_commit }}${{ inputs.cache_key_suffix }}" >> $GITHUB_OUTPUT + shell: bash + run: | + echo "key=0-llvm-libraries-${{ inputs.os }}-${{ inputs.arch }}-${{ steps.get_last_commit.outputs.last_commit }}${{ inputs.cache_key_suffix }}" >> $GITHUB_OUTPUT - name: Cache LLVM libraries id: retrieve_llvm_libs @@ -107,7 +119,20 @@ jobs: - run: brew install ccache ninja if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && startsWith(inputs.os, 'macos') + - uses: actions/cache@v4 + with: + path: ~/.cache/ccache + key: 0-ccache-${{ inputs.os }}-${{ steps.get_last_commit.outputs.last_commit }} + restore-keys: | + 0-ccache-${{ inputs.os }} + if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && inputs.os == 'windows-latest' + + # Install tools on Windows + - run: choco install -y ccache ninja + if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' && inputs.os == 'windows-latest' + - name: Build LLVM libraries if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' + shell: bash run: /usr/bin/env python3 ./build_llvm.py ${{ inputs.extra_build_llvm_options }} --arch ${{ inputs.arch }} working-directory: build-scripts diff --git a/.github/workflows/build_wamr_lldb.yml b/.github/workflows/build_wamr_lldb.yml index 03474c53e1..b5cf53a4ce 100644 --- a/.github/workflows/build_wamr_lldb.yml +++ b/.github/workflows/build_wamr_lldb.yml @@ -28,8 +28,13 @@ on: required: false default: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz" +permissions: + contents: read + jobs: try_reuse: + permissions: + contents: write # for uploading release artifacts uses: ./.github/workflows/reuse_latest_release_binaries.yml with: binary_name_stem: "wamr-lldb-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}" @@ -46,6 +51,9 @@ jobs: PYTHON_VERSION: '3.10' PYTHON_UBUNTU_STANDALONE_BUILD: https://github.com/indygreg/python-build-standalone/releases/download/20230507/cpython-3.10.11+20230507-x86_64-unknown-linux-gnu-install_only.tar.gz PYTHON_MACOS_STANDALONE_BUILD: https://github.com/indygreg/python-build-standalone/releases/download/20230507/cpython-3.10.11+20230507-x86_64-apple-darwin-install_only.tar.gz + permissions: + contents: write # for uploading release artifacts + steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/build_wamr_sdk.yml b/.github/workflows/build_wamr_sdk.yml index 519bf96367..266c3a6466 100644 --- a/.github/workflows/build_wamr_sdk.yml +++ b/.github/workflows/build_wamr_sdk.yml @@ -35,9 +35,15 @@ on: type: string required: true +permissions: + contents: read + jobs: build: runs-on: ${{ inputs.runner }} + permissions: + contents: write # for uploading release artifacts + steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/build_wamr_vscode_ext.yml b/.github/workflows/build_wamr_vscode_ext.yml index 756215e600..d0fa3b18ee 100644 --- a/.github/workflows/build_wamr_vscode_ext.yml +++ b/.github/workflows/build_wamr_vscode_ext.yml @@ -14,9 +14,15 @@ on: type: string required: true +permissions: + contents: read + jobs: build: runs-on: ubuntu-22.04 + permissions: + contents: write # for uploading release artifacts + steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/build_wamrc.yml b/.github/workflows/build_wamrc.yml index 7c4dab039f..6b687c749d 100644 --- a/.github/workflows/build_wamrc.yml +++ b/.github/workflows/build_wamrc.yml @@ -31,9 +31,15 @@ on: type: string required: false +permissions: + contents: read + jobs: build: runs-on: ${{ inputs.runner }} + permissions: + contents: write # for uploading release artifacts + steps: - uses: actions/checkout@v4 @@ -56,8 +62,16 @@ jobs: cmake --build build --config Release --parallel 4 working-directory: wamr-compiler - - name: compress the binary - if: inputs.release + - name: Compress the binary on Windows + if: inputs.runner == 'windows-latest' && inputs.release + run: | + tar -czf wamrc-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz wamrc.exe + Compress-Archive -Path wamrc.exe -DestinationPath wamrc-${{ inputs.ver_num }}-${{ inputs.runner }}.zip + mv wamrc-${{ inputs.ver_num }}-${{ inputs.runner }}.* ../ + working-directory: wamr-compiler/build/Release + + - name: compress the binary on non-Windows + if: inputs.runner != 'windows-latest' && inputs.release run: | tar czf wamrc-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz wamrc zip wamrc-${{ inputs.ver_num }}-${{ inputs.runner }}.zip wamrc diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5a9c12d334..b458606c08 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,6 +19,9 @@ on: # allow to be triggered manually workflow_dispatch: +permissions: + contents: read + jobs: analyze: if: github.repository == 'bytecodealliance/wasm-micro-runtime' @@ -30,10 +33,6 @@ jobs: # Consider using larger runners for possible analysis time improvements. runs-on: ${{ (matrix.language == 'swift' && 'macos-13') || 'ubuntu-22.04' }} timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} - permissions: - actions: read - contents: read - security-events: write strategy: fail-fast: false @@ -41,6 +40,11 @@ jobs: language: [ 'cpp' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] + permissions: + contents: read + actions: read + security-events: write + steps: - name: Checkout repository uses: actions/checkout@v3 @@ -49,7 +53,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v3.26.13 with: languages: ${{ matrix.language }} @@ -66,7 +70,7 @@ jobs: - run: | ./.github/scripts/codeql_buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v3.26.13 with: category: "/language:${{matrix.language}}" upload: false @@ -95,14 +99,14 @@ jobs: output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif - name: Upload CodeQL results to code scanning - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@v3.26.13 with: sarif_file: ${{ steps.step1.outputs.sarif-output }} category: "/language:${{matrix.language}}" - name: Upload CodeQL results as an artifact if: success() || failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.4.3 with: name: codeql-results path: ${{ steps.step1.outputs.sarif-output }} diff --git a/.github/workflows/coding_guidelines.yml b/.github/workflows/coding_guidelines.yml index b0aa0a2b86..5692377782 100644 --- a/.github/workflows/coding_guidelines.yml +++ b/.github/workflows/coding_guidelines.yml @@ -14,6 +14,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: compliance_job: runs-on: ubuntu-20.04 diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 249a6f276c..8ba6e0e809 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -70,8 +70,14 @@ env: MEMORY64_TEST_OPTIONS: "-s spec -W -b -P" MULTI_MEMORY_TEST_OPTIONS: "-s spec -E -b -P" +permissions: + contents: read + jobs: build_llvm_libraries_on_ubuntu_2204: + permissions: + contents: read + actions: write uses: ./.github/workflows/build_llvm_libraries.yml with: os: "ubuntu-22.04" @@ -578,6 +584,15 @@ jobs: ./run.sh test1 ./run.sh test2 + - name: Build Sample [shared-heap] + run: | + cd samples/shared-heap + mkdir build && cd build + cmake .. + cmake --build . --config Debug --parallel 4 + ./shared_heap_test + ./shared_heap_test --aot + test: needs: [ diff --git a/.github/workflows/compilation_on_macos.yml b/.github/workflows/compilation_on_macos.yml index 3b92f45256..66938905cc 100644 --- a/.github/workflows/compilation_on_macos.yml +++ b/.github/workflows/compilation_on_macos.yml @@ -52,13 +52,22 @@ env: LLVM_LAZY_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1" LLVM_EAGER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0" +permissions: + contents: read + jobs: build_llvm_libraries_on_intel_macos: + permissions: + contents: read + actions: write uses: ./.github/workflows/build_llvm_libraries.yml with: os: "macos-13" arch: "X86" build_llvm_libraries_on_arm_macos: + permissions: + contents: read + actions: write uses: ./.github/workflows/build_llvm_libraries.yml with: os: "macos-14" @@ -386,3 +395,12 @@ jobs: ./build.sh ./run.sh test1 ./run.sh test2 + + - name: Build Sample [shared-heap] + run: | + cd samples/shared-heap + mkdir build && cd build + cmake .. + cmake --build . --config Debug --parallel 4 + ./shared_heap_test + ./shared_heap_test --aot diff --git a/.github/workflows/compilation_on_nuttx.yml b/.github/workflows/compilation_on_nuttx.yml index e10784fe23..ef0799b42b 100644 --- a/.github/workflows/compilation_on_nuttx.yml +++ b/.github/workflows/compilation_on_nuttx.yml @@ -46,6 +46,9 @@ concurrency: env: WASI_SDK_PATH: "/opt/wasi-sdk" +permissions: + contents: read + jobs: build_iwasm_on_nuttx: runs-on: ubuntu-latest diff --git a/.github/workflows/compilation_on_sgx.yml b/.github/workflows/compilation_on_sgx.yml index b7bc216eb5..70597c366a 100644 --- a/.github/workflows/compilation_on_sgx.yml +++ b/.github/workflows/compilation_on_sgx.yml @@ -54,8 +54,14 @@ env: LLVM_LAZY_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1" LLVM_EAGER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0" +permissions: + contents: read + jobs: build_llvm_libraries: + permissions: + contents: read + actions: write uses: ./.github/workflows/build_llvm_libraries.yml with: os: "ubuntu-20.04" diff --git a/.github/workflows/compilation_on_windows.yml b/.github/workflows/compilation_on_windows.yml index 8c5db4fdf1..369980ba94 100644 --- a/.github/workflows/compilation_on_windows.yml +++ b/.github/workflows/compilation_on_windows.yml @@ -53,6 +53,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: build: runs-on: windows-latest diff --git a/.github/workflows/create_tag.yml b/.github/workflows/create_tag.yml index 5480592a93..7a90ea5f74 100644 --- a/.github/workflows/create_tag.yml +++ b/.github/workflows/create_tag.yml @@ -15,6 +15,9 @@ on: description: "the new tag just created" value: ${{ jobs.create_tag.outputs.new_tag}} +permissions: + contents: read + jobs: create_tag: runs-on: ubuntu-latest @@ -22,6 +25,8 @@ jobs: minor_version: ${{ steps.preparation.outputs.minor_version }} new_ver: ${{ steps.preparation.outputs.new_ver }} new_tag: ${{ steps.preparation.outputs.new_tag }} + permissions: + contents: write # create and push tags steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/hadolint_dockerfiles.yml b/.github/workflows/hadolint_dockerfiles.yml index c540649c89..f9d8c38934 100644 --- a/.github/workflows/hadolint_dockerfiles.yml +++ b/.github/workflows/hadolint_dockerfiles.yml @@ -28,6 +28,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: run-hadolint-on-dockerfiles: runs-on: ubuntu-22.04 diff --git a/.github/workflows/nightly_run.yml b/.github/workflows/nightly_run.yml index f39085d09d..5e9b4a4f29 100644 --- a/.github/workflows/nightly_run.yml +++ b/.github/workflows/nightly_run.yml @@ -44,13 +44,22 @@ env: X86_32_TARGET_TEST_OPTIONS: "-m x86_32 -P" WASI_TEST_OPTIONS: "-s wasi_certification -w" +permissions: + contents: read + jobs: build_llvm_libraries_on_ubuntu_2004: + permissions: + contents: read + actions: write uses: ./.github/workflows/build_llvm_libraries.yml with: os: "ubuntu-20.04" arch: "X86" build_llvm_libraries_on_ubuntu_2204: + permissions: + contents: read + actions: write uses: ./.github/workflows/build_llvm_libraries.yml with: os: "ubuntu-22.04" @@ -593,6 +602,15 @@ jobs: exit $? working-directory: ./wamr-app-framework/samples/simple + - name: Build Sample [shared-heap] + run: | + cd samples/shared-heap + mkdir build && cd build + cmake .. + cmake --build . --config Debug --parallel 4 + ./shared_heap_test + ./shared_heap_test --aot + test: needs: [ diff --git a/.github/workflows/release_process.yml b/.github/workflows/release_process.yml index 2dce1b55c9..031d578841 100644 --- a/.github/workflows/release_process.yml +++ b/.github/workflows/release_process.yml @@ -18,11 +18,18 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: create_tag: + permissions: + contents: write # create and push tags uses: ./.github/workflows/create_tag.yml create_release: + permissions: + contents: write # create release needs: [create_tag] runs-on: ubuntu-latest outputs: @@ -52,6 +59,9 @@ jobs: # # LLVM_LIBRARIES build_llvm_libraries_on_ubuntu_2004: + permissions: + contents: read + actions: write needs: [create_tag, create_release] uses: ./.github/workflows/build_llvm_libraries.yml with: @@ -59,6 +69,9 @@ jobs: arch: "AArch64 ARM Mips RISCV X86" build_llvm_libraries_on_ubuntu_2204: + permissions: + contents: read + actions: write needs: [create_tag, create_release] uses: ./.github/workflows/build_llvm_libraries.yml with: @@ -66,15 +79,30 @@ jobs: arch: "AArch64 ARM Mips RISCV X86" build_llvm_libraries_on_macos: + permissions: + contents: read + actions: write needs: [create_tag, create_release] uses: ./.github/workflows/build_llvm_libraries.yml with: os: "macos-13" arch: "AArch64 ARM Mips RISCV X86" + build_llvm_libraries_on_windows: + permissions: + contents: read + actions: write + needs: [create_tag, create_release] + uses: ./.github/workflows/build_llvm_libraries.yml + with: + os: "windows-latest" + arch: "AArch64 ARM Mips RISCV X86" + # # WAMRC release_wamrc_on_ubuntu_2004: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release, build_llvm_libraries_on_ubuntu_2004] uses: ./.github/workflows/build_wamrc.yml with: @@ -85,6 +113,8 @@ jobs: ver_num: ${{ needs.create_tag.outputs.new_ver}} release_wamrc_on_ubuntu_2204: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release, build_llvm_libraries_on_ubuntu_2204 ] uses: ./.github/workflows/build_wamrc.yml with: @@ -95,6 +125,8 @@ jobs: ver_num: ${{ needs.create_tag.outputs.new_ver }} release_wamrc_on_ubuntu_macos: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release, build_llvm_libraries_on_macos] uses: ./.github/workflows/build_wamrc.yml with: @@ -103,10 +135,24 @@ jobs: runner: macos-13 upload_url: ${{ needs.create_release.outputs.upload_url }} ver_num: ${{ needs.create_tag.outputs.new_ver }} + + release_wamrc_on_windows: + permissions: + contents: write # upload release artifact + needs: [create_tag, create_release, build_llvm_libraries_on_windows] + uses: ./.github/workflows/build_wamrc.yml + with: + llvm_cache_key: ${{ needs.build_llvm_libraries_on_windows.outputs.cache_key }} + release: true + runner: windows-latest + upload_url: ${{ needs.create_release.outputs.upload_url }} + ver_num: ${{ needs.create_tag.outputs.new_ver }} # # IWASM release_iwasm_on_ubuntu_2004: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release, build_llvm_libraries_on_ubuntu_2004] uses: ./.github/workflows/build_iwasm_release.yml with: @@ -117,6 +163,8 @@ jobs: ver_num: ${{ needs.create_tag.outputs.new_ver}} release_iwasm_on_ubuntu_2204: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release, build_llvm_libraries_on_ubuntu_2204] uses: ./.github/workflows/build_iwasm_release.yml with: @@ -127,6 +175,8 @@ jobs: ver_num: ${{ needs.create_tag.outputs.new_ver}} release_iwasm_on_macos: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release, build_llvm_libraries_on_macos] uses: ./.github/workflows/build_iwasm_release.yml with: @@ -136,9 +186,23 @@ jobs: upload_url: ${{ needs.create_release.outputs.upload_url }} ver_num: ${{ needs.create_tag.outputs.new_ver}} + release_iwasm_on_windows: + permissions: + contents: write # upload release artifact + needs: [create_tag, create_release, build_llvm_libraries_on_windows] + uses: ./.github/workflows/build_iwasm_release.yml + with: + cwd: product-mini/platforms/windows + llvm_cache_key: ${{ needs.build_llvm_libraries_on_windows.outputs.cache_key }} + runner: windows-latest + upload_url: ${{ needs.create_release.outputs.upload_url }} + ver_num: ${{ needs.create_tag.outputs.new_ver}} + # # WAMR_SDK release_wamr_sdk_on_ubuntu_2004: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release] uses: ./.github/workflows/build_wamr_sdk.yml with: @@ -150,6 +214,8 @@ jobs: wamr_app_framework_url: https://github.com/bytecodealliance/wamr-app-framework.git release_wamr_sdk_on_ubuntu_2204: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release] uses: ./.github/workflows/build_wamr_sdk.yml with: @@ -161,6 +227,8 @@ jobs: wamr_app_framework_url: https://github.com/bytecodealliance/wamr-app-framework.git release_wamr_sdk_on_macos: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release] uses: ./.github/workflows/build_wamr_sdk.yml with: @@ -174,6 +242,8 @@ jobs: # # vscode extension cross-platform release_wamr_ide_vscode_ext: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release] uses: ./.github/workflows/build_wamr_vscode_ext.yml secrets: inherit @@ -184,6 +254,8 @@ jobs: # # vscode extension docker images package release_wamr_ide_docker_images_package: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release] uses: ./.github/workflows/build_docker_images.yml with: @@ -193,6 +265,8 @@ jobs: # # WAMR_LLDB release_wamr_lldb_on_ubuntu_2004: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release] uses: ./.github/workflows/build_wamr_lldb.yml with: @@ -201,6 +275,8 @@ jobs: ver_num: ${{ needs.create_tag.outputs.new_ver}} release_wamr_lldb_on_ubuntu_2204: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release] uses: ./.github/workflows/build_wamr_lldb.yml with: @@ -209,6 +285,8 @@ jobs: ver_num: ${{ needs.create_tag.outputs.new_ver}} release_wamr_lldb_on_macos_universal: + permissions: + contents: write # upload release artifact needs: [create_tag, create_release] uses: ./.github/workflows/build_wamr_lldb.yml with: diff --git a/.github/workflows/reuse_latest_release_binaries.yml b/.github/workflows/reuse_latest_release_binaries.yml index c9832cec95..77fe7329f5 100644 --- a/.github/workflows/reuse_latest_release_binaries.yml +++ b/.github/workflows/reuse_latest_release_binaries.yml @@ -22,11 +22,17 @@ on: result: value: ${{ jobs.build.outputs.result }} +permissions: + contents: read + jobs: reuse: runs-on: ubuntu-latest outputs: result: ${{ steps.try_reuse.outputs.result }} + permissions: + contents: write # for creating realease and uploading release artifacts + steps: - uses: actions/checkout@v4 # Full git history is needed to get a proper list of commits and tags diff --git a/.github/workflows/spec_test_on_nuttx.yml b/.github/workflows/spec_test_on_nuttx.yml index 712bd06bcb..31427d43fc 100644 --- a/.github/workflows/spec_test_on_nuttx.yml +++ b/.github/workflows/spec_test_on_nuttx.yml @@ -29,8 +29,14 @@ env: LLVM_CACHE_SUFFIX: "build-llvm_libraries_ex" WASI_SDK_PATH: "/opt/wasi-sdk" +permissions: + contents: read + jobs: build_llvm_libraries: + permissions: + contents: read + actions: write uses: ./.github/workflows/build_llvm_libraries.yml with: os: "ubuntu-22.04" @@ -38,6 +44,9 @@ jobs: container_image: ghcr.io/no1wudi/nuttx/apache-nuttx-ci-linux@sha256:8c4e00b607d4d6d66ba8f51c4544819a616eac69d3a2ac669e2af2150e2eb0f9 build_llvm_libraries_xtensa: + permissions: + contents: read + actions: write uses: ./.github/workflows/build_llvm_libraries.yml with: os: "ubuntu-22.04" @@ -341,7 +350,7 @@ jobs: - name: upload the log if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.4.3 with: name: spec-test-log-${{ github.run_id }}-${{ strategy.job-index }}-${{ matrix.target_config.target }} path: log diff --git a/.github/workflows/supply_chain.yml b/.github/workflows/supply_chain.yml new file mode 100644 index 0000000000..26ad7d33e7 --- /dev/null +++ b/.github/workflows/supply_chain.yml @@ -0,0 +1,65 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +# Check current WASM Micro Runtime results here: https://securityscorecards.dev/viewer/?uri=github.com/bytecodealliance/wasm-micro-runtime + +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + # midnight UTC + schedule: + - cron: "0 0 * * *" + # allow to be triggered manually + workflow_dispatch: + +# Declare default permissions as read only. +permissions: + contents: read + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + if: github.repository == 'bytecodealliance/wasm-micro-runtime' + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + + steps: + - name: "Checkout code" + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + with: + results_file: results.sarif + results_format: sarif + + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@184d73b71b93c222403b2e7f1ffebe4508014249 # v3.1.0 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@af56b044b5d41c317aef5d19920b3183cb4fbbec # v2.2.4 + with: + sarif_file: results.sarif diff --git a/ATTRIBUTIONS.md b/ATTRIBUTIONS.md index cba0e5c4b0..ce0d4f8526 100644 --- a/ATTRIBUTIONS.md +++ b/ATTRIBUTIONS.md @@ -60,7 +60,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the ### llvm -[LICENSE](./LICENCE.txt) +[LICENSE](./LICENSE) ### wasm-c-api diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000..d8ec4c1b38 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,29 @@ +# In this project, we use CODEOWNERS to identify people who are likely to know +# who should review a pull request. +# +# People listed in this file are committing to respond in a timely fashion to +# PRs in the selected areas. However, that response doesn't have to be a full +# code review; it could also take any of these forms: +# +# - "I intend to review this but I can't yet. Please leave me a message if I +# haven't responded by (a specific date in the near future)." +# +# - "I think (a specific other contributor) should review this." (Note that the +# best reviewer for a PR may not necessarily be listed in this file.) +# +# People must only be added to this file if they've agreed to provide one of +# the above responses in a reasonable amount of time for every PR to which +# they're assigned. +# +# We only ask for this commitment from people who are employed full-time to +# work on this project. We gratefully welcome reviews from other contributors, +# but we don't believe it's fair to ask volunteers to respond quickly. + +# If none of the later patterns match, assign to anyone. This team is the +# parent of all the other teams and automatically includes everyone on those +# teams. +* @loganek @lum1n0us @no1wudi @wenyongh @xujuntwt95329 @yamt + +# Some parts of the project require more specialized knowledge. In those areas +# we designate smaller groups who are more likely to be aware of who's working +# in specific areas. diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e296cdf9e4..e0bb032cf8 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,85 @@ +## WAMR-2.2.0 + +### Breaking changes + +### New features +- Add support for multi-memory proposal in classic interpreter (#3742) +- wasi-nn: Add a new target for llama.cpp as a wasi-nn backend (#3709) +- Add memory instance support apis (#3786) +- Implement a first version of shared heap feature (#3789) +- Support dynamic aot debug (#3788) +- Implement shared heap for AOT (#3815) +- Support table64 extension in classic-interp and AOT running modes (#3811) + + +### Bug fixes +- Enable merged os_mmap for aot data sections (#3681) +- Fix arm64 issues on mac (#3688) +- aot loader: Call os_mmap with MMAP_MAP_32BIT only when target is x86-64 or riscv64 (#3755) +- Fix building iwasm_shared and iwasm_static libs on win32 (#3762) +- Fix compile error when multi-module and tags are enabled (#3781) +- Fix aot multi export memory support (#3791) +- Fix Windows compile error when uvwasi is enabled (#3810) +- Fix missing symbols when using aot mode on riscv platforms (#3812) +- Fix mac build of libc_emcc_wrapper.c (#3836) +- aot_comp_option.h: Add missing stdint.h header (#3834) +- Fix compilation error found in tflite test (#3820) +- Fix exec_env_tls assertion in module instantiation (#3844) +- Fix issues of destroy_shared_heaps (#3847) + +### Enhancements +- aot loader: Refine os_mmap related code (#3711) +- Enable merged os_mmap for aot data sections and aot text (#3743) +- Improve posix mmap retry logic (#3714) +- Remove unnecessary code duplication in aot runtime (#3767) +- Add wamrc parameter to configure stack frame features (#3763) +- refactoring: Re-use commit IP functionality between exception handling and other cases (#3768) +- AOT call stack optimizations (#3773) +- Appease GCC strict prototypes warning (#3775) +- Appease GCC -Wformat (#3783) +- Fix compiler warnings (#3784) +- Implement option for skipping function index in the callstack (#3785) +- Fix a compile warning in aot_emit_function.c (#3793) +- Restore cmake hidden compile symbol visibility (#3796) +- Refactor shared heap feature for interpreter mode (#3794) +- Add no_resolve to LoadArgs and wasm_runtime_resolve_symbols (#3790) +- shared heap: Fix some issues and add basic unit test case (#3801) +- Add shared heap sample (#3806) +- Fix unused param warning when GC is enabled (#3814) +- Add scoreboard CI for supply-chain security (#3819) +- Emit load_addr and load_size if WAMR_ENABLE_COMPILER is set (#3835) +- libc-emcc: Use alternate method to check getrandom support (#3848) +- Enable libc-wasi for windows msvc build (#3852) +- Remove unused folder samples/gui and samples/littlevgl (#3853) +- Fix some compile warnings and typos (#3854) +- Allow to set native stack boundary to exec_env (#3862) +- Refine wasm/aot function instance lookup (#3865) +- Fix quadratic runtime for duplicate export name detection (#3861) + + +### Others +- Add a comment on AOT_SECTION_TYPE_SIGNATURE (#3746) +- CI: Freeze version of bloaty for NuttX compilation (#3756) +- aot compiler: Allow to control stack boundary check when boundary check is enabled (#3754) +- Update ref to the multi-memory tests (#3764) +- compilation_on_nuttx.yml: Update checkout action to suppress warnings (#3765) +- CI: Disable parallel test in spectest for NuttX (#3780) +- spec_test_on_nuttx.yml: Disable riscv32_ilp32f for now (#3777) +- Ignore temporary file from aider (#3787) +- Add CODEOWNERS (#3822) +- build(deps): bump github/codeql-action from 2.2.4 to 3.26.9 (#3826) +- build(deps): bump actions/upload-artifact from 3.1.0 to 4.4.0 (#3827) +- build(deps): bump ossf/scorecard-action from 2.3.1 to 2.4.0 (#3828) +- build(deps): bump github/codeql-action from 3.26.9 to 3.26.11 (#3843) +- build(deps): bump actions/upload-artifact from 4.4.0 to 4.4.3 (#3855) +- build(deps): bump github/codeql-action from 3.26.11 to 3.26.12 (#3856) +- Add Windows wamrc and iwasm build in release CI (#3857) +- Fix syntax error in codeql_buildscript.sh (#3864) +- release CI: Add another iwasm binary that supports Garbage Collection and Exception Handling (#3866) +- Fix lookup function issue reported in nightly run (#3868) + +--- + ## WAMR-2.1.2 ### Breaking Changes diff --git a/build-scripts/build_llvm.py b/build-scripts/build_llvm.py index 40765d0fe7..7de55b6a0c 100755 --- a/build-scripts/build_llvm.py +++ b/build-scripts/build_llvm.py @@ -125,9 +125,7 @@ def build_llvm(llvm_dir, platform, backends, projects, use_clang=False, extra_fl if not llvm_dir.exists(): raise Exception(f"{llvm_dir} doesn't exist") - build_dir = llvm_dir.joinpath( - "win32build" if "windows" == platform else "build" - ).resolve() + build_dir = llvm_dir.joinpath("build").resolve() build_dir.mkdir(exist_ok=True) lib_llvm_core_library = build_dir.joinpath("lib/libLLVMCore.a").resolve() @@ -178,6 +176,7 @@ def repackage_llvm(llvm_dir): raise Exception("Find more than one LLVM-*.tar.gz") if not packs: + raise Exception("Didn't find any LLVM-* package") return llvm_package = packs[0].name @@ -193,6 +192,31 @@ def repackage_llvm(llvm_dir): # rm ./LLVM-1*.gz os.remove(llvm_dir.joinpath(llvm_package).resolve()) +def repackage_llvm_windows(llvm_dir): + build_dir = llvm_dir.joinpath("./build").resolve() + + packs_path = [f for f in build_dir.glob("./_CPack_Packages/win64/NSIS/LLVM-*-win64")] + if len(packs_path) > 1: + raise Exception("Find more than one LLVM-* package") + + if not packs_path: + raise Exception("Didn't find any LLVM-* package") + return + + llvm_package_path = f"_CPack_Packages/win64/NSIS/{packs_path[0].name}" + windows_package_dir = build_dir.joinpath(llvm_package_path).resolve() + + # mv package dir outside of build + shutil.move(str(windows_package_dir), str(llvm_dir)) + # rm -r build + shutil.rmtree(str(build_dir)) + # mkdir build + build_dir.mkdir() + # move back all the subdiretories under cpack directory(bin/include/lib) to build dir + moved_package_dir = llvm_dir.joinpath(packs_path[0].name) + for sub_dir in moved_package_dir.iterdir(): + shutil.move(str(sub_dir), str(build_dir)) + moved_package_dir.rmdir() def main(): parser = argparse.ArgumentParser(description="build necessary LLVM libraries") @@ -304,7 +328,11 @@ def main(): ) is not None ): - repackage_llvm(llvm_dir) + # TODO: repackage process may change in the future, this work for LLVM 15.x + if "windows" == platform: + repackage_llvm_windows(llvm_dir) + else: + repackage_llvm(llvm_dir) return True except subprocess.CalledProcessError: diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 3d0d6bef76..48c5f7be4b 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -102,9 +102,6 @@ if (WAMR_BUILD_JIT EQUAL 1) if (NOT DEFINED LLVM_DIR) set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm") set (LLVM_BUILD_ROOT "${LLVM_SRC_ROOT}/build") - if (WAMR_BUILD_PLATFORM STREQUAL "windows") - set (LLVM_BUILD_ROOT "${LLVM_SRC_ROOT}/win32build") - endif () if (NOT EXISTS "${LLVM_BUILD_ROOT}") message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_BUILD_ROOT}") endif () @@ -256,6 +253,11 @@ if (WAMR_BUILD_SHARED_MEMORY EQUAL 1) else () add_definitions (-DWASM_ENABLE_SHARED_MEMORY=0) endif () +if (WAMR_BUILD_SHARED_HEAP EQUAL 1) + add_definitions (-DWASM_ENABLE_SHARED_HEAP=1) + message (" Shared heap enabled") +endif() + if (WAMR_BUILD_MEMORY64 EQUAL 1) # if native is 32-bit or cross-compiled to 32-bit if (NOT WAMR_BUILD_TARGET MATCHES ".*64.*") @@ -493,7 +495,7 @@ if (WAMR_BUILD_MODULE_INST_CONTEXT EQUAL 1) message (" Module instance context enabled") endif () if (WAMR_BUILD_GC_HEAP_VERIFY EQUAL 1) - add_definitions (-DWASM_ENABLE_GC_VERIFY=1) + add_definitions (-DBH_ENABLE_GC_VERIFY=1) message (" GC heap verification enabled") endif () if ("$ENV{COLLECT_CODE_COVERAGE}" STREQUAL "1" OR COLLECT_CODE_COVERAGE EQUAL 1) diff --git a/build-scripts/runtime_lib.cmake b/build-scripts/runtime_lib.cmake index 3ab0cff4fb..c57cfc57af 100644 --- a/build-scripts/runtime_lib.cmake +++ b/build-scripts/runtime_lib.cmake @@ -59,7 +59,12 @@ if (WAMR_BUILD_INTERP EQUAL 1) endif () if (WAMR_BUILD_FAST_JIT EQUAL 1) - include (${IWASM_DIR}/fast-jit/iwasm_fast_jit.cmake) + if (WAMR_BUILD_PLATFORM STREQUAL "windows") + message ("Fast JIT currently not supported on Windows") + set (WAMR_BUILD_FAST_JIT 0) + else () + include (${IWASM_DIR}/fast-jit/iwasm_fast_jit.cmake) + endif () endif () if (WAMR_BUILD_JIT EQUAL 1) @@ -104,6 +109,10 @@ if (WAMR_BUILD_WASI_NN EQUAL 1) endif () if (WAMR_BUILD_LIB_PTHREAD EQUAL 1) + if (WAMR_BUILD_PLATFORM STREQUAL "windows") + set (WAMR_BUILD_LIB_PTHREAD_SEMAPHORE 0) + message ("Lib pthread semaphore currently not supported on Windows") + endif () include (${IWASM_DIR}/libraries/lib-pthread/lib_pthread.cmake) # Enable the dependent feature if lib pthread is enabled set (WAMR_BUILD_THREAD_MGR 1) @@ -119,6 +128,10 @@ if (WAMR_BUILD_LIB_WASI_THREADS EQUAL 1) set (WAMR_BUILD_SHARED_MEMORY 1) endif () +if (WAMR_BUILD_SHARED_HEAP EQUAL 1) + include (${IWASM_DIR}/libraries/shared-heap/shared_heap.cmake) +endif () + if (WAMR_BUILD_DEBUG_INTERP EQUAL 1) set (WAMR_BUILD_THREAD_MGR 1) include (${IWASM_DIR}/libraries/debug-engine/debug_engine.cmake) @@ -193,6 +206,7 @@ set (source_all ${LIBC_EMCC_SOURCE} ${LIB_RATS_SOURCE} ${DEBUG_ENGINE_SOURCE} + ${LIB_SHARED_HEAP_SOURCE} ) set (WAMR_RUNTIME_LIB_SOURCE ${source_all}) diff --git a/ci/coding_guidelines_check.py b/ci/coding_guidelines_check.py index d96446266b..a0b4535f9c 100644 --- a/ci/coding_guidelines_check.py +++ b/ci/coding_guidelines_check.py @@ -180,6 +180,7 @@ def check_file_name(path: Path) -> bool: "docker-compose", "package-lock", "vite-env.d", + "osv-scanner", ]: return True diff --git a/core/config.h b/core/config.h index 50f7989224..6bab4da908 100644 --- a/core/config.h +++ b/core/config.h @@ -396,7 +396,9 @@ #define APP_HEAP_SIZE_DEFAULT (8 * 1024) #endif #define APP_HEAP_SIZE_MIN (256) -#define APP_HEAP_SIZE_MAX (512 * 1024 * 1024) +/* The ems memory allocator supports maximal heap size 1GB, + see ems_gc_internal.h */ +#define APP_HEAP_SIZE_MAX (1024 * 1024 * 1024) /* Default min/max gc heap size of each app */ #ifndef GC_HEAP_SIZE_DEFAULT @@ -692,4 +694,8 @@ #endif #endif /* WASM_ENABLE_FUZZ_TEST != 0 */ +#ifndef WASM_ENABLE_SHARED_HEAP +#define WASM_ENABLE_SHARED_HEAP 0 +#endif + #endif /* end of _CONFIG_H_ */ diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 5c81318332..01e246aa32 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -4,9 +4,8 @@ */ #include "aot_runtime.h" -#include "bh_common.h" -#include "bh_log.h" #include "aot_reloc.h" +#include "bh_platform.h" #include "../common/wasm_runtime_common.h" #include "../common/wasm_native.h" #include "../common/wasm_loader_common.h" @@ -1382,6 +1381,12 @@ load_table_list(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, for (i = 0; i < module->table_count; i++, table++) { read_uint8(buf, buf_end, table->table_type.elem_type); read_uint8(buf, buf_end, table->table_type.flags); + + if (!wasm_table_check_flags(table->table_type.flags, error_buf, + error_buf_size, true)) { + return false; + } + read_uint8(buf, buf_end, table->table_type.possible_grow); #if WASM_ENABLE_GC != 0 if (wasm_is_type_multi_byte_type(table->table_type.elem_type)) { @@ -2506,6 +2511,15 @@ try_merge_data_and_text(const uint8 **buf, const uint8 **buf_end, /* merge failed but may be not critical for some targets */ return false; } + +#ifdef BH_PLATFORM_WINDOWS + if (!os_mem_commit(sections, code_size, + MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC)) { + os_munmap(sections, (uint32)total_size); + return false; + } +#endif + /* change the code part to be executable */ if (os_mprotect(sections, code_size, MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC) @@ -2520,7 +2534,7 @@ try_merge_data_and_text(const uint8 **buf, const uint8 **buf_end, /* order not essential just as compiler does: .text section first */ *buf = sections; *buf_end = sections + code_size; - bh_memcpy_s(sections, code_size, old_buf, code_size); + bh_memcpy_s(sections, (uint32)code_size, old_buf, (uint32)code_size); os_munmap(old_buf, code_size); sections += align_uint((uint32)code_size, page_size); @@ -2738,6 +2752,48 @@ destroy_exports(AOTExport *exports) wasm_runtime_free(exports); } +static int +cmp_export_name(const void *a, const void *b) +{ + return strcmp(*(char **)a, *(char **)b); +} + +static bool +check_duplicate_exports(AOTModule *module, char *error_buf, + uint32 error_buf_size) +{ + uint32 i; + bool result = false; + char *names_buf[32], **names = names_buf; + if (module->export_count > 32) { + names = loader_malloc(module->export_count * sizeof(char *), error_buf, + error_buf_size); + if (!names) { + return result; + } + } + + for (i = 0; i < module->export_count; i++) { + names[i] = module->exports[i].name; + } + + qsort(names, module->export_count, sizeof(char *), cmp_export_name); + + for (i = 1; i < module->export_count; i++) { + if (!strcmp(names[i], names[i - 1])) { + set_error_buf(error_buf, error_buf_size, "duplicate export name"); + goto cleanup; + } + } + + result = true; +cleanup: + if (module->export_count > 32) { + wasm_runtime_free(names); + } + return result; +} + static bool load_exports(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, bool is_load_from_file_buf, char *error_buf, uint32 error_buf_size) @@ -2759,14 +2815,58 @@ load_exports(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, read_uint32(buf, buf_end, exports[i].index); read_uint8(buf, buf_end, exports[i].kind); read_string(buf, buf_end, exports[i].name); -#if 0 /* TODO: check kind and index */ - if (export_funcs[i].index >= - module->func_count + module->import_func_count) { - set_error_buf(error_buf, error_buf_size, - "function index is out of range"); + + /* Check export kind and index */ + switch (exports[i].kind) { + case EXPORT_KIND_FUNC: + if (exports[i].index + >= module->import_func_count + module->func_count) { + set_error_buf(error_buf, error_buf_size, + "unknown function"); + return false; + } + break; + case EXPORT_KIND_TABLE: + if (exports[i].index + >= module->import_table_count + module->table_count) { + set_error_buf(error_buf, error_buf_size, "unknown table"); + return false; + } + break; + case EXPORT_KIND_MEMORY: + if (exports[i].index + >= module->import_memory_count + module->memory_count) { + set_error_buf(error_buf, error_buf_size, "unknown memory"); + return false; + } + break; + case EXPORT_KIND_GLOBAL: + if (exports[i].index + >= module->import_global_count + module->global_count) { + set_error_buf(error_buf, error_buf_size, "unknown global"); + return false; + } + break; +#if WASM_ENABLE_TAGS != 0 + /* TODO + case EXPORT_KIND_TAG: + if (index >= module->import_tag_count + module->tag_count) { + set_error_buf(error_buf, error_buf_size, "unknown tag"); + return false; + } + break; + */ +#endif + default: + set_error_buf(error_buf, error_buf_size, "invalid export kind"); + return false; + } + } + + if (module->export_count > 0) { + if (!check_duplicate_exports(module, error_buf, error_buf_size)) { return false; } -#endif } *p_buf = buf; diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 63a3c83c90..7e6d6360c2 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -57,6 +57,9 @@ bh_static_assert(sizeof(AOTMemoryInstance) == 120); bh_static_assert(offsetof(AOTTableInstance, elems) == 24); bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0); +bh_static_assert(offsetof(AOTModuleInstanceExtra, shared_heap_base_addr_adj) + == 8); +bh_static_assert(offsetof(AOTModuleInstanceExtra, shared_heap_start_off) == 16); bh_static_assert(sizeof(CApiFuncImport) == sizeof(uintptr_t) * 3); @@ -134,6 +137,7 @@ is_frame_per_function(WASMExecEnv *exec_env) return module->feature_flags & WASM_FEATURE_FRAME_PER_FUNCTION; } +#if WASM_ENABLE_DUMP_CALL_STACK != 0 static bool is_frame_func_idx_disabled(WASMExecEnv *exec_env) { @@ -142,6 +146,7 @@ is_frame_func_idx_disabled(WASMExecEnv *exec_env) return module->feature_flags & WASM_FEATURE_FRAME_NO_FUNC_IDX; } +#endif static void * get_top_frame(WASMExecEnv *exec_env) @@ -737,18 +742,24 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #if WASM_ENABLE_REF_TYPES != 0 bh_assert( - table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST + table_seg->offset.init_expr_type + == (tbl_inst->is_table64 ? INIT_EXPR_TYPE_I64_CONST + : INIT_EXPR_TYPE_I32_CONST) || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_REFNULL_CONST); #else - bh_assert(table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST + bh_assert(table_seg->offset.init_expr_type + == (tbl_inst->is_table64 ? INIT_EXPR_TYPE_I64_CONST + : INIT_EXPR_TYPE_I32_CONST) || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL); #endif /* Resolve table data base offset */ + /* TODO: The table64 current implementation assumes table max size + * UINT32_MAX, so the offset conversion here is safe */ if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) { global_index = table_seg->offset.u.global_index; @@ -1368,6 +1379,15 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module, return true; } +static int +cmp_func_inst(const void *a, const void *b) +{ + const AOTFunctionInstance *func_inst1 = (const AOTFunctionInstance *)a; + const AOTFunctionInstance *func_inst2 = (const AOTFunctionInstance *)b; + + return strcmp(func_inst1->func_name, func_inst2->func_name); +} + static bool create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module, char *error_buf, uint32 error_buf_size) @@ -1408,6 +1428,9 @@ create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module, export_func++; } } + + qsort(module_inst->export_functions, module_inst->export_func_count, + sizeof(AOTFunctionInstance), cmp_func_inst); } return true; @@ -1469,9 +1492,7 @@ create_exports(AOTModuleInstance *module_inst, AOTModule *module, } } -#if WASM_ENABLE_MULTI_MEMORY == 0 - bh_assert(module_inst->export_memory_count <= 1); -#else +#if WASM_ENABLE_MULTI_MEMORY != 0 if (module_inst->export_memory_count) { module_inst->export_memories = export_memories_instantiate( module, module_inst, module_inst->export_memory_count, error_buf, @@ -1560,8 +1581,12 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, if (is_sub_inst) { bh_assert(exec_env_main); #ifdef OS_ENABLE_HW_BOUND_CHECK - bh_assert(exec_env_tls == exec_env_main); - (void)exec_env_tls; + /* May come from pthread_create_wrapper, thread_spawn_wrapper and + wasm_cluster_spawn_exec_env. If it comes from the former two, + the exec_env_tls must be not NULL and equal to exec_env_main, + else if it comes from the last one, it may be NULL. */ + if (exec_env_tls) + bh_assert(exec_env_tls == exec_env_main); #endif exec_env = exec_env_main; @@ -1885,6 +1910,24 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, extra->stack_sizes = aot_get_data_section_addr(module, AOT_STACK_SIZES_SECTION_NAME, NULL); + /* + * The AOT code checks whether the n bytes to access are in shared heap + * by checking whether the beginning address meets: + * addr >= start_off && addr <= end_off - n-bytes + 1 + * where n is 1/2/4/8/16 and `end_off - n-bytes + 1` is constant, e.g., + * UINT32_MAX, UINT32_MAX-1, UINT32_MAX-3 for n = 1, 2 or 4 in 32-bit + * target. To simplify the check, when shared heap is disabled, we set + * the start off to UINT64_MAX in 64-bit target and UINT32_MAX in 32-bit + * target, so in the checking, the above formula will be false, we don't + * need to check whether the shared heap is enabled or not in the AOT + * code. + */ +#if UINTPTR_MAX == UINT64_MAX + extra->shared_heap_start_off.u64 = UINT64_MAX; +#else + extra->shared_heap_start_off.u32[0] = UINT32_MAX; +#endif + #if WASM_ENABLE_PERF_PROFILING != 0 total_size = sizeof(AOTFuncPerfProfInfo) * ((uint64)module->import_func_count + module->func_count); @@ -2175,14 +2218,15 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) AOTFunctionInstance * aot_lookup_function(const AOTModuleInstance *module_inst, const char *name) { - uint32 i; AOTFunctionInstance *export_funcs = (AOTFunctionInstance *)module_inst->export_functions; + AOTFunctionInstance key = { .func_name = (char *)name }; - for (i = 0; i < module_inst->export_func_count; i++) - if (!strcmp(export_funcs[i].func_name, name)) - return &export_funcs[i]; - return NULL; + if (!export_funcs) + return NULL; + + return bsearch(&key, export_funcs, module_inst->export_func_count, + sizeof(AOTFunctionInstance), cmp_func_inst); } #ifdef OS_ENABLE_HW_BOUND_CHECK diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 9c73dd4017..bf5e4366c7 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -111,6 +111,14 @@ typedef struct AOTFunctionInstance { typedef struct AOTModuleInstanceExtra { DefPointer(const uint32 *, stack_sizes); + /* + * Adjusted shared heap based addr to simple the calculation + * in the aot code. The value is: + * shared_heap->base_addr - shared_heap->start_off + */ + DefPointer(uint8 *, shared_heap_base_addr_adj); + MemBound shared_heap_start_off; + WASMModuleInstanceExtraCommon common; AOTFunctionInstance **functions; uint32 function_count; @@ -119,6 +127,10 @@ typedef struct AOTModuleInstanceExtra { bh_list *sub_module_inst_list; WASMModuleInstanceCommon **import_func_module_insts; #endif + +#if WASM_ENABLE_SHARED_HEAP != 0 + WASMSharedHeap *shared_heap; +#endif } AOTModuleInstanceExtra; #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index 058ad0e10a..8df9f9f8ed 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -24,6 +24,7 @@ #undef NEED_SOFT_I32_DIV #undef NEED_SOFT_I64_MUL #undef NEED_SOFT_I64_DIV +#undef NEED_SOFT_ATOMIC #ifdef __riscv_flen #if __riscv_flen == 32 @@ -48,6 +49,10 @@ #define NEED_SOFT_I64_DIV #endif +#ifndef __riscv_atomic +#define NEED_SOFT_ATOMIC +#endif + /* clang-format off */ void __adddf3(void); void __addsf3(void); @@ -101,6 +106,9 @@ void __umoddi3(void); void __umodsi3(void); void __unorddf2(void); void __unordsf2(void); +bool __atomic_compare_exchange_4(volatile void *, void *, unsigned int, + bool, int, int); +void __atomic_store_4(volatile void *, unsigned int, int); /* clang-format on */ static SymbolMap target_sym_map[] = { @@ -127,6 +135,7 @@ static SymbolMap target_sym_map[] = { * to convert float and long long */ REG_SYM(__floatundisf), + REG_SYM(__floatdisf), #endif #ifdef NEED_SOFT_DP REG_SYM(__adddf3), @@ -175,6 +184,10 @@ static SymbolMap target_sym_map[] = { REG_SYM(__moddi3), REG_SYM(__udivdi3), REG_SYM(__umoddi3), +#endif +#ifdef NEED_SOFT_ATOMIC + REG_SYM(__atomic_compare_exchange_4), + REG_SYM(__atomic_store_4), #endif /* clang-format on */ }; diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 01109658ff..5c1e9efd38 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -3391,8 +3391,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params, if (export->kind == EXPORT_KIND_FUNC) { if (export->index == func->func_idx_rt) { func_comm_rt = - (AOTFunctionInstance *)inst_aot->export_functions - + export_func_j; + aot_lookup_function(inst_aot, export->name); ((wasm_func_t *)func)->func_comm_rt = func_comm_rt; break; } diff --git a/core/iwasm/common/wasm_exec_env.c b/core/iwasm/common/wasm_exec_env.c index 7128b4c63d..48465fc940 100644 --- a/core/iwasm/common/wasm_exec_env.c +++ b/core/iwasm/common/wasm_exec_env.c @@ -282,8 +282,13 @@ wasm_exec_env_set_thread_info(WASMExecEnv *exec_env) os_mutex_lock(&exec_env->wait_lock); #endif exec_env->handle = os_self_thread(); - exec_env->native_stack_boundary = - stack_boundary ? stack_boundary + WASM_STACK_GUARD_SIZE : NULL; + if (exec_env->user_native_stack_boundary) + /* WASM_STACK_GUARD_SIZE isn't added for flexibility to developer, + he must ensure that enough guard bytes are kept. */ + exec_env->native_stack_boundary = exec_env->user_native_stack_boundary; + else + exec_env->native_stack_boundary = + stack_boundary ? stack_boundary + WASM_STACK_GUARD_SIZE : NULL; exec_env->native_stack_top_min = (void *)UINTPTR_MAX; #if WASM_ENABLE_THREAD_MGR != 0 os_mutex_unlock(&exec_env->wait_lock); diff --git a/core/iwasm/common/wasm_exec_env.h b/core/iwasm/common/wasm_exec_env.h index 53d2487555..ce0c1fa7fa 100644 --- a/core/iwasm/common/wasm_exec_env.h +++ b/core/iwasm/common/wasm_exec_env.h @@ -136,6 +136,10 @@ typedef struct WASMExecEnv { void *user_data; + /* The boundary of native stack set by host embedder. It is used + if it is not NULL when calling wasm functions. */ + uint8 *user_native_stack_boundary; + /* The native thread handle of current thread */ korp_tid handle; diff --git a/core/iwasm/common/wasm_loader_common.c b/core/iwasm/common/wasm_loader_common.c index 4a9d8a57b2..6018f90a65 100644 --- a/core/iwasm/common/wasm_loader_common.c +++ b/core/iwasm/common/wasm_loader_common.c @@ -19,6 +19,37 @@ wasm_loader_set_error_buf(char *error_buf, uint32 error_buf_size, } } +#if WASM_ENABLE_MEMORY64 != 0 +bool +check_memory64_flags_consistency(WASMModule *module, char *error_buf, + uint32 error_buf_size, bool is_aot) +{ + uint32 i; + bool wasm64_flag, all_wasm64 = true, none_wasm64 = true; + + for (i = 0; i < module->import_memory_count; ++i) { + wasm64_flag = + module->import_memories[i].u.memory.mem_type.flags & MEMORY64_FLAG; + all_wasm64 &= wasm64_flag; + none_wasm64 &= !wasm64_flag; + } + + for (i = 0; i < module->memory_count; ++i) { + wasm64_flag = module->memories[i].flags & MEMORY64_FLAG; + all_wasm64 &= wasm64_flag; + none_wasm64 &= !wasm64_flag; + } + + if (!(all_wasm64 || none_wasm64)) { + wasm_loader_set_error_buf( + error_buf, error_buf_size, + "inconsistent limits wasm64 flags for memory sections", is_aot); + return false; + } + return true; +} +#endif + bool wasm_memory_check_flags(const uint8 mem_flag, char *error_buf, uint32 error_buf_size, bool is_aot) @@ -60,6 +91,37 @@ wasm_memory_check_flags(const uint8 mem_flag, char *error_buf, return true; } +bool +wasm_table_check_flags(const uint8 table_flag, char *error_buf, + uint32 error_buf_size, bool is_aot) +{ + /* Check whether certain features indicated by mem_flag are enabled in + * runtime */ + if (table_flag > MAX_TABLE_SIZE_FLAG) { + if (table_flag & SHARED_TABLE_FLAG) { + wasm_loader_set_error_buf(error_buf, error_buf_size, + "tables cannot be shared", is_aot); + } +#if WASM_ENABLE_MEMORY64 == 0 + if (table_flag & TABLE64_FLAG) { + wasm_loader_set_error_buf(error_buf, error_buf_size, + "invalid limits flags(table64 flag was " + "found, please enable memory64)", + is_aot); + return false; + } +#endif + } + + if (table_flag > MAX_TABLE_SIZE_FLAG + TABLE64_FLAG) { + wasm_loader_set_error_buf(error_buf, error_buf_size, + "invalid limits flags", is_aot); + return false; + } + + return true; +} + /* * compare with a bigger type set in `wasm_value_type_size_internal()`, * this function will only cover global value type, function's param diff --git a/core/iwasm/common/wasm_loader_common.h b/core/iwasm/common/wasm_loader_common.h index d574110ba0..81174fb264 100644 --- a/core/iwasm/common/wasm_loader_common.h +++ b/core/iwasm/common/wasm_loader_common.h @@ -13,10 +13,22 @@ extern "C" { #endif +#if WASM_ENABLE_MEMORY64 != 0 +/* check consistency of memory64 flags across all memories, + * they must be either all wasm64 or all wasm32 */ +bool +check_memory64_flags_consistency(WASMModule *module, char *error_buf, + uint32 error_buf_size, bool is_aot); +#endif + bool wasm_memory_check_flags(const uint8 mem_flag, char *error_buf, uint32 error_buf_size, bool is_aot); +bool +wasm_table_check_flags(const uint8 table_flag, char *error_buf, + uint32 error_buf_size, bool is_aot); + bool is_valid_value_type(uint8 value_tpye); diff --git a/core/iwasm/common/wasm_memory.c b/core/iwasm/common/wasm_memory.c index 03260589d3..5f5a1be90c 100644 --- a/core/iwasm/common/wasm_memory.c +++ b/core/iwasm/common/wasm_memory.c @@ -13,6 +13,10 @@ #include "../common/wasm_shared_memory.h" #endif +#if WASM_ENABLE_THREAD_MGR != 0 +#include "../libraries/thread-mgr/thread_manager.h" +#endif + typedef enum Memory_Mode { MEMORY_MODE_UNKNOWN = 0, MEMORY_MODE_POOL, @@ -24,6 +28,11 @@ static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN; static mem_allocator_t pool_allocator = NULL; +#if WASM_ENABLE_SHARED_HEAP != 0 +static WASMSharedHeap *shared_heap_list = NULL; +static korp_mutex shared_heap_list_lock; +#endif + static enlarge_memory_error_callback_t enlarge_memory_error_cb; static void *enlarge_memory_error_user_data; @@ -132,16 +141,371 @@ is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst) #endif } +#if WASM_ENABLE_SHARED_HEAP != 0 +static void * +wasm_mmap_linear_memory(uint64_t map_size, uint64 commit_size); +static void +wasm_munmap_linear_memory(void *mapped_mem, uint64 commit_size, + uint64 map_size); + +static void * +runtime_malloc(uint64 size) +{ + void *mem; + + if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) { + LOG_WARNING("Allocate memory failed"); + return NULL; + } + + memset(mem, 0, (uint32)size); + return mem; +} + +WASMSharedHeap * +wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args) +{ + uint64 heap_struct_size = sizeof(WASMSharedHeap), map_size; + uint32 size = init_args->size; + WASMSharedHeap *heap; + + if (size == 0) { + goto fail1; + } + + if (!(heap = runtime_malloc(heap_struct_size))) { + goto fail1; + } + + if (!(heap->heap_handle = + runtime_malloc(mem_allocator_get_heap_struct_size()))) { + goto fail2; + } + + size = align_uint(size, os_getpagesize()); + heap->size = size; + heap->start_off_mem64 = UINT64_MAX - heap->size + 1; + heap->start_off_mem32 = UINT32_MAX - heap->size + 1; + + if (size > APP_HEAP_SIZE_MAX || size < APP_HEAP_SIZE_MIN) { + LOG_WARNING("Invalid size of shared heap"); + goto fail3; + } + +#ifndef OS_ENABLE_HW_BOUND_CHECK + map_size = size; +#else + /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G: + * ea = i + memarg.offset + * both i and memarg.offset are u32 in range 0 to 4G + * so the range of ea is 0 to 8G + */ + map_size = 8 * (uint64)BH_GB; +#endif + + if (!(heap->base_addr = wasm_mmap_linear_memory(map_size, size))) { + goto fail3; + } + if (!mem_allocator_create_with_struct_and_pool( + heap->heap_handle, heap_struct_size, heap->base_addr, size)) { + LOG_WARNING("init share heap failed"); + goto fail4; + } + + os_mutex_lock(&shared_heap_list_lock); + if (shared_heap_list == NULL) { + shared_heap_list = heap; + } + else { + heap->next = shared_heap_list; + shared_heap_list = heap; + } + os_mutex_unlock(&shared_heap_list_lock); + return heap; + +fail4: + wasm_munmap_linear_memory(heap->base_addr, size, map_size); +fail3: + wasm_runtime_free(heap->heap_handle); +fail2: + wasm_runtime_free(heap); +fail1: + return NULL; +} + +bool +wasm_runtime_attach_shared_heap_internal(WASMModuleInstanceCommon *module_inst, + WASMSharedHeap *shared_heap) +{ + WASMMemoryInstance *memory = + wasm_get_default_memory((WASMModuleInstance *)module_inst); + uint64 linear_mem_size; + + if (!memory) + return false; + + linear_mem_size = memory->memory_data_size; + + /* check if linear memory and shared heap are overlapped */ + if ((memory->is_memory64 && linear_mem_size > shared_heap->start_off_mem64) + || (!memory->is_memory64 + && linear_mem_size > shared_heap->start_off_mem32)) { + LOG_WARNING("Linear memory address is overlapped with shared heap"); + return false; + } + +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) { + WASMModuleInstanceExtra *e = + (WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e; + if (e->shared_heap) { + LOG_WARNING("A shared heap is already attached"); + return false; + } + e->shared_heap = shared_heap; +#if WASM_ENABLE_JIT != 0 +#if UINTPTR_MAX == UINT64_MAX + if (memory->is_memory64) + e->shared_heap_start_off.u64 = shared_heap->start_off_mem64; + else + e->shared_heap_start_off.u64 = shared_heap->start_off_mem32; + e->shared_heap_base_addr_adj = + shared_heap->base_addr - e->shared_heap_start_off.u64; +#else + e->shared_heap_start_off.u32[0] = (uint32)shared_heap->start_off_mem32; + e->shared_heap_base_addr_adj = + shared_heap->base_addr - e->shared_heap_start_off.u32[0]; +#endif +#endif /* end of WASM_ENABLE_JIT != 0 */ + } +#endif /* end of WASM_ENABLE_INTERP != 0 */ +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) { + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e; + if (e->shared_heap) { + LOG_WARNING("A shared heap is already attached"); + return false; + } + e->shared_heap = shared_heap; +#if UINTPTR_MAX == UINT64_MAX + if (memory->is_memory64) + e->shared_heap_start_off.u64 = shared_heap->start_off_mem64; + else + e->shared_heap_start_off.u64 = shared_heap->start_off_mem32; + e->shared_heap_base_addr_adj = + shared_heap->base_addr - e->shared_heap_start_off.u64; +#else + e->shared_heap_start_off.u32[0] = (uint32)shared_heap->start_off_mem32; + e->shared_heap_base_addr_adj = + shared_heap->base_addr - e->shared_heap_start_off.u32[0]; +#endif + } +#endif /* end of WASM_ENABLE_AOT != 0 */ + + return true; +} + +bool +wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst, + WASMSharedHeap *shared_heap) +{ +#if WASM_ENABLE_THREAD_MGR != 0 + return wasm_cluster_attach_shared_heap(module_inst, shared_heap); +#else + return wasm_runtime_attach_shared_heap_internal(module_inst, shared_heap); +#endif +} + +void +wasm_runtime_detach_shared_heap_internal(WASMModuleInstanceCommon *module_inst) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) { + WASMModuleInstanceExtra *e = + (WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e; + e->shared_heap = NULL; +#if WASM_ENABLE_JIT != 0 +#if UINTPTR_MAX == UINT64_MAX + e->shared_heap_start_off.u64 = UINT64_MAX; +#else + e->shared_heap_start_off.u32[0] = UINT32_MAX; +#endif + e->shared_heap_base_addr_adj = NULL; +#endif + } +#endif /* end of WASM_ENABLE_INTERP != 0 */ +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) { + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e; + e->shared_heap = NULL; +#if UINTPTR_MAX == UINT64_MAX + e->shared_heap_start_off.u64 = UINT64_MAX; +#else + e->shared_heap_start_off.u32[0] = UINT32_MAX; +#endif + e->shared_heap_base_addr_adj = NULL; + } +#endif /* end of WASM_ENABLE_AOT != 0 */ +} + +void +wasm_runtime_detach_shared_heap(WASMModuleInstanceCommon *module_inst) +{ +#if WASM_ENABLE_THREAD_MGR != 0 + wasm_cluster_detach_shared_heap(module_inst); +#else + wasm_runtime_detach_shared_heap_internal(module_inst); +#endif +} + +static WASMSharedHeap * +get_shared_heap(WASMModuleInstanceCommon *module_inst_comm) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_inst_comm->module_type == Wasm_Module_Bytecode) { + return ((WASMModuleInstance *)module_inst_comm)->e->shared_heap; + } +#endif +#if WASM_ENABLE_AOT != 0 + if (module_inst_comm->module_type == Wasm_Module_AoT) { + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_comm) + ->e; + return e->shared_heap; + } +#endif + return NULL; +} + +WASMSharedHeap * +wasm_runtime_get_shared_heap(WASMModuleInstanceCommon *module_inst_comm) +{ + return get_shared_heap(module_inst_comm); +} + +static bool +is_app_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst, + bool is_memory64, uint64 app_offset, uint32 bytes) +{ + WASMSharedHeap *heap = get_shared_heap(module_inst); + + if (!heap) { + return false; + } + + if (bytes == 0) { + bytes = 1; + } + + if (!is_memory64) { + if (app_offset >= heap->start_off_mem32 + && app_offset <= UINT32_MAX - bytes + 1) { + return true; + } + } + else { + if (app_offset >= heap->start_off_mem64 + && app_offset <= UINT64_MAX - bytes + 1) { + return true; + } + } + + return false; +} + +static bool +is_native_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst, + uint8 *addr, uint32 bytes) +{ + WASMSharedHeap *heap = get_shared_heap(module_inst); + + if (heap && addr >= heap->base_addr + && addr + bytes <= heap->base_addr + heap->size + && addr + bytes > addr) { + return true; + } + return false; +} + +uint64 +wasm_runtime_shared_heap_malloc(WASMModuleInstanceCommon *module_inst, + uint64_t size, void **p_native_addr) +{ + WASMMemoryInstance *memory = + wasm_get_default_memory((WASMModuleInstance *)module_inst); + WASMSharedHeap *shared_heap = get_shared_heap(module_inst); + void *native_addr = NULL; + + if (!memory || !shared_heap) + return 0; + + native_addr = mem_allocator_malloc(shared_heap->heap_handle, size); + if (!native_addr) + return 0; + + if (p_native_addr) { + *p_native_addr = native_addr; + } + + if (memory->is_memory64) + return shared_heap->start_off_mem64 + + ((uint8 *)native_addr - shared_heap->base_addr); + else + return shared_heap->start_off_mem32 + + ((uint8 *)native_addr - shared_heap->base_addr); +} + +void +wasm_runtime_shared_heap_free(WASMModuleInstanceCommon *module_inst, uint64 ptr) +{ + WASMMemoryInstance *memory = + wasm_get_default_memory((WASMModuleInstance *)module_inst); + WASMSharedHeap *shared_heap = get_shared_heap(module_inst); + uint8 *addr = NULL; + + if (!memory || !shared_heap) { + return; + } + + if (memory->is_memory64) { + if (ptr < shared_heap->start_off_mem64) { /* ptr can not > UINT64_MAX */ + LOG_WARNING("The address to free isn't in shared heap"); + return; + } + addr = shared_heap->base_addr + (ptr - shared_heap->start_off_mem64); + } + else { + if (ptr < shared_heap->start_off_mem32 || ptr > UINT32_MAX) { + LOG_WARNING("The address to free isn't in shared heap"); + return; + } + addr = shared_heap->base_addr + (ptr - shared_heap->start_off_mem32); + } + + mem_allocator_free(shared_heap->heap_handle, addr); +} +#endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */ + bool wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type, const MemAllocOption *alloc_option) { + bool ret = false; + +#if WASM_ENABLE_SHARED_HEAP != 0 + if (os_mutex_init(&shared_heap_list_lock)) { + return false; + } +#endif + if (mem_alloc_type == Alloc_With_Pool) { - return wasm_memory_init_with_pool(alloc_option->pool.heap_buf, - alloc_option->pool.heap_size); + ret = wasm_memory_init_with_pool(alloc_option->pool.heap_buf, + alloc_option->pool.heap_size); } else if (mem_alloc_type == Alloc_With_Allocator) { - return wasm_memory_init_with_allocator( + ret = wasm_memory_init_with_allocator( #if WASM_MEM_ALLOC_WITH_USER_DATA != 0 alloc_option->allocator.user_data, #endif @@ -151,16 +515,58 @@ wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type, } else if (mem_alloc_type == Alloc_With_System_Allocator) { memory_mode = MEMORY_MODE_SYSTEM_ALLOCATOR; - return true; + ret = true; } else { - return false; + ret = false; + } + +#if WASM_ENABLE_SHARED_HEAP != 0 + if (!ret) { + os_mutex_destroy(&shared_heap_list_lock); + } +#endif + + return ret; +} + +#if WASM_ENABLE_SHARED_HEAP != 0 +static void +destroy_shared_heaps() +{ + WASMSharedHeap *heap; + WASMSharedHeap *cur; + uint64 map_size; + + os_mutex_lock(&shared_heap_list_lock); + heap = shared_heap_list; + shared_heap_list = NULL; + os_mutex_unlock(&shared_heap_list_lock); + + while (heap) { + cur = heap; + heap = heap->next; + mem_allocator_destroy(cur->heap_handle); + wasm_runtime_free(cur->heap_handle); +#ifndef OS_ENABLE_HW_BOUND_CHECK + map_size = cur->size; +#else + map_size = 8 * (uint64)BH_GB; +#endif + wasm_munmap_linear_memory(cur->base_addr, cur->size, map_size); + wasm_runtime_free(cur); } + os_mutex_destroy(&shared_heap_list_lock); } +#endif void wasm_runtime_memory_destroy(void) { +#if WASM_ENABLE_SHARED_HEAP != 0 + destroy_shared_heaps(); +#endif + if (memory_mode == MEMORY_MODE_POOL) { #if BH_ENABLE_GC_VERIFY == 0 (void)mem_allocator_destroy(pool_allocator); @@ -335,6 +741,13 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm, goto fail; } +#if WASM_ENABLE_SHARED_HEAP != 0 + if (is_app_addr_in_shared_heap(module_inst_comm, memory_inst->is_memory64, + app_offset, size)) { + return true; + } +#endif + #if WASM_ENABLE_MEMORY64 != 0 if (memory_inst->is_memory64) max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE; @@ -364,6 +777,7 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm, uint64 app_str_offset) { WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; + WASMMemoryInstance *memory_inst; uint64 app_end_offset, max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE; char *str, *str_end; @@ -374,22 +788,42 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm, return true; } - if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset, NULL, - &app_end_offset)) + memory_inst = wasm_get_default_memory(module_inst); + if (!memory_inst) { goto fail; + } + +#if WASM_ENABLE_SHARED_HEAP != 0 + if (is_app_addr_in_shared_heap(module_inst_comm, memory_inst->is_memory64, + app_str_offset, 1)) { + WASMSharedHeap *shared_heap = get_shared_heap(module_inst_comm); + str = (char *)shared_heap->base_addr + + (memory_inst->is_memory64 + ? (app_str_offset - shared_heap->start_off_mem64) + : (app_str_offset - shared_heap->start_off_mem32)); + str_end = (char *)shared_heap->base_addr + shared_heap->size; + } + else +#endif + { + if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset, + NULL, &app_end_offset)) + goto fail; #if WASM_ENABLE_MEMORY64 != 0 - if (module_inst->memories[0]->is_memory64) - max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE; + if (memory_inst->is_memory64) + max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE; #endif - /* boundary overflow check, max start offset can only be size - 1, while end - * offset can be size */ - if (app_str_offset >= max_linear_memory_size - || app_end_offset > max_linear_memory_size) - goto fail; + /* boundary overflow check, max start offset can be size - 1, while end + offset can be size */ + if (app_str_offset >= max_linear_memory_size + || app_end_offset > max_linear_memory_size) + goto fail; + + str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset); + str_end = str + (app_end_offset - app_str_offset); + } - str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset); - str_end = str + (app_end_offset - app_str_offset); while (str < str_end && *str != '\0') str++; if (str == str_end) @@ -431,6 +865,12 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm, goto fail; } +#if WASM_ENABLE_SHARED_HEAP != 0 + if (is_native_addr_in_shared_heap(module_inst_comm, native_ptr, size)) { + return true; + } +#endif + SHARED_MEMORY_LOCK(memory_inst); if (memory_inst->memory_data <= addr @@ -465,6 +905,23 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm, return NULL; } +#if WASM_ENABLE_SHARED_HEAP != 0 + if (is_app_addr_in_shared_heap(module_inst_comm, memory_inst->is_memory64, + app_offset, 1)) { + WASMSharedHeap *shared_heap = get_shared_heap(module_inst_comm); + uint64 shared_heap_start = 0; + + if (memory_inst && !memory_inst->is_memory64) { + shared_heap_start = shared_heap->start_off_mem32; + } + else if (memory_inst && memory_inst->is_memory64) { + shared_heap_start = shared_heap->start_off_mem64; + } + + return shared_heap->base_addr + app_offset - shared_heap_start; + } +#endif + SHARED_MEMORY_LOCK(memory_inst); addr = memory_inst->memory_data + (uintptr_t)app_offset; @@ -499,11 +956,32 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm, bounds_checks = is_bounds_checks_enabled(module_inst_comm); +#if WASM_ENABLE_SHARED_HEAP != 0 + /* If shared heap is enabled, bounds check is always needed */ + bounds_checks = true; +#endif + memory_inst = wasm_get_default_memory(module_inst); if (!memory_inst) { return 0; } +#if WASM_ENABLE_SHARED_HEAP != 0 + if (is_native_addr_in_shared_heap(module_inst_comm, addr, 1)) { + WASMSharedHeap *shared_heap = get_shared_heap(module_inst_comm); + uint64 shared_heap_start = 0; + + if (memory_inst && !memory_inst->is_memory64) { + shared_heap_start = shared_heap->start_off_mem32; + } + else if (memory_inst && memory_inst->is_memory64) { + shared_heap_start = shared_heap->start_off_mem64; + } + + return shared_heap_start + (addr - shared_heap->base_addr); + } +#endif + SHARED_MEMORY_LOCK(memory_inst); if (bounds_checks) { @@ -601,6 +1079,10 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str, WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst); uint8 *native_addr; bool bounds_checks; +#if WASM_ENABLE_SHARED_HEAP != 0 + WASMSharedHeap *shared_heap; + bool is_in_shared_heap = false; +#endif bh_assert(app_buf_addr <= UINTPTR_MAX && app_buf_size <= UINTPTR_MAX); @@ -609,9 +1091,25 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str, return false; } - native_addr = memory_inst->memory_data + (uintptr_t)app_buf_addr; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (is_app_addr_in_shared_heap((WASMModuleInstanceCommon *)module_inst, + memory_inst->is_memory64, app_buf_addr, + app_buf_size)) { + shared_heap = get_shared_heap((WASMModuleInstanceCommon *)module_inst); + native_addr = shared_heap->base_addr + + (memory_inst->is_memory64 + ? (app_buf_addr - shared_heap->start_off_mem64) + : (app_buf_addr - shared_heap->start_off_mem32)); + is_in_shared_heap = true; + } + else +#endif + { + native_addr = memory_inst->memory_data + (uintptr_t)app_buf_addr; + } - bounds_checks = is_bounds_checks_enabled((wasm_module_inst_t)module_inst); + bounds_checks = + is_bounds_checks_enabled((WASMModuleInstanceCommon *)module_inst); if (!bounds_checks) { if (app_buf_addr == 0) { @@ -620,6 +1118,24 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str, goto success; } +#if WASM_ENABLE_SHARED_HEAP != 0 + if (is_in_shared_heap) { + const char *str, *str_end; + + /* The whole string must be in the linear memory */ + str = (const char *)native_addr; + str_end = (const char *)shared_heap->base_addr + shared_heap->size; + while (str < str_end && *str != '\0') + str++; + if (str == str_end) { + wasm_set_exception(module_inst, "out of bounds memory access"); + return false; + } + else + goto success; + } +#endif + /* No need to check the app_offset and buf_size if memory access boundary check with hardware trap is enabled */ #ifndef OS_ENABLE_HW_BOUND_CHECK @@ -749,7 +1265,7 @@ wasm_mremap_linear_memory(void *mapped_mem, uint64 old_size, uint64 new_size, } static void * -wasm_mmap_linear_memory(uint64_t map_size, uint64 commit_size) +wasm_mmap_linear_memory(uint64 map_size, uint64 commit_size) { return wasm_mremap_linear_memory(NULL, 0, map_size, commit_size); } @@ -758,6 +1274,9 @@ static bool wasm_enlarge_memory_internal(WASMModuleInstanceCommon *module, WASMMemoryInstance *memory, uint32 inc_page_count) { +#if WASM_ENABLE_SHARED_HEAP != 0 + WASMSharedHeap *shared_heap; +#endif uint8 *memory_data_old, *memory_data_new, *heap_data_old; uint32 num_bytes_per_page, heap_size; uint32 cur_page_count, max_page_count, total_page_count; @@ -805,6 +1324,24 @@ wasm_enlarge_memory_internal(WASMModuleInstanceCommon *module, goto return_func; } +#if WASM_ENABLE_SHARED_HEAP != 0 + shared_heap = get_shared_heap(module); + if (shared_heap) { + if (memory->is_memory64 + && total_size_new > shared_heap->start_off_mem64) { + LOG_WARNING("Linear memory address is overlapped with shared heap"); + ret = false; + goto return_func; + } + else if (!memory->is_memory64 + && total_size_new > shared_heap->start_off_mem32) { + LOG_WARNING("Linear memory address is overlapped with shared heap"); + ret = false; + goto return_func; + } + } +#endif + bh_assert(total_size_new <= GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64)); diff --git a/core/iwasm/common/wasm_memory.h b/core/iwasm/common/wasm_memory.h index 2f20d3f684..bceea0ee43 100644 --- a/core/iwasm/common/wasm_memory.h +++ b/core/iwasm/common/wasm_memory.h @@ -41,6 +41,35 @@ SET_LINEAR_MEMORY_SIZE(WASMMemoryInstance *memory, uint64 size) #define SET_LINEAR_MEMORY_SIZE(memory, size) memory->memory_data_size = size #endif +#if WASM_ENABLE_SHARED_HEAP != 0 +WASMSharedHeap * +wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args); + +bool +wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst, + WASMSharedHeap *shared_heap); +bool +wasm_runtime_attach_shared_heap_internal(WASMModuleInstanceCommon *module_inst, + WASMSharedHeap *shared_heap); + +void +wasm_runtime_detach_shared_heap(WASMModuleInstanceCommon *module_inst); + +void +wasm_runtime_detach_shared_heap_internal(WASMModuleInstanceCommon *module_inst); + +WASMSharedHeap * +wasm_runtime_get_shared_heap(WASMModuleInstanceCommon *module_inst_comm); + +uint64 +wasm_runtime_shared_heap_malloc(WASMModuleInstanceCommon *module_inst, + uint64 size, void **p_native_addr); + +void +wasm_runtime_shared_heap_free(WASMModuleInstanceCommon *module_inst, + uint64 ptr); +#endif + bool wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type, const MemAllocOption *alloc_option); diff --git a/core/iwasm/common/wasm_native.c b/core/iwasm/common/wasm_native.c index 0ff3053fa9..060bb2c3d3 100644 --- a/core/iwasm/common/wasm_native.c +++ b/core/iwasm/common/wasm_native.c @@ -33,6 +33,11 @@ uint32 get_spectest_export_apis(NativeSymbol **p_libc_builtin_apis); #endif +#if WASM_ENABLE_SHARED_HEAP != 0 +uint32 +get_lib_shared_heap_export_apis(NativeSymbol **p_shared_heap_apis); +#endif + uint32 get_libc_wasi_export_apis(NativeSymbol **p_libc_wasi_apis); @@ -512,6 +517,14 @@ wasm_native_init() goto fail; #endif +#if WASM_ENABLE_SHARED_HEAP != 0 + n_native_symbols = get_lib_shared_heap_export_apis(&native_symbols); + if (n_native_symbols > 0 + && !wasm_native_register_natives("env", native_symbols, + n_native_symbols)) + goto fail; +#endif + #if WASM_ENABLE_BASE_LIB != 0 n_native_symbols = get_base_lib_export_apis(&native_symbols); if (n_native_symbols > 0 diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 667cbba03f..fb16aa0f3c 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -185,6 +185,9 @@ static bool is_sig_addr_in_guard_pages(void *sig_addr, WASMModuleInstance *module_inst) { WASMMemoryInstance *memory_inst; +#if WASM_ENABLE_SHARED_HEAP != 0 + WASMSharedHeap *shared_heap; +#endif uint8 *mapped_mem_start_addr = NULL; uint8 *mapped_mem_end_addr = NULL; uint32 i; @@ -202,6 +205,21 @@ is_sig_addr_in_guard_pages(void *sig_addr, WASMModuleInstance *module_inst) } } +#if WASM_ENABLE_SHARED_HEAP != 0 + shared_heap = + wasm_runtime_get_shared_heap((WASMModuleInstanceCommon *)module_inst); + if (shared_heap) { + mapped_mem_start_addr = shared_heap->base_addr; + mapped_mem_end_addr = shared_heap->base_addr + 8 * (uint64)BH_GB; + if (mapped_mem_start_addr <= (uint8 *)sig_addr + && (uint8 *)sig_addr < mapped_mem_end_addr) { + /* The address which causes segmentation fault is inside + the shared heap's guard regions */ + return true; + } + } +#endif + return false; } @@ -340,7 +358,6 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info) PEXCEPTION_RECORD ExceptionRecord = exce_info->ExceptionRecord; uint8 *sig_addr = (uint8 *)ExceptionRecord->ExceptionInformation[1]; WASMModuleInstance *module_inst; - WASMMemoryInstance *memory_inst; WASMJmpBuf *jmpbuf_node; uint8 *mapped_mem_start_addr = NULL; uint8 *mapped_mem_end_addr = NULL; @@ -2208,6 +2225,13 @@ wasm_runtime_get_user_data(WASMExecEnv *exec_env) return exec_env->user_data; } +void +wasm_runtime_set_native_stack_boundary(WASMExecEnv *exec_env, + uint8 *native_stack_boundary) +{ + exec_env->user_native_stack_boundary = native_stack_boundary; +} + #ifdef OS_ENABLE_HW_BOUND_CHECK void wasm_runtime_access_exce_check_guard_page() @@ -3593,7 +3617,8 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, char mapping_copy_buf[256]; char *mapping_copy = mapping_copy_buf; char *map_mapped = NULL, *map_host = NULL; - const unsigned long max_len = strlen(map_dir_list[i]) * 2 + 3; + const unsigned long max_len = + (unsigned long)strlen(map_dir_list[i]) * 2 + 3; /* Allocation limit for runtime environments with reduced stack size */ if (max_len > 256) { @@ -3883,23 +3908,18 @@ wasm_runtime_is_wasi_mode(WASMModuleInstanceCommon *module_inst) WASMFunctionInstanceCommon * wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst) { - uint32 i; - #if WASM_ENABLE_INTERP != 0 if (module_inst->module_type == Wasm_Module_Bytecode) { WASMModuleInstance *wasm_inst = (WASMModuleInstance *)module_inst; - WASMFunctionInstance *func; - for (i = 0; i < wasm_inst->export_func_count; i++) { - if (!strcmp(wasm_inst->export_functions[i].name, "_start")) { - func = wasm_inst->export_functions[i].function; - if (func->u.func->func_type->param_count != 0 - || func->u.func->func_type->result_count != 0) { - LOG_ERROR("Lookup wasi _start function failed: " - "invalid function type.\n"); - return NULL; - } - return (WASMFunctionInstanceCommon *)func; + WASMFunctionInstance *func = wasm_lookup_function(wasm_inst, "_start"); + if (func) { + if (func->u.func->func_type->param_count != 0 + || func->u.func->func_type->result_count != 0) { + LOG_ERROR("Lookup wasi _start function failed: " + "invalid function type.\n"); + return NULL; } + return (WASMFunctionInstanceCommon *)func; } return NULL; } @@ -3908,19 +3928,15 @@ wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst) #if WASM_ENABLE_AOT != 0 if (module_inst->module_type == Wasm_Module_AoT) { AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst; - AOTFunctionInstance *export_funcs = - (AOTFunctionInstance *)aot_inst->export_functions; - for (i = 0; i < aot_inst->export_func_count; i++) { - if (!strcmp(export_funcs[i].func_name, "_start")) { - AOTFuncType *func_type = export_funcs[i].u.func.func_type; - if (func_type->param_count != 0 - || func_type->result_count != 0) { - LOG_ERROR("Lookup wasi _start function failed: " - "invalid function type.\n"); - return NULL; - } - return (WASMFunctionInstanceCommon *)&export_funcs[i]; + AOTFunctionInstance *func = aot_lookup_function(aot_inst, "_start"); + if (func) { + AOTFuncType *func_type = func->u.func.func_type; + if (func_type->param_count != 0 || func_type->result_count != 0) { + LOG_ERROR("Lookup wasi _start function failed: " + "invalid function type.\n"); + return NULL; } + return func; } return NULL; } @@ -4514,9 +4530,14 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr, uint32 *argv, uint32 argc, uint32 *argv_ret) { WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env); +#if WASM_ENABLE_MEMORY64 != 0 + WASMMemoryInstance *memory = + wasm_get_default_memory((WASMModuleInstance *)module); + bool is_memory64 = memory ? memory->is_memory64 : false; +#endif typedef void (*NativeRawFuncPtr)(WASMExecEnv *, uint64 *); NativeRawFuncPtr invoke_native_raw = (NativeRawFuncPtr)func_ptr; - uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size, arg_i64; + uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size; uint32 *argv_src = argv, i, argc1, ptr_len; uint32 arg_i32; bool ret = false; @@ -4541,11 +4562,11 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr, #endif { *(uint32 *)argv_dst = arg_i32 = *argv_src++; - /* TODO: memory64 if future there is a way for supporting - * wasm64 and wasm32 in libc at the same time, remove the - * macro control */ -#if WASM_ENABLE_MEMORY64 == 0 - if (signature) { + if (signature +#if WASM_ENABLE_MEMORY64 != 0 + && !is_memory64 +#endif + ) { if (signature[i + 1] == '*') { /* param is a pointer */ if (signature[i + 2] == '~') @@ -4574,17 +4595,18 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr, module, (uint64)arg_i32); } } -#endif break; } case VALUE_TYPE_I64: #if WASM_ENABLE_MEMORY64 != 0 { + uint64 arg_i64; + PUT_I64_TO_ADDR((uint32 *)argv_dst, GET_I64_FROM_ADDR(argv_src)); argv_src += 2; arg_i64 = *argv_dst; - if (signature) { + if (signature && is_memory64) { /* TODO: memory64 pointer with length need a new symbol * to represent type i64, with '~' still represent i32 * length */ @@ -4745,9 +4767,6 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr, fail: if (argv1 != argv_buf) wasm_runtime_free(argv1); -#if WASM_ENABLE_MEMORY64 == 0 - (void)arg_i64; -#endif return ret; } @@ -5671,6 +5690,11 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, uint32 *argv_ret) { WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env); +#if WASM_ENABLE_MEMORY64 != 0 + WASMMemoryInstance *memory = + wasm_get_default_memory((WASMModuleInstance *)module); + bool is_memory64 = memory ? memory->is_memory64 : false; +#endif uint64 argv_buf[32] = { 0 }, *argv1 = argv_buf, *ints, *stacks, size, arg_i64; uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0; @@ -5736,11 +5760,11 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, { arg_i32 = *argv_src++; arg_i64 = arg_i32; - /* TODO: memory64 if future there is a way for supporting - * wasm64 and wasm32 in libc at the same time, remove the - * macro control */ -#if WASM_ENABLE_MEMORY64 == 0 - if (signature) { + if (signature +#if WASM_ENABLE_MEMORY64 != 0 + && !is_memory64 +#endif + ) { if (signature[i + 1] == '*') { /* param is a pointer */ if (signature[i + 2] == '~') @@ -5767,7 +5791,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, module, (uint64)arg_i32); } } -#endif if (n_ints < MAX_REG_INTS) ints[n_ints++] = arg_i64; else @@ -5779,7 +5802,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, { arg_i64 = GET_I64_FROM_ADDR(argv_src); argv_src += 2; - if (signature) { + if (signature && is_memory64) { /* TODO: memory64 pointer with length need a new symbol * to represent type i64, with '~' still represent i32 * length */ diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 0b89edf5e8..8ec5ea3a50 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -698,6 +698,11 @@ wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data); WASM_RUNTIME_API_EXTERN void * wasm_runtime_get_user_data(WASMExecEnv *exec_env); +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_native_stack_boundary(WASMExecEnv *exec_env, + uint8 *native_stack_boundary); + #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0 /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN void diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index 9cfdd0926c..2027a57200 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -8,6 +8,9 @@ #if WASM_ENABLE_THREAD_MGR != 0 #include "../libraries/thread-mgr/thread_manager.h" #endif +#if WASM_ENABLE_AOT != 0 +#include "../aot/aot_runtime.h" +#endif /* * Note: this lock can be per memory. @@ -243,6 +246,31 @@ map_try_release_wait_info(HashMap *wait_hash_map, AtomicWaitInfo *wait_info, destroy_wait_info(wait_info); } +#if WASM_ENABLE_SHARED_HEAP != 0 +static bool +is_native_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst, + uint8 *addr, uint32 bytes) +{ + WASMSharedHeap *shared_heap = NULL; + +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) { + shared_heap = ((WASMModuleInstance *)module_inst)->e->shared_heap; + } +#endif +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) { + AOTModuleInstanceExtra *e = + (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e; + shared_heap = e->shared_heap; + } +#endif + + return shared_heap && addr >= shared_heap->base_addr + && addr + bytes <= shared_heap->base_addr + shared_heap->size; +} +#endif + uint32 wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, uint64 expect, int64 timeout, bool wait64) @@ -271,9 +299,17 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, } shared_memory_lock(module_inst->memories[0]); - if ((uint8 *)address < module_inst->memories[0]->memory_data - || (uint8 *)address + (wait64 ? 8 : 4) - > module_inst->memories[0]->memory_data_end) { + if ( +#if WASM_ENABLE_SHARED_HEAP != 0 + /* not in shared heap */ + !is_native_addr_in_shared_heap((WASMModuleInstanceCommon *)module_inst, + address, wait64 ? 8 : 4) + && +#endif + /* and not in linear memory */ + ((uint8 *)address < module_inst->memories[0]->memory_data + || (uint8 *)address + (wait64 ? 8 : 4) + > module_inst->memories[0]->memory_data_end)) { shared_memory_unlock(module_inst->memories[0]); wasm_runtime_set_exception(module, "out of bounds memory access"); return -1; @@ -397,6 +433,11 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, shared_memory_lock(module_inst->memories[0]); out_of_bounds = +#if WASM_ENABLE_SHARED_HEAP != 0 + /* not in shared heap */ + !is_native_addr_in_shared_heap(module, address, 4) && +#endif + /* and not in linear memory */ ((uint8 *)address < module_inst->memories[0]->memory_data || (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end); shared_memory_unlock(module_inst->memories[0]); diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index e560049725..07734b3b41 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -146,9 +146,20 @@ aot_validate_wasm(AOTCompContext *comp_ctx) } #if WASM_ENABLE_MEMORY64 != 0 - if (comp_ctx->pointer_size < sizeof(uint64) && IS_MEMORY64) { - aot_set_last_error("Compiling wasm64 to 32bit platform is not allowed"); - return false; + if (comp_ctx->pointer_size < sizeof(uint64)) { + if (IS_MEMORY64) { + aot_set_last_error("Compiling wasm64(contains i64 memory section) " + "to 32bit platform is not allowed"); + return false; + } + + for (uint32 i = 0; i < comp_ctx->comp_data->table_count; ++i) { + if (IS_TABLE64(i)) { + aot_set_last_error("Compiling wasm64(contains i64 table " + "section) to 32bit platform is not allowed"); + return false; + } + } } #endif diff --git a/core/iwasm/compilation/aot_compiler.h b/core/iwasm/compilation/aot_compiler.h index 895d2416b4..06d8e42bdb 100644 --- a/core/iwasm/compilation/aot_compiler.h +++ b/core/iwasm/compilation/aot_compiler.h @@ -532,8 +532,13 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type) #define IS_MEMORY64 (comp_ctx->comp_data->memories[0].flags & MEMORY64_FLAG) #define MEMORY64_COND_VALUE(VAL_IF_ENABLED, VAL_IF_DISABLED) \ (IS_MEMORY64 ? VAL_IF_ENABLED : VAL_IF_DISABLED) +#define IS_TABLE64(i) \ + (comp_ctx->comp_data->tables[i].table_type.flags & TABLE64_FLAG) +#define TABLE64_COND_VALUE(i, VAL_IF_ENABLED, VAL_IF_DISABLED) \ + (IS_TABLE64(i) ? VAL_IF_ENABLED : VAL_IF_DISABLED) #else #define MEMORY64_COND_VALUE(VAL_IF_ENABLED, VAL_IF_DISABLED) (VAL_IF_DISABLED) +#define TABLE64_COND_VALUE(i, VAL_IF_ENABLED, VAL_IF_DISABLED) (VAL_IF_DISABLED) #endif #define POP_I32(v) POP(v, VALUE_TYPE_I32) @@ -548,6 +553,9 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type) POP(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32)) #define POP_PAGE_COUNT(v) \ POP(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32)) +#define POP_TBL_ELEM_IDX(v) \ + POP(v, TABLE64_COND_VALUE(tbl_idx, VALUE_TYPE_I64, VALUE_TYPE_I32)) +#define POP_TBL_ELEM_LEN(v) POP_TBL_ELEM_IDX(v) #define POP_COND(llvm_value) \ do { \ @@ -613,6 +621,9 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type) #define PUSH_GC_REF(v) PUSH(v, VALUE_TYPE_GC_REF) #define PUSH_PAGE_COUNT(v) \ PUSH(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32)) +#define PUSH_TBL_ELEM_IDX(v) \ + PUSH(v, TABLE64_COND_VALUE(tbl_idx, VALUE_TYPE_I64, VALUE_TYPE_I32)) +#define PUSH_TBL_ELEM_LEN(v) PUSH_TBL_ELEM_IDX(v) #define SET_CONST(v) \ do { \ diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 945f63952b..1c50fe75f6 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -912,7 +912,7 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build LOAD failed"); return false; } - /* Set terminate_flags memory accecc to volatile, so that the value + /* Set terminate_flags memory access to volatile, so that the value will always be loaded from memory rather than register */ LLVMSetVolatile(terminate_flags, true); diff --git a/core/iwasm/compilation/aot_emit_function.c b/core/iwasm/compilation/aot_emit_function.c index 85a9239aa5..49b1ac1cb4 100644 --- a/core/iwasm/compilation/aot_emit_function.c +++ b/core/iwasm/compilation/aot_emit_function.c @@ -2089,6 +2089,9 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef ext_ret_offset, ext_ret_ptr, ext_ret, res; LLVMValueRef *param_values = NULL, *value_rets = NULL; LLVMValueRef *result_phis = NULL, value_ret, import_func_count; +#if WASM_ENABLE_MEMORY64 != 0 + LLVMValueRef u32_max, u32_cmp_result = NULL; +#endif LLVMTypeRef *param_types = NULL, ret_type; LLVMTypeRef llvm_func_type, llvm_func_ptr_type; LLVMTypeRef ext_ret_ptr_type; @@ -2153,7 +2156,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, func_param_count = func_type->param_count; func_result_count = func_type->result_count; - POP_I32(elem_idx); + POP_TBL_ELEM_IDX(elem_idx); /* get the cur size of the table instance */ if (!(offset = I32_CONST(get_tbl_inst_offset(comp_ctx, func_ctx, tbl_idx) @@ -2182,6 +2185,27 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } +#if WASM_ENABLE_MEMORY64 != 0 + /* Check if elem index >= UINT32_MAX */ + if (IS_TABLE64(tbl_idx)) { + if (!(u32_max = I64_CONST(UINT32_MAX))) { + aot_set_last_error("llvm build const failed"); + goto fail; + } + if (!(u32_cmp_result = + LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, elem_idx, + u32_max, "cmp_elem_idx_u32_max"))) { + aot_set_last_error("llvm build icmp failed."); + goto fail; + } + if (!(elem_idx = LLVMBuildTrunc(comp_ctx->builder, elem_idx, I32_TYPE, + "elem_idx_i32"))) { + aot_set_last_error("llvm build trunc failed."); + goto fail; + } + } +#endif + /* Check if (uint32)elem index >= table size */ if (!(cmp_elem_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, elem_idx, table_size_const, "cmp_elem_idx"))) { @@ -2189,7 +2213,19 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - /* Throw exception if elem index >= table size */ +#if WASM_ENABLE_MEMORY64 != 0 + if (IS_TABLE64(tbl_idx)) { + if (!(cmp_elem_idx = + LLVMBuildOr(comp_ctx->builder, cmp_elem_idx, u32_cmp_result, + "larger_than_u32_max_or_cur_size"))) { + aot_set_last_error("llvm build or failed."); + goto fail; + } + } +#endif + + /* Throw exception if elem index >= table size or elem index >= UINT32_MAX + */ if (!(check_elem_idx_succ = LLVMAppendBasicBlockInContext( comp_ctx->context, func_ctx->func, "check_elem_idx_succ"))) { aot_set_last_error("llvm add basic block failed."); diff --git a/core/iwasm/compilation/aot_emit_memory.c b/core/iwasm/compilation/aot_emit_memory.c index 806150ff19..869a1dbb27 100644 --- a/core/iwasm/compilation/aot_emit_memory.c +++ b/core/iwasm/compilation/aot_emit_memory.c @@ -118,10 +118,10 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, { LLVMValueRef offset_const = MEMORY64_COND_VALUE(I64_CONST(offset), I32_CONST(offset)); - LLVMValueRef addr, maddr, offset1, cmp1, cmp2, cmp; + LLVMValueRef addr, maddr, maddr_phi = NULL, offset1, cmp1, cmp2, cmp; LLVMValueRef mem_base_addr, mem_check_bound; LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); - LLVMBasicBlockRef check_succ; + LLVMBasicBlockRef check_succ, block_maddr_phi = NULL; AOTValue *aot_value_top; uint32 local_idx_of_aot_value = 0; uint64 const_value; @@ -131,6 +131,11 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, bool is_shared_memory = comp_ctx->comp_data->memories[0].flags & SHARED_MEMORY_FLAG; #endif +#if WASM_ENABLE_MEMORY64 == 0 + bool is_memory64 = false; +#else + bool is_memory64 = IS_MEMORY64; +#endif is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false; @@ -268,8 +273,137 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* offset1 = offset + addr; */ + /* TODO: check whether integer overflow occurs when memory is 64-bit + and boundary check is enabled */ BUILD_OP(Add, offset_const, addr, offset1, "offset1"); + if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) { + LLVMBasicBlockRef app_addr_in_shared_heap, app_addr_in_linear_mem; + LLVMValueRef is_in_shared_heap, shared_heap_check_bound = NULL; + + /* Add basic blocks */ + ADD_BASIC_BLOCK(app_addr_in_shared_heap, "app_addr_in_shared_heap"); + ADD_BASIC_BLOCK(app_addr_in_linear_mem, "app_addr_in_linear_mem"); + ADD_BASIC_BLOCK(block_maddr_phi, "maddr_phi"); + + LLVMMoveBasicBlockAfter(app_addr_in_shared_heap, block_curr); + LLVMMoveBasicBlockAfter(app_addr_in_linear_mem, + app_addr_in_shared_heap); + LLVMMoveBasicBlockAfter(block_maddr_phi, app_addr_in_linear_mem); + + LLVMPositionBuilderAtEnd(comp_ctx->builder, block_maddr_phi); + if (!(maddr_phi = + LLVMBuildPhi(comp_ctx->builder, + enable_segue ? INT8_PTR_TYPE_GS : INT8_PTR_TYPE, + "maddr_phi"))) { + aot_set_last_error("llvm build phi failed"); + goto fail; + } + + LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr); + + if (!is_target_64bit) { + /* Check whether interger overflow occurs in addr + offset */ + LLVMBasicBlockRef check_integer_overflow_end; + ADD_BASIC_BLOCK(check_integer_overflow_end, + "check_integer_overflow_end"); + LLVMMoveBasicBlockAfter(check_integer_overflow_end, block_curr); + + BUILD_ICMP(LLVMIntULT, offset1, addr, cmp1, "cmp1"); + if (!aot_emit_exception(comp_ctx, func_ctx, + EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, + cmp1, check_integer_overflow_end)) { + goto fail; + } + SET_BUILD_POS(check_integer_overflow_end); + } + + shared_heap_check_bound = + is_memory64 ? I64_CONST(UINT64_MAX - bytes + 1) + : (comp_ctx->pointer_size == sizeof(uint64) + ? I64_CONST(UINT32_MAX - bytes + 1) + : I32_CONST(UINT32_MAX - bytes + 1)); + CHECK_LLVM_CONST(shared_heap_check_bound); + + /* Check whether the bytes to access are in shared heap */ + if (!comp_ctx->enable_bound_check) { + /* Use IntUGT but not IntUGE to compare, since (1) in the ems + memory allocator, the hmu node includes hmu header and hmu + memory, only the latter is returned to the caller as the + allocated memory, the hmu header isn't returned so the + first byte of the shared heap won't be accesed, (2) using + IntUGT gets better performance than IntUGE in some cases */ + BUILD_ICMP(LLVMIntUGT, offset1, func_ctx->shared_heap_start_off, + is_in_shared_heap, "is_in_shared_heap"); + /* We don't check the shared heap's upper boundary if boundary + check isn't enabled, the runtime may also use the guard pages + of shared heap to check the boundary if hardware boundary + check feature is enabled. */ + } + else { + /* Use IntUGT but not IntUGE to compare, same as above */ + BUILD_ICMP(LLVMIntUGT, offset1, func_ctx->shared_heap_start_off, + cmp1, "cmp1"); + /* Check the shared heap's upper boundary if boundary check is + enabled */ + BUILD_ICMP(LLVMIntULE, offset1, shared_heap_check_bound, cmp2, + "cmp2"); + BUILD_OP(And, cmp1, cmp2, is_in_shared_heap, "is_in_shared_heap"); + } + + if (!LLVMBuildCondBr(comp_ctx->builder, is_in_shared_heap, + app_addr_in_shared_heap, app_addr_in_linear_mem)) { + aot_set_last_error("llvm build cond br failed"); + goto fail; + } + + LLVMPositionBuilderAtEnd(comp_ctx->builder, app_addr_in_shared_heap); + + /* Get native address inside shared heap */ + if (!(maddr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->shared_heap_base_addr_adj, + &offset1, 1, "maddr_shared_heap"))) { + aot_set_last_error("llvm build inbounds gep failed"); + goto fail; + } + + if (enable_segue) { + LLVMValueRef mem_base_addr_u64, maddr_u64, offset_to_mem_base; + + if (!(maddr_u64 = LLVMBuildPtrToInt(comp_ctx->builder, maddr, + I64_TYPE, "maddr_u64")) + || !(mem_base_addr_u64 = + LLVMBuildPtrToInt(comp_ctx->builder, mem_base_addr, + I64_TYPE, "mem_base_addr_u64"))) { + aot_set_last_error("llvm build ptr to int failed"); + goto fail; + } + if (!(offset_to_mem_base = + LLVMBuildSub(comp_ctx->builder, maddr_u64, + mem_base_addr_u64, "offset_to_mem_base"))) { + aot_set_last_error("llvm build sub failed"); + goto fail; + } + if (!(maddr = LLVMBuildIntToPtr( + comp_ctx->builder, offset_to_mem_base, INT8_PTR_TYPE_GS, + "maddr_shared_heap_segue"))) { + aot_set_last_error("llvm build int to ptr failed."); + goto fail; + } + } + + LLVMAddIncoming(maddr_phi, &maddr, &app_addr_in_shared_heap, 1); + + if (!LLVMBuildBr(comp_ctx->builder, block_maddr_phi)) { + aot_set_last_error("llvm build br failed"); + goto fail; + } + + LLVMPositionBuilderAtEnd(comp_ctx->builder, app_addr_in_linear_mem); + block_curr = LLVMGetInsertBlock(comp_ctx->builder); + } + if (comp_ctx->enable_bound_check && !(is_local_of_aot_value && aot_checked_addr_list_find(func_ctx, local_idx_of_aot_value, @@ -305,10 +439,16 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, BUILD_ICMP(LLVMIntUGT, offset1, mem_check_bound, cmp, "cmp"); } else { - /* Check integer overflow */ - BUILD_ICMP(LLVMIntULT, offset1, addr, cmp1, "cmp1"); - BUILD_ICMP(LLVMIntUGT, offset1, mem_check_bound, cmp2, "cmp2"); - BUILD_OP(Or, cmp1, cmp2, cmp, "cmp"); + if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) { + /* Check integer overflow has been checked above */ + BUILD_ICMP(LLVMIntUGT, offset1, mem_check_bound, cmp, "cmp"); + } + else { + /* Check integer overflow */ + BUILD_ICMP(LLVMIntULT, offset1, addr, cmp1, "cmp1"); + BUILD_ICMP(LLVMIntUGT, offset1, mem_check_bound, cmp2, "cmp2"); + BUILD_OP(Or, cmp1, cmp2, cmp, "cmp"); + } } /* Add basic blocks */ @@ -354,7 +494,19 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } } - return maddr; + + if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) { + block_curr = LLVMGetInsertBlock(comp_ctx->builder); + LLVMAddIncoming(maddr_phi, &maddr, &block_curr, 1); + if (!LLVMBuildBr(comp_ctx->builder, block_maddr_phi)) { + aot_set_last_error("llvm build br failed"); + goto fail; + } + LLVMPositionBuilderAtEnd(comp_ctx->builder, block_maddr_phi); + return maddr_phi; + } + else + return maddr; fail: return NULL; } @@ -985,10 +1137,15 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef offset, LLVMValueRef bytes) { LLVMValueRef maddr, max_addr, cmp; - LLVMValueRef mem_base_addr; + LLVMValueRef mem_base_addr, maddr_phi = NULL; LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); - LLVMBasicBlockRef check_succ; + LLVMBasicBlockRef check_succ, block_maddr_phi = NULL; LLVMValueRef mem_size; +#if WASM_ENABLE_MEMORY64 == 0 + bool is_memory64 = false; +#else + bool is_memory64 = IS_MEMORY64; +#endif /* Get memory base address and memory data size */ #if WASM_ENABLE_SHARED_MEMORY != 0 @@ -1053,9 +1210,96 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, offset = LLVMBuildZExt(comp_ctx->builder, offset, I64_TYPE, "extend_offset"); bytes = LLVMBuildZExt(comp_ctx->builder, bytes, I64_TYPE, "extend_len"); + if (!offset || !bytes) { + aot_set_last_error("llvm build zext failed."); + goto fail; + } + /* TODO: check whether integer overflow occurs when memory is 64-bit + and boundary check is enabled */ BUILD_OP(Add, offset, bytes, max_addr, "max_addr"); + + if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) { + LLVMBasicBlockRef app_addr_in_shared_heap, app_addr_in_linear_mem; + LLVMValueRef shared_heap_start_off, shared_heap_check_bound; + LLVMValueRef max_offset, cmp1, cmp2, is_in_shared_heap; + + /* Add basic blocks */ + ADD_BASIC_BLOCK(app_addr_in_shared_heap, "app_addr_in_shared_heap"); + ADD_BASIC_BLOCK(app_addr_in_linear_mem, "app_addr_in_linear_mem"); + ADD_BASIC_BLOCK(block_maddr_phi, "maddr_phi"); + + LLVMMoveBasicBlockAfter(app_addr_in_shared_heap, block_curr); + LLVMMoveBasicBlockAfter(app_addr_in_linear_mem, + app_addr_in_shared_heap); + LLVMMoveBasicBlockAfter(block_maddr_phi, check_succ); + + LLVMPositionBuilderAtEnd(comp_ctx->builder, block_maddr_phi); + if (!(maddr_phi = LLVMBuildPhi(comp_ctx->builder, INT8_PTR_TYPE, + "maddr_phi"))) { + aot_set_last_error("llvm build phi failed"); + goto fail; + } + + LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr); + + shared_heap_start_off = func_ctx->shared_heap_start_off; + if (comp_ctx->pointer_size == sizeof(uint32)) { + if (!(shared_heap_start_off = + LLVMBuildZExt(comp_ctx->builder, shared_heap_start_off, + I64_TYPE, "shared_heap_start_off_u64"))) { + aot_set_last_error("llvm build zext failed"); + goto fail; + } + } + shared_heap_check_bound = + is_memory64 ? I64_CONST(UINT64_MAX) : I64_CONST(UINT32_MAX); + CHECK_LLVM_CONST(shared_heap_check_bound); + + /* Check whether the bytes to access are in shared heap */ + if (!comp_ctx->enable_bound_check) { + /* Use IntUGT but not IntUGE to compare, same as the check + in aot_check_memory_overflow */ + BUILD_ICMP(LLVMIntUGT, offset, func_ctx->shared_heap_start_off, + is_in_shared_heap, "is_in_shared_heap"); + } + else { + BUILD_ICMP(LLVMIntUGT, offset, func_ctx->shared_heap_start_off, + cmp1, "cmp1"); + BUILD_OP(Add, max_addr, I64_NEG_ONE, max_offset, "max_offset"); + BUILD_ICMP(LLVMIntULE, max_offset, shared_heap_check_bound, cmp2, + "cmp2"); + BUILD_OP(And, cmp1, cmp2, is_in_shared_heap, "is_in_shared_heap"); + } + + if (!LLVMBuildCondBr(comp_ctx->builder, is_in_shared_heap, + app_addr_in_shared_heap, app_addr_in_linear_mem)) { + aot_set_last_error("llvm build cond br failed"); + goto fail; + } + + LLVMPositionBuilderAtEnd(comp_ctx->builder, app_addr_in_shared_heap); + + /* Get native address inside shared heap */ + if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->shared_heap_base_addr_adj, + &offset, 1, "maddr_shared_heap"))) { + aot_set_last_error("llvm build inbounds gep failed"); + goto fail; + } + LLVMAddIncoming(maddr_phi, &maddr, &app_addr_in_shared_heap, 1); + + if (!LLVMBuildBr(comp_ctx->builder, block_maddr_phi)) { + aot_set_last_error("llvm build br failed"); + goto fail; + } + + LLVMPositionBuilderAtEnd(comp_ctx->builder, app_addr_in_linear_mem); + block_curr = LLVMGetInsertBlock(comp_ctx->builder); + } + BUILD_ICMP(LLVMIntUGT, max_addr, mem_size, cmp, "cmp_max_mem_addr"); + if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp, check_succ)) { @@ -1068,11 +1312,23 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build add failed."); goto fail; } - return maddr; + + if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) { + block_curr = LLVMGetInsertBlock(comp_ctx->builder); + LLVMAddIncoming(maddr_phi, &maddr, &block_curr, 1); + if (!LLVMBuildBr(comp_ctx->builder, block_maddr_phi)) { + aot_set_last_error("llvm build br failed"); + goto fail; + } + LLVMPositionBuilderAtEnd(comp_ctx->builder, block_maddr_phi); + return maddr_phi; + } + else + return maddr; fail: return NULL; } -#endif /* end of WASM_ENABLE_BULK_MEMORY != 0 or WASM_ENABLE_STRINGREF != 0 */ +#endif /* end of WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_STRINGREF != 0 */ #if WASM_ENABLE_BULK_MEMORY != 0 bool diff --git a/core/iwasm/compilation/aot_emit_table.c b/core/iwasm/compilation/aot_emit_table.c index f968bacddf..e8dae410bd 100644 --- a/core/iwasm/compilation/aot_emit_table.c +++ b/core/iwasm/compilation/aot_emit_table.c @@ -10,6 +10,78 @@ #include "aot_emit_gc.h" #endif +#if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 +#if WASM_ENABLE_MEMORY64 != 0 +static bool +zero_extend_u64(AOTCompContext *comp_ctx, LLVMValueRef *value, const char *name) +{ + if (comp_ctx->pointer_size == sizeof(uint64)) { + /* zero extend to uint64 if the target is 64-bit */ + *value = LLVMBuildZExt(comp_ctx->builder, *value, I64_TYPE, name); + if (!*value) { + aot_set_last_error("llvm build zero extend failed."); + return false; + } + } + return true; +} +#endif + +/* check whether a table64 elem idx is greater than UINT32_MAX, if so, throw + * exception, otherwise trunc it to uint32 */ +static bool +check_tbl_elem_idx_and_trunc(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + LLVMValueRef *elem_idx, uint32 tbl_idx) +{ +#if WASM_ENABLE_MEMORY64 != 0 + LLVMValueRef u32_max, u32_cmp_result; + LLVMBasicBlockRef check_elem_idx_succ; + + if (!IS_TABLE64(tbl_idx)) { + return true; + } + + /* Check if elem index >= UINT32_MAX */ + if (!(u32_max = I64_CONST(UINT32_MAX))) { + aot_set_last_error("llvm build const failed"); + goto fail; + } + if (!(u32_cmp_result = + LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, *elem_idx, u32_max, + "cmp_elem_idx_u32_max"))) { + aot_set_last_error("llvm build icmp failed."); + goto fail; + } + if (!(*elem_idx = LLVMBuildTrunc(comp_ctx->builder, *elem_idx, I32_TYPE, + "elem_idx_i32"))) { + aot_set_last_error("llvm build trunc failed."); + goto fail; + } + + /* Throw exception if elem index >= UINT32_MAX*/ + if (!(check_elem_idx_succ = LLVMAppendBasicBlockInContext( + comp_ctx->context, func_ctx->func, "check_elem_idx_succ"))) { + aot_set_last_error("llvm add basic block failed."); + goto fail; + } + + LLVMMoveBasicBlockAfter(check_elem_idx_succ, + LLVMGetInsertBlock(comp_ctx->builder)); + + if (!(aot_emit_exception(comp_ctx, func_ctx, + EXCE_OUT_OF_BOUNDS_TABLE_ACCESS, true, + u32_cmp_result, check_elem_idx_succ))) + goto fail; + + return true; +fail: + return false; +#else + return true; +#endif +} +#endif /* WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC !=0 */ + uint64 get_tbl_inst_offset(const AOTCompContext *comp_ctx, const AOTFuncContext *func_ctx, uint32 tbl_idx) @@ -158,6 +230,10 @@ aot_check_table_access(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, &elem_idx, tbl_idx)) { + goto fail; + } + /* Check if (uint32)elem index >= table size */ if (!(cmp_elem_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, elem_idx, tbl_sz, "cmp_elem_idx"))) { @@ -192,7 +268,7 @@ aot_compile_op_table_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef elem_idx, offset, func_idx; LLVMValueRef table_elem_base, table_elem_addr, table_elem; - POP_I32(elem_idx); + POP_TBL_ELEM_IDX(elem_idx); if (!aot_check_table_access(comp_ctx, func_ctx, tbl_idx, elem_idx)) { goto fail; @@ -289,7 +365,7 @@ aot_compile_op_table_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } } - POP_I32(elem_idx); + POP_TBL_ELEM_IDX(elem_idx); if (!aot_check_table_access(comp_ctx, func_ctx, tbl_idx, elem_idx)) { goto fail; @@ -388,7 +464,11 @@ aot_compile_op_table_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* s */ POP_I32(param_values[4]); /* d */ - POP_I32(param_values[5]); + POP_TBL_ELEM_IDX(param_values[5]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[5], + tbl_idx)) { + goto fail; + } /* "" means return void */ if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 6, @@ -408,6 +488,7 @@ aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, { LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type; LLVMValueRef func, param_values[6], value; + uint32 tbl_idx; param_types[0] = INT8_PTR_TYPE; param_types[1] = I32_TYPE; @@ -434,12 +515,34 @@ aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } + /* In table64, the length should be i32 type if any one of src/dst table + * is i32 type, set the table index to the lesser-or-equal table when + * popping length n */ + if (!(comp_ctx->comp_data->tables[src_tbl_idx].table_type.flags + & TABLE64_FLAG)) + tbl_idx = src_tbl_idx; + else + tbl_idx = dst_tbl_idx; /* n */ - POP_I32(param_values[3]); + POP_TBL_ELEM_LEN(param_values[3]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[3], + tbl_idx)) { + goto fail; + } /* s */ - POP_I32(param_values[4]); + tbl_idx = src_tbl_idx; + POP_TBL_ELEM_IDX(param_values[4]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[4], + tbl_idx)) { + goto fail; + } /* d */ - POP_I32(param_values[5]); + tbl_idx = dst_tbl_idx; + POP_TBL_ELEM_IDX(param_values[5]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[5], + tbl_idx)) { + goto fail; + } /* "" means return void */ if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 6, @@ -484,7 +587,14 @@ aot_compile_op_table_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - PUSH_I32(tbl_sz); +#if WASM_ENABLE_MEMORY64 != 0 + if (IS_TABLE64(tbl_idx)) { + if (!zero_extend_u64(comp_ctx, &tbl_sz, "length64")) { + goto fail; + } + } +#endif + PUSH_TBL_ELEM_IDX(tbl_sz); return true; fail: @@ -517,7 +627,11 @@ aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* n */ - POP_I32(param_values[2]); + POP_TBL_ELEM_LEN(param_values[2]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[2], + tbl_idx)) { + goto fail; + } /* v */ if (comp_ctx->enable_gc) { @@ -545,7 +659,14 @@ aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - PUSH_I32(ret); +#if WASM_ENABLE_MEMORY64 != 0 + if (IS_TABLE64(tbl_idx)) { + if (!zero_extend_u64(comp_ctx, &ret, "table_size64")) { + goto fail; + } + } +#endif + PUSH_TBL_ELEM_LEN(ret); return true; fail: @@ -579,7 +700,11 @@ aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* n */ - POP_I32(param_values[2]); + POP_TBL_ELEM_LEN(param_values[2]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[2], + tbl_idx)) { + goto fail; + } /* v */ if (comp_ctx->enable_gc) { @@ -601,7 +726,11 @@ aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } } /* i */ - POP_I32(param_values[4]); + POP_TBL_ELEM_IDX(param_values[4]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[4], + tbl_idx)) { + goto fail; + } /* "" means return void */ if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 5, @@ -615,4 +744,4 @@ aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } -#endif /* WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC !=0 */ +#endif /* WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC !=0 */ diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 820a55e965..fb1c4308b2 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -1518,6 +1518,75 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return true; } +static bool +create_shared_heap_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) +{ + LLVMValueRef offset, base_addr_p, start_off_p, cmp; + uint32 offset_u32; + + /* Load aot_inst->e->shared_heap_base_addr_adj */ + offset_u32 = get_module_inst_extra_offset(comp_ctx); +#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_SHARED_HEAP != 0 + if (comp_ctx->is_jit_mode) + offset_u32 += + offsetof(WASMModuleInstanceExtra, shared_heap_base_addr_adj); + else +#endif + offset_u32 += + offsetof(AOTModuleInstanceExtra, shared_heap_base_addr_adj); + offset = I32_CONST(offset_u32); + CHECK_LLVM_CONST(offset); + + if (!(base_addr_p = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "shared_heap_base_addr_adj_p"))) { + aot_set_last_error("llvm build inbounds gep failed"); + return false; + } + if (!(func_ctx->shared_heap_base_addr_adj = + LLVMBuildLoad2(comp_ctx->builder, INT8_PTR_TYPE, base_addr_p, + "shared_heap_base_addr_adj"))) { + aot_set_last_error("llvm build load failed"); + return false; + } + + /* Load aot_inst->e->shared_heap_start_off */ + offset_u32 = get_module_inst_extra_offset(comp_ctx); +#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_SHARED_HEAP != 0 + if (comp_ctx->is_jit_mode) + offset_u32 += offsetof(WASMModuleInstanceExtra, shared_heap_start_off); + else +#endif + offset_u32 += offsetof(AOTModuleInstanceExtra, shared_heap_start_off); + offset = I32_CONST(offset_u32); + CHECK_LLVM_CONST(offset); + + if (!(start_off_p = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "shared_heap_start_off_p"))) { + aot_set_last_error("llvm build inbounds gep failed"); + return false; + } + if (!(func_ctx->shared_heap_start_off = LLVMBuildLoad2( + comp_ctx->builder, + comp_ctx->pointer_size == sizeof(uint64) ? I64_TYPE : I32_TYPE, + start_off_p, "shared_heap_start_off"))) { + aot_set_last_error("llvm build load failed"); + return false; + } + + if (!(cmp = LLVMBuildIsNotNull(comp_ctx->builder, + func_ctx->shared_heap_base_addr_adj, + "has_shared_heap"))) { + aot_set_last_error("llvm build is not null failed"); + return false; + } + + return true; +fail: + return false; +} + static bool create_cur_exception(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) { @@ -1808,6 +1877,12 @@ aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx, goto fail; } + /* Load shared heap, shared heap start off mem32 or mem64 */ + if (comp_ctx->enable_shared_heap + && !create_shared_heap_info(comp_ctx, func_ctx)) { + goto fail; + } + return func_ctx; fail: @@ -2619,6 +2694,9 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option) if (option->enable_gc) comp_ctx->enable_gc = true; + if (option->enable_shared_heap) + comp_ctx->enable_shared_heap = true; + comp_ctx->opt_level = option->opt_level; comp_ctx->size_level = option->size_level; diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index 43212e5027..0dce988bc9 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -242,6 +242,9 @@ typedef struct AOTFuncContext { bool mem_space_unchanged; AOTCheckedAddrList checked_addr_list; + LLVMValueRef shared_heap_base_addr_adj; + LLVMValueRef shared_heap_start_off; + LLVMBasicBlockRef got_exception_block; LLVMBasicBlockRef func_return_block; LLVMValueRef exception_id_phi; @@ -467,6 +470,8 @@ typedef struct AOTCompContext { /* Enable GC */ bool enable_gc; + bool enable_shared_heap; + uint32 opt_level; uint32 size_level; diff --git a/core/iwasm/include/aot_comp_option.h b/core/iwasm/include/aot_comp_option.h index 98f33a1608..a97275d242 100644 --- a/core/iwasm/include/aot_comp_option.h +++ b/core/iwasm/include/aot_comp_option.h @@ -6,6 +6,8 @@ #ifndef __AOT_COMP_OPTION_H__ #define __AOT_COMP_OPTION_H__ +#include + typedef struct { /* Enables or disables bounds checks for stack frames. When enabled, the AOT * compiler generates code to check if the stack pointer is within the @@ -71,6 +73,7 @@ typedef struct AOTCompOption { bool enable_llvm_pgo; bool enable_stack_estimation; bool quick_invoke_c_api_import; + bool enable_shared_heap; char *use_prof_file; uint32_t opt_level; uint32_t size_level; diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index c9037b3cc1..aa6cfaae75 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -139,6 +139,9 @@ typedef struct wasm_section_t { struct WASMExecEnv; typedef struct WASMExecEnv *wasm_exec_env_t; +struct WASMSharedHeap; +typedef struct WASMSharedHeap *wasm_shared_heap_t; + /* Package Type */ typedef enum { Wasm_Module_Bytecode = 0, @@ -329,6 +332,10 @@ typedef enum { WASM_LOG_LEVEL_VERBOSE = 4 } log_level_t; +typedef struct SharedHeapInitArgs { + uint32_t size; +} SharedHeapInitArgs; + /** * Initialize the WASM runtime environment, and also initialize * the memory allocator with system allocator, which calls os_malloc @@ -1159,8 +1166,8 @@ wasm_application_execute_main(wasm_module_inst_t module_inst, int32_t argc, char *argv[]); /** - * Find the specified function in argv[0] from a WASM module instance - * and execute that function. + * Find the specified function from a WASM module instance and execute + * that function. * * @param module_inst the WASM module instance * @param name the name of the function to execute. @@ -1748,6 +1755,26 @@ wasm_runtime_set_user_data(wasm_exec_env_t exec_env, void *user_data); WASM_RUNTIME_API_EXTERN void * wasm_runtime_get_user_data(wasm_exec_env_t exec_env); +/** + * Set native stack boundary to execution environment, if it is set, + * it will be used instead of getting the boundary with the platform + * layer API when calling wasm functions. This is useful for some + * fiber cases. + * + * Note: unlike setting the boundary by runtime, this API doesn't add + * the WASM_STACK_GUARD_SIZE(see comments in core/config.h) to the + * exec_env's native_stack_boundary to reserve bytes to the native + * thread stack boundary, which is used to throw native stack overflow + * exception if the guard boundary is reached. Developer should ensure + * that enough guard bytes are kept. + * + * @param exec_env the execution environment + * @param native_stack_boundary the user data to be set + */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_native_stack_boundary(wasm_exec_env_t exec_env, + uint8_t *native_stack_boundary); + /** * Dump runtime memory consumption, including: * Exec env memory consumption @@ -2219,6 +2246,60 @@ wasm_runtime_detect_native_stack_overflow_size(wasm_exec_env_t exec_env, WASM_RUNTIME_API_EXTERN bool wasm_runtime_is_underlying_binary_freeable(const wasm_module_t module); +/** + * Create a shared heap + * + * @param init_args the initialization arguments + * @return the shared heap created + */ +WASM_RUNTIME_API_EXTERN wasm_shared_heap_t +wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args); + +/** + * Attach a shared heap to a module instance + * + * @param module_inst the module instance + * @param shared_heap the shared heap + * @return true if success, false if failed + */ +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_attach_shared_heap(wasm_module_inst_t module_inst, + wasm_shared_heap_t shared_heap); + +/** + * Detach a shared heap from a module instance + * + * @param module_inst the module instance + */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_detach_shared_heap(wasm_module_inst_t module_inst); + +/** + * Allocate memory from a shared heap + * + * @param module_inst the module instance + * @param size required memory size + * @param p_native_addr native address of allocated memory + * + * @return return the allocated memory address, which re-uses part of the wasm + * address space and is in the range of [UINT32 - shared_heap_size + 1, UINT32] + * (when the wasm memory is 32-bit) or [UINT64 - shared_heap_size + 1, UINT64] + * (when the wasm memory is 64-bit). Note that it is not an absolute address. + * Return non-zero if success, zero if failed. + */ +WASM_RUNTIME_API_EXTERN uint64_t +wasm_runtime_shared_heap_malloc(wasm_module_inst_t module_inst, uint64_t size, + void **p_native_addr); + +/** + * Free the memory allocated from shared heap + * + * @param module_inst the module instance + * @param ptr the offset in wasm app + */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_shared_heap_free(wasm_module_inst_t module_inst, uint64_t ptr); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index e043465d44..6023b07020 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -93,6 +93,10 @@ extern "C" { #define MAX_PAGE_COUNT_FLAG 0x01 #define SHARED_MEMORY_FLAG 0x02 #define MEMORY64_FLAG 0x04 +#define MAX_TABLE_SIZE_FLAG 0x01 +/* the shared flag for table is not actual used now */ +#define SHARED_TABLE_FLAG 0x02 +#define TABLE64_FLAG 0x04 /** * In the multi-memory proposal, the memarg in loads and stores are @@ -494,6 +498,7 @@ typedef struct WASMTableType { * 0: no max size and not shared * 1: has max size * 2: shared + * 4: table64 */ uint8 flags; bool possible_grow; @@ -520,6 +525,7 @@ typedef uint64 mem_offset_t; typedef uint32 mem_offset_t; #define PR_MEM_OFFSET PRIu32 #endif +typedef mem_offset_t tbl_elem_idx_t; typedef struct WASMMemory { uint32 flags; @@ -976,8 +982,9 @@ struct WASMModule { uint64 buf_code_size; #endif -#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_FAST_JIT != 0 \ - || WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_JIT != 0 +#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_FAST_JIT != 0 \ + || WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_JIT != 0 \ + || WASM_ENABLE_WAMR_COMPILER != 0 uint8 *load_addr; uint64 load_size; #endif @@ -1238,6 +1245,9 @@ wasm_value_type_size_internal(uint8 value_type, uint8 pointer_size) else { bh_assert(0); } +#if WASM_ENABLE_GC == 0 + (void)pointer_size; +#endif return 0; } diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 67f8c2d455..7041fd89c0 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -46,6 +46,28 @@ typedef float64 CellType_F64; #define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory) #endif +#if WASM_ENABLE_SHARED_HEAP != 0 +#if WASM_ENABLE_MULTI_MEMORY != 0 +/* Only enable shared heap for the default memory */ +#define is_default_memory (memidx == 0) +#else +#define is_default_memory true +#endif +#define app_addr_in_shared_heap(app_addr, bytes) \ + (shared_heap && is_default_memory && (app_addr) >= shared_heap_start_off \ + && (app_addr) <= shared_heap_end_off - bytes + 1) + +#define shared_heap_addr_app_to_native(app_addr, native_addr) \ + native_addr = shared_heap_base_addr + ((app_addr)-shared_heap_start_off) + +#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr) \ + if (app_addr_in_shared_heap(app_addr, bytes)) \ + shared_heap_addr_app_to_native(app_addr, native_addr); \ + else +#else +#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr) +#endif + #if WASM_ENABLE_MEMORY64 == 0 #if (!defined(OS_ENABLE_HW_BOUND_CHECK) \ @@ -53,6 +75,7 @@ typedef float64 CellType_F64; #define CHECK_MEMORY_OVERFLOW(bytes) \ do { \ uint64 offset1 = (uint64)offset + (uint64)addr; \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ if (disable_bounds_checks || offset1 + bytes <= get_linear_mem_size()) \ /* If offset1 is in valid range, maddr must also \ be in valid range, no need to check it again. */ \ @@ -64,6 +87,7 @@ typedef float64 CellType_F64; #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ do { \ uint64 offset1 = (uint32)(start); \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ if (disable_bounds_checks || offset1 + bytes <= get_linear_mem_size()) \ /* App heap space is not valid space for \ bulk memory operation */ \ @@ -71,18 +95,24 @@ typedef float64 CellType_F64; else \ goto out_of_bounds; \ } while (0) + #else /* else of !defined(OS_ENABLE_HW_BOUND_CHECK) || \ WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */ -#define CHECK_MEMORY_OVERFLOW(bytes) \ - do { \ - uint64 offset1 = (uint64)offset + (uint64)addr; \ - maddr = memory->memory_data + offset1; \ + +#define CHECK_MEMORY_OVERFLOW(bytes) \ + do { \ + uint64 offset1 = (uint64)offset + (uint64)addr; \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ + maddr = memory->memory_data + offset1; \ } while (0) -#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ - do { \ - maddr = memory->memory_data + (uint32)(start); \ +#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ + do { \ + uint64 offset1 = (uint32)(start); \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ + maddr = memory->memory_data + offset1; \ } while (0) + #endif /* end of !defined(OS_ENABLE_HW_BOUND_CHECK) || \ WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */ @@ -91,6 +121,7 @@ typedef float64 CellType_F64; #define CHECK_MEMORY_OVERFLOW(bytes) \ do { \ uint64 offset1 = (uint64)offset + (uint64)addr; \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ /* If memory64 is enabled, offset1, offset1 + bytes can overflow */ \ if (disable_bounds_checks \ || (offset1 >= offset && offset1 + bytes >= offset1 \ @@ -99,9 +130,11 @@ typedef float64 CellType_F64; else \ goto out_of_bounds; \ } while (0) + #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ do { \ uint64 offset1 = (uint64)(start); \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ /* If memory64 is enabled, offset1 + bytes can overflow */ \ if (disable_bounds_checks \ || (offset1 + bytes >= offset1 \ @@ -511,9 +544,9 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) #endif #if WASM_ENABLE_MEMORY64 != 0 -#define PUSH_MEM_OFFSET(value) \ +#define COND_PUSH_TEMPLATE(cond, value) \ do { \ - if (is_memory64) { \ + if (cond) { \ PUT_I64_TO_ADDR(frame_sp, value); \ frame_sp += 2; \ } \ @@ -521,8 +554,11 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) *(int32 *)frame_sp++ = (int32)(value); \ } \ } while (0) +#define PUSH_MEM_OFFSET(value) COND_PUSH_TEMPLATE(is_memory64, value) +#define PUSH_TBL_ELEM_IDX(value) COND_PUSH_TEMPLATE(is_table64, value) #else #define PUSH_MEM_OFFSET(value) PUSH_I32(value) +#define PUSH_TBL_ELEM_IDX(value) PUSH_I32(value) #endif #define PUSH_PAGE_COUNT(value) PUSH_MEM_OFFSET(value) @@ -558,8 +594,10 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) #if WASM_ENABLE_MEMORY64 != 0 #define POP_MEM_OFFSET() (is_memory64 ? POP_I64() : POP_I32()) +#define POP_TBL_ELEM_IDX() (is_table64 ? POP_I64() : POP_I32()) #else #define POP_MEM_OFFSET() POP_I32() +#define POP_TBL_ELEM_IDX() POP_I32() #endif #define POP_PAGE_COUNT() POP_MEM_OFFSET() @@ -1562,7 +1600,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint8 opcode; uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0; uint32 all_cell_num = 0; - int32 val; + tbl_elem_idx_t val; uint8 *else_addr, *end_addr, *maddr = NULL; uint32 local_idx, local_offset, global_idx; uint8 local_type, *global_addr; @@ -1602,9 +1640,26 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /* TODO: multi-memories for now assuming the memory idx type is consistent * across multi-memories */ bool is_memory64 = false; + bool is_table64 = false; if (memory) is_memory64 = memory->is_memory64; #endif +#if WASM_ENABLE_SHARED_HEAP != 0 + WASMSharedHeap *shared_heap = module->e->shared_heap; + uint8 *shared_heap_base_addr = shared_heap ? shared_heap->base_addr : NULL; +#if WASM_ENABLE_MEMORY64 != 0 + uint64 shared_heap_start_off = + shared_heap ? (is_memory64 ? shared_heap->start_off_mem64 + : shared_heap->start_off_mem32) + : 0; + uint64 shared_heap_end_off = + shared_heap ? (is_memory64 ? UINT64_MAX : UINT32_MAX) : 0; +#else + uint64 shared_heap_start_off = + shared_heap ? shared_heap->start_off_mem32 : 0; + uint64 shared_heap_end_off = shared_heap ? UINT32_MAX : 0; +#endif +#endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */ #if WASM_ENABLE_MULTI_MEMORY != 0 uint32 memidx = 0; uint32 memidx_cached = (uint32)-1; @@ -2315,7 +2370,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /** * type check. compiler will make sure all like - * (call_indirect (type $x) (i32.const 1)) + * (call_indirect (type $x) (it.const 1)) * the function type has to be defined in the module also * no matter it is used or not */ @@ -2334,9 +2389,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /* clang-format on */ tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif - val = POP_I32(); - if ((uint32)val >= tbl_inst->cur_size) { + val = POP_TBL_ELEM_IDX(); + if (val >= tbl_inst->cur_size) { wasm_set_exception(module, "undefined element"); goto got_exception; } @@ -2482,15 +2540,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, HANDLE_OP(WASM_OP_TABLE_GET) { - uint32 tbl_idx, elem_idx; + uint32 tbl_idx; + tbl_elem_idx_t elem_idx; WASMTableInstance *tbl_inst; read_leb_uint32(frame_ip, frame_ip_end, tbl_idx); bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif - elem_idx = POP_I32(); + elem_idx = POP_TBL_ELEM_IDX(); if (elem_idx >= tbl_inst->cur_size) { wasm_set_exception(module, "out of bounds table access"); goto got_exception; @@ -2507,20 +2569,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, HANDLE_OP(WASM_OP_TABLE_SET) { WASMTableInstance *tbl_inst; - uint32 tbl_idx, elem_idx; + uint32 tbl_idx; + tbl_elem_idx_t elem_idx; table_elem_type_t elem_val; read_leb_uint32(frame_ip, frame_ip_end, tbl_idx); bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif #if WASM_ENABLE_GC == 0 elem_val = POP_I32(); #else elem_val = POP_REF(); #endif - elem_idx = POP_I32(); + elem_idx = POP_TBL_ELEM_IDX(); if (elem_idx >= tbl_inst->cur_size) { wasm_set_exception(module, "out of bounds table access"); goto got_exception; @@ -3455,8 +3521,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, str_obj = (WASMString)wasm_stringref_obj_get_value( stringref_obj); - memory_inst = module->memories[mem_idx]; - maddr = memory_inst->memory_data + addr; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)addr, 1)) + shared_heap_addr_app_to_native((uint64)addr, maddr); + else +#endif + { + memory_inst = module->memories[mem_idx]; + maddr = memory_inst->memory_data + addr; + } if (opcode == WASM_OP_STRING_ENCODE_WTF16) { flag = WTF16; @@ -3623,8 +3696,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, addr = POP_I32(); stringview_wtf8_obj = POP_REF(); - memory_inst = module->memories[mem_idx]; - maddr = memory_inst->memory_data + addr; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)addr, 1)) + shared_heap_addr_app_to_native((uint64)addr, maddr); + else +#endif + { + memory_inst = module->memories[mem_idx]; + maddr = memory_inst->memory_data + addr; + } bytes_written = wasm_string_encode( (WASMString)wasm_stringview_wtf8_obj_get_value( @@ -4616,13 +4696,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, HANDLE_OP(WASM_OP_MEMORY_GROW) { - uint32 mem_idx, delta, prev_page_count; + uint32 mem_idx, prev_page_count; + mem_offset_t delta; read_leb_memidx(frame_ip, frame_ip_end, mem_idx); prev_page_count = memory->cur_page_count; - delta = (uint32)POP_PAGE_COUNT(); + delta = POP_PAGE_COUNT(); - if (!wasm_enlarge_memory_with_idx(module, delta, mem_idx)) { + if ( +#if WASM_ENABLE_MEMORY64 != 0 + delta > UINT32_MAX || +#endif + !wasm_enlarge_memory_with_idx(module, (uint32)delta, + mem_idx)) { /* failed to memory.grow, return -1 */ PUSH_PAGE_COUNT(-1); } @@ -5651,9 +5737,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr); #else - if ((uint64)(uint32)addr + bytes > linear_mem_size) - goto out_of_bounds; - maddr = memory->memory_data + (uint32)addr; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)(uint32)addr, + bytes)) + shared_heap_addr_app_to_native((uint64)(uint32)addr, + maddr); + else +#endif + { + if ((uint64)(uint32)addr + bytes > linear_mem_size) + goto out_of_bounds; + maddr = memory->memory_data + (uint32)addr; + } #endif if (bh_bitmap_get_bit(module->e->common.data_dropped, @@ -5703,15 +5798,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if WASM_ENABLE_THREAD_MGR != 0 linear_mem_size = get_linear_mem_size(); #endif + + dlen = linear_mem_size - dst; + /* dst boundary check */ #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); -#else - if ((uint64)dst + len > linear_mem_size) - goto out_of_bounds; - mdst = memory->memory_data + dst; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)dst, len)) + dlen = shared_heap_end_off - dst + 1; #endif - dlen = linear_mem_size - dst; +#else /* else of OS_ENABLE_HW_BOUND_CHECK */ +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)dst, len)) { + shared_heap_addr_app_to_native((uint64)dst, mdst); + dlen = shared_heap_end_off - dst + 1; + } + else +#endif + { + if ((uint64)dst + len > linear_mem_size) + goto out_of_bounds; + mdst = memory->memory_data + dst; + } +#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ #if WASM_ENABLE_MULTI_MEMORY != 0 /* src memidx */ @@ -5727,9 +5837,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc); #else - if ((uint64)src + len > linear_mem_size) - goto out_of_bounds; - msrc = memory->memory_data + src; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)src, len)) + shared_heap_addr_app_to_native((uint64)src, msrc); + else +#endif + { + if ((uint64)src + len > linear_mem_size) + goto out_of_bounds; + msrc = memory->memory_data + src; + } #endif #if WASM_ENABLE_MEMORY64 == 0 @@ -5766,9 +5883,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); #else - if ((uint64)(uint32)dst + len > linear_mem_size) - goto out_of_bounds; - mdst = memory->memory_data + (uint32)dst; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)(uint32)dst, len)) + shared_heap_addr_app_to_native((uint64)(uint32)dst, + mdst); + else +#endif + { + if ((uint64)(uint32)dst + len > linear_mem_size) + goto out_of_bounds; + mdst = memory->memory_data + (uint32)dst; + } #endif memset(mdst, fill_val, len); @@ -5778,8 +5903,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 case WASM_OP_TABLE_INIT: { - uint32 tbl_idx, elem_idx; - uint32 n, s, d; + uint32 tbl_idx; + tbl_elem_idx_t elem_idx, d; + uint32 n, s; WASMTableInstance *tbl_inst; table_elem_type_t *table_elems; InitializerExpression *tbl_seg_init_values = NULL, @@ -5793,10 +5919,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, bh_assert(tbl_idx < module->module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif n = (uint32)POP_I32(); s = (uint32)POP_I32(); - d = (uint32)POP_I32(); + d = (tbl_elem_idx_t)POP_TBL_ELEM_IDX(); if (!bh_bitmap_get_bit(module->e->common.elem_dropped, elem_idx)) { @@ -5809,8 +5938,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, .value_count; } - if (offset_len_out_of_bounds(s, n, tbl_seg_len) - || offset_len_out_of_bounds(d, n, + /* TODO: memory64 current implementation of table64 + * still assumes the max table size UINT32_MAX + */ + if ( +#if WASM_ENABLE_MEMORY64 != 0 + d > UINT32_MAX || +#endif + offset_len_out_of_bounds(s, n, tbl_seg_len) + || offset_len_out_of_bounds((uint32)d, n, tbl_inst->cur_size)) { wasm_set_exception(module, "out of bounds table access"); @@ -5864,7 +6000,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, case WASM_OP_TABLE_COPY: { uint32 src_tbl_idx, dst_tbl_idx; - uint32 n, s, d; + tbl_elem_idx_t n, s, d; WASMTableInstance *src_tbl_inst, *dst_tbl_inst; read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx); @@ -5877,14 +6013,29 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, src_tbl_inst = wasm_get_table_inst(module, src_tbl_idx); - n = (uint32)POP_I32(); - s = (uint32)POP_I32(); - d = (uint32)POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = src_tbl_inst->is_table64 + && dst_tbl_inst->is_table64; +#endif + n = (tbl_elem_idx_t)POP_TBL_ELEM_IDX(); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = src_tbl_inst->is_table64; +#endif + s = (tbl_elem_idx_t)POP_TBL_ELEM_IDX(); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = dst_tbl_inst->is_table64; +#endif + d = (tbl_elem_idx_t)POP_TBL_ELEM_IDX(); - if (offset_len_out_of_bounds(d, n, + if ( +#if WASM_ENABLE_MEMORY64 != 0 + n > UINT32_MAX || s > UINT32_MAX || d > UINT32_MAX + || +#endif + offset_len_out_of_bounds((uint32)d, (uint32)n, dst_tbl_inst->cur_size) || offset_len_out_of_bounds( - s, n, src_tbl_inst->cur_size)) { + (uint32)s, (uint32)n, src_tbl_inst->cur_size)) { wasm_set_exception(module, "out of bounds table access"); goto got_exception; @@ -5907,28 +6058,37 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, case WASM_OP_TABLE_GROW: { WASMTableInstance *tbl_inst; - uint32 tbl_idx, n, orig_tbl_sz; + uint32 tbl_idx, orig_tbl_sz; + tbl_elem_idx_t n; table_elem_type_t init_val; read_leb_uint32(frame_ip, frame_ip_end, tbl_idx); bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif orig_tbl_sz = tbl_inst->cur_size; - n = POP_I32(); + n = POP_TBL_ELEM_IDX(); #if WASM_ENABLE_GC == 0 init_val = POP_I32(); #else init_val = POP_REF(); #endif - if (!wasm_enlarge_table(module, tbl_idx, n, init_val)) { - PUSH_I32(-1); + if ( +#if WASM_ENABLE_MEMORY64 != 0 + n > UINT32_MAX || +#endif + !wasm_enlarge_table(module, tbl_idx, (uint32)n, + init_val)) { + PUSH_TBL_ELEM_IDX(-1); } else { - PUSH_I32(orig_tbl_sz); + PUSH_TBL_ELEM_IDX(orig_tbl_sz); } break; } @@ -5941,13 +6101,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif - PUSH_I32(tbl_inst->cur_size); + PUSH_TBL_ELEM_IDX(tbl_inst->cur_size); break; } case WASM_OP_TABLE_FILL: { - uint32 tbl_idx, n; + uint32 tbl_idx; + tbl_elem_idx_t n, elem_idx; WASMTableInstance *tbl_inst; table_elem_type_t fill_val; @@ -5955,24 +6119,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif - n = POP_I32(); + n = POP_TBL_ELEM_IDX(); #if WASM_ENABLE_GC == 0 fill_val = POP_I32(); #else fill_val = POP_REF(); #endif - i = POP_I32(); + elem_idx = POP_TBL_ELEM_IDX(); - if (offset_len_out_of_bounds(i, n, + if ( +#if WASM_ENABLE_MEMORY64 != 0 + n > UINT32_MAX || elem_idx > UINT32_MAX || +#endif + offset_len_out_of_bounds((uint32)elem_idx, + (uint32)n, tbl_inst->cur_size)) { wasm_set_exception(module, "out of bounds table access"); goto got_exception; } - for (; n != 0; i++, n--) { - tbl_inst->elems[i] = fill_val; + for (; n != 0; elem_idx++, n--) { + tbl_inst->elems[elem_idx] = fill_val; } break; } @@ -6555,7 +6727,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 = get_linear_mem_size(); + linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); #endif if (wasm_copy_exception(module, NULL)) { #if WASM_ENABLE_EXCE_HANDLING != 0 diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 9d3b743382..73e54fca7a 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -37,11 +37,28 @@ typedef float64 CellType_F64; #define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory) #endif +#if WASM_ENABLE_SHARED_HEAP != 0 +#define app_addr_in_shared_heap(app_addr, bytes) \ + (shared_heap && (app_addr) >= shared_heap_start_off \ + && (app_addr) <= shared_heap_end_off - bytes + 1) + +#define shared_heap_addr_app_to_native(app_addr, native_addr) \ + native_addr = shared_heap_base_addr + ((app_addr)-shared_heap_start_off) + +#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr) \ + if (app_addr_in_shared_heap(app_addr, bytes)) \ + shared_heap_addr_app_to_native(app_addr, native_addr); \ + else +#else +#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr) +#endif + #if !defined(OS_ENABLE_HW_BOUND_CHECK) \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 #define CHECK_MEMORY_OVERFLOW(bytes) \ do { \ uint64 offset1 = (uint64)offset + (uint64)addr; \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ if (disable_bounds_checks || offset1 + bytes <= get_linear_mem_size()) \ /* If offset1 is in valid range, maddr must also \ be in valid range, no need to check it again. */ \ @@ -53,6 +70,7 @@ typedef float64 CellType_F64; #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ do { \ uint64 offset1 = (uint32)(start); \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ if (disable_bounds_checks || offset1 + bytes <= get_linear_mem_size()) \ /* App heap space is not valid space for \ bulk memory operation */ \ @@ -61,15 +79,18 @@ typedef float64 CellType_F64; goto out_of_bounds; \ } while (0) #else -#define CHECK_MEMORY_OVERFLOW(bytes) \ - do { \ - uint64 offset1 = (uint64)offset + (uint64)addr; \ - maddr = memory->memory_data + offset1; \ +#define CHECK_MEMORY_OVERFLOW(bytes) \ + do { \ + uint64 offset1 = (uint64)offset + (uint64)addr; \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ + maddr = memory->memory_data + offset1; \ } while (0) -#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ - do { \ - maddr = memory->memory_data + (uint32)(start); \ +#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ + do { \ + uint64 offset1 = (uint32)(start); \ + CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \ + maddr = memory->memory_data + offset1; \ } while (0) #endif /* !defined(OS_ENABLE_HW_BOUND_CHECK) \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */ @@ -1520,6 +1541,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0 bool is_return_call = false; #endif +#if WASM_ENABLE_SHARED_HEAP != 0 + WASMSharedHeap *shared_heap = module->e ? module->e->shared_heap : NULL; + uint8 *shared_heap_base_addr = shared_heap ? shared_heap->base_addr : NULL; + /* +#if WASM_ENABLE_MEMORY64 != 0 + uint64 shared_heap_start_off = + shared_heap ? (is_memory64 ? shared_heap->start_off_mem64 + : shared_heap->start_off_mem32) + : 0; + uint64 shared_heap_end_off = + shared_heap ? (is_memory64 ? UINT64_MAX : UINT32_MAX) : 0; +#else + */ /* TODO: uncomment the code when memory64 is enabled for fast-interp */ + uint64 shared_heap_start_off = + shared_heap ? shared_heap->start_off_mem32 : 0; + uint64 shared_heap_end_off = shared_heap ? UINT32_MAX : 0; +/* #endif */ +#endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */ #if WASM_ENABLE_LABELS_AS_VALUES != 0 #define HANDLE_OPCODE(op) &&HANDLE_##op @@ -2835,8 +2874,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, str_obj = (WASMString)wasm_stringref_obj_get_value( stringref_obj); - memory_inst = module->memories[mem_idx]; - maddr = memory_inst->memory_data + addr; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)addr, 1)) + shared_heap_addr_app_to_native((uint64)addr, maddr); + else +#endif + { + memory_inst = module->memories[mem_idx]; + maddr = memory_inst->memory_data + addr; + } if (opcode == WASM_OP_STRING_ENCODE_WTF16) { flag = WTF16; @@ -3003,8 +3049,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, addr = POP_I32(); stringview_wtf8_obj = POP_REF(); - memory_inst = module->memories[mem_idx]; - maddr = memory_inst->memory_data + addr; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)addr, 1)) + shared_heap_addr_app_to_native((uint64)addr, maddr); + else +#endif + { + memory_inst = module->memories[mem_idx]; + maddr = memory_inst->memory_data + addr; + } bytes_written = wasm_string_encode( (WASMString)wasm_stringview_wtf8_obj_get_value( @@ -4989,9 +5042,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr); #else - if ((uint64)(uint32)addr + bytes > linear_mem_size) - goto out_of_bounds; - maddr = memory->memory_data + (uint32)addr; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)(uint32)addr, + bytes)) + shared_heap_addr_app_to_native((uint64)(uint32)addr, + maddr); + else +#endif + { + if ((uint64)(uint32)addr + bytes > linear_mem_size) + goto out_of_bounds; + maddr = memory->memory_data + (uint32)addr; + } #endif if (bh_bitmap_get_bit(module->e->common.data_dropped, segment)) { @@ -5024,6 +5086,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, { uint32 dst, src, len; uint8 *mdst, *msrc; + uint64 dlen; len = POP_I32(); src = POP_I32(); @@ -5033,22 +5096,43 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, linear_mem_size = get_linear_mem_size(); #endif + dlen = linear_mem_size - dst; + #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc); CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); -#else - if ((uint64)(uint32)src + len > linear_mem_size) - goto out_of_bounds; - msrc = memory->memory_data + (uint32)src; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)dst, len)) + dlen = shared_heap_end_off - dst + 1; +#endif +#else /* else of OS_ENABLE_HW_BOUND_CHECK */ +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)src, len)) + shared_heap_addr_app_to_native((uint64)src, msrc); + else +#endif + { + if ((uint64)(uint32)src + len > linear_mem_size) + goto out_of_bounds; + msrc = memory->memory_data + (uint32)src; + } - if ((uint64)(uint32)dst + len > linear_mem_size) - goto out_of_bounds; - mdst = memory->memory_data + (uint32)dst; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)dst, len)) { + shared_heap_addr_app_to_native((uint64)dst, mdst); + dlen = shared_heap_end_off - dst + 1; + } + else #endif + { + if ((uint64)(uint32)dst + len > linear_mem_size) + goto out_of_bounds; + mdst = memory->memory_data + (uint32)dst; + } +#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ /* allowing the destination and source to overlap */ - bh_memmove_s(mdst, (uint32)(linear_mem_size - dst), - msrc, len); + bh_memmove_s(mdst, (uint32)dlen, msrc, len); break; } case WASM_OP_MEMORY_FILL: @@ -5067,9 +5151,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); #else - if ((uint64)(uint32)dst + len > linear_mem_size) - goto out_of_bounds; - mdst = memory->memory_data + (uint32)dst; +#if WASM_ENABLE_SHARED_HEAP != 0 + if (app_addr_in_shared_heap((uint64)(uint32)dst, len)) + shared_heap_addr_app_to_native((uint64)(uint32)dst, + mdst); + else +#endif + { + if ((uint64)(uint32)dst + len > linear_mem_size) + goto out_of_bounds; + mdst = memory->memory_data + (uint32)dst; + } #endif memset(mdst, fill_val, len); @@ -6357,7 +6449,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 = get_linear_mem_size(); + linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); #endif if (wasm_copy_exception(module, NULL)) goto got_exception; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 5005fc63bf..47995e03f6 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -4,8 +4,7 @@ */ #include "wasm_loader.h" -#include "bh_common.h" -#include "bh_log.h" +#include "bh_platform.h" #include "wasm.h" #include "wasm_opcode.h" #include "wasm_runtime.h" @@ -51,6 +50,18 @@ has_module_memory64(WASMModule *module) return false; } + +static bool +is_table_64bit(WASMModule *module, uint32 table_idx) +{ + if (table_idx < module->import_table_count) + return !!(module->import_tables[table_idx].u.table.table_type.flags + & TABLE64_FLAG); + else + return !!(module->tables[table_idx].table_type.flags & TABLE64_FLAG); + + return false; +} #endif static void @@ -2205,10 +2216,14 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } static void -adjust_table_max_size(uint32 init_size, uint32 max_size_flag, uint32 *max_size) +adjust_table_max_size(bool is_table64, uint32 init_size, uint32 max_size_flag, + uint32 *max_size) { uint32 default_max_size; + /* TODO: current still use UINT32_MAX as upper limit for table size to keep + * ABI unchanged */ + (void)is_table64; if (UINT32_MAX / 2 > init_size) default_max_size = init_size * 2; else @@ -2503,9 +2518,9 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, const char *table_name, WASMTableImport *table, char *error_buf, uint32 error_buf_size) { - const uint8 *p = *p_buf, *p_end = buf_end; - uint32 declare_elem_type = 0, declare_max_size_flag = 0, - declare_init_size = 0, declare_max_size = 0; + const uint8 *p = *p_buf, *p_end = buf_end, *p_org; + uint32 declare_elem_type = 0, table_flag = 0, declare_init_size = 0, + declare_max_size = 0; #if WASM_ENABLE_MULTI_MODULE != 0 WASMModule *sub_module = NULL; WASMTable *linked_table = NULL; @@ -2514,6 +2529,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, WASMRefType ref_type; bool need_ref_type_map; #endif + bool is_table64 = false; #if WASM_ENABLE_GC == 0 CHECK_BUF(p, p_end, 1); @@ -2552,23 +2568,29 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, #endif #endif /* end of WASM_ENABLE_GC == 0 */ - read_leb_uint32(p, p_end, declare_max_size_flag); - if (declare_max_size_flag > 1) { - set_error_buf(error_buf, error_buf_size, "integer too large"); + p_org = p; + read_leb_uint32(p, p_end, table_flag); + is_table64 = table_flag & TABLE64_FLAG; + if (p - p_org > 1) { + LOG_VERBOSE("integer representation too long(import table)"); + set_error_buf(error_buf, error_buf_size, "invalid limits flags"); return false; } - read_leb_uint32(p, p_end, declare_init_size); + if (!wasm_table_check_flags(table_flag, error_buf, error_buf_size, false)) { + return false; + } - if (declare_max_size_flag) { + read_leb_uint32(p, p_end, declare_init_size); + if (table_flag & MAX_TABLE_SIZE_FLAG) { read_leb_uint32(p, p_end, declare_max_size); if (!check_table_max_size(declare_init_size, declare_max_size, error_buf, error_buf_size)) return false; } - adjust_table_max_size(declare_init_size, declare_max_size_flag, - &declare_max_size); + adjust_table_max_size(is_table64, declare_init_size, + table_flag & MAX_TABLE_SIZE_FLAG, &declare_max_size); *p_buf = p; @@ -2586,7 +2608,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, declare_elem_type = linked_table->table_type.elem_type; declare_init_size = linked_table->table_type.init_size; declare_max_size = linked_table->table_type.max_size; - declare_max_size_flag = linked_table->table_type.flags; + table_flag = linked_table->table_type.flags; table->import_table_linked = linked_table; table->import_module = sub_module; } @@ -2595,12 +2617,17 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, #endif /* WASM_ENABLE_MULTI_MODULE != 0 */ /* (table (export "table") 10 20 funcref) */ + /* (table (export "table64") 10 20 funcref) */ /* we need this section working in wamrc */ if (!strcmp("spectest", sub_module_name)) { const uint32 spectest_table_init_size = 10; const uint32 spectest_table_max_size = 20; - if (strcmp("table", table_name)) { + if (strcmp("table", table_name) +#if WASM_ENABLE_MEMORY64 != 0 + && strcmp("table64", table_name) +#endif + ) { set_error_buf(error_buf, error_buf_size, "incompatible import type or unknown import"); return false; @@ -2620,7 +2647,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, /* now we believe all declaration are ok */ table->table_type.elem_type = declare_elem_type; table->table_type.init_size = declare_init_size; - table->table_type.flags = declare_max_size_flag; + table->table_type.flags = table_flag; table->table_type.max_size = declare_max_size; #if WASM_ENABLE_WAMR_COMPILER != 0 @@ -2713,7 +2740,7 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end, read_leb_uint32(p, p_end, mem_flag); is_memory64 = mem_flag & MEMORY64_FLAG; if (p - p_org > 1) { - LOG_VERBOSE("integer representation too long"); + LOG_VERBOSE("integer representation too long(import memory)"); set_error_buf(error_buf, error_buf_size, "invalid limits flags"); return false; } @@ -3028,6 +3055,7 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module, WASMRefType ref_type; bool need_ref_type_map; #endif + bool is_table64 = false; #if WASM_ENABLE_GC == 0 CHECK_BUF(p, p_end, 1); @@ -3065,34 +3093,20 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module, p_org = p; read_leb_uint32(p, p_end, table->table_type.flags); -#if WASM_ENABLE_SHARED_MEMORY == 0 - if (p - p_org > 1) { - set_error_buf(error_buf, error_buf_size, - "integer representation too long"); - return false; - } - if (table->table_type.flags > 1) { - set_error_buf(error_buf, error_buf_size, "integer too large"); - return false; - } -#else + is_table64 = table->table_type.flags & TABLE64_FLAG; if (p - p_org > 1) { + LOG_VERBOSE("integer representation too long(table)"); set_error_buf(error_buf, error_buf_size, "invalid limits flags"); return false; } - if (table->table_type.flags == 2) { - set_error_buf(error_buf, error_buf_size, "tables cannot be shared"); - return false; - } - if (table->table_type.flags > 1) { - set_error_buf(error_buf, error_buf_size, "invalid limits flags"); + + if (!wasm_table_check_flags(table->table_type.flags, error_buf, + error_buf_size, false)) { return false; } -#endif read_leb_uint32(p, p_end, table->table_type.init_size); - - if (table->table_type.flags) { + if (table->table_type.flags & MAX_TABLE_SIZE_FLAG) { read_leb_uint32(p, p_end, table->table_type.max_size); if (!check_table_max_size(table->table_type.init_size, table->table_type.max_size, error_buf, @@ -3100,7 +3114,8 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module, return false; } - adjust_table_max_size(table->table_type.init_size, table->table_type.flags, + adjust_table_max_size(is_table64, table->table_type.init_size, + table->table_type.flags & MAX_TABLE_SIZE_FLAG, &table->table_type.max_size); #if WASM_ENABLE_WAMR_COMPILER != 0 @@ -3132,7 +3147,7 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory, read_leb_uint32(p, p_end, memory->flags); is_memory64 = memory->flags & MEMORY64_FLAG; if (p - p_org > 1) { - LOG_VERBOSE("integer representation too long"); + LOG_VERBOSE("integer representation too long(memory)"); set_error_buf(error_buf, error_buf_size, "invalid limits flags"); return false; } @@ -3172,6 +3187,12 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory, return false; } +static int +cmp_export_name(const void *a, const void *b) +{ + return strcmp(*(char **)a, *(char **)b); +} + static bool load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, bool is_load_from_file_buf, bool no_resolve, @@ -4042,17 +4063,53 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, return false; } +static bool +check_duplicate_exports(WASMModule *module, char *error_buf, + uint32 error_buf_size) +{ + uint32 i; + bool result = false; + char *names_buf[32], **names = names_buf; + + if (module->export_count > 32) { + names = loader_malloc(module->export_count * sizeof(char *), error_buf, + error_buf_size); + if (!names) { + return result; + } + } + + for (i = 0; i < module->export_count; i++) { + names[i] = module->exports[i].name; + } + + qsort(names, module->export_count, sizeof(char *), cmp_export_name); + + for (i = 1; i < module->export_count; i++) { + if (!strcmp(names[i], names[i - 1])) { + set_error_buf(error_buf, error_buf_size, "duplicate export name"); + goto cleanup; + } + } + + result = true; +cleanup: + if (module->export_count > 32) { + wasm_runtime_free(names); + } + return result; +} + static bool load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, bool is_load_from_file_buf, char *error_buf, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end; - uint32 export_count, i, j, index; + uint32 export_count, i, index; uint64 total_size; uint32 str_len; WASMExport *export; - const char *name; read_leb_uint32(p, p_end, export_count); @@ -4078,15 +4135,6 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, read_leb_uint32(p, p_end, str_len); CHECK_BUF(p, p_end, str_len); - for (j = 0; j < i; j++) { - name = module->exports[j].name; - if (strlen(name) == str_len && memcmp(name, p, str_len) == 0) { - set_error_buf(error_buf, error_buf_size, - "duplicate export name"); - return false; - } - } - if (!(export->name = wasm_const_str_list_insert( p, str_len, module, is_load_from_file_buf, error_buf, error_buf_size))) { @@ -4160,6 +4208,10 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, return false; } } + + if (!check_duplicate_exports(module, error_buf, error_buf_size)) { + return false; + } } if (p != p_end) { @@ -4407,6 +4459,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end; + uint8 table_elem_idx_type; uint32 table_segment_count, i; uint64 total_size; WASMTableSeg *table_segment; @@ -4429,6 +4482,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, "invalid elements segment kind"); return false; } + table_elem_idx_type = VALUE_TYPE_I32; #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 read_leb_uint32(p, p_end, table_segment->mode); @@ -4464,9 +4518,17 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, if (!check_table_index(module, table_segment->table_index, error_buf, error_buf_size)) return false; - if (!load_init_expr( - module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, NULL, error_buf, error_buf_size)) + +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + if (!load_init_expr(module, &p, p_end, + &table_segment->base_offset, + table_elem_idx_type, NULL, error_buf, + error_buf_size)) return false; if (table_segment->mode == 0) { @@ -4514,9 +4576,16 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, &table_segment->table_index, error_buf, error_buf_size)) return false; - if (!load_init_expr( - module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, NULL, error_buf, error_buf_size)) +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + if (!load_init_expr(module, &p, p_end, + &table_segment->base_offset, + table_elem_idx_type, NULL, error_buf, + error_buf_size)) return false; if (!load_elem_type(module, &p, p_end, &table_segment->elem_type, @@ -4568,7 +4637,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, "unknown element segment kind"); return false; } -#else /* else of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */ +#else /* else of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */ /* * like: 00 41 05 0b 04 00 01 00 01 * for: (elem 0 (offset (i32.const 5)) $f1 $f2 $f1 $f2) @@ -4577,8 +4646,14 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, &table_segment->table_index, error_buf, error_buf_size)) return false; +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (!load_init_expr(module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, NULL, error_buf, + table_elem_idx_type, NULL, error_buf, error_buf_size)) return false; if (!load_func_index_vec(&p, p_end, module, table_segment, @@ -4593,6 +4668,16 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, return false; #endif /* end of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */ +#if WASM_ENABLE_MEMORY64 != 0 + if (table_elem_idx_type == VALUE_TYPE_I64 + && table_segment->base_offset.u.u64 > UINT32_MAX) { + set_error_buf(error_buf, error_buf_size, + "In table64, table base offset can't be " + "larger than UINT32_MAX"); + return false; + } +#endif + #if WASM_ENABLE_WAMR_COMPILER != 0 if (table_segment->elem_type == VALUE_TYPE_EXTERNREF) module->is_ref_types_used = true; @@ -5335,6 +5420,9 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf, option.enable_memory_profiling = true; option.enable_stack_estimation = true; #endif +#if WASM_ENABLE_SHARED_HEAP != 0 + option.enable_shared_heap = true; +#endif module->comp_ctx = aot_create_comp_context(module->comp_data, &option); if (!module->comp_ctx) { @@ -6115,6 +6203,12 @@ load_from_sections(WASMModule *module, WASMSection *sections, #endif } +#if WASM_ENABLE_MEMORY64 != 0 + if (!check_memory64_flags_consistency(module, error_buf, error_buf_size, + false)) + return false; +#endif + calculate_global_data_offset(module); #if WASM_ENABLE_FAST_JIT != 0 @@ -9615,6 +9709,7 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, #define POP_REF(Type) TEMPLATE_POP_REF(Type) #define PUSH_MEM_OFFSET() TEMPLATE_PUSH_REF(mem_offset_type) #define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET() +#define PUSH_TBL_ELEM_IDX() TEMPLATE_PUSH_REF(table_elem_idx_type) #define POP_I32() TEMPLATE_POP(I32) #define POP_F32() TEMPLATE_POP(F32) @@ -9625,6 +9720,7 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, #define POP_EXTERNREF() TEMPLATE_POP(EXTERNREF) #define POP_STRINGREF() TEMPLATE_POP(STRINGREF) #define POP_MEM_OFFSET() TEMPLATE_POP_REF(mem_offset_type) +#define POP_TBL_ELEM_IDX() TEMPLATE_POP_REF(table_elem_idx_type) #if WASM_ENABLE_FAST_INTERP != 0 @@ -10811,7 +10907,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org; uint32 param_count, local_count, global_count; - uint8 *param_types, *local_types, local_type, global_type, mem_offset_type; + uint8 *param_types, *local_types, local_type, global_type, mem_offset_type, + table_elem_idx_type; BlockType func_block_type; uint16 *local_offsets, local_offset; uint32 type_idx, func_idx, local_idx, global_idx, table_idx; @@ -10846,6 +10943,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32; #else mem_offset_type = VALUE_TYPE_I32; + table_elem_idx_type = VALUE_TYPE_I32; #endif uint32 memidx; @@ -12005,8 +12103,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif /* skip elem idx */ - POP_I32(); + POP_TBL_ELEM_IDX(); if (type_idx >= module->type_count) { set_error_buf(error_buf, error_buf_size, "unknown type"); @@ -12396,8 +12499,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; } - /* table.get x. tables[x]. [i32] -> [t] */ - /* table.set x. tables[x]. [i32 t] -> [] */ + /* table.get x. tables[x]. [it] -> [t] */ + /* table.set x. tables[x]. [it t] -> [] */ case WASM_OP_TABLE_GET: case WASM_OP_TABLE_SET: { @@ -12428,8 +12531,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (opcode == WASM_OP_TABLE_GET) { - POP_I32(); + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_FAST_INTERP != 0 PUSH_OFFSET_TYPE(decl_ref_type); #endif @@ -12440,7 +12548,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, POP_OFFSET_TYPE(decl_ref_type); #endif POP_TYPE(decl_ref_type); - POP_I32(); + POP_TBL_ELEM_IDX(); } #if WASM_ENABLE_WAMR_COMPILER != 0 @@ -14723,7 +14831,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif POP_I32(); POP_I32(); - POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_WAMR_COMPILER != 0 module->is_ref_types_used = true; @@ -14748,7 +14861,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } case WASM_OP_TABLE_COPY: { - uint8 src_type, dst_type; + uint8 src_type, dst_type, src_tbl_idx_type, + dst_tbl_idx_type, min_tbl_idx_type; #if WASM_ENABLE_GC != 0 WASMRefType *src_ref_type = NULL, *dst_ref_type = NULL; #endif @@ -14794,9 +14908,31 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, dst_tbl_idx); emit_uint32(loader_ctx, src_tbl_idx); #endif - POP_I32(); - POP_I32(); - POP_I32(); + +#if WASM_ENABLE_MEMORY64 != 0 + src_tbl_idx_type = is_table_64bit(module, src_tbl_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; + dst_tbl_idx_type = is_table_64bit(module, dst_tbl_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; + min_tbl_idx_type = + (src_tbl_idx_type == VALUE_TYPE_I32 + || dst_tbl_idx_type == VALUE_TYPE_I32) + ? VALUE_TYPE_I32 + : VALUE_TYPE_I64; +#else + src_tbl_idx_type = VALUE_TYPE_I32; + dst_tbl_idx_type = VALUE_TYPE_I32; + min_tbl_idx_type = VALUE_TYPE_I32; +#endif + + table_elem_idx_type = min_tbl_idx_type; + POP_TBL_ELEM_IDX(); + table_elem_idx_type = src_tbl_idx_type; + POP_TBL_ELEM_IDX(); + table_elem_idx_type = dst_tbl_idx_type; + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_WAMR_COMPILER != 0 module->is_ref_types_used = true; @@ -14816,7 +14952,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif - PUSH_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + PUSH_TBL_ELEM_IDX(); #if WASM_ENABLE_WAMR_COMPILER != 0 module->is_ref_types_used = true; @@ -14865,15 +15006,20 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif - POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_FAST_INTERP != 0 POP_OFFSET_TYPE(decl_type); #endif POP_TYPE(decl_type); if (opcode1 == WASM_OP_TABLE_GROW) - PUSH_I32(); + PUSH_TBL_ELEM_IDX(); else - POP_I32(); + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_WAMR_COMPILER != 0 module->is_ref_types_used = true; diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 968eaf0096..0d1f837049 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -33,12 +33,25 @@ has_module_memory64(WASMModule *module) /* TODO: multi-memories for now assuming the memory idx type is consistent * across multi-memories */ if (module->import_memory_count > 0) - return !!(module->import_memories[0].u.mem_type.flags & MEMORY64_FLAG); + return !!(module->import_memories[0].u.memory.mem_type.flags + & MEMORY64_FLAG); else if (module->memory_count > 0) return !!(module->memories[0].flags & MEMORY64_FLAG); return false; } + +static bool +is_table_64bit(WASMModule *module, uint32 table_idx) +{ + if (table_idx < module->import_table_count) + return !!(module->import_tables[table_idx].u.table.table_type.flags + & TABLE64_FLAG); + else + return !!(module->tables[table_idx].table_type.flags & TABLE64_FLAG); + + return false; +} #endif static void @@ -577,11 +590,15 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } static void -adjust_table_max_size(uint32 init_size, uint32 max_size_flag, uint32 *max_size) +adjust_table_max_size(bool is_table64, uint32 init_size, uint32 max_size_flag, + uint32 *max_size) { uint32 default_max_size = init_size * 2 > WASM_TABLE_MAX_SIZE ? init_size * 2 : WASM_TABLE_MAX_SIZE; + /* TODO: current still use UINT32_MAX as upper limit for table size to keep + * ABI unchanged */ + (void)is_table64; if (max_size_flag) { /* module defines the table limitation */ @@ -642,8 +659,8 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, char *error_buf, uint32 error_buf_size) { const uint8 *p = *p_buf, *p_end = buf_end; - uint32 declare_elem_type = 0, declare_max_size_flag = 0, - declare_init_size = 0, declare_max_size = 0; + uint32 declare_elem_type = 0, table_flag = 0, declare_init_size = 0, + declare_max_size = 0; CHECK_BUF(p, p_end, 1); /* 0x70 or 0x6F */ @@ -654,24 +671,29 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, #endif ); - read_leb_uint32(p, p_end, declare_max_size_flag); + read_leb_uint32(p, p_end, table_flag); + + if (!wasm_table_check_flags(table_flag, error_buf, error_buf_size, false)) { + return false; + } + read_leb_uint32(p, p_end, declare_init_size); - if (declare_max_size_flag & 1) { + if (table_flag & MAX_TABLE_SIZE_FLAG) { read_leb_uint32(p, p_end, declare_max_size); bh_assert(table->table_type.init_size <= table->table_type.max_size); } - adjust_table_max_size(declare_init_size, declare_max_size_flag, - &declare_max_size); + adjust_table_max_size(table_flag & TABLE64_FLAG, declare_init_size, + table_flag & MAX_TABLE_SIZE_FLAG, &declare_max_size); *p_buf = p; - bh_assert( - !((declare_max_size_flag & 1) && declare_init_size > declare_max_size)); + bh_assert(!((table_flag & MAX_TABLE_SIZE_FLAG) + && declare_init_size > declare_max_size)); /* now we believe all declaration are ok */ table->table_type.elem_type = declare_elem_type; table->table_type.init_size = declare_init_size; - table->table_type.flags = declare_max_size_flag; + table->table_type.flags = table_flag; table->table_type.max_size = declare_max_size; return true; } @@ -789,16 +811,22 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMTable *table, p_org = p; read_leb_uint32(p, p_end, table->table_type.flags); bh_assert(p - p_org <= 1); - bh_assert(table->table_type.flags <= 1); (void)p_org; + if (!wasm_table_check_flags(table->table_type.flags, error_buf, + error_buf_size, false)) { + return false; + } + read_leb_uint32(p, p_end, table->table_type.init_size); - if (table->table_type.flags == 1) { + if (table->table_type.flags == MAX_TABLE_SIZE_FLAG) { read_leb_uint32(p, p_end, table->table_type.max_size); bh_assert(table->table_type.init_size <= table->table_type.max_size); } - adjust_table_max_size(table->table_type.init_size, table->table_type.flags, + adjust_table_max_size(table->table_type.flags & TABLE64_FLAG, + table->table_type.init_size, + table->table_type.flags & MAX_TABLE_SIZE_FLAG, &table->table_type.max_size); *p_buf = p; @@ -1575,6 +1603,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end; + uint8 table_elem_idx_type; uint32 table_segment_count, i, table_index, function_count; uint64 total_size; WASMTableSeg *table_segment; @@ -1592,6 +1621,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, table_segment = module->table_segments; for (i = 0; i < table_segment_count; i++, table_segment++) { bh_assert(p < p_end); + table_elem_idx_type = VALUE_TYPE_I32; #if WASM_ENABLE_REF_TYPES != 0 read_leb_uint32(p, p_end, table_segment->mode); @@ -1608,9 +1638,15 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, error_buf, error_buf_size)) return false; +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (!load_init_expr( module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, error_buf, error_buf_size)) + table_elem_idx_type, error_buf, error_buf_size)) return false; if (table_segment->mode == 0) { @@ -1646,9 +1682,15 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, &table_segment->table_index, error_buf, error_buf_size)) return false; +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (!load_init_expr( module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, error_buf, error_buf_size)) + table_elem_idx_type, error_buf, error_buf_size)) return false; if (!load_elem_type(&p, p_end, &table_segment->elem_type, table_segment->mode == 2 ? true : false, @@ -1691,13 +1733,29 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, &table_segment->table_index, error_buf, error_buf_size)) return false; +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (!load_init_expr(module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, error_buf, error_buf_size)) + table_elem_idx_type, error_buf, error_buf_size)) return false; if (!load_func_index_vec(&p, p_end, module, table_segment, error_buf, error_buf_size)) return false; #endif /* WASM_ENABLE_REF_TYPES != 0 */ + +#if WASM_ENABLE_MEMORY64 != 0 + if (table_elem_idx_type == VALUE_TYPE_I64 + && table_segment->base_offset.u.u64 > UINT32_MAX) { + set_error_buf(error_buf, error_buf_size, + "In table64, table base offset can't be " + "larger than UINT32_MAX"); + return false; + } +#endif } } @@ -1781,8 +1839,8 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end, /* This memory_flag is from memory instead of data segment */ uint8 memory_flag; if (module->import_memory_count > 0) { - memory_flag = - module->import_memories[mem_index].u.mem_type.flags; + memory_flag = module->import_memories[mem_index] + .u.memory.mem_type.flags; } else { memory_flag = @@ -2158,6 +2216,9 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf, option.enable_memory_profiling = true; option.enable_stack_estimation = true; #endif +#if WASM_ENABLE_SHARED_HEAP != 0 + option.enable_shared_heap = true; +#endif module->comp_ctx = aot_create_comp_context(module->comp_data, &option); if (!module->comp_ctx) { @@ -2948,6 +3009,12 @@ load_from_sections(WASMModule *module, WASMSection *sections, } } +#if WASM_ENABLE_MEMORY64 != 0 + if (!check_memory64_flags_consistency(module, error_buf, error_buf_size, + false)) + return false; +#endif + calculate_global_data_offset(module); #if WASM_ENABLE_FAST_JIT != 0 @@ -5214,6 +5281,13 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, } while (0) #define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET() +#define PUSH_TBL_ELEM_IDX() \ + do { \ + if (!(wasm_loader_push_frame_ref(loader_ctx, table_elem_idx_type, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #define POP_MEM_OFFSET() \ do { \ if (!wasm_loader_pop_frame_ref_offset(loader_ctx, mem_offset_type, \ @@ -5221,6 +5295,13 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, goto fail; \ } while (0) +#define POP_TBL_ELEM_IDX() \ + do { \ + if (!(wasm_loader_pop_frame_ref(loader_ctx, table_elem_idx_type, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #define POP_AND_PUSH(type_pop, type_push) \ do { \ if (!(wasm_loader_push_pop_frame_ref_offset( \ @@ -5284,6 +5365,13 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, #define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET() +#define PUSH_TBL_ELEM_IDX() \ + do { \ + if (!(wasm_loader_push_frame_ref(loader_ctx, table_elem_idx_type, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #define POP_I32() \ do { \ if (!(wasm_loader_pop_frame_ref(loader_ctx, VALUE_TYPE_I32, error_buf, \ @@ -5326,6 +5414,13 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, goto fail; \ } while (0) +#define POP_TBL_ELEM_IDX() \ + do { \ + if (!(wasm_loader_pop_frame_ref(loader_ctx, table_elem_idx_type, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #define POP_AND_PUSH(type_pop, type_push) \ do { \ if (!(wasm_loader_push_pop_frame_ref(loader_ctx, 1, type_push, \ @@ -5945,7 +6040,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org; uint32 param_count, local_count, global_count; - uint8 *param_types, *local_types, local_type, global_type, mem_offset_type; + uint8 *param_types, *local_types, local_type, global_type, mem_offset_type, + table_elem_idx_type; BlockType func_block_type; uint16 *local_offsets, local_offset; uint32 count, local_idx, global_idx, u32, align, i, memidx; @@ -5976,6 +6072,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32; #else mem_offset_type = VALUE_TYPE_I32; + table_elem_idx_type = VALUE_TYPE_I32; #endif global_count = module->import_global_count + module->global_count; @@ -6588,8 +6685,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif /* skip elem idx */ - POP_I32(); + POP_TBL_ELEM_IDX(); bh_assert(type_idx < module->type_count); @@ -6865,8 +6967,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; } - /* table.get x. tables[x]. [i32] -> [t] */ - /* table.set x. tables[x]. [i32 t] -> [] */ + /* table.get x. tables[x]. [it] -> [t] */ + /* table.set x. tables[x]. [it t] -> [] */ case WASM_OP_TABLE_GET: case WASM_OP_TABLE_SET: { @@ -6882,8 +6984,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (opcode == WASM_OP_TABLE_GET) { - POP_I32(); + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_FAST_INTERP != 0 PUSH_OFFSET_TYPE(decl_ref_type); #endif @@ -6894,7 +7001,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, POP_OFFSET_TYPE(decl_ref_type); #endif POP_TYPE(decl_ref_type); - POP_I32(); + POP_TBL_ELEM_IDX(); } break; } @@ -7819,7 +7926,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif POP_I32(); POP_I32(); - POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + POP_TBL_ELEM_IDX(); break; } case WASM_OP_ELEM_DROP: @@ -7838,7 +7950,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_TABLE_COPY: { uint8 src_ref_type, dst_ref_type; - uint32 src_tbl_idx, dst_tbl_idx; + uint32 src_tbl_idx, dst_tbl_idx, src_tbl_idx_type, + dst_tbl_idx_type, min_tbl_idx_type; read_leb_uint32(p, p_end, src_tbl_idx); if (!get_table_elem_type(module, src_tbl_idx, @@ -7862,9 +7975,31 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, src_tbl_idx); emit_uint32(loader_ctx, dst_tbl_idx); #endif - POP_I32(); - POP_I32(); - POP_I32(); + +#if WASM_ENABLE_MEMORY64 != 0 + src_tbl_idx_type = is_table_64bit(module, src_tbl_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; + dst_tbl_idx_type = is_table_64bit(module, dst_tbl_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; + min_tbl_idx_type = + (src_tbl_idx_type == VALUE_TYPE_I32 + || dst_tbl_idx_type == VALUE_TYPE_I32) + ? VALUE_TYPE_I32 + : VALUE_TYPE_I64; +#else + src_tbl_idx_type = VALUE_TYPE_I32; + dst_tbl_idx_type = VALUE_TYPE_I32; + min_tbl_idx_type = VALUE_TYPE_I32; +#endif + + table_elem_idx_type = min_tbl_idx_type; + POP_TBL_ELEM_IDX(); + table_elem_idx_type = src_tbl_idx_type; + POP_TBL_ELEM_IDX(); + table_elem_idx_type = dst_tbl_idx_type; + POP_TBL_ELEM_IDX(); break; } case WASM_OP_TABLE_SIZE: @@ -7882,7 +8017,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif - PUSH_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + PUSH_TBL_ELEM_IDX(); break; } case WASM_OP_TABLE_GROW: @@ -7914,15 +8054,20 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif - POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_FAST_INTERP != 0 POP_OFFSET_TYPE(decl_ref_type); #endif POP_TYPE(decl_ref_type); if (opcode1 == WASM_OP_TABLE_GROW) - PUSH_I32(); + PUSH_TBL_ELEM_IDX(); else - POP_I32(); + PUSH_TBL_ELEM_IDX(); break; } #endif /* WASM_ENABLE_REF_TYPES */ diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index e4142ab88c..accb403196 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -678,6 +678,8 @@ tables_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, uninitialized elements */ #endif + table->is_table64 = import->u.table.table_type.flags & TABLE64_FLAG; + #if WASM_ENABLE_MULTI_MODULE != 0 *table_linked = table_inst_linked; if (table_inst_linked != NULL) { @@ -736,6 +738,7 @@ tables_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, /* For GC, all elements have already been set to NULL_REF (0) as uninitialized elements */ #endif + table->is_table64 = module->tables[i].table_type.flags & TABLE64_FLAG; table->elem_type = module->tables[i].table_type.elem_type; #if WASM_ENABLE_GC != 0 table->elem_ref_type.elem_ref_type = @@ -1364,6 +1367,17 @@ export_functions_deinstantiate(WASMExportFuncInstance *functions) wasm_runtime_free(functions); } +static int +cmp_export_func_inst(const void *a, const void *b) +{ + const WASMExportFuncInstance *export_func1 = + (const WASMExportFuncInstance *)a; + const WASMExportFuncInstance *export_func2 = + (const WASMExportFuncInstance *)b; + + return strcmp(export_func1->name, export_func2->name); +} + /** * Instantiate export functions in a module. */ @@ -1392,6 +1406,9 @@ export_functions_instantiate(const WASMModule *module, } bh_assert((uint32)(export_func - export_funcs) == export_func_count); + + qsort(export_funcs, export_func_count, sizeof(WASMExportFuncInstance), + cmp_export_func_inst); return export_funcs; } @@ -1594,8 +1611,12 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, if (is_sub_inst) { bh_assert(exec_env_main); #ifdef OS_ENABLE_HW_BOUND_CHECK - bh_assert(exec_env_tls == exec_env_main); - (void)exec_env_tls; + /* May come from pthread_create_wrapper, thread_spawn_wrapper and + wasm_cluster_spawn_exec_env. If it comes from the former two, + the exec_env_tls must be not NULL and equal to exec_env_main, + else if it comes from the last one, it may be NULL. */ + if (exec_env_tls) + bh_assert(exec_env_tls == exec_env_main); #endif exec_env = exec_env_main; @@ -2791,6 +2812,14 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, } } +#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_SHARED_HEAP != 0 +#if UINTPTR_MAX == UINT64_MAX + module_inst->e->shared_heap_start_off.u64 = UINT64_MAX; +#else + module_inst->e->shared_heap_start_off.u32[0] = UINT32_MAX; +#endif +#endif + #if WASM_ENABLE_GC != 0 /* Initialize the table data with init expr */ for (i = 0; i < module->table_count; i++) { @@ -3405,11 +3434,20 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) WASMFunctionInstance * wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name) { - uint32 i; - for (i = 0; i < module_inst->export_func_count; i++) - if (!strcmp(module_inst->export_functions[i].name, name)) - return module_inst->export_functions[i].function; - return NULL; + WASMExportFuncInstance key = { .name = (char *)name }; + WASMExportFuncInstance *export_func_inst; + + if (!module_inst->export_functions) + return NULL; + + export_func_inst = bsearch( + &key, module_inst->export_functions, module_inst->export_func_count, + sizeof(WASMExportFuncInstance), cmp_export_func_inst); + + if (!export_func_inst) + return NULL; + + return export_func_inst->function; } WASMMemoryInstance * diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index e46b63cda1..00e9ad107f 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -92,6 +92,15 @@ typedef union { uint32 u32[2]; } MemBound; +typedef struct WASMSharedHeap { + struct WASMSharedHeap *next; + void *heap_handle; + uint8 *base_addr; + uint64 size; + uint64 start_off_mem64; + uint64 start_off_mem32; +} WASMSharedHeap; + struct WASMMemoryInstance { /* Module type */ uint32 module_type; @@ -157,7 +166,8 @@ struct WASMMemoryInstance { struct WASMTableInstance { /* The element type */ uint8 elem_type; - uint8 __padding__[7]; + uint8 is_table64; + uint8 __padding__[6]; union { #if WASM_ENABLE_GC != 0 WASMRefType *elem_ref_type; @@ -353,6 +363,19 @@ typedef struct WASMModuleInstanceExtra { uint32 max_aux_stack_used; #endif +#if WASM_ENABLE_SHARED_HEAP != 0 + WASMSharedHeap *shared_heap; +#if WASM_ENABLE_JIT != 0 + /* + * Adjusted shared heap based addr to simple the calculation + * in the aot code. The value is: + * shared_heap->base_addr - shared_heap->start_off + */ + uint8 *shared_heap_base_addr_adj; + MemBound shared_heap_start_off; +#endif +#endif + #if WASM_ENABLE_DEBUG_INTERP != 0 \ || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ && WASM_ENABLE_LAZY_JIT != 0) diff --git a/core/iwasm/libraries/lib-pthread/lib_pthread.cmake b/core/iwasm/libraries/lib-pthread/lib_pthread.cmake index 134edf0e87..a1d183ee1e 100644 --- a/core/iwasm/libraries/lib-pthread/lib_pthread.cmake +++ b/core/iwasm/libraries/lib-pthread/lib_pthread.cmake @@ -6,7 +6,7 @@ set (LIB_PTHREAD_DIR ${CMAKE_CURRENT_LIST_DIR}) add_definitions (-DWASM_ENABLE_LIB_PTHREAD=1) if (WAMR_BUILD_LIB_PTHREAD_SEMAPHORE EQUAL 1) -add_definitions (-DWASM_ENABLE_LIB_PTHREAD_SEMAPHORE=1) + add_definitions (-DWASM_ENABLE_LIB_PTHREAD_SEMAPHORE=1) endif() include_directories(${LIB_PTHREAD_DIR}) diff --git a/core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c b/core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c index 427bfd6569..3bb6bc6b76 100644 --- a/core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c +++ b/core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c @@ -7,8 +7,13 @@ #include "bh_log.h" #include "wasm_export.h" #include "../interpreter/wasm.h" -#if !defined(_DEFAULT_SOURCE) && !defined(BH_PLATFORM_LINUX_SGX) -#include "sys/syscall.h" + +#if defined(__linux__) +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) +#define HAVE_SYSCALL_GETRANDOM +#include +#endif #endif /* clang-format off */ @@ -168,12 +173,21 @@ statbuf_native2app(const struct stat *statbuf_native, statbuf_app->st_blksize = (unsigned)statbuf_native->st_blksize; statbuf_app->st_blocks = (unsigned)statbuf_native->st_blocks; statbuf_app->st_ino = (int64)statbuf_native->st_ino; +#if defined(__APPLE__) + statbuf_app->st_atim.tv_sec = (int)statbuf_native->st_atimespec.tv_sec; + statbuf_app->st_atim.tv_nsec = (int)statbuf_native->st_atimespec.tv_nsec; + statbuf_app->st_mtim.tv_sec = (int)statbuf_native->st_mtimespec.tv_sec; + statbuf_app->st_mtim.tv_nsec = (int)statbuf_native->st_mtimespec.tv_nsec; + statbuf_app->st_ctim.tv_sec = (int)statbuf_native->st_ctimespec.tv_sec; + statbuf_app->st_ctim.tv_nsec = (int)statbuf_native->st_ctimespec.tv_nsec; +#else statbuf_app->st_atim.tv_sec = (int)statbuf_native->st_atim.tv_sec; statbuf_app->st_atim.tv_nsec = (int)statbuf_native->st_atim.tv_nsec; statbuf_app->st_mtim.tv_sec = (int)statbuf_native->st_mtim.tv_sec; statbuf_app->st_mtim.tv_nsec = (int)statbuf_native->st_mtim.tv_nsec; statbuf_app->st_ctim.tv_sec = (int)statbuf_native->st_ctim.tv_sec; statbuf_app->st_ctim.tv_nsec = (int)statbuf_native->st_ctim.tv_nsec; +#endif } static int @@ -261,10 +275,10 @@ getentropy_wrapper(wasm_exec_env_t exec_env, void *buffer, uint32 length) { if (buffer == NULL) return -1; -#if defined(_DEFAULT_SOURCE) || defined(BH_PLATFORM_LINUX_SGX) - return getentropy(buffer, length); -#else +#if defined(HAVE_SYSCALL_GETRANDOM) return syscall(SYS_getrandom, buffer, length, 0); +#else + return getentropy(buffer, length); #endif } diff --git a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c index aef8f17035..6d057a6a18 100644 --- a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c +++ b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c @@ -1022,8 +1022,8 @@ execute_interruptible_poll_oneoff( uint32 i; const __wasi_timestamp_t timeout = get_timeout_for_poll_oneoff( - in, nsubscriptions), - time_quant = 1e9; + in, (uint32)nsubscriptions), + time_quant = (__wasi_timestamp_t)1e9; const uint64 size_to_copy = nsubscriptions * (uint64)sizeof(wasi_subscription_t); __wasi_subscription_t *in_copy = NULL; @@ -1034,12 +1034,13 @@ execute_interruptible_poll_oneoff( return __WASI_ENOMEM; } - bh_memcpy_s(in_copy, size_to_copy, in, size_to_copy); + bh_memcpy_s(in_copy, (uint32)size_to_copy, in, (uint32)size_to_copy); while (timeout == (__wasi_timestamp_t)-1 || elapsed <= timeout) { /* update timeout for clock subscription events */ update_clock_subscription_data( - in_copy, nsubscriptions, min_uint64(time_quant, timeout - elapsed)); + in_copy, (uint32)nsubscriptions, + min_uint64(time_quant, timeout - elapsed)); err = wasmtime_ssp_poll_oneoff(exec_env, curfds, in_copy, out, nsubscriptions, nevents); elapsed += time_quant; diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index a313b9be54..d26c460fed 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -3130,7 +3130,7 @@ compare_address(const struct addr_pool *addr_pool_entry, } addr_size = 16; } - max_addr_mask = addr_size * 8; + max_addr_mask = (uint8)(addr_size * 8); /* IPv4 0.0.0.0 or IPv6 :: means any address */ if (basebuf[0] == 0 && !memcmp(basebuf, basebuf + 1, addr_size - 1)) { diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/refcount.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/refcount.h index 03b4b87ac3..79b16cc175 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/refcount.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/refcount.h @@ -132,6 +132,35 @@ refcount_release(struct refcount *r) #error "Reference counter isn't implemented" #endif /* end of __GNUC_PREREQ (4.7) */ +#elif defined(_MSC_VER) + +/* Simple reference counter. */ +struct LOCKABLE refcount { + LONG count; +}; + +/* Initialize the reference counter. */ +static inline void +refcount_init(struct refcount *r, unsigned int count) +{ + InterlockedExchange(&r->count, (LONG)count); +} + +/* Increment the reference counter. */ +static inline void +refcount_acquire(struct refcount *r) +{ + InterlockedIncrement(&r->count); +} + +/* Decrement the reference counter, returning whether the reference + dropped to zero. */ +static inline bool +refcount_release(struct refcount *r) +{ + return InterlockedDecrement(&r->count) == 0 ? true : false; +} + #else /* else of CONFIG_HAS_STD_ATOMIC */ #error "Reference counter isn't implemented" #endif /* end of CONFIG_HAS_STD_ATOMIC */ diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index 4ef29ccdbd..8296772131 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -70,9 +70,11 @@ #endif #if !defined(BH_PLATFORM_LINUX_SGX) + /* Clang's __GNUC_PREREQ macro has a different meaning than GCC one, so we have to handle this case specially */ #if defined(__clang__) + /* Clang provides stdatomic.h since 3.6.0 See https://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html */ #if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) @@ -80,7 +82,9 @@ See https://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html */ #else #define CONFIG_HAS_STD_ATOMIC 0 #endif + #elif defined(__GNUC_PREREQ) + /* Even though older versions of GCC support C11, atomics were not implemented until 4.9. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58016 */ @@ -89,11 +93,21 @@ not implemented until 4.9. See #else /* else of __GNUC_PREREQ(4, 9) */ #define CONFIG_HAS_STD_ATOMIC 0 #endif /* end of __GNUC_PREREQ(4, 9) */ -#else /* else of defined(__GNUC_PREREQ) */ + +#elif defined(_MSC_VER) + +#define CONFIG_HAS_STD_ATOMIC 0 + +#else + #define CONFIG_HAS_STD_ATOMIC 1 -#endif /* end of defined(__GNUC_PREREQ) */ -#else /* else of !defined(BH_PLATFORM_LINUX_SGX) */ + +#endif /* end of defined(__clang__) */ + +#else /* else of !defined(BH_PLATFORM_LINUX_SGX) */ + #define CONFIG_HAS_STD_ATOMIC 0 + #endif /* end of !defined(BH_PLATFORM_LINUX_SGX) */ -#endif +#endif /* end of SSP_CONFIG_H */ diff --git a/core/iwasm/libraries/shared-heap/shared_heap.cmake b/core/iwasm/libraries/shared-heap/shared_heap.cmake new file mode 100644 index 0000000000..ec91dabcd0 --- /dev/null +++ b/core/iwasm/libraries/shared-heap/shared_heap.cmake @@ -0,0 +1,8 @@ +# Copyright (C) 2024 Xiaomi Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +set (LIB_SHARED_HEAP ${CMAKE_CURRENT_LIST_DIR}) +add_definitions (-DWASM_ENABLE_SHARED_HEAP=1) +include_directories(${LIB_SHARED_HEAP_DIR}) +file (GLOB source_all ${LIB_SHARED_HEAP}/*.c) +set (LIB_SHARED_HEAP_SOURCE ${source_all}) \ No newline at end of file diff --git a/core/iwasm/libraries/shared-heap/shared_heap_wrapper.c b/core/iwasm/libraries/shared-heap/shared_heap_wrapper.c new file mode 100644 index 0000000000..b7b78307ae --- /dev/null +++ b/core/iwasm/libraries/shared-heap/shared_heap_wrapper.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024 Xiaomi Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "bh_common.h" +#include "bh_log.h" +#include "wasm_export.h" +#include "../interpreter/wasm.h" +#include "../common/wasm_runtime_common.h" +/* clang-format off */ +#define validate_native_addr(addr, size) \ + wasm_runtime_validate_native_addr(module_inst, addr, size) + +#define module_shared_malloc(size, p_native_addr) \ + wasm_runtime_shared_heap_malloc(module_inst, size, p_native_addr) + +#define module_shared_free(offset) \ + wasm_runtime_shared_heap_free(module_inst, offset) +/* clang-format on */ + +static uint32 +shared_heap_malloc_wrapper(wasm_exec_env_t exec_env, uint32 size) +{ + wasm_module_inst_t module_inst = get_module_inst(exec_env); + return (uint32)module_shared_malloc((uint64)size, NULL); +} + +static void +shared_heap_free_wrapper(wasm_exec_env_t exec_env, void *ptr) +{ + wasm_module_inst_t module_inst = get_module_inst(exec_env); + + if (!validate_native_addr(ptr, (uint64)sizeof(uintptr_t))) { + LOG_WARNING("Invalid app address"); + return; + } + + module_shared_free(addr_native_to_app(ptr)); +} + +/* clang-format off */ +#define REG_NATIVE_FUNC(func_name, signature) \ + { #func_name, func_name##_wrapper, signature, NULL } +/* clang-format on */ + +static NativeSymbol native_symbols_shared_heap[] = { + REG_NATIVE_FUNC(shared_heap_malloc, "(i)i"), + REG_NATIVE_FUNC(shared_heap_free, "(*)"), +}; + +uint32 +get_lib_shared_heap_export_apis(NativeSymbol **p_shared_heap_apis) +{ + *p_shared_heap_apis = native_symbols_shared_heap; + return sizeof(native_symbols_shared_heap) / sizeof(NativeSymbol); +} diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index ebb56ba7ca..55e0526c3b 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -1402,6 +1402,82 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst, } } +#if WASM_ENABLE_SHARED_HEAP != 0 +static void +attach_shared_heap_visitor(void *node, void *heap) +{ + WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; + WASMModuleInstanceCommon *module_inst = get_module_inst(curr_exec_env); + + wasm_runtime_attach_shared_heap_internal(module_inst, heap); +} + +static void +detach_shared_heap_visitor(void *node, void *heap) +{ + WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; + WASMModuleInstanceCommon *module_inst = get_module_inst(curr_exec_env); + + (void)heap; + wasm_runtime_detach_shared_heap_internal(module_inst); +} + +bool +wasm_cluster_attach_shared_heap(WASMModuleInstanceCommon *module_inst, + WASMSharedHeap *heap) +{ + WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst); + + if (exec_env == NULL) { + /* Maybe threads have not been started yet. */ + return wasm_runtime_attach_shared_heap_internal(module_inst, heap); + } + else { + WASMCluster *cluster; + + cluster = wasm_exec_env_get_cluster(exec_env); + bh_assert(cluster); + + os_mutex_lock(&cluster->lock); + /* Try attaching shared heap to this module instance first + to ensure that we can attach it to all other instances. */ + if (!wasm_runtime_attach_shared_heap_internal(module_inst, heap)) { + os_mutex_unlock(&cluster->lock); + return false; + } + /* Detach the shared heap so it can be attached again. */ + wasm_runtime_detach_shared_heap_internal(module_inst); + traverse_list(&cluster->exec_env_list, attach_shared_heap_visitor, + heap); + os_mutex_unlock(&cluster->lock); + } + + return true; +} + +void +wasm_cluster_detach_shared_heap(WASMModuleInstanceCommon *module_inst) +{ + WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst); + + if (exec_env == NULL) { + /* Maybe threads have not been started yet. */ + wasm_runtime_detach_shared_heap_internal(module_inst); + } + else { + WASMCluster *cluster; + + cluster = wasm_exec_env_get_cluster(exec_env); + bh_assert(cluster); + + os_mutex_lock(&cluster->lock); + traverse_list(&cluster->exec_env_list, detach_shared_heap_visitor, + NULL); + os_mutex_unlock(&cluster->lock); + } +} +#endif + #if WASM_ENABLE_MODULE_INST_CONTEXT != 0 struct inst_set_context_data { void *key; diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index 7ad6c772aa..90d97b0be7 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -11,6 +11,9 @@ #include "wasm_export.h" #include "../interpreter/wasm.h" #include "../common/wasm_runtime_common.h" +#if WASM_ENABLE_SHARED_HEAP != 0 +#include "../common/wasm_memory.h" +#endif #ifdef __cplusplus extern "C" { @@ -167,6 +170,15 @@ wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key, bool wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env); +#if WASM_ENABLE_SHARED_HEAP != 0 +bool +wasm_cluster_attach_shared_heap(WASMModuleInstanceCommon *module_inst, + WASMSharedHeap *heap); + +void +wasm_cluster_detach_shared_heap(WASMModuleInstanceCommon *module_inst); +#endif + #if WASM_ENABLE_DEBUG_INTERP != 0 #define WAMR_SIG_TRAP (5) #define WAMR_SIG_STOP (19) diff --git a/core/iwasm/libraries/wasi-nn/README.md b/core/iwasm/libraries/wasi-nn/README.md index 5536f6d57b..99a7664676 100644 --- a/core/iwasm/libraries/wasi-nn/README.md +++ b/core/iwasm/libraries/wasi-nn/README.md @@ -103,7 +103,6 @@ docker run \ wasi-nn-cpu \ --dir=/ \ --env="TARGET=cpu" \ - --native-lib=/lib/libwasi-nn-tflite.so \ /assets/test_tensorflow.wasm ``` @@ -119,7 +118,6 @@ docker run \ wasi-nn-nvidia-gpu \ --dir=/ \ --env="TARGET=gpu" \ - --native-lib=/lib/libwasi-nn-tflite.so \ /assets/test_tensorflow.wasm ``` @@ -131,7 +129,6 @@ docker run \ wasi-nn-vx-delegate \ --dir=/ \ --env="TARGET=gpu" \ - --native-lib=/lib/libwasi-nn-tflite.so \ /assets/test_tensorflow_quantized.wasm ``` @@ -147,7 +144,6 @@ docker run \ wasi-nn-tpu \ --dir=/ \ --env="TARGET=tpu" \ - --native-lib=/lib/libwasi-nn-tflite.so \ /assets/test_tensorflow_quantized.wasm ``` @@ -155,8 +151,8 @@ docker run \ Supported: -- Graph encoding: `tensorflowlite`. -- Execution target: `cpu`, `gpu` and `tpu`. +- Graph encoding: `tensorflowlite`, `openvino` and `ggml` +- Execution target: `cpu` for all. `gpu` and `tpu` for `tensorflowlite`. - Tensor type: `fp32`. ## Smoke test diff --git a/core/iwasm/libraries/wasi-nn/cmake/Findcjson.cmake b/core/iwasm/libraries/wasi-nn/cmake/Findcjson.cmake index 1136f41adc..6c921bbc93 100644 --- a/core/iwasm/libraries/wasi-nn/cmake/Findcjson.cmake +++ b/core/iwasm/libraries/wasi-nn/cmake/Findcjson.cmake @@ -4,13 +4,21 @@ include(FetchContent) set(CJSON_SOURCE_DIR "${WAMR_ROOT_DIR}/core/deps/cjson") - -FetchContent_Declare( - cjson - GIT_REPOSITORY https://github.com/DaveGamble/cJSON.git - GIT_TAG v1.7.18 - SOURCE_DIR ${CJSON_SOURCE_DIR} -) +if(EXISTS ${CJSON_SOURCE_DIR}) + message("Use existed source code under ${CJSON_SOURCE_DIR}") + FetchContent_Declare( + cjson + SOURCE_DIR ${CJSON_SOURCE_DIR} + ) +else() + message("download source code and store it at ${CJSON_SOURCE_DIR}") + FetchContent_Declare( + cjson + GIT_REPOSITORY https://github.com/DaveGamble/cJSON.git + GIT_TAG v1.7.18 + SOURCE_DIR ${CJSON_SOURCE_DIR} + ) +endif() set(ENABLE_CJSON_TEST OFF CACHE INTERNAL "Turn off tests") set(ENABLE_CJSON_UNINSTALL OFF CACHE INTERNAL "Turn off uninstall to avoid targets conflict") diff --git a/core/iwasm/libraries/wasi-nn/cmake/Findllamacpp.cmake b/core/iwasm/libraries/wasi-nn/cmake/Findllamacpp.cmake index 431e15db59..8f4f8d1aa7 100644 --- a/core/iwasm/libraries/wasi-nn/cmake/Findllamacpp.cmake +++ b/core/iwasm/libraries/wasi-nn/cmake/Findllamacpp.cmake @@ -4,13 +4,21 @@ include(FetchContent) set(LLAMA_SOURCE_DIR "${WAMR_ROOT_DIR}/core/deps/llama.cpp") - -FetchContent_Declare( - llamacpp - GIT_REPOSITORY https://github.com/ggerganov/llama.cpp.git - GIT_TAG b3573 - SOURCE_DIR ${LLAMA_SOURCE_DIR} -) +if(EXISTS ${LLAMA_SOURCE_DIR}) + message("Use existed source code under ${LLAMA_SOURCE_DIR}") + FetchContent_Declare( + llamacpp + SOURCE_DIR ${LLAMA_SOURCE_DIR} + ) +else() + message("download source code and store it at ${LLAMA_SOURCE_DIR}") + FetchContent_Declare( + llamacpp + GIT_REPOSITORY https://github.com/ggerganov/llama.cpp.git + GIT_TAG b3573 + SOURCE_DIR ${LLAMA_SOURCE_DIR} + ) +endif() set(LLAMA_BUILD_TESTS OFF) set(LLAMA_BUILD_EXAMPLES OFF) diff --git a/core/iwasm/libraries/wasi-nn/cmake/Findtensorflow_lite.cmake b/core/iwasm/libraries/wasi-nn/cmake/Findtensorflow_lite.cmake index 39480741d3..d2b3f74e04 100644 --- a/core/iwasm/libraries/wasi-nn/cmake/Findtensorflow_lite.cmake +++ b/core/iwasm/libraries/wasi-nn/cmake/Findtensorflow_lite.cmake @@ -4,20 +4,32 @@ include(FetchContent) set(TFLITE_SOURCE_DIR "${WAMR_ROOT_DIR}/core/deps/tensorflow-src") +if(EXISTS ${TFLITE_SOURCE_DIR}) + message("Use existed source code under ${TFLITE_SOURCE_DIR}") + FetchContent_Declare( + tensorflow_lite + SOURCE_DIR ${TFLITE_SOURCE_DIR} + SOURCE_SUBDIR tensorflow/lite + ) +else() + message("download source code and store it at ${TFLITE_SOURCE_DIR}") + FetchContent_Declare( + tensorflow_lite + GIT_REPOSITORY https://github.com/tensorflow/tensorflow.git + GIT_TAG v2.12.0 + GIT_SHALLOW ON + GIT_PROGRESS ON + SOURCE_DIR ${TFLITE_SOURCE_DIR} + SOURCE_SUBDIR tensorflow/lite + PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/add_telemetry.patch + ) +endif() -FetchContent_Declare( - tensorflow_lite - GIT_REPOSITORY https://github.com/tensorflow/tensorflow.git - GIT_TAG v2.12.0 - GIT_SHALLOW ON - GIT_PROGRESS ON - SOURCE_DIR ${TFLITE_SOURCE_DIR} - SOURCE_SUBDIR tensorflow/lite -) if(WAMR_BUILD_WASI_NN_ENABLE_GPU EQUAL 1) set(TFLITE_ENABLE_GPU ON) endif() + if (CMAKE_SIZEOF_VOID_P EQUAL 4) set(TFLITE_ENABLE_XNNPACK OFF) endif() diff --git a/core/iwasm/libraries/wasi-nn/cmake/add_telemetry.patch b/core/iwasm/libraries/wasi-nn/cmake/add_telemetry.patch new file mode 100644 index 0000000000..8dbf5c355c --- /dev/null +++ b/core/iwasm/libraries/wasi-nn/cmake/add_telemetry.patch @@ -0,0 +1,12 @@ +diff --git a/tensorflow/lite/CMakeLists.txt b/tensorflow/lite/CMakeLists.txt +index c71a3925ac..39591a3bd7 100644 +--- a/tensorflow/lite/CMakeLists.txt ++++ b/tensorflow/lite/CMakeLists.txt +@@ -493,6 +493,7 @@ set(TFLITE_PROFILER_SRCS + ${TFLITE_SOURCE_DIR}/profiling/root_profiler.h + ${TFLITE_SOURCE_DIR}/profiling/root_profiler.cc + ${TFLITE_SOURCE_DIR}/profiling/telemetry/profiler.cc ++ ${TFLITE_SOURCE_DIR}/profiling/telemetry/telemetry.cc + ) + if(CMAKE_SYSTEM_NAME MATCHES "Android") + list(APPEND TFLITE_PROFILER_SRCS diff --git a/core/iwasm/libraries/wasi-nn/test/Dockerfile.cpu b/core/iwasm/libraries/wasi-nn/test/Dockerfile.cpu index a33bebff51..67bfbfe0e5 100644 --- a/core/iwasm/libraries/wasi-nn/test/Dockerfile.cpu +++ b/core/iwasm/libraries/wasi-nn/test/Dockerfile.cpu @@ -14,19 +14,32 @@ WORKDIR /usr/local/share/ca-certificates/cacert.org RUN wget -qP /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt \ && update-ca-certificates +# need a newer cmake +RUN apt-get purge -y cmake + +ARG CMAKE_VER=3.27.0 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \ + -q -O /tmp/cmake-install.sh \ + && chmod u+x /tmp/cmake-install.sh \ + && mkdir /opt/cmake-${CMAKE_VER} \ + && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \ + && rm /tmp/cmake-install.sh \ + && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin + WORKDIR /home/wamr COPY . . RUN git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt WORKDIR /home/wamr/product-mini/platforms/linux RUN rm -rf build \ - && cmake -S . -B build -DWAMR_BUILD_WASI_NN=1 \ + && cmake -S . -B build\ + -DWAMR_BUILD_WASI_NN=1 -DWAMR_BUILD_WASI_NN_TFLITE=1\ && cmake --build build -j "$(grep -c ^processor /proc/cpuinfo)" FROM ubuntu:22.04 -COPY --from=base /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin/iwasm -COPY --from=base /home/wamr/product-mini/platforms/linux/build/libiwasm.so /lib/libiwasm.so -COPY --from=base /home/wamr/product-mini/platforms/linux/build/libwasi-nn-*.so /lib/ +COPY --from=base /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin +COPY --from=base /home/wamr/product-mini/platforms/linux/build/lib*.so /usr/lib +ENV LD_LIBRARY_PATH=/usr/lib ENTRYPOINT [ "iwasm" ] diff --git a/core/iwasm/libraries/wasi-nn/test/Dockerfile.nvidia-gpu b/core/iwasm/libraries/wasi-nn/test/Dockerfile.nvidia-gpu index 49ee51a15e..8fe82510a6 100644 --- a/core/iwasm/libraries/wasi-nn/test/Dockerfile.nvidia-gpu +++ b/core/iwasm/libraries/wasi-nn/test/Dockerfile.nvidia-gpu @@ -14,14 +14,26 @@ WORKDIR /usr/local/share/ca-certificates/cacert.org RUN wget -qP /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt \ && update-ca-certificates +# need a newer cmake +RUN apt-get purge -y cmake + +ARG CMAKE_VER=3.27.0 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \ + -q -O /tmp/cmake-install.sh \ + && chmod u+x /tmp/cmake-install.sh \ + && mkdir /opt/cmake-${CMAKE_VER} \ + && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \ + && rm /tmp/cmake-install.sh \ + && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin + WORKDIR /home/wamr COPY . . RUN git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt -WORKDIR /home/wamr/product-mini/platforms/linux/build +WORKDIR /home/wamr/product-mini/platforms/linux RUN rm -rf build \ && cmake -S . -B build \ - -DWAMR_BUILD_WASI_NN=1 \ + -DWAMR_BUILD_WASI_NN=1 -DWAMR_BUILD_WASI_NN_TFLITE=1\ -DWAMR_BUILD_WASI_NN_ENABLE_GPU=1 \ && cmake --build build -j "$(grep -c ^processor /proc/cpuinfo)" @@ -40,8 +52,8 @@ RUN mkdir -p /etc/OpenCL/vendors && \ ENV NVIDIA_VISIBLE_DEVICES=all ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility -COPY --from=base /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin/iwasm -COPY --from=base /home/wamr/product-mini/platforms/linux/build/libiwasm.so /lib/libiwasm.so -COPY --from=base /home/wamr/product-mini/platforms/linux/build/libwasi-nn-*.so /lib/ +COPY --from=base /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin +COPY --from=base /home/wamr/product-mini/platforms/linux/build/lib*.so /usr/lib +ENV LD_LIBRARY_PATH=/usr/lib ENTRYPOINT [ "iwasm" ] diff --git a/core/iwasm/libraries/wasi-nn/test/Dockerfile.tpu b/core/iwasm/libraries/wasi-nn/test/Dockerfile.tpu index a0ae29a63f..6a7dc15341 100644 --- a/core/iwasm/libraries/wasi-nn/test/Dockerfile.tpu +++ b/core/iwasm/libraries/wasi-nn/test/Dockerfile.tpu @@ -14,22 +14,35 @@ WORKDIR /usr/local/share/ca-certificates/cacert.org RUN wget -qP /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt \ && update-ca-certificates +# need a newer cmake +RUN apt-get purge -y cmake + +ARG CMAKE_VER=3.27.0 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \ + -q -O /tmp/cmake-install.sh \ + && chmod u+x /tmp/cmake-install.sh \ + && mkdir /opt/cmake-${CMAKE_VER} \ + && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \ + && rm /tmp/cmake-install.sh \ + && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin + WORKDIR /home/wamr COPY . . RUN git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt WORKDIR /home/wamr/product-mini/platforms/linux RUN rm -rf build \ - && cmake -S . -B build -DWAMR_BUILD_WASI_NN=1 \ - -DWAMR_BUILD_WASI_NN=1 \ + && cmake -S . -B build\ + -DWAMR_BUILD_WASI_NN=1\ + -DWAMR_BUILD_WASI_NN_TFLITE=1\ -DWAMR_BUILD_WASI_NN_ENABLE_EXTERNAL_DELEGATE=1 \ -DWAMR_BUILD_WASI_NN_EXTERNAL_DELEGATE_PATH="libedgetpu.so.1.0" \ -DWAMR_BUILD_WASI_NN_ENABLE_GPU=1 \ && cmake --build build -j "$(grep -c ^processor /proc/cpuinfo)" -RUN cp /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin/iwasm \ - && cp /home/wamr/product-mini/platforms/linux/build/libiwasm.so /lib/libiwasm.so \ - && cp /home/wamr/product-mini/platforms/linux/build/libwasi-nn-*.so /lib/ +RUN cp /home/wamr/core/iwasm/libraries/wasi-nn/test/build/iwasm /run/iwasm \ + && cp /home/wamr/product-mini/platforms/linux/build/lib*.so /usr/lib +ENV LD_LIBRARY_PATH=/usr/lib WORKDIR /assets ENTRYPOINT [ "iwasm" ] diff --git a/core/iwasm/libraries/wasi-nn/test/Dockerfile.vx-delegate b/core/iwasm/libraries/wasi-nn/test/Dockerfile.vx-delegate index f078045b94..e05b30119d 100644 --- a/core/iwasm/libraries/wasi-nn/test/Dockerfile.vx-delegate +++ b/core/iwasm/libraries/wasi-nn/test/Dockerfile.vx-delegate @@ -21,6 +21,18 @@ RUN apt-get update && apt-get install -y wget ca-certificates --no-install-recom && update-ca-certificates \ && git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt +# need a newer cmake +RUN apt-get purge -y cmake + +ARG CMAKE_VER=3.27.0 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \ + -q -O /tmp/cmake-install.sh \ + && chmod u+x /tmp/cmake-install.sh \ + && mkdir /opt/cmake-${CMAKE_VER} \ + && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \ + && rm /tmp/cmake-install.sh \ + && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin + # Build TensorFlow Lite VX delegate default built for x86-64 simulator WORKDIR /tmp RUN git clone https://github.com/VeriSilicon/TIM-VX.git tim-vx \ @@ -89,7 +101,6 @@ ENV VSIMULATOR_CONFIG=czl ENV LD_LIBRARY_PATH=/tmp/tim-vx/prebuilt-sdk/x86_64_linux/lib:/usr/local/lib:/lib/x86_64-linux-gnu/:/lib64/:/usr/lib:$LD_LIBRARY_PATH - # Build WASI-NN WORKDIR /home/wamr @@ -102,12 +113,14 @@ RUN cmake \ -DCMAKE_LIBRARY_PATH=${CMAKE_LIBRARY_PATH}:/usr/local/lib/ \ -DCMAKE_INCLUDE_PATH=${CMAKE_INCLUDE_PATH}:/usr/local/include/ \ -DWAMR_BUILD_WASI_NN=1 \ + -DWAMR_BUILD_WASI_NN_TFLITE=1\ -DWAMR_BUILD_WASI_NN_ENABLE_EXT=1 \ -DWASI_NN_EXT_DELEGATE_PATH="/usr/lib/libvx_delegate.so" \ .. RUN make -j "$(grep -c ^processor /proc/cpuinfo)" -RUN cp /home/wamr/core/iwasm/libraries/wasi-nn/test/build/iwasm /run/iwasm +RUN cp /home/wamr/core/iwasm/libraries/wasi-nn/test/build/iwasm /run/iwasm \ + && cp /home/wamr/product-mini/platforms/linux/build/lib*.so /usr/lib ENTRYPOINT [ "/run/iwasm" ] diff --git a/core/iwasm/libraries/wasi-nn/test/build.sh b/core/iwasm/libraries/wasi-nn/test/build.sh index da6cfa5f8e..dda400f161 100755 --- a/core/iwasm/libraries/wasi-nn/test/build.sh +++ b/core/iwasm/libraries/wasi-nn/test/build.sh @@ -8,9 +8,9 @@ CURR_PATH=$(cd $(dirname $0) && pwd -P) # WASM application that uses WASI-NN /opt/wasi-sdk/bin/clang \ + --target=wasm32-wasi \ + -DNN_LOG_LEVEL=1 \ -Wl,--allow-undefined \ - -Wl,--strip-all,--no-entry \ - --sysroot=/opt/wasi-sdk/share/wasi-sysroot \ -I../include -I../src/utils \ -o test_tensorflow.wasm \ test_tensorflow.c utils.c @@ -28,9 +28,9 @@ python3 sum.py cd ${CURR_PATH} /opt/wasi-sdk/bin/clang \ + --target=wasm32-wasi \ + -DNN_LOG_LEVEL=1 \ -Wl,--allow-undefined \ - -Wl,--strip-all,--no-entry \ - --sysroot=/opt/wasi-sdk/share/wasi-sysroot \ -I../include -I../src/utils \ -o test_tensorflow_quantized.wasm \ test_tensorflow_quantized.c utils.c diff --git a/core/iwasm/libraries/wasi-nn/test/requirements.txt b/core/iwasm/libraries/wasi-nn/test/requirements.txt index 177c22c19f..1643b91b00 100644 --- a/core/iwasm/libraries/wasi-nn/test/requirements.txt +++ b/core/iwasm/libraries/wasi-nn/test/requirements.txt @@ -1,2 +1,2 @@ tensorflow==2.12.1 -numpy==1.26.4 +numpy==1.24.4 diff --git a/core/iwasm/libraries/wasi-nn/test/utils.c b/core/iwasm/libraries/wasi-nn/test/utils.c index c499adc5b9..9e43ec9854 100644 --- a/core/iwasm/libraries/wasi-nn/test/utils.c +++ b/core/iwasm/libraries/wasi-nn/test/utils.c @@ -5,6 +5,7 @@ #include "utils.h" #include "logger.h" +#include "wasi_nn.h" #include #include @@ -57,7 +58,7 @@ wasm_load(char *model_name, graph *g, execution_target target) wasi_nn_error wasm_load_by_name(const char *model_name, graph *g) { - wasm_nn_error res = load_by_name(model_name, g); + wasi_nn_error res = load_by_name(model_name, g); return res; } diff --git a/core/shared/platform/windows/platform_internal.h b/core/shared/platform/windows/platform_internal.h index ed021a9aa1..8ff541016a 100644 --- a/core/shared/platform/windows/platform_internal.h +++ b/core/shared/platform/windows/platform_internal.h @@ -6,6 +6,12 @@ #ifndef _PLATFORM_INTERNAL_H #define _PLATFORM_INTERNAL_H +/* + * Suppress the noisy warnings: + * winbase.h: warning C5105: macro expansion producing 'defined' has + * undefined behavior + */ +#pragma warning(disable : 5105) #include #include #include @@ -168,12 +174,13 @@ typedef struct windows_dir_stream { windows_handle *handle; } windows_dir_stream; -typedef windows_handle *os_file_handle; typedef windows_dir_stream *os_dir_stream; -#if WASM_ENABLE_UVWASI != 1 +#if WASM_ENABLE_UVWASI == 0 +typedef windows_handle *os_file_handle; typedef HANDLE os_raw_file_handle; #else +typedef uint32_t os_file_handle; typedef uint32_t os_raw_file_handle; #endif @@ -190,7 +197,11 @@ typedef uint32_t os_raw_file_handle; static inline os_file_handle os_get_invalid_handle(void) { +#if WASM_ENABLE_UVWASI == 0 return NULL; +#else + return -1; +#endif } #ifdef __cplusplus diff --git a/core/shared/platform/windows/shared_platform.cmake b/core/shared/platform/windows/shared_platform.cmake index 502a8a2ed9..c2d74463fb 100644 --- a/core/shared/platform/windows/shared_platform.cmake +++ b/core/shared/platform/windows/shared_platform.cmake @@ -15,6 +15,9 @@ file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1) list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/win_file.c) +elseif (WAMR_BUILD_LIBC_UVWASI EQUAL 1) + # uvwasi doesn't need to compile win_file.c + list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/win_file.c) else() include (${CMAKE_CURRENT_LIST_DIR}/../common/libc-util/platform_common_libc_util.cmake) set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE}) diff --git a/core/shared/platform/windows/win_clock.c b/core/shared/platform/windows/win_clock.c index c96bdfb3b4..ec0bc85664 100644 --- a/core/shared/platform/windows/win_clock.c +++ b/core/shared/platform/windows/win_clock.c @@ -10,6 +10,10 @@ #define NANOSECONDS_PER_SECOND 1000000000ULL #define NANOSECONDS_PER_TICK 100 +extern NTSTATUS +NtQueryTimerResolution(PULONG MinimumResolution, PULONG MaximumResolution, + PULONG CurrentResolution); + static __wasi_errno_t calculate_monotonic_clock_frequency(uint64 *out_frequency) { @@ -54,7 +58,7 @@ os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution) case __WASI_CLOCK_PROCESS_CPUTIME_ID: case __WASI_CLOCK_THREAD_CPUTIME_ID: { -#if WINAPI_PARTITION_DESKTOP +#if WINAPI_PARTITION_DESKTOP && WASM_ENABLE_WAMR_COMPILER == 0 ULONG maximum_time; ULONG minimum_time; ULONG current_time; @@ -140,4 +144,4 @@ os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision, default: return __WASI_EINVAL; } -} \ No newline at end of file +} diff --git a/core/shared/platform/windows/win_socket.c b/core/shared/platform/windows/win_socket.c index b19e5b0976..8d61c45ccc 100644 --- a/core/shared/platform/windows/win_socket.c +++ b/core/shared/platform/windows/win_socket.c @@ -182,8 +182,8 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr, (*sock)->type = windows_handle_type_socket; (*sock)->access_mode = windows_access_mode_read | windows_access_mode_write; (*sock)->fdflags = 0; - (*sock)->raw.socket = - accept(server_sock->raw.socket, (struct sockaddr *)&addr_tmp, &len); + (*sock)->raw.socket = accept(server_sock->raw.socket, + (struct sockaddr *)&addr_tmp, (int *)&len); if ((*sock)->raw.socket == INVALID_SOCKET) { BH_FREE(*sock); diff --git a/core/shared/platform/windows/win_util.h b/core/shared/platform/windows/win_util.h index 033c393b59..7fda508c72 100644 --- a/core/shared/platform/windows/win_util.h +++ b/core/shared/platform/windows/win_util.h @@ -7,7 +7,13 @@ #define _WIN_UTIL_H #include "platform_wasi_types.h" -#include "windows.h" +/* + * Suppress the noisy warnings: + * winbase.h: warning C5105: macro expansion producing 'defined' has + * undefined behavior + */ +#pragma warning(disable : 5105) +#include __wasi_timestamp_t convert_filetime_to_wasi_timestamp(LPFILETIME filetime); @@ -23,4 +29,4 @@ convert_windows_error_code(DWORD windows_error_code); __wasi_errno_t convert_winsock_error_code(int error_code); -#endif /* end of _WIN_UTIL_H */ \ No newline at end of file +#endif /* end of _WIN_UTIL_H */ diff --git a/core/version.h b/core/version.h index 4e2cbaefc5..4fe37e2d76 100644 --- a/core/version.h +++ b/core/version.h @@ -6,6 +6,6 @@ #ifndef _WAMR_VERSION_H_ #define _WAMR_VERSION_H_ #define WAMR_VERSION_MAJOR 2 -#define WAMR_VERSION_MINOR 1 -#define WAMR_VERSION_PATCH 2 +#define WAMR_VERSION_MINOR 2 +#define WAMR_VERSION_PATCH 0 #endif diff --git a/doc/build_wamr.md b/doc/build_wamr.md index 2adb17f6a1..4537ee0841 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -300,6 +300,22 @@ Currently we only profile the memory consumption of module, module_instance and wasm_runtime_get_context ``` +#### **Shared heap among wasm apps and host native** +- **WAMR_BUILD_SHARED_HEAP**=1/0, default to disable if not set +> Note: If it is enabled, allow to create one or more shared heaps, and attach one to a module instance, the belows APIs ared provided: +```C + wasm_runtime_create_shared_heap + wasm_runtime_attach_shared_heap + wasm_runtime_detach_shared_heap + wasm_runtime_shared_heap_malloc + wasm_runtime_shared_heap_free +``` +And the wasm app can calls below APIs to allocate/free memory from/to the shared heap if it is attached to the app's module instance: +```C + void *shared_heap_malloc(); + void shared_heap_free(void *ptr); +``` + **Combination of configurations:** We can combine the configurations. For example, if we want to disable interpreter, enable AOT and WASI, we can run command: diff --git a/product-mini/platforms/windows/CMakeLists.txt b/product-mini/platforms/windows/CMakeLists.txt index 02aa3f31b4..40e925b16a 100644 --- a/product-mini/platforms/windows/CMakeLists.txt +++ b/product-mini/platforms/windows/CMakeLists.txt @@ -52,9 +52,9 @@ if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN) set (WAMR_BUILD_LIBC_BUILTIN 1) endif () -if (NOT DEFINED WAMR_BUILD_LIBC_UVWASI) - # Enable libc uvwasi support by default - set (WAMR_BUILD_LIBC_UVWASI 1) +if (NOT DEFINED WAMR_BUILD_LIBC_WASI) + # Enable libc wasi support by default + set (WAMR_BUILD_LIBC_WASI 1) endif () if (NOT DEFINED WAMR_BUILD_FAST_INTERP) diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index f51c9dcc59..e85e869c28 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -45,6 +45,10 @@ print_help() #endif printf(" --stack-size=n Set maximum stack size in bytes, default is 64 KB\n"); printf(" --heap-size=n Set maximum heap size in bytes, default is 16 KB\n"); +#if WASM_ENABLE_GC != 0 + printf(" --gc-heap-size=n Set maximum gc heap size in bytes,\n"); + printf(" default is %u KB\n", GC_HEAP_SIZE_DEFAULT / 1024); +#endif #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"); @@ -271,6 +275,9 @@ main(int argc, char *argv[]) #else uint32 heap_size = 16 * 1024; #endif +#if WASM_ENABLE_GC != 0 + uint32 gc_heap_size = GC_HEAP_SIZE_DEFAULT; +#endif #if WASM_ENABLE_JIT != 0 uint32 llvm_jit_size_level = 3; uint32 llvm_jit_opt_level = 3; @@ -346,6 +353,13 @@ main(int argc, char *argv[]) return print_help(); heap_size = atoi(argv[0] + 12); } +#if WASM_ENABLE_GC != 0 + else if (!strncmp(argv[0], "--gc-heap-size=", 15)) { + if (argv[0][15] == '\0') + return print_help(); + gc_heap_size = atoi(argv[0] + 15); + } +#endif #if WASM_ENABLE_JIT != 0 else if (!strncmp(argv[0], "--llvm-jit-size-level=", 22)) { if (argv[0][22] == '\0') @@ -456,6 +470,10 @@ main(int argc, char *argv[]) init_args.mem_alloc_option.allocator.free_func = free_func; #endif +#if WASM_ENABLE_GC != 0 + init_args.gc_heap_size = gc_heap_size; +#endif + #if WASM_ENABLE_JIT != 0 init_args.llvm_jit_size_level = llvm_jit_size_level; init_args.llvm_jit_opt_level = llvm_jit_opt_level; diff --git a/samples/gui/wasm-apps/decrease/src/main.c b/samples/gui/wasm-apps/decrease/src/main.c deleted file mode 100644 index 9635ebea83..0000000000 --- a/samples/gui/wasm-apps/decrease/src/main.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - */ - -#include -#include "wasm_app.h" -#include "wa-inc/lvgl/lvgl.h" -#include "wa-inc/timer_wasm_app.h" - -extern char g_widget_text[]; - -static void -btn_event_cb(lv_obj_t *btn, lv_event_t event); - -uint32_t count = 0; -char count_str[11] = { 0 }; -lv_obj_t *hello_world_label; -lv_obj_t *count_label; -lv_obj_t *btn1; -lv_obj_t *label_count1; -int label_count1_value = 100; -char label_count1_str[11] = { 0 }; - -void -timer1_update(user_timer_t timer1) -{ - if ((count % 100) == 0) { - snprintf(count_str, sizeof(count_str), "%d", count / 100); - lv_label_set_text(count_label, count_str); - } - ++count; -} - -void -on_init() -{ - char *text; - - hello_world_label = lv_label_create(NULL, NULL); - lv_label_set_text(hello_world_label, "Hello world!"); - text = lv_label_get_text(hello_world_label); - printf("Label text %lu %s \n", strlen(text), text); - lv_obj_align(hello_world_label, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); - - count_label = lv_label_create(NULL, NULL); - lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); - - /* Create a button on the currently loaded screen */ - btn1 = lv_btn_create(NULL, NULL); - /* Set function to be called when the button is released */ - lv_obj_set_event_cb(btn1, (lv_event_cb_t)btn_event_cb); - /* Align below the label */ - lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); - - /* Create a label on the button */ - lv_obj_t *btn_label = lv_label_create(btn1, NULL); - lv_label_set_text(btn_label, "Click --"); - - label_count1 = lv_label_create(NULL, NULL); - lv_label_set_text(label_count1, "100"); - lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); - - /* Set up a timer */ - user_timer_t timer; - timer = api_timer_create(10, true, false, timer1_update); - if (timer) - api_timer_restart(timer, 10); - else - printf("Fail to create timer.\n"); -} - -static void -btn_event_cb(lv_obj_t *btn, lv_event_t event) -{ - if (event == LV_EVENT_RELEASED) { - label_count1_value--; - snprintf(label_count1_str, sizeof(label_count1_str), "%d", - label_count1_value); - lv_label_set_text(label_count1, label_count1_str); - if (label_count1_value == 0) - label_count1_value = 100; - } -} diff --git a/samples/gui/wasm-apps/increase/src/main.c b/samples/gui/wasm-apps/increase/src/main.c deleted file mode 100644 index 31118f7be4..0000000000 --- a/samples/gui/wasm-apps/increase/src/main.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - */ - -#include -#include "wasm_app.h" -#include "wa-inc/lvgl/lvgl.h" -#include "wa-inc/timer_wasm_app.h" - -extern char g_widget_text[]; - -static void -btn_event_cb(lv_obj_t *btn, lv_event_t event); - -uint32_t count = 0; -char count_str[11] = { 0 }; -lv_obj_t *hello_world_label; -lv_obj_t *count_label; -lv_obj_t *btn1; -lv_obj_t *label_count1; -int label_count1_value = 1; -char label_count1_str[11] = { 0 }; - -void -timer1_update(user_timer_t timer1) -{ - if ((count % 100) == 0) { - snprintf(count_str, sizeof(count_str), "%d", count / 100); - lv_label_set_text(count_label, count_str); - } - ++count; -} - -void -on_init() -{ - char *text; - - hello_world_label = lv_label_create(NULL, NULL); - lv_label_set_text(hello_world_label, "Hello world!"); - text = lv_label_get_text(hello_world_label); - printf("Label text %lu %s \n", strlen(text), text); - lv_obj_align(hello_world_label, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); - - count_label = lv_label_create(NULL, NULL); - lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); - - /* Create a button on the current loaded screen */ - btn1 = lv_btn_create(NULL, NULL); - /* Set function to be called when the button is released */ - lv_obj_set_event_cb(btn1, (lv_event_cb_t)btn_event_cb); - /* Align below the label */ - lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); - - /* Create a label on the button */ - lv_obj_t *btn_label = lv_label_create(btn1, NULL); - lv_label_set_text(btn_label, "Click ++"); - - label_count1 = lv_label_create(NULL, NULL); - lv_label_set_text(label_count1, "1"); - lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); - - /* Set up a timer */ - user_timer_t timer; - timer = api_timer_create(10, true, false, timer1_update); - if (timer) - api_timer_restart(timer, 10); - else - printf("Fail to create timer.\n"); -} - -static void -btn_event_cb(lv_obj_t *btn, lv_event_t event) -{ - if (event == LV_EVENT_RELEASED) { - label_count1_value++; - snprintf(label_count1_str, sizeof(label_count1_str), "%d", - label_count1_value); - lv_label_set_text(label_count1, label_count1_str); - if (label_count1_value == 100) - label_count1_value = 0; - } -} diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c deleted file mode 100644 index 5502cfd89d..0000000000 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c +++ /dev/null @@ -1,348 +0,0 @@ -/** - * @file XPT2046.c - */ -/********************* - * INCLUDES - *********************/ -#include "XPT2046.h" -#include "board_config.h" -#include "stdio.h" -#include -#include "drivers/spi.h" - -#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */ -#include -#include -#else -#include -#endif - -#if USE_XPT2046 - -#include - -#define abs(x) ((x) < 0 ? -(x) : (x)) - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static void -xpt2046_corr(int16_t *x, int16_t *y); -#if 0 -static void xpt2046_avg(int16_t * x, int16_t * y); -#endif - -/********************** - * STATIC VARIABLES - **********************/ -int16_t avg_buf_x[XPT2046_AVG]; -int16_t avg_buf_y[XPT2046_AVG]; -uint8_t avg_last; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -/** - * Initialize the XPT2046 - */ -struct device *input_dev; - -struct spi_config spi_conf_xpt2046; -struct spi_cs_control xpt2046_cs_ctrl; -struct device *xpt2046_pen_gpio_dev; -static struct gpio_callback gpio_cb; -lv_indev_data_t touch_point; -lv_indev_data_t last_touch_point; - -#define TOUCH_READ_THREAD_STACK_SIZE 4096 -static K_THREAD_STACK_DEFINE(touch_read_thread_stack, - TOUCH_READ_THREAD_STACK_SIZE); -static struct k_thread touch_thread_data; -static struct k_sem sem_touch_read; - -K_MUTEX_DEFINE(spi_display_touch_mutex); - -int cnt = 0; -int touch_read_times = 0; -int last_pen_interrupt_time = 0; -void -xpt2046_pen_gpio_callback(struct device *port, struct gpio_callback *cb, - u32_t pins) -{ - cnt++; - if ((k_uptime_get_32() - last_pen_interrupt_time) > 500) { - k_sem_give(&sem_touch_read); - touch_read_times++; - last_pen_interrupt_time = k_uptime_get_32(); - } -} - -void -disable_pen_interrupt() -{ - int ret = 0; - ret = gpio_disable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); - if (ret != 0) { - printf("gpio_pin_configure GPIO_INPUT failed\n"); - } -} -void -enable_pen_interrupt() -{ - int ret = 0; - ret = gpio_enable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); - if (ret != 0) { - printf("gpio_pin_configure failed\n"); - } -} - -void -touch_screen_read_thread() -{ - int i; - bool ret = false; - - for (;;) { - k_sem_take(&sem_touch_read, K_FOREVER); - memset(&last_touch_point, 0, sizeof(lv_indev_data_t)); - memset(&touch_point, 0, sizeof(lv_indev_data_t)); - memset(avg_buf_x, 0, sizeof(avg_buf_x)); - memset(avg_buf_y, 0, sizeof(avg_buf_y)); - k_mutex_lock(&spi_display_touch_mutex, K_FOREVER); - disable_pen_interrupt(); - for (i = 0; i < 100; i++) { - ret = xpt2046_read(&touch_point); - if (ret) { - if ((abs(last_touch_point.point.x - touch_point.point.x) < 4) - && (abs(last_touch_point.point.y - touch_point.point.y) - < 4)) { - break; - } - last_touch_point = touch_point; - } - } - enable_pen_interrupt(); - k_mutex_unlock(&spi_display_touch_mutex); - } -} - -void -xpt2046_init(void) -{ - int ret; - input_dev = device_get_binding(XPT2046_SPI_DEVICE_NAME); - - if (input_dev == NULL) { - printf("device not found. Aborting test."); - return; - } - memset((void *)&touch_point, 0, sizeof(lv_indev_data_t)); - - spi_conf_xpt2046.frequency = XPT2046_SPI_MAX_FREQUENCY; - spi_conf_xpt2046.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8); - spi_conf_xpt2046.slave = 0; - spi_conf_xpt2046.cs = NULL; -#ifdef XPT2046_CS_GPIO_CONTROLLER - xpt2046_cs_ctrl.gpio_dev = device_get_binding(XPT2046_CS_GPIO_CONTROLLER); - if (xpt2046_cs_ctrl.gpio_dev == NULL) { - printk("Cannot find %s!\n", XPT2046_CS_GPIO_CONTROLLER); - return; - } - gpio_pin_configure(xpt2046_cs_ctrl.gpio_dev, XPT2046_CS_GPIO_PIN, - GPIO_OUTPUT); - gpio_pin_set(xpt2046_cs_ctrl.gpio_dev, XPT2046_CS_GPIO_PIN, 1); - xpt2046_cs_ctrl.gpio_pin = XPT2046_CS_GPIO_PIN; - xpt2046_cs_ctrl.delay = 0; - spi_conf_xpt2046.cs = &xpt2046_cs_ctrl; - -#endif - -#ifdef XPT2046_PEN_GPIO_CONTROLLER - - xpt2046_pen_gpio_dev = device_get_binding(XPT2046_PEN_GPIO_CONTROLLER); - if (!xpt2046_pen_gpio_dev) { - printk("Cannot find %s!\n", XPT2046_PEN_GPIO_CONTROLLER); - return; - } - /* Setup GPIO input */ - ret = gpio_pin_configure(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN, - (GPIO_INPUT | GPIO_INT_ENABLE | GPIO_INT_EDGE - | GPIO_INT_LOW_0 | GPIO_INT_DEBOUNCE)); - if (ret) { - printk("Error configuring pin %d!\n", XPT2046_PEN_GPIO_PIN); - } - - gpio_init_callback(&gpio_cb, xpt2046_pen_gpio_callback, - BIT(XPT2046_PEN_GPIO_PIN)); - - ret = gpio_add_callback(xpt2046_pen_gpio_dev, &gpio_cb); - if (ret) { - printk("gpio_add_callback error\n"); - } - ret = gpio_enable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); - if (ret) { - printk("gpio_enable_callback error\n"); - } -#endif - - k_sem_init(&sem_touch_read, 0, 1); - - k_thread_create(&touch_thread_data, touch_read_thread_stack, - TOUCH_READ_THREAD_STACK_SIZE, touch_screen_read_thread, - NULL, NULL, NULL, 5, 0, K_NO_WAIT); - printf("xpt2046_init ok \n"); -} - -/** - * Get the current position and state of the touchpad - * @param data store the read data here - * @return false: because no ore data to be read - */ -bool -xpt2046_read(lv_indev_data_t *data) -{ - static int16_t last_x = 0; - static int16_t last_y = 0; - bool valid = true; - int s32_ret = 0; - - int16_t x = 0; - int16_t y = 0; - - char tx1[16] = { 0 }; - char rx1[16] = { 0 }; - - struct spi_buf tx_buf = { .buf = &tx1, .len = 3 }; - struct spi_buf_set tx_bufs = { .buffers = &tx_buf, .count = 1 }; - struct spi_buf rx_buf = { .buf = &rx1, .len = 3 }; - struct spi_buf_set rx_bufs = { .buffers = &rx_buf, .count = 1 }; - - tx1[0] = CMD_X_READ; - s32_ret = spi_transceive(input_dev, &spi_conf_xpt2046, &tx_bufs, &rx_bufs); - if (s32_ret != 0) { - printf("spi_transceive return failed:%d\n", s32_ret); - } - x = rx1[1] << 8; - x += rx1[2]; - - tx1[0] = CMD_Y_READ; - s32_ret = spi_transceive(input_dev, &spi_conf_xpt2046, &tx_bufs, &rx_bufs); - if (s32_ret != 0) { - printf("spi_transceive return failed:%d\n", s32_ret); - } - y = rx1[1] << 8; - y += rx1[2]; - x = x >> 3; - y = y >> 3; - - xpt2046_corr(&x, &y); - if (y <= 0 || (x > 320)) { - valid = false; - } - - last_x = x; - last_y = y; - - data->point.x = x; - data->point.y = y; - data->state = valid == false ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR; - - return valid; -} - -/********************** - * STATIC FUNCTIONS - **********************/ -static void -xpt2046_corr(int16_t *x, int16_t *y) -{ -#if XPT2046_XY_SWAP != 0 - int16_t swap_tmp; - swap_tmp = *x; - *x = *y; - *y = swap_tmp; -#endif - - if ((*x) > XPT2046_X_MIN) - (*x) -= XPT2046_X_MIN; - else - (*x) = 0; - - if ((*y) > XPT2046_Y_MIN) - (*y) -= XPT2046_Y_MIN; - else - (*y) = 0; - - (*x) = (uint32_t)((uint32_t)(*x) * XPT2046_HOR_RES) - / (XPT2046_X_MAX - XPT2046_X_MIN); - - (*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) - / (XPT2046_Y_MAX - XPT2046_Y_MIN); - -#if XPT2046_X_INV != 0 - (*x) = XPT2046_HOR_RES - (*x); -#endif - -#if XPT2046_Y_INV != 0 - (*y) = XPT2046_VER_RES - (*y); -#endif -} - -#if 0 -static void xpt2046_avg(int16_t * x, int16_t * y) -{ - /*Shift out the oldest data*/ - uint8_t i; - for (i = XPT2046_AVG - 1; i > 0; i--) { - avg_buf_x[i] = avg_buf_x[i - 1]; - avg_buf_y[i] = avg_buf_y[i - 1]; - } - - /*Insert the new point*/ - avg_buf_x[0] = *x; - avg_buf_y[0] = *y; - if (avg_last < XPT2046_AVG) - avg_last++; - - /*Sum the x and y coordinates*/ - int32_t x_sum = 0; - int32_t y_sum = 0; - for (i = 0; i < avg_last; i++) { - x_sum += avg_buf_x[i]; - y_sum += avg_buf_y[i]; - } - - /*Normalize the sums*/ - (*x) = (int32_t) x_sum / avg_last; - (*y) = (int32_t) y_sum / avg_last; -} -#endif - -bool -touchscreen_read(lv_indev_data_t *data) -{ - /*Store the collected data*/ - data->point.x = last_touch_point.point.x; - data->point.y = last_touch_point.point.y; - data->state = last_touch_point.state; - - if (last_touch_point.state == LV_INDEV_STATE_PR) { - last_touch_point.state = LV_INDEV_STATE_REL; - } - return false; -} - -#endif diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.h b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.h deleted file mode 100644 index ddc396e1d7..0000000000 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2017 Jan Van Winkel - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ -#define ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ -#include "board_config.h" -#include - -#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */ -#include -#else -#include -#endif - -#define ILI9340_CMD_ENTER_SLEEP 0x10 -#define ILI9340_CMD_EXIT_SLEEP 0x11 -#define ILI9340_CMD_GAMMA_SET 0x26 -#define ILI9340_CMD_DISPLAY_OFF 0x28 -#define ILI9340_CMD_DISPLAY_ON 0x29 -#define ILI9340_CMD_COLUMN_ADDR 0x2a -#define ILI9340_CMD_PAGE_ADDR 0x2b -#define ILI9340_CMD_MEM_WRITE 0x2c -#define ILI9340_CMD_MEM_ACCESS_CTRL 0x36 -#define ILI9340_CMD_PIXEL_FORMAT_SET 0x3A -#define ILI9340_CMD_FRAME_CTRL_NORMAL_MODE 0xB1 -#define ILI9340_CMD_DISPLAY_FUNCTION_CTRL 0xB6 -#define ILI9340_CMD_POWER_CTRL_1 0xC0 -#define ILI9340_CMD_POWER_CTRL_2 0xC1 -#define ILI9340_CMD_VCOM_CTRL_1 0xC5 -#define ILI9340_CMD_VCOM_CTRL_2 0xC7 -#define ILI9340_CMD_POSITVE_GAMMA_CORRECTION 0xE0 -#define ILI9340_CMD_NEGATIVE_GAMMA_CORRECTION 0xE1 - -#define ILI9340_DATA_MEM_ACCESS_CTRL_MY 0x80 -#define ILI9340_DATA_MEM_ACCESS_CTRL_MX 0x40 -#define ILI9340_DATA_MEM_ACCESS_CTRL_MV 0x20 -#define ILI9340_DATA_MEM_ACCESS_CTRL_ML 0x10 -#define ILI9340_DATA_MEM_ACCESS_CTRL_BGR 0x08 -#define ILI9340_DATA_MEM_ACCESS_CTRL_MH 0x04 - -#define ILI9340_DATA_PIXEL_FORMAT_RGB_18_BIT 0x60 -#define ILI9340_DATA_PIXEL_FORMAT_RGB_16_BIT 0x50 -#define ILI9340_DATA_PIXEL_FORMAT_MCU_18_BIT 0x06 -#define ILI9340_DATA_PIXEL_FORMAT_MCU_16_BIT 0x05 - -struct ili9340_data; - -/** - * Send data to ILI9340 display controller - * - * @param data Device data structure - * @param cmd Command to send to display controller - * @param tx_data Data to transmit to the display controller - * In case no data should be transmitted pass a NULL pointer - * @param tx_len Number of bytes in tx_data buffer - * - */ -void -ili9340_transmit(struct ili9340_data *data, u8_t cmd, void *tx_data, - size_t tx_len); - -/** - * Perform LCD specific initialization - * - * @param data Device data structure - */ -void -ili9340_lcd_init(struct ili9340_data *data); - -#define DT_ILITEK_ILI9340_0_LABEL "DISPLAY" -#define CONFIG_DISPLAY_LOG_LEVEL 0 - -#endif /* ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ */ diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c deleted file mode 100644 index 9ce0c11cd0..0000000000 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - */ -#include "bh_platform.h" -#include "runtime_lib.h" -#include "native_interface.h" -#include "app_manager_export.h" -#include "board_config.h" -#include "bh_common.h" -#include "bh_queue.h" -#include "runtime_sensor.h" -#include "bi-inc/attr_container.h" -#include "module_wasm_app.h" -#include "wasm_export.h" -#include "display.h" -#include "lvgl.h" - -extern bool -init_sensor_framework(); -extern void -exit_sensor_framework(); -extern int -aee_host_msg_callback(void *msg, uint32_t msg_len); -extern bool -touchscreen_read(lv_indev_data_t *data); -extern int -ili9340_init(); -extern void -xpt2046_init(void); -extern void -wgl_init(); - -#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */ -#include -#else -#include -#endif - -#include -#include - -int uart_char_cnt = 0; - -static void -uart_irq_callback(struct device *dev) -{ - unsigned char ch; - - while (uart_poll_in(dev, &ch) == 0) { - uart_char_cnt++; - aee_host_msg_callback(&ch, 1); - } -} - -struct device *uart_dev = NULL; - -static bool -host_init() -{ - uart_dev = device_get_binding(HOST_DEVICE_COMM_UART_NAME); - if (!uart_dev) { - printf("UART: Device driver not found.\n"); - return false; - } - uart_irq_rx_enable(uart_dev); - uart_irq_callback_set(uart_dev, uart_irq_callback); - return true; -} - -int -host_send(void *ctx, const char *buf, int size) -{ - if (!uart_dev) - return 0; - - for (int i = 0; i < size; i++) - uart_poll_out(uart_dev, buf[i]); - - return size; -} - -void -host_destroy() -{} - -/* clang-format off */ -host_interface interface = { - .init = host_init, - .send = host_send, - .destroy = host_destroy -}; -/* clang-format on */ - -timer_ctx_t timer_ctx; - -static char global_heap_buf[270 * 1024] = { 0 }; - -static uint8_t color_copy[320 * 10 * 3]; - -static void -display_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color) -{ - u16_t w = area->x2 - area->x1 + 1; - u16_t h = area->y2 - area->y1 + 1; - struct display_buffer_descriptor desc; - int i; - uint8_t *color_p = color_copy; - - desc.buf_size = 3 * w * h; - desc.width = w; - desc.pitch = w; - desc.height = h; - - for (i = 0; i < w * h; i++, color++) { - color_p[i * 3] = color->ch.red; - color_p[i * 3 + 1] = color->ch.green; - color_p[i * 3 + 2] = color->ch.blue; - } - - display_write(NULL, area->x1, area->y1, &desc, (void *)color_p); - - lv_disp_flush_ready(disp_drv); /* in v5.3 is lv_flush_ready */ -} - -static bool -display_input_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) -{ - return touchscreen_read(data); -} - -/** - * Initialize the Hardware Abstraction Layer (HAL) for the Littlev graphics - * library - */ -static void -hal_init(void) -{ - xpt2046_init(); - ili9340_init(); - display_blanking_off(NULL); - - /*Create a display buffer*/ - static lv_disp_buf_t disp_buf1; - static lv_color_t buf1_1[320 * 10]; - lv_disp_buf_init(&disp_buf1, buf1_1, NULL, 320 * 10); - - /*Create a display*/ - lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); /*Basic initialization*/ - disp_drv.buffer = &disp_buf1; - disp_drv.flush_cb = display_flush; - // disp_drv.hor_res = 200; - // disp_drv.ver_res = 100; - lv_disp_drv_register(&disp_drv); - - lv_indev_drv_t indev_drv; - lv_indev_drv_init(&indev_drv); /*Basic initialization*/ - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.read_cb = display_input_read; - lv_indev_drv_register(&indev_drv); -} - -int -iwasm_main() -{ - RuntimeInitArgs init_args; - host_init(); - - memset(&init_args, 0, sizeof(RuntimeInitArgs)); - - init_args.mem_alloc_type = Alloc_With_Pool; - init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; - init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); - - /* initialize runtime environment */ - if (!wasm_runtime_full_init(&init_args)) { - printf("Init runtime environment failed.\n"); - return -1; - } - - wgl_init(); - hal_init(); - - /* timer manager */ - if (!init_wasm_timer()) { - goto fail; - } - - app_manager_startup(&interface); - -fail: - wasm_runtime_destroy(); - return -1; -} diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c deleted file mode 100644 index e3948e2f20..0000000000 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c +++ /dev/null @@ -1,349 +0,0 @@ -/** - * @file XPT2046.c - */ -/********************* - * INCLUDES - *********************/ -#include "XPT2046.h" -#include "board_config.h" -#include "stdio.h" -#include -#include "drivers/spi.h" - -#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */ -#include -#include -#else -#include -#endif - -#if USE_XPT2046 - -#include - -#define abs(x) ((x) < 0 ? -(x) : (x)) - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static void -xpt2046_corr(int16_t *x, int16_t *y); -#if 0 -static void xpt2046_avg(int16_t * x, int16_t * y); -#endif - -/********************** - * STATIC VARIABLES - **********************/ -int16_t avg_buf_x[XPT2046_AVG]; -int16_t avg_buf_y[XPT2046_AVG]; -uint8_t avg_last; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -/** - * Initialize the XPT2046 - */ -struct device *input_dev; - -struct spi_config spi_conf_xpt2046; -struct spi_cs_control xpt2046_cs_ctrl; -struct device *xpt2046_pen_gpio_dev; -static struct gpio_callback gpio_cb; -lv_indev_data_t touch_point; -lv_indev_data_t last_touch_point; - -#define TOUCH_READ_THREAD_STACK_SIZE 4096 -static K_THREAD_STACK_DEFINE(touch_read_thread_stack, - TOUCH_READ_THREAD_STACK_SIZE); -static struct k_thread touch_thread_data; -static struct k_sem sem_touch_read; - -K_MUTEX_DEFINE(spi_display_touch_mutex); - -int cnt = 0; -int touch_read_times = 0; -int last_pen_interrupt_time = 0; - -void -xpt2046_pen_gpio_callback(struct device *port, struct gpio_callback *cb, - uint32_t pins) -{ - cnt++; - if ((k_uptime_get_32() - last_pen_interrupt_time) > 500) { - k_sem_give(&sem_touch_read); - touch_read_times++; - last_pen_interrupt_time = k_uptime_get_32(); - } -} - -void -disable_pen_interrupt() -{ - int ret = 0; - ret = gpio_disable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); - if (ret != 0) { - printf("gpio_pin_configure GPIO_INPUT failed\n"); - } -} -void -enable_pen_interrupt() -{ - int ret = 0; - ret = gpio_enable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); - if (ret != 0) { - printf("gpio_pin_configure failed\n"); - } -} - -void -touch_screen_read_thread() -{ - int i; - bool ret = false; - - for (;;) { - k_sem_take(&sem_touch_read, K_FOREVER); - memset(&last_touch_point, 0, sizeof(lv_indev_data_t)); - memset(&touch_point, 0, sizeof(lv_indev_data_t)); - memset(avg_buf_x, 0, sizeof(avg_buf_x)); - memset(avg_buf_y, 0, sizeof(avg_buf_y)); - k_mutex_lock(&spi_display_touch_mutex, K_FOREVER); - disable_pen_interrupt(); - for (i = 0; i < 100; i++) { - ret = xpt2046_read(&touch_point); - if (ret) { - if ((abs(last_touch_point.point.x - touch_point.point.x) < 4) - && (abs(last_touch_point.point.y - touch_point.point.y) - < 4)) { - break; - } - last_touch_point = touch_point; - } - } - enable_pen_interrupt(); - k_mutex_unlock(&spi_display_touch_mutex); - } -} - -void -xpt2046_init(void) -{ - int ret; - input_dev = device_get_binding(XPT2046_SPI_DEVICE_NAME); - - if (input_dev == NULL) { - printf("device not found. Aborting test."); - return; - } - memset((void *)&touch_point, 0, sizeof(lv_indev_data_t)); - - spi_conf_xpt2046.frequency = XPT2046_SPI_MAX_FREQUENCY; - spi_conf_xpt2046.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8); - spi_conf_xpt2046.slave = 0; - spi_conf_xpt2046.cs = NULL; -#ifdef XPT2046_CS_GPIO_CONTROLLER - xpt2046_cs_ctrl.gpio_dev = device_get_binding(XPT2046_CS_GPIO_CONTROLLER); - if (xpt2046_cs_ctrl.gpio_dev == NULL) { - printk("Cannot find %s!\n", XPT2046_CS_GPIO_CONTROLLER); - return; - } - gpio_pin_configure(xpt2046_cs_ctrl.gpio_dev, XPT2046_CS_GPIO_PIN, - GPIO_OUTPUT); - gpio_pin_set(xpt2046_cs_ctrl.gpio_dev, XPT2046_CS_GPIO_PIN, 1); - xpt2046_cs_ctrl.gpio_pin = XPT2046_CS_GPIO_PIN; - xpt2046_cs_ctrl.delay = 0; - spi_conf_xpt2046.cs = &xpt2046_cs_ctrl; - -#endif - -#ifdef XPT2046_PEN_GPIO_CONTROLLER - - xpt2046_pen_gpio_dev = device_get_binding(XPT2046_PEN_GPIO_CONTROLLER); - if (!xpt2046_pen_gpio_dev) { - printk("Cannot find %s!\n", XPT2046_PEN_GPIO_CONTROLLER); - return; - } - /* Setup GPIO input */ - ret = gpio_pin_configure(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN, - (GPIO_INPUT | GPIO_INT_ENABLE | GPIO_INT_EDGE - | GPIO_INT_LOW_0 | GPIO_INT_DEBOUNCE)); - if (ret) { - printk("Error configuring pin %d!\n", XPT2046_PEN_GPIO_PIN); - } - - gpio_init_callback(&gpio_cb, xpt2046_pen_gpio_callback, - BIT(XPT2046_PEN_GPIO_PIN)); - - ret = gpio_add_callback(xpt2046_pen_gpio_dev, &gpio_cb); - if (ret) { - printk("gpio_add_callback error\n"); - } - ret = gpio_enable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); - if (ret) { - printk("gpio_enable_callback error\n"); - } -#endif - - k_sem_init(&sem_touch_read, 0, 1); - - k_thread_create(&touch_thread_data, touch_read_thread_stack, - TOUCH_READ_THREAD_STACK_SIZE, touch_screen_read_thread, - NULL, NULL, NULL, 5, 0, K_NO_WAIT); - printf("xpt2046_init ok \n"); -} - -/** - * Get the current position and state of the touchpad - * @param data store the read data here - * @return false: because no ore data to be read - */ -bool -xpt2046_read(lv_indev_data_t *data) -{ - static int16_t last_x = 0; - static int16_t last_y = 0; - bool valid = true; - int s32_ret = 0; - - int16_t x = 0; - int16_t y = 0; - - char tx1[16] = { 0 }; - char rx1[16] = { 0 }; - - struct spi_buf tx_buf = { .buf = &tx1, .len = 3 }; - struct spi_buf_set tx_bufs = { .buffers = &tx_buf, .count = 1 }; - struct spi_buf rx_buf = { .buf = &rx1, .len = 3 }; - struct spi_buf_set rx_bufs = { .buffers = &rx_buf, .count = 1 }; - - tx1[0] = CMD_X_READ; - s32_ret = spi_transceive(input_dev, &spi_conf_xpt2046, &tx_bufs, &rx_bufs); - if (s32_ret != 0) { - printf("spi_transceive return failed:%d\n", s32_ret); - } - x = rx1[1] << 8; - x += rx1[2]; - - tx1[0] = CMD_Y_READ; - s32_ret = spi_transceive(input_dev, &spi_conf_xpt2046, &tx_bufs, &rx_bufs); - if (s32_ret != 0) { - printf("spi_transceive return failed:%d\n", s32_ret); - } - y = rx1[1] << 8; - y += rx1[2]; - x = x >> 3; - y = y >> 3; - - xpt2046_corr(&x, &y); - if (y <= 0 || (x > 320)) { - valid = false; - } - - last_x = x; - last_y = y; - - data->point.x = x; - data->point.y = y; - data->state = valid == false ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR; - - return valid; -} - -/********************** - * STATIC FUNCTIONS - **********************/ -static void -xpt2046_corr(int16_t *x, int16_t *y) -{ -#if XPT2046_XY_SWAP != 0 - int16_t swap_tmp; - swap_tmp = *x; - *x = *y; - *y = swap_tmp; -#endif - - if ((*x) > XPT2046_X_MIN) - (*x) -= XPT2046_X_MIN; - else - (*x) = 0; - - if ((*y) > XPT2046_Y_MIN) - (*y) -= XPT2046_Y_MIN; - else - (*y) = 0; - - (*x) = (uint32_t)((uint32_t)(*x) * XPT2046_HOR_RES) - / (XPT2046_X_MAX - XPT2046_X_MIN); - - (*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) - / (XPT2046_Y_MAX - XPT2046_Y_MIN); - -#if XPT2046_X_INV != 0 - (*x) = XPT2046_HOR_RES - (*x); -#endif - -#if XPT2046_Y_INV != 0 - (*y) = XPT2046_VER_RES - (*y); -#endif -} - -#if 0 -static void xpt2046_avg(int16_t * x, int16_t * y) -{ - /*Shift out the oldest data*/ - uint8_t i; - for (i = XPT2046_AVG - 1; i > 0; i--) { - avg_buf_x[i] = avg_buf_x[i - 1]; - avg_buf_y[i] = avg_buf_y[i - 1]; - } - - /*Insert the new point*/ - avg_buf_x[0] = *x; - avg_buf_y[0] = *y; - if (avg_last < XPT2046_AVG) - avg_last++; - - /*Sum the x and y coordinates*/ - int32_t x_sum = 0; - int32_t y_sum = 0; - for (i = 0; i < avg_last; i++) { - x_sum += avg_buf_x[i]; - y_sum += avg_buf_y[i]; - } - - /*Normalize the sums*/ - (*x) = (int32_t) x_sum / avg_last; - (*y) = (int32_t) y_sum / avg_last; -} -#endif - -bool -touchscreen_read(lv_indev_data_t *data) -{ - /*Store the collected data*/ - data->point.x = last_touch_point.point.x; - data->point.y = last_touch_point.point.y; - data->state = last_touch_point.state; - - if (last_touch_point.state == LV_INDEV_STATE_PR) { - last_touch_point.state = LV_INDEV_STATE_REL; - } - return false; -} - -#endif diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.h b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.h deleted file mode 100644 index 39257a29a6..0000000000 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2017 Jan Van Winkel - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ -#define ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ -#include "board_config.h" -#include - -#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */ -#include -#else -#include -#endif - -#define ILI9340_CMD_ENTER_SLEEP 0x10 -#define ILI9340_CMD_EXIT_SLEEP 0x11 -#define ILI9340_CMD_GAMMA_SET 0x26 -#define ILI9340_CMD_DISPLAY_OFF 0x28 -#define ILI9340_CMD_DISPLAY_ON 0x29 -#define ILI9340_CMD_COLUMN_ADDR 0x2a -#define ILI9340_CMD_PAGE_ADDR 0x2b -#define ILI9340_CMD_MEM_WRITE 0x2c -#define ILI9340_CMD_MEM_ACCESS_CTRL 0x36 -#define ILI9340_CMD_PIXEL_FORMAT_SET 0x3A -#define ILI9340_CMD_FRAME_CTRL_NORMAL_MODE 0xB1 -#define ILI9340_CMD_DISPLAY_FUNCTION_CTRL 0xB6 -#define ILI9340_CMD_POWER_CTRL_1 0xC0 -#define ILI9340_CMD_POWER_CTRL_2 0xC1 -#define ILI9340_CMD_VCOM_CTRL_1 0xC5 -#define ILI9340_CMD_VCOM_CTRL_2 0xC7 -#define ILI9340_CMD_POSITVE_GAMMA_CORRECTION 0xE0 -#define ILI9340_CMD_NEGATIVE_GAMMA_CORRECTION 0xE1 - -#define ILI9340_DATA_MEM_ACCESS_CTRL_MY 0x80 -#define ILI9340_DATA_MEM_ACCESS_CTRL_MX 0x40 -#define ILI9340_DATA_MEM_ACCESS_CTRL_MV 0x20 -#define ILI9340_DATA_MEM_ACCESS_CTRL_ML 0x10 -#define ILI9340_DATA_MEM_ACCESS_CTRL_BGR 0x08 -#define ILI9340_DATA_MEM_ACCESS_CTRL_MH 0x04 - -#define ILI9340_DATA_PIXEL_FORMAT_RGB_18_BIT 0x60 -#define ILI9340_DATA_PIXEL_FORMAT_RGB_16_BIT 0x50 -#define ILI9340_DATA_PIXEL_FORMAT_MCU_18_BIT 0x06 -#define ILI9340_DATA_PIXEL_FORMAT_MCU_16_BIT 0x05 - -struct ili9340_data; - -/** - * Send data to ILI9340 display controller - * - * @param data Device data structure - * @param cmd Command to send to display controller - * @param tx_data Data to transmit to the display controller - * In case no data should be transmitted pass a NULL pointer - * @param tx_len Number of bytes in tx_data buffer - * - */ -void -ili9340_transmit(struct ili9340_data *data, uint8_t cmd, void *tx_data, - size_t tx_len); - -/** - * Perform LCD specific initialization - * - * @param data Device data structure - */ -void -ili9340_lcd_init(struct ili9340_data *data); - -#define DT_ILITEK_ILI9340_0_LABEL "DISPLAY" -#define CONFIG_DISPLAY_LOG_LEVEL 0 - -#endif /* ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ */ diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c deleted file mode 100644 index 10f4980268..0000000000 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - */ -#include "bh_platform.h" -#include "runtime_lib.h" -#include "native_interface.h" -#include "app_manager_export.h" -#include "board_config.h" -#include "bh_platform.h" -#include "runtime_sensor.h" -#include "bi-inc/attr_container.h" -#include "module_wasm_app.h" -#include "wasm_export.h" -#include "sensor_native_api.h" -#include "connection_native_api.h" -#include "display_indev.h" - -#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */ -#include -#else -#include -#endif - -#include -#include - -extern bool -init_sensor_framework(); -extern void -exit_sensor_framework(); -extern int -aee_host_msg_callback(void *msg, uint32_t msg_len); - -int uart_char_cnt = 0; - -static void -uart_irq_callback(const struct device *dev, void *user_data) -{ - unsigned char ch; - - while (uart_poll_in(dev, &ch) == 0) { - uart_char_cnt++; - aee_host_msg_callback(&ch, 1); - } - (void)user_data; -} - -const struct device *uart_dev = NULL; - -static bool -host_init() -{ - uart_dev = device_get_binding(HOST_DEVICE_COMM_UART_NAME); - if (!uart_dev) { - printf("UART: Device driver not found.\n"); - return false; - } - uart_irq_rx_enable(uart_dev); - uart_irq_callback_set(uart_dev, uart_irq_callback); - return true; -} - -int -host_send(void *ctx, const char *buf, int size) -{ - if (!uart_dev) - return 0; - - for (int i = 0; i < size; i++) - uart_poll_out(uart_dev, buf[i]); - - return size; -} - -void -host_destroy() -{} - -/* clang-format off */ -host_interface interface = { - .init = host_init, - .send = host_send, - .destroy = host_destroy -}; -/* clang-format on */ - -timer_ctx_t timer_ctx; - -static char global_heap_buf[350 * 1024] = { 0 }; - -static NativeSymbol native_symbols[] = { - EXPORT_WASM_API_WITH_SIG(display_input_read, "(*)i"), - EXPORT_WASM_API_WITH_SIG(display_flush, "(iiii*)"), - EXPORT_WASM_API_WITH_SIG(display_fill, "(iiii*)"), - EXPORT_WASM_API_WITH_SIG(display_vdb_write, "(*iii*i)"), - EXPORT_WASM_API_WITH_SIG(display_map, "(iiii*)"), - EXPORT_WASM_API_WITH_SIG(time_get_ms, "()i") -}; - -int -iwasm_main() -{ - RuntimeInitArgs init_args; - - host_init(); - - memset(&init_args, 0, sizeof(RuntimeInitArgs)); - - init_args.mem_alloc_type = Alloc_With_Pool; - init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; - init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); - - init_args.native_module_name = "env"; - init_args.n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol); - init_args.native_symbols = native_symbols; - - /* initialize runtime environment */ - if (!wasm_runtime_full_init(&init_args)) { - printf("Init runtime environment failed.\n"); - return -1; - } - - display_init(); - - /* timer manager */ - if (!init_wasm_timer()) { - goto fail; - } - - app_manager_startup(&interface); - -fail: - wasm_runtime_destroy(); - return -1; -} diff --git a/samples/multi-thread/wasm-apps/CMakeLists.txt b/samples/multi-thread/wasm-apps/CMakeLists.txt index d7352e4274..5442398f94 100644 --- a/samples/multi-thread/wasm-apps/CMakeLists.txt +++ b/samples/multi-thread/wasm-apps/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (C) 2019 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.14) project(wasm-apps) set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) @@ -43,4 +43,4 @@ add_executable(main_thread_exception.wasm main_thread_exception.c) target_link_libraries(main_thread_exception.wasm) add_executable(main_global_atomic.wasm main_global_atomic.c) -target_link_libraries(main_global_atomic.wasm) \ No newline at end of file +target_link_libraries(main_global_atomic.wasm) diff --git a/samples/shared-heap/CMakeLists.txt b/samples/shared-heap/CMakeLists.txt new file mode 100644 index 0000000000..6346d077e7 --- /dev/null +++ b/samples/shared-heap/CMakeLists.txt @@ -0,0 +1,127 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required (VERSION 3.14) + +include(CheckPIESupported) + +if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows") + project (shared_heap_test) +else() + project (shared_heap_test C ASM) +endif() + +################ runtime settings ################ +string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM) +if (APPLE) + add_definitions(-DBH_PLATFORM_DARWIN) +endif () + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +# WAMR features switch + +# Set WAMR_BUILD_TARGET, currently values supported: +# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", +# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]" + +if (NOT DEFINED WAMR_BUILD_TARGET) + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)") + set (WAMR_BUILD_TARGET "AARCH64") + elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") + set (WAMR_BUILD_TARGET "RISCV64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + # Build as X86_64 by default in 64-bit platform + set (WAMR_BUILD_TARGET "X86_64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) + # Build as X86_32 by default in 32-bit platform + set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") + endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set (CMAKE_BUILD_TYPE Debug) +endif () + +set (WAMR_BUILD_INTERP 1) +set (WAMR_BUILD_FAST_INTERP 1) +set (WAMR_BUILD_AOT 1) +set (WAMR_BUILD_JIT 0) +set (WAMR_BUILD_LIBC_BUILTIN 1) +set (WAMR_BUILD_LIBC_WASI 0) +set (WAMR_BUILD_SHARED_HEAP 1) +set (WAMR_BUILD_GC_HEAP_VERIFY 1) + +if (NOT MSVC) + # linker flags + if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") + endif () + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security") + if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") + if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register") + endif () + endif () +endif () + +# build out vmlib +set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) +include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) + +add_library(vmlib STATIC ${WAMR_RUNTIME_LIB_SOURCE}) +if (MSVC) + target_compile_definitions(vmlib PRIVATE WASM_API_EXTERN=) +endif() +target_link_libraries(vmlib ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread) + +################ application related ################ +include_directories(${CMAKE_CURRENT_LIST_DIR}/src) +include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) + +add_executable (shared_heap_test src/main.c ${UNCOMMON_SHARED_SOURCE}) + +check_pie_supported() +set_target_properties (shared_heap_test PROPERTIES POSITION_INDEPENDENT_CODE ON) + +if (APPLE) + target_link_libraries (shared_heap_test vmlib -lm -ldl -lpthread) +else () + target_link_libraries (shared_heap_test vmlib -lm -ldl -lpthread -lrt) +endif () + +add_subdirectory(wasm-apps) + +if (WAMR_BUILD_AOT EQUAL 1) + set (WAMR_COMPILER_DIR ${CMAKE_CURRENT_LIST_DIR}/../../wamr-compiler/build) + message (CHECK_START "Detecting WAMR_COMPILER at ${WAMR_COMPILER_DIR}") + find_file (WAMR_COMPILER + wamrc + PATHS "${CMAKE_CURRENT_LIST_DIR}/../../wamr-compiler/build" + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + if (WAMR_COMPILER) + message (CHECK_PASS "found") + else() + message (CHECK_FAIL "not found") + endif() + if (NOT EXISTS ${WAMR_COMPILER}) + message (FATAL_ERROR "Please build wamrc under ${WAMR_ROOT_DIR}/wamr-compiler") + else() + message (STATUS "WAMR_COMPILER is ${WAMR_COMPILER}") + endif() + + add_custom_target( + wasm_to_aot + ALL + DEPENDS wasm-apps/test1.wasm wasm-apps/test2.wasm ${WAMR_COMPILER} + COMMAND ${WAMR_COMPILER} --enable-shared-heap -o wasm-apps/test1.aot wasm-apps/test1.wasm + COMMAND ${WAMR_COMPILER} --enable-shared-heap -o wasm-apps/test2.aot wasm-apps/test2.wasm + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) +endif() diff --git a/samples/shared-heap/src/main.c b/samples/shared-heap/src/main.c new file mode 100644 index 0000000000..f4024f08c2 --- /dev/null +++ b/samples/shared-heap/src/main.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_export.h" +#include "bh_platform.h" +#include "bh_read_file.h" + +typedef struct thread_arg { + bh_queue *queue; + wasm_module_inst_t module_inst; +} thread_arg; + +static void * +thread1_callback(void *arg) +{ + thread_arg *targ = arg; + wasm_module_inst_t module_inst = targ->module_inst; + bh_queue *queue = targ->queue; + wasm_exec_env_t exec_env; + wasm_function_inst_t my_shared_heap_malloc_func; + wasm_function_inst_t my_shared_heap_free_func; + uint32 i, argv[2]; + + /* lookup wasm functions */ + if (!(my_shared_heap_malloc_func = wasm_runtime_lookup_function( + module_inst, "my_shared_heap_malloc")) + || !(my_shared_heap_free_func = wasm_runtime_lookup_function( + module_inst, "my_shared_heap_free"))) { + printf("Failed to lookup function.\n"); + } + + /* create exec env */ + if (!(exec_env = wasm_runtime_create_exec_env(module_inst, 32768))) { + printf("Failed to create exec env.\n"); + return NULL; + } + + /* allocate memory with wasm_runtime_shared_heap_malloc and send it + to wasm app2 */ + for (i = 0; i < 5; i++) { + uint8 *buf; + uint64 offset; + + offset = wasm_runtime_shared_heap_malloc(module_inst, 1024 * (i + 1), + (void **)&buf); + + if (offset == 0) { + printf("Failed to allocate memory from shared heap\n"); + break; + } + + snprintf(buf, 1024, "Hello, this is buf %u allocated from shared heap", + i + 1); + + printf("wasm app1 send buf: %s\n\n", buf); + if (!bh_post_msg(queue, 1, buf, 1024 * i)) { + printf("Failed to post message to queue\n"); + wasm_runtime_shared_heap_free(module_inst, offset); + break; + } + } + + /* allocate memory by calling my_shared_heap_malloc function and send it + to wasm app2 */ + for (i = 5; i < 10; i++) { + uint8 *buf; + + argv[0] = 1024 * (i + 1); + argv[1] = i + 1; + wasm_runtime_call_wasm(exec_env, my_shared_heap_malloc_func, 2, argv); + + if (wasm_runtime_get_exception(module_inst)) { + printf("Failed to call 'my_shared_heap_malloc' function: %s\n", + wasm_runtime_get_exception(module_inst)); + break; + } + if (argv[0] == 0) { + printf("Failed to allocate memory from shared heap\n"); + break; + } + + buf = wasm_runtime_addr_app_to_native(module_inst, argv[0]); + + printf("wasm app1 send buf: %s\n\n", buf); + if (!bh_post_msg(queue, 1, buf, 1024 * i)) { + printf("Failed to post message to queue\n"); + wasm_runtime_shared_heap_free(module_inst, argv[0]); + break; + } + } + + wasm_runtime_destroy_exec_env(exec_env); + + return NULL; +} + +static void +queue_callback(void *message, void *arg) +{ + bh_message_t msg = (bh_message_t)message; + wasm_exec_env_t exec_env = arg; + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + wasm_function_inst_t print_buf_func; + uint32 argv[2]; + + /* lookup wasm function */ + if (!(print_buf_func = + wasm_runtime_lookup_function(module_inst, "print_buf"))) { + printf("Failed to lookup function.\n"); + return; + } + + char *buf = bh_message_payload(msg); + printf("wasm app's native queue received buf: %s\n\n", buf); + + /* call wasm function */ + argv[0] = wasm_runtime_addr_native_to_app(module_inst, buf); + wasm_runtime_call_wasm(exec_env, print_buf_func, 1, argv); + if (wasm_runtime_get_exception(module_inst)) { + printf("Failed to call 'print_buf' function: %s\n", + wasm_runtime_get_exception(module_inst)); + } +} + +static void * +thread2_callback(void *arg) +{ + thread_arg *targ = arg; + bh_queue *queue = targ->queue; + wasm_module_inst_t module_inst = targ->module_inst; + wasm_exec_env_t exec_env; + + /* create exec env */ + if (!(exec_env = wasm_runtime_create_exec_env(module_inst, 32768))) { + printf("Failed to create exec env.\n"); + return NULL; + } + + /* enter queue's message loop until bh_queue_exit_loop_run + is called */ + bh_queue_enter_loop_run(queue, queue_callback, exec_env); + + wasm_runtime_destroy_exec_env(exec_env); + + return NULL; +} + +static char global_heap_buf[512 * 1024]; + +int +main(int argc, char **argv) +{ + char *wasm_file1 = NULL, *wasm_file2 = NULL; + uint8 *wasm_file1_buf = NULL, *wasm_file2_buf = NULL; + uint32 wasm_file1_size, wasm_file2_size; + wasm_module_t wasm_module1 = NULL, wasm_module2 = NULL; + wasm_module_inst_t module_inst1 = NULL; + wasm_module_inst_t module_inst2 = NULL; + wasm_shared_heap_t shared_heap = NULL; + bh_queue *queue = NULL; + RuntimeInitArgs init_args; + SharedHeapInitArgs heap_init_args; + char error_buf[128] = { 0 }; + bool aot_mode = false; + int ret = -1; + + if (argc > 1 && !strcmp(argv[1], "--aot")) + aot_mode = true; + + if (!aot_mode) + printf("Test shared heap in interpreter mode\n\n"); + else + printf("Test shared heap in AOT mode\n\n"); + + memset(&init_args, 0, sizeof(RuntimeInitArgs)); + + init_args.mem_alloc_type = Alloc_With_Pool; + init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; + init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); + + /* init wasm runtime */ + if (!wasm_runtime_full_init(&init_args)) { + printf("Init runtime environment failed.\n"); + return -1; + } + + /* create queue */ + if (!(queue = bh_queue_create())) { + printf("Create queue failed.\n"); + goto fail; + } + + /* read wasm file */ + if (!aot_mode) + wasm_file1 = "./wasm-apps/test1.wasm"; + else + wasm_file1 = "./wasm-apps/test1.aot"; + if (!(wasm_file1_buf = + bh_read_file_to_buffer(wasm_file1, &wasm_file1_size))) { + printf("Open wasm file %s failed.\n", wasm_file1); + goto fail; + } + + /* load wasm file */ + wasm_module1 = wasm_runtime_load((uint8 *)wasm_file1_buf, wasm_file1_size, + error_buf, sizeof(error_buf)); + if (!wasm_module1) { + printf("Load wasm module failed. error: %s\n", error_buf); + goto fail; + } + + /* instantiate module */ + module_inst1 = wasm_runtime_instantiate(wasm_module1, 65536, 0, error_buf, + sizeof(error_buf)); + if (!module_inst1) { + printf("Instantiate wasm module failed. error: %s\n", error_buf); + goto fail; + } + + /* read wasm file */ + if (!aot_mode) + wasm_file2 = "./wasm-apps/test2.wasm"; + else + wasm_file2 = "./wasm-apps/test2.aot"; + if (!(wasm_file2_buf = + bh_read_file_to_buffer(wasm_file2, &wasm_file2_size))) { + printf("Open wasm file %s failed.\n", wasm_file1); + goto fail; + } + + /* load wasm file */ + wasm_module2 = wasm_runtime_load((uint8 *)wasm_file2_buf, wasm_file2_size, + error_buf, sizeof(error_buf)); + if (!wasm_module2) { + printf("Load wasm module failed. error: %s\n", error_buf); + goto fail; + } + + /* instantiate module */ + module_inst2 = wasm_runtime_instantiate(wasm_module2, 65536, 0, error_buf, + sizeof(error_buf)); + if (!module_inst2) { + printf("Instantiate wasm module failed. error: %s\n", error_buf); + goto fail; + } + + /* create shared heap */ + memset(&heap_init_args, 0, sizeof(heap_init_args)); + heap_init_args.size = 65536; + shared_heap = wasm_runtime_create_shared_heap(&heap_init_args); + if (!shared_heap) { + printf("Create shared heap failed. error: %s\n", error_buf); + goto fail; + } + + /* attach module instance 1 to the shared heap */ + if (!wasm_runtime_attach_shared_heap(module_inst1, shared_heap)) { + printf("Attach shared heap failed.\n"); + goto fail; + } + + /* attach module instance 2 to the shared heap */ + if (!wasm_runtime_attach_shared_heap(module_inst2, shared_heap)) { + printf("Attach shared heap failed.\n"); + goto fail; + } + + /* create thread 1 */ + struct thread_arg targ1 = { 0 }; + korp_tid tid1; + targ1.queue = queue; + targ1.module_inst = module_inst1; + if (os_thread_create(&tid1, thread1_callback, &targ1, + APP_THREAD_STACK_SIZE_DEFAULT)) { + printf("Failed to create thread 1\n"); + goto fail; + } + + /* create thread 2 */ + struct thread_arg targ2 = { 0 }; + korp_tid tid2; + targ2.queue = queue; + targ2.module_inst = module_inst2; + if (os_thread_create(&tid2, thread2_callback, &targ2, + APP_THREAD_STACK_SIZE_DEFAULT)) { + printf("Failed to create thread 2\n"); + os_thread_join(tid1, NULL); + goto fail; + } + + /* wait until all messages are post to wasm app2 and wasm app2 + handles all of them, then exit the queue message loop */ + usleep(10000); + bh_queue_exit_loop_run(queue); + + os_thread_join(tid1, NULL); + os_thread_join(tid2, NULL); + + ret = 0; + +fail: + if (module_inst2) + wasm_runtime_deinstantiate(module_inst2); + + if (module_inst1) + wasm_runtime_deinstantiate(module_inst1); + + if (wasm_module2) + wasm_runtime_unload(wasm_module2); + + if (wasm_module1) + wasm_runtime_unload(wasm_module1); + + if (wasm_file2_buf) + wasm_runtime_free(wasm_file2_buf); + + if (wasm_file1_buf) + wasm_runtime_free(wasm_file1_buf); + + if (queue) + bh_queue_destroy(queue); + + wasm_runtime_destroy(); + + return ret; +} diff --git a/samples/shared-heap/wasm-apps/CMakeLists.txt b/samples/shared-heap/wasm-apps/CMakeLists.txt new file mode 100644 index 0000000000..c0010af6a8 --- /dev/null +++ b/samples/shared-heap/wasm-apps/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required(VERSION 3.14) +project(wasm-apps) + +set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) + +if (APPLE) + set (HAVE_FLAG_SEARCH_PATHS_FIRST 0) + set (CMAKE_C_LINK_FLAGS "") + set (CMAKE_CXX_LINK_FLAGS "") +endif () + +set (CMAKE_SYSTEM_PROCESSOR wasm32) +set (CMAKE_SYSROOT ${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot) + +if (NOT DEFINED WASI_SDK_DIR) + set (WASI_SDK_DIR "/opt/wasi-sdk") +endif () + +set (CMAKE_C_FLAGS "-nostdlib -Qunused-arguments -z stack-size=32768") +set (CMAKE_C_COMPILER_TARGET "wasm32") +set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang") + +set (DEFINED_SYMBOLS "${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt") + +set (CMAKE_EXE_LINKER_FLAGS + "-O0 -Wl,--initial-memory=65536, \ + -Wl,--no-entry,--strip-all, \ + -Wl,--export=__heap_base,--export=__data_end \ + -Wl,--export=__wasm_call_ctors \ + -Wl,--export=my_shared_heap_malloc \ + -Wl,--export=my_shared_heap_free \ + -Wl,--export=print_buf \ + -Wl,--allow-undefined" +) + +add_executable(test1.wasm test1.c) +target_link_libraries(test1.wasm) + +add_executable(test2.wasm test2.c) +target_link_libraries(test2.wasm) diff --git a/samples/shared-heap/wasm-apps/test1.c b/samples/shared-heap/wasm-apps/test1.c new file mode 100644 index 0000000000..c8fe0c7553 --- /dev/null +++ b/samples/shared-heap/wasm-apps/test1.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include +#include + +extern void * +shared_heap_malloc(uint32_t size); +extern void +shared_heap_free(void *ptr); + +void * +my_shared_heap_malloc(uint32_t size, uint32_t index) +{ + char *buf1 = NULL, *buf2 = NULL, *buf; + + buf1 = shared_heap_malloc(128); + if (!buf1) + return NULL; + + buf1[0] = 'H'; + buf1[1] = 'e'; + buf1[2] = 'l'; + buf1[3] = 'l'; + buf1[4] = 'o'; + buf1[5] = ','; + buf1[6] = ' '; + + buf2 = shared_heap_malloc(128); + if (!buf2) { + shared_heap_free(buf1); + return NULL; + } + + snprintf(buf2, 128, "this is buf %u allocated from shared heap", index); + + buf = shared_heap_malloc(size); + if (!buf) { + shared_heap_free(buf1); + shared_heap_free(buf2); + return NULL; + } + + memset(buf, 0, size); + memcpy(buf, buf1, strlen(buf1)); + memcpy(buf + strlen(buf1), buf2, strlen(buf2)); + + shared_heap_free(buf1); + shared_heap_free(buf2); + return buf; +} + +void +my_shared_heap_free(void *ptr) +{ + shared_heap_free(ptr); +} diff --git a/samples/shared-heap/wasm-apps/test2.c b/samples/shared-heap/wasm-apps/test2.c new file mode 100644 index 0000000000..b63efcd1a2 --- /dev/null +++ b/samples/shared-heap/wasm-apps/test2.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include + +#include + +extern void +shared_heap_free(void *ptr); + +void +print_buf(char *buf) +{ + printf("wasm app2's wasm func received buf: %s\n\n", buf); + shared_heap_free(buf); +} diff --git a/samples/spawn-thread/wasm-apps/CMakeLists.txt b/samples/spawn-thread/wasm-apps/CMakeLists.txt index 0996d5841d..df21b4485c 100644 --- a/samples/spawn-thread/wasm-apps/CMakeLists.txt +++ b/samples/spawn-thread/wasm-apps/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (C) 2019 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.14) project(wasm-apps) set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) diff --git a/tests/fuzz/wasm-mutator-fuzz/portal/osv-scanner.toml b/tests/fuzz/wasm-mutator-fuzz/portal/osv-scanner.toml new file mode 100644 index 0000000000..1eb55cd8df --- /dev/null +++ b/tests/fuzz/wasm-mutator-fuzz/portal/osv-scanner.toml @@ -0,0 +1,52 @@ +# GHSA-67hx-6x53-jw92 +[[PackageOverrides]] +name = "@babel/traverse" +ecosystem = "npm" +ignore = true +reason = "Accepted known vulnerabilities for testing purposes" + +# GHSA-67hx-6x53-jw92 +[[PackageOverrides]] +name = "babel-traverse" +ecosystem = "npm" +ignore = true +reason = "Accepted known vulnerabilities for testing purposes" + +# GHSA-9c47-m6qq-7p4h +[[PackageOverrides]] +name = "json5" +ecosystem = "npm" +ignore = true +reason = "Dependency not critical for security" + +# GHSA-7fh5-64p2-3v2j +[[PackageOverrides]] +name = "postcss" +ecosystem = "npm" +ignore = true +reason = "Vulnerabilities do not affect current use case" + +# GHSA-gcx4-mw62-g8wm +[[PackageOverrides]] +name = "rollup" +ecosystem = "npm" +ignore = true +reason = "Legacy build tool under controlled environment" + +# GHSA-c2qf-rxjj-qqgw +[[PackageOverrides]] +name = "semver" +ecosystem = "npm" +ignore = true +reason = "Version parsing is managed securely" + +# GHSA-353f-5xf4-qw67 +# GHSA-c24v-8rfc-w8vw +# GHSA-8jhw-289h-jh2g +# GHSA-64vr-g452-qvp3 +# GHSA-9cwx-2883-4wfx +[[PackageOverrides]] +name = "vite" +ecosystem = "npm" +ignore = true +reason = "Development server not exposed to untrusted networks" diff --git a/tests/fuzz/wasm-mutator-fuzz/server/osv-scanner.toml b/tests/fuzz/wasm-mutator-fuzz/server/osv-scanner.toml new file mode 100644 index 0000000000..430d8ca8cb --- /dev/null +++ b/tests/fuzz/wasm-mutator-fuzz/server/osv-scanner.toml @@ -0,0 +1,32 @@ +# GHSA-m2qf-hxjv-5gpq / PYSEC-2023-62 +[[PackageOverrides]] +name = "Flask" +ecosystem = "PyPI" +ignore = true +reason = "Accepted known vulnerabilities for testing purposes" + +# GHSA-m2qf-hxjv-5gpq / PYSEC-2023-62 +[[PackageOverrides]] +name = "flask" +ecosystem = "PyPI" +ignore = true +reason = "Accepted known vulnerabilities for testing purposes" + +# GHSA-84pr-m4jr-85g5 +# GHSA-hxwh-jpp2-84pm / PYSEC-2024-71 +[[PackageOverrides]] +name = "flask-cors" +ecosystem = "PyPI" +ignore = true +reason = "Accepted known vulnerabilities for testing purposes" + +# GHSA-2g68-c3qc-8985 +# GHSA-hrfv-mqp8-q5rw / PYSEC-2023-221 +# GHSA-px8h-6qxv-m22q / PYSEC-2023-57 +# GHSA-xg9f-g7g7-2323 / PYSEC-2023-58 +# PYSEC-2022-203 +[[PackageOverrides]] +name = "werkzeug" +ecosystem = "PyPI" +ignore = true +reason = "Accepted known vulnerabilities for testing purposes" diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 40c9bb6aed..9f7a69229f 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -50,3 +50,4 @@ add_subdirectory(linux-perf) add_subdirectory(gc) add_subdirectory(memory64) add_subdirectory(tid-allocator) +add_subdirectory(shared-heap) \ No newline at end of file diff --git a/tests/unit/runtime-common/wasm-apps/main.aot b/tests/unit/runtime-common/wasm-apps/main.aot deleted file mode 100644 index 79319145a9..0000000000 Binary files a/tests/unit/runtime-common/wasm-apps/main.aot and /dev/null differ diff --git a/tests/unit/shared-heap/CMakeLists.txt b/tests/unit/shared-heap/CMakeLists.txt new file mode 100644 index 0000000000..6baf420f89 --- /dev/null +++ b/tests/unit/shared-heap/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright (C) 2024 Xiaomi Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required(VERSION 3.14) + +project(test-shared-heap) + +add_definitions(-DRUN_ON_LINUX) + +set(WAMR_BUILD_APP_FRAMEWORK 0) +set(WAMR_BUILD_AOT 0) +set(WAMR_BUILD_INTERP 1) +set(WAMR_BUILD_FAST_INTERP 1) +set(WAMR_BUILD_JIT 0) +set(WAMR_BUILD_MEMORY64 1) +set(WAMR_BUILD_SHARED_HEAP 1) + +# Compile wasm modules +add_subdirectory(wasm-apps) + +# if only load this CMake other than load it as subdirectory +include(../unit_common.cmake) + +set(LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm") + +if (NOT EXISTS "${LLVM_SRC_ROOT}/build") + message(FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build") +endif () + +set(CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}") +find_package(LLVM REQUIRED CONFIG) +include_directories(${LLVM_INCLUDE_DIRS}) +add_definitions(${LLVM_DEFINITIONS}) +message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") +message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") + +include(${IWASM_DIR}/compilation/iwasm_compl.cmake) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +file(GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc) + +set(UNIT_SOURCE ${source_all}) + +aux_source_directory(. SRC_LIST) + +set(unit_test_sources + ${UNIT_SOURCE} + ${WAMR_RUNTIME_LIB_SOURCE} + ${UNCOMMON_SHARED_SOURCE} + ${SRC_LIST} + ) + +# Now simply link against gtest or gtest_main as needed. Eg +add_executable(shared_heap_test ${unit_test_sources}) + +target_link_libraries(shared_heap_test ${LLVM_AVAILABLE_LIBS} gtest_main) + +gtest_discover_tests(shared_heap_test) \ No newline at end of file diff --git a/tests/unit/shared-heap/shared_heap_test.cc b/tests/unit/shared-heap/shared_heap_test.cc new file mode 100644 index 0000000000..5e45d31119 --- /dev/null +++ b/tests/unit/shared-heap/shared_heap_test.cc @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2024 Xiaomi Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "test_helper.h" +#include "gtest/gtest.h" + +#include "bh_read_file.h" +#include "wasm_runtime_common.h" + +class shared_heap_test : public testing::Test +{ + protected: + virtual void SetUp() {} + static void SetUpTestCase() {} + virtual void TearDown() {} + WAMRRuntimeRAII<512 * 1024> runtime; +}; + +struct ret_env { + wasm_exec_env_t exec_env; + wasm_module_t wasm_module; + wasm_module_inst_t wasm_module_inst; + unsigned char *wasm_file_buf; + char error_buf[128]; +}; + +struct ret_env +load_wasm(char *wasm_file_tested, unsigned int app_heap_size) +{ + std::string wasm_mem_page = wasm_file_tested; + const char *wasm_file = strdup(wasm_mem_page.c_str()); + wasm_module_inst_t wasm_module_inst = nullptr; + wasm_module_t wasm_module = nullptr; + wasm_exec_env_t exec_env = nullptr; + unsigned char *wasm_file_buf = nullptr; + unsigned int wasm_file_size = 0; + unsigned int stack_size = 16 * 1024, heap_size = app_heap_size; + char error_buf[128] = { 0 }; + struct ret_env ret_module_env; + + memset(ret_module_env.error_buf, 0, 128); + wasm_file_buf = + (unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size); + if (!wasm_file_buf) { + goto fail; + } + + wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf, + sizeof(error_buf)); + if (!wasm_module) { + memcpy(ret_module_env.error_buf, error_buf, 128); + goto fail; + } + + wasm_module_inst = wasm_runtime_instantiate( + wasm_module, stack_size, heap_size, error_buf, sizeof(error_buf)); + if (!wasm_module_inst) { + memcpy(ret_module_env.error_buf, error_buf, 128); + goto fail; + } + + exec_env = wasm_runtime_create_exec_env(wasm_module_inst, stack_size); + +fail: + ret_module_env.exec_env = exec_env; + ret_module_env.wasm_module = wasm_module; + ret_module_env.wasm_module_inst = wasm_module_inst; + ret_module_env.wasm_file_buf = wasm_file_buf; + + return ret_module_env; +} + +void +destroy_module_env(struct ret_env module_env) +{ + if (module_env.exec_env) { + wasm_runtime_destroy_exec_env(module_env.exec_env); + } + + if (module_env.wasm_module_inst) { + wasm_runtime_deinstantiate(module_env.wasm_module_inst); + } + + if (module_env.wasm_module) { + wasm_runtime_unload(module_env.wasm_module); + } + + if (module_env.wasm_file_buf) { + wasm_runtime_free(module_env.wasm_file_buf); + } +} + +TEST_F(shared_heap_test, test_shared_heap) +{ + struct ret_env tmp_module_env; + WASMFunctionInstanceCommon *func_test = nullptr; + bool ret = false; + uint32 argv[1] = { 65535 }; + const char *exception = nullptr; + SharedHeapInitArgs args; + WASMSharedHeap *shared_heap = nullptr; + + args.size = 1024; + shared_heap = wasm_runtime_create_shared_heap(&args); + tmp_module_env = load_wasm((char *)"test.wasm", 0); + + if (!shared_heap) { + printf("Failed to create shared heap\n"); + goto test_failed; + } + if (!wasm_runtime_attach_shared_heap(tmp_module_env.wasm_module_inst, shared_heap)) { + printf("Failed to attach shared heap\n"); + goto test_failed; + } + func_test = wasm_runtime_lookup_function( + tmp_module_env.wasm_module_inst, "test"); + if (!func_test) { + printf("\nFailed to wasm_runtime_lookup_function!\n"); + goto test_failed; + } + + ret = + wasm_runtime_call_wasm(tmp_module_env.exec_env, func_test, 1, argv); + if (!ret) { + printf("\nFailed to wasm_runtime_call_wasm!\n"); + const char *s = wasm_runtime_get_exception(tmp_module_env.wasm_module_inst); + printf("exception: %s\n", s); + goto test_failed; + } + + wasm_runtime_detach_shared_heap(tmp_module_env.wasm_module_inst); + + EXPECT_EQ(10, argv[0]); + + destroy_module_env(tmp_module_env); + return; +test_failed: + destroy_module_env(tmp_module_env); + EXPECT_EQ(1, 0); +} diff --git a/tests/unit/shared-heap/wasm-apps/CMakeLists.txt b/tests/unit/shared-heap/wasm-apps/CMakeLists.txt new file mode 100644 index 0000000000..3627a2c144 --- /dev/null +++ b/tests/unit/shared-heap/wasm-apps/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (C) 2024 Xiaomi Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required(VERSION 3.14) +project(wasm-apps) + +set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../..) + +set(CMAKE_SYSTEM_PROCESSOR wasm32) +set(CMAKE_SYSROOT ${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot) + +if (NOT DEFINED WASI_SDK_DIR) + set(WASI_SDK_DIR "/opt/wasi-sdk") +endif () + +set(CMAKE_C_FLAGS "-nostdlib -pthread -Qunused-arguments") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -z stack-size=8192 -nostdlib -O0") +set(CMAKE_C_COMPILER_TARGET "wasm32") +set(CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang") + +set(DEFINED_SYMBOLS + "${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt") + +set(CMAKE_EXE_LINKER_FLAGS + "-Wl,--no-entry \ + -Wl,--initial-memory=65536 \ + -Wl,--export-all \ + -Wl,--allow-undefined" + ) + +add_executable(test.wasm test.c) +target_link_libraries(test.wasm) + +add_custom_command(TARGET test.wasm POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_BINARY_DIR}/test.wasm + ${CMAKE_CURRENT_BINARY_DIR}/../ + COMMENT "Copy test.wasm to the same directory of google test" + ) \ No newline at end of file diff --git a/tests/unit/shared-heap/wasm-apps/test.c b/tests/unit/shared-heap/wasm-apps/test.c new file mode 100644 index 0000000000..b83ee64ffa --- /dev/null +++ b/tests/unit/shared-heap/wasm-apps/test.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2024 Xiaomi Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include + +extern void * +shared_heap_malloc(int size); +extern void +shared_heap_free(void *offset); + +int +test() +{ + int *ptr = (int *)shared_heap_malloc(10); + + *ptr = 10; + int a = *ptr; + shared_heap_free(ptr); + return a; +} diff --git a/tests/unit/wasm-vm/wasm-apps/binarydump b/tests/unit/wasm-vm/wasm-apps/binarydump deleted file mode 100755 index e7c4d2a1da..0000000000 Binary files a/tests/unit/wasm-vm/wasm-apps/binarydump and /dev/null differ diff --git a/tests/unit/wasm-vm/wasm-apps/build.sh b/tests/unit/wasm-vm/wasm-apps/build.sh index dbf062ae7a..28496ff2f2 100755 --- a/tests/unit/wasm-vm/wasm-apps/build.sh +++ b/tests/unit/wasm-vm/wasm-apps/build.sh @@ -1,6 +1,17 @@ # Copyright (C) 2019 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +readonly CURR_DIR=$PWD +readonly BINARYDUMP_DIR=$PWD/../../../../test-tools/binarydump-tool + +# build binarydump +cd $BINARYDUMP_DIR +mkdir -p build && cd build +cmake .. && make -j +cp -a binarydump $CURR_DIR + +cd $CURR_DIR + ## build app1 /opt/wasi-sdk/bin/clang -O3 \ -z stack-size=4096 -Wl,--initial-memory=65536 \ diff --git a/tests/wamr-test-suites/spec-test-script/memory64_ignore_cases.patch b/tests/wamr-test-suites/spec-test-script/memory64_ignore_cases.patch index 5e7afd9d18..afd0536d9e 100644 --- a/tests/wamr-test-suites/spec-test-script/memory64_ignore_cases.patch +++ b/tests/wamr-test-suites/spec-test-script/memory64_ignore_cases.patch @@ -1,5 +1,5 @@ diff --git a/test/core/address.wast b/test/core/address.wast -index 8e52030..de0d0cb 100644 +index 8e52030e..de0d0cb9 100644 --- a/test/core/address.wast +++ b/test/core/address.wast @@ -210,7 +210,7 @@ @@ -12,7 +12,7 @@ index 8e52030..de0d0cb 100644 "(memory 1)" "(func (drop (i32.load offset=4294967296 (i32.const 0))))" diff --git a/test/core/binary.wast b/test/core/binary.wast -index 4090b2c..18f66b4 100644 +index 4090b2cd..18f66b42 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -206,7 +206,7 @@ @@ -70,7 +70,7 @@ index 4090b2c..18f66b4 100644 ;; Start section (module binary diff --git a/test/core/data.wast b/test/core/data.wast -index 4f339be..0b5b3e6 100644 +index 4f339bed..0b5b3e6b 100644 --- a/test/core/data.wast +++ b/test/core/data.wast @@ -306,9 +306,10 @@ @@ -124,7 +124,7 @@ index 4f339be..0b5b3e6 100644 ;; Invalid offsets diff --git a/test/core/elem.wast b/test/core/elem.wast -index 575ecef..dd1106c 100644 +index 575ecef8..dd1106c7 100644 --- a/test/core/elem.wast +++ b/test/core/elem.wast @@ -562,6 +562,7 @@ @@ -151,7 +151,7 @@ index 575ecef..dd1106c 100644 (assert_return (invoke $module1 "call-9") (i32.const 70)) +;) diff --git a/test/core/global.wast b/test/core/global.wast -index e40a305..8f8f25b 100644 +index e40a305f..8f8f25bb 100644 --- a/test/core/global.wast +++ b/test/core/global.wast @@ -328,10 +328,12 @@ @@ -168,7 +168,7 @@ index e40a305..8f8f25b 100644 (assert_invalid (module (global (import "test" "global-i32") i32) (global i32 (global.get 0) (global.get 0))) diff --git a/test/core/if.wast b/test/core/if.wast -index 2ea45f6..b6dd504 100644 +index 2ea45f6f..b6dd5044 100644 --- a/test/core/if.wast +++ b/test/core/if.wast @@ -527,11 +527,12 @@ @@ -199,7 +199,7 @@ index 2ea45f6..b6dd504 100644 (assert_malformed (module quote diff --git a/test/core/imports.wast b/test/core/imports.wast -index 69f76a0..a3844c6 100644 +index 69f76a0b..a3844c65 100644 --- a/test/core/imports.wast +++ b/test/core/imports.wast @@ -572,6 +572,7 @@ @@ -219,7 +219,7 @@ index 69f76a0..a3844c6 100644 ;; Syntax errors diff --git a/test/core/linking.wast b/test/core/linking.wast -index 994e0f4..d0bfb5f 100644 +index 994e0f49..d0bfb5f6 100644 --- a/test/core/linking.wast +++ b/test/core/linking.wast @@ -64,6 +64,7 @@ @@ -376,7 +376,7 @@ index 994e0f4..d0bfb5f 100644 (assert_return (invoke $Ms "get table[0]") (i32.const 0xdead)) +;) diff --git a/test/core/memory.wast b/test/core/memory.wast -index 1dd5b84..497b69f 100644 +index 1dd5b845..497b69fc 100644 --- a/test/core/memory.wast +++ b/test/core/memory.wast @@ -76,17 +76,17 @@ @@ -404,7 +404,7 @@ index 1dd5b84..497b69f 100644 (module diff --git a/test/core/ref_func.wast b/test/core/ref_func.wast -index adb5cb7..590f626 100644 +index adb5cb78..590f6262 100644 --- a/test/core/ref_func.wast +++ b/test/core/ref_func.wast @@ -4,7 +4,8 @@ @@ -417,8 +417,65 @@ index adb5cb7..590f626 100644 (func $g (param $x i32) (result i32) (i32.add (local.get $x) (i32.const 1)) ) +diff --git a/test/core/table.wast b/test/core/table.wast +index 1b6afe9b..45dd1145 100644 +--- a/test/core/table.wast ++++ b/test/core/table.wast +@@ -8,16 +8,20 @@ + (module (table 0 65536 funcref)) + (module (table 0 0xffff_ffff funcref)) + ++(; TODO: wabt not unsupported gc yet + (module (table 1 (ref null func))) + (module (table 1 (ref null extern))) + (module (table 1 (ref null $t)) (type $t (func))) ++;) + + (module (table 0 funcref) (table 0 funcref)) + (module (table (import "spectest" "table") 0 funcref) (table 0 funcref)) + ++(; TODO: wabt not unsupported gc yet + (module (table 0 funcref (ref.null func))) + (module (table 1 funcref (ref.null func))) + (module (table 1 (ref null func) (ref.null func))) ++;) + + (assert_invalid (module (elem (i32.const 0))) "unknown table") + (assert_invalid (module (elem (i32.const 0) $f) (func $f)) "unknown table") +@@ -31,6 +35,7 @@ + "size minimum must not be greater than maximum" + ) + ++(; TODO: wabt not unsupported gc yet + (assert_invalid + (module quote "(table 0x1_0000_0000 funcref)") + "table size must be at most 2^32-1" +@@ -43,6 +48,7 @@ + (module quote "(table 0 0x1_0000_0000 funcref)") + "table size must be at most 2^32-1" + ) ++;) + + ;; Same as above but with i64 index types + +@@ -71,6 +77,7 @@ + (assert_invalid (module (elem (i32.const 0))) "unknown table") + (assert_invalid (module (elem (i32.const 0) $f) (func $f)) "unknown table") + ++(; TODO: wabt not unsupported gc yet + (assert_invalid + (module (table 1 (ref null func) (i32.const 0))) + "type mismatch" +@@ -159,6 +166,7 @@ + ) + "type mismatch" + ) ++;) + + + ;; Duplicate table identifiers diff --git a/test/core/table_copy.wast b/test/core/table_copy.wast -index 380e84e..f37e745 100644 +index 613fc529..abeca22c 100644 --- a/test/core/table_copy.wast +++ b/test/core/table_copy.wast @@ -14,11 +14,12 @@ @@ -728,8 +785,46 @@ index 380e84e..f37e745 100644 (table $t0 30 30 funcref) (table $t1 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) +diff --git a/test/core/table_grow.wast b/test/core/table_grow.wast +index e0872d78..6a84f239 100644 +--- a/test/core/table_grow.wast ++++ b/test/core/table_grow.wast +@@ -147,19 +147,20 @@ + ) + (register "grown-table" $Tgt) + (assert_return (invoke $Tgt "grow") (i32.const 1)) ;; now size is 2 +-(module $Tgit1 +- ;; imported table limits should match, because external table size is 2 now +- (table (export "table") (import "grown-table" "table") 2 funcref) +- (func (export "grow") (result i32) (table.grow (ref.null func) (i32.const 1))) +-) +-(register "grown-imported-table" $Tgit1) +-(assert_return (invoke $Tgit1 "grow") (i32.const 2)) ;; now size is 3 +-(module $Tgit2 +- ;; imported table limits should match, because external table size is 3 now +- (import "grown-imported-table" "table" (table 3 funcref)) +- (func (export "size") (result i32) (table.size)) +-) +-(assert_return (invoke $Tgit2 "size") (i32.const 3)) ++;; TODO: No dynnamic linking yet ++;; (module $Tgit1 ++;; ;; imported table limits should match, because external table size is 2 now ++;; (table (export "table") (import "grown-table" "table") 2 funcref) ++;; (func (export "grow") (result i32) (table.grow (ref.null func) (i32.const 1))) ++;; ) ++;; (register "grown-imported-table" $Tgit1) ++;; (assert_return (invoke $Tgit1 "grow") (i32.const 2)) ;; now size is 3 ++;; (module $Tgit2 ++;; ;; imported table limits should match, because external table size is 3 now ++;; (import "grown-imported-table" "table" (table 3 funcref)) ++;; (func (export "size") (result i32) (table.size)) ++;; ) ++;; (assert_return (invoke $Tgit2 "size") (i32.const 3)) + + + ;; Type errors diff --git a/test/core/table_init.wast b/test/core/table_init.wast -index 0b2d26f..bdab6a0 100644 +index 5c3679ab..76782794 100644 --- a/test/core/table_init.wast +++ b/test/core/table_init.wast @@ -14,11 +14,12 @@ @@ -749,8 +844,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) -@@ -72,11 +73,12 @@ + (table $t2 i64 30 30 funcref) +@@ -73,11 +74,12 @@ (module (type (func (result i32))) ;; type #0 @@ -767,8 +862,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) -@@ -130,11 +132,12 @@ + (table $t2 i64 30 30 funcref) +@@ -132,11 +134,12 @@ (module (type (func (result i32))) ;; type #0 @@ -785,8 +880,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) -@@ -196,11 +199,12 @@ + (table $t2 i64 30 30 funcref) +@@ -199,11 +202,12 @@ (module (type (func (result i32))) ;; type #0 @@ -803,8 +898,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) -@@ -254,11 +258,12 @@ + (table $t2 i64 30 30 funcref) +@@ -258,11 +262,12 @@ (module (type (func (result i32))) ;; type #0 @@ -821,8 +916,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) -@@ -312,11 +317,12 @@ + (table $t2 i64 30 30 funcref) +@@ -317,11 +322,12 @@ (module (type (func (result i32))) ;; type #0 @@ -839,9 +934,63 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) + (table $t2 i64 30 30 funcref) +@@ -384,11 +390,12 @@ + + (module + (type (func (result i32))) ;; type #0 +- (import "a" "ef0" (func (result i32))) ;; index 0 +- (import "a" "ef1" (func (result i32))) +- (import "a" "ef2" (func (result i32))) +- (import "a" "ef3" (func (result i32))) +- (import "a" "ef4" (func (result i32))) ;; index 4 ++ ;; aot mode does not support module linking ++ (func (result i32) (i32.const 0)) ;; index 0 ++ (func (result i32) (i32.const 1)) ++ (func (result i32) (i32.const 2)) ++ (func (result i32) (i32.const 3)) ++ (func (result i32) (i32.const 4)) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) +@@ -443,11 +450,12 @@ + + (module + (type (func (result i32))) ;; type #0 +- (import "a" "ef0" (func (result i32))) ;; index 0 +- (import "a" "ef1" (func (result i32))) +- (import "a" "ef2" (func (result i32))) +- (import "a" "ef3" (func (result i32))) +- (import "a" "ef4" (func (result i32))) ;; index 4 ++ ;; aot mode does not support module linking ++ (func (result i32) (i32.const 0)) ;; index 0 ++ (func (result i32) (i32.const 1)) ++ (func (result i32) (i32.const 2)) ++ (func (result i32) (i32.const 3)) ++ (func (result i32) (i32.const 4)) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) +@@ -502,11 +510,12 @@ + + (module + (type (func (result i32))) ;; type #0 +- (import "a" "ef0" (func (result i32))) ;; index 0 +- (import "a" "ef1" (func (result i32))) +- (import "a" "ef2" (func (result i32))) +- (import "a" "ef3" (func (result i32))) +- (import "a" "ef4" (func (result i32))) ;; index 4 ++ ;; aot mode does not support module linking ++ (func (result i32) (i32.const 0)) ;; index 0 ++ (func (result i32) (i32.const 1)) ++ (func (result i32) (i32.const 2)) ++ (func (result i32) (i32.const 3)) ++ (func (result i32) (i32.const 4)) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) diff --git a/test/core/unreached-valid.wast b/test/core/unreached-valid.wast -index b7ebabf..4f2abfb 100644 +index b7ebabfd..4f2abfbf 100644 --- a/test/core/unreached-valid.wast +++ b/test/core/unreached-valid.wast @@ -46,6 +46,7 @@ diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index 87e1568658..70a8b687cb 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -375,7 +375,7 @@ function sightglass_test() function setup_wabt() { - WABT_VERSION=1.0.34 + WABT_VERSION=1.0.36 if [ ${WABT_BINARY_RELEASE} == "YES" ]; then echo "download a binary release and install" local WAT2WASM=${WORK_DIR}/wabt/out/gcc/Release/wat2wasm @@ -384,7 +384,7 @@ function setup_wabt() cosmopolitan) ;; linux) - WABT_PLATFORM=ubuntu + WABT_PLATFORM=ubuntu-20.04 ;; darwin) WABT_PLATFORM=macos-12 @@ -502,6 +502,8 @@ function spec_test() # Reset to commit: "Merge remote-tracking branch 'upstream/main' into merge2" git reset --hard 48e69f394869c55b7bbe14ac963c09f4605490b6 git checkout 044d0d2e77bdcbe891f7e0b9dd2ac01d56435f0b -- test/core/elem.wast test/core/data.wast + # Patch table64 extension + git checkout 940398cd4823522a9b36bec4984be4b153dedb81 -- test/core/call_indirect.wast test/core/table.wast test/core/table_copy.wast test/core/table_copy_mixed.wast test/core/table_fill.wast test/core/table_get.wast test/core/table_grow.wast test/core/table_init.wast test/core/table_set.wast test/core/table_size.wast git apply ../../spec-test-script/memory64_ignore_cases.patch || exit 1 elif [[ ${ENABLE_MULTI_MEMORY} == 1 ]]; then echo "checkout spec for multi memory proposal" diff --git a/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index 2ab0462b20..ab98b03825 100644 --- a/wamr-compiler/CMakeLists.txt +++ b/wamr-compiler/CMakeLists.txt @@ -163,17 +163,10 @@ endif() # Enable LLVM if (NOT WAMR_BUILD_WITH_CUSTOM_LLVM) set (LLVM_SRC_ROOT "${PROJECT_SOURCE_DIR}/../core/deps/llvm") - if (WAMR_BUILD_PLATFORM STREQUAL "windows") - if (NOT EXISTS "${LLVM_SRC_ROOT}/win32build") - message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/win32build") - endif () - set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/win32build;${CMAKE_PREFIX_PATH}") - else() - if (NOT EXISTS "${LLVM_SRC_ROOT}/build") - message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build") - endif () - set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}") + if (NOT EXISTS "${LLVM_SRC_ROOT}/build") + message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build") endif () + set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}") endif () find_package(LLVM REQUIRED CONFIG) @@ -223,24 +216,14 @@ include_directories (${SHARED_DIR}/include enable_language (ASM) -if (NOT MINGW AND NOT MSVC) - if ((NOT DEFINED WAMR_BUILD_LIBC_WASI) AND (NOT DEFINED WAMR_BUILD_LIBC_UVWASI)) - set (WAMR_BUILD_LIBC_WASI 1) - endif () - - if ((WAMR_BUILD_LIBC_WASI EQUAL 1) AND (WAMR_BUILD_LIBC_UVWASI EQUAL 1)) - message (WARNING "-- pick WAMR_BULID_LIBC_UVWASI when both are enabled") - set (WAMR_BUILD_LIBC_WASI 0) - endif () -else () - if (NOT DEFINED WAMR_BUILD_LIBC_UVWASI) - set (WAMR_BUILD_LIBC_UVWASI 1) - endif () +if ((NOT DEFINED WAMR_BUILD_LIBC_WASI) AND (NOT DEFINED WAMR_BUILD_LIBC_UVWASI)) + # Enable WAMR_BUILD_LIBC_WASI if both are not set + set (WAMR_BUILD_LIBC_WASI 1) +endif () - if (WAMR_BUILD_LIBC_WASI EQUAL 1) - message (WARNING "-- don't accept WAMR_BUILD_LIBC_WASI=1 on MINGW or MSVC") - set (WAMR_BUILD_LIBC_WASI 0) - endif () +if ((WAMR_BUILD_LIBC_WASI EQUAL 1) AND (WAMR_BUILD_LIBC_UVWASI EQUAL 1)) + message (WARNING "-- pick WAMR_BULID_LIBC_UVWASI when both are enabled") + set (WAMR_BUILD_LIBC_WASI 0) endif () if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN) @@ -308,6 +291,16 @@ if (WAMR_BUILD_LIBC_WASI EQUAL 1) include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake) endif () +if (WAMR_BUILD_LIBC_WASI EQUAL 1) + # Enable _Static_assert + set (CMAKE_C_STANDARD 11) + if (MSVC) + add_compile_options(/experimental:c11atomics) + endif() +else() + set (CMAKE_C_STANDARD 99) +endif() + if (WAMR_BUILD_LIB_PTHREAD EQUAL 1) include (${IWASM_DIR}/libraries/lib-pthread/lib_pthread.cmake) endif () diff --git a/wamr-compiler/main.c b/wamr-compiler/main.c index 8dca712cd1..3efe344e6a 100644 --- a/wamr-compiler/main.c +++ b/wamr-compiler/main.c @@ -206,6 +206,7 @@ print_help() printf(" --enable-linux-perf Enable linux perf support\n"); #endif printf(" --mllvm=