diff --git a/.github/actions/binary-compatible-builds/main.js b/.github/actions/binary-compatible-builds/main.js index 6230126fcb81..378c5c202c9c 100755 --- a/.github/actions/binary-compatible-builds/main.js +++ b/.github/actions/binary-compatible-builds/main.js @@ -34,7 +34,7 @@ if (process.env.CENTOS !== undefined) { return; } -const name = process.env.INPUT_NAME.replace(/-min$/, ''); +const name = process.env.INPUT_NAME; child_process.execFileSync('docker', [ 'build', diff --git a/.github/actions/install-rust/action.yml b/.github/actions/install-rust/action.yml index b15c33c0a4cd..003c994f6dfc 100644 --- a/.github/actions/install-rust/action.yml +++ b/.github/actions/install-rust/action.yml @@ -61,14 +61,6 @@ runs: CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse EOF - - name: Require semicolons in WIT - shell: bash - run: echo WIT_REQUIRE_SEMICOLONS=1 >> "$GITHUB_ENV" - - - name: Install the WASI target - shell: bash - run: rustup target add wasm32-wasi wasm32-unknown-unknown - - name: Choose registry cache key shell: bash # Update the registry index cache at most once per day. actions/cache diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fa44e2d9bb38..d5b777e48338 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -125,7 +125,6 @@ jobs: outputs: run-full: ${{ steps.calculate.outputs.run-full }} test-matrix: ${{ steps.calculate.outputs.test-matrix }} - build-matrix: ${{ steps.calculate.outputs.build-matrix }} test-capi: ${{ steps.calculate.outputs.test-capi }} build-fuzz: ${{ steps.calculate.outputs.build-fuzz }} audit: ${{ steps.calculate.outputs.audit }} @@ -171,9 +170,6 @@ jobs: echo "test-matrix={\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT echo "$matrix" - matrix="$(node ./ci/build-build-matrix.js)" - echo "build-matrix={\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT - if [ "$run_full" = "true" ]; then echo run-full=true >> $GITHUB_OUTPUT echo test-capi=true >> $GITHUB_OUTPUT @@ -200,7 +196,7 @@ jobs: submodules: true - uses: ./.github/actions/install-rust with: - toolchain: nightly-2023-10-10 + toolchain: nightly-2023-07-02 # Build C API documentation - run: curl -L https://sourceforge.net/projects/doxygen/files/rel-1.9.3/doxygen-1.9.3.linux.bin.tar.gz/download | tar xzf - @@ -270,7 +266,8 @@ jobs: # Check some feature combinations of the `wasmtime` crate - run: cargo check -p wasmtime --no-default-features - run: cargo check -p wasmtime --no-default-features --features wat - - run: cargo check -p wasmtime --no-default-features --features profiling + - run: cargo check -p wasmtime --no-default-features --features jitdump + - run: cargo check -p wasmtime --no-default-features --features vtune - run: cargo check -p wasmtime --no-default-features --features cache - run: cargo check -p wasmtime --no-default-features --features async - run: cargo check -p wasmtime --no-default-features --features pooling-allocator @@ -279,20 +276,12 @@ jobs: - run: cargo check -p wasmtime --no-default-features --features cranelift,wat,async,cache - run: cargo check -p wasmtime --no-default-features --features winch - run: cargo check -p wasmtime --no-default-features --features wmemcheck - - run: cargo check -p wasmtime --no-default-features --features demangle - - run: cargo check -p wasmtime --no-default-features --features addr2line - run: cargo check --features component-model - run: cargo check -p wasmtime --features incremental-cache - # Feature combinations of the `wasmtime-cli` - - run: cargo check -p wasmtime-cli --no-default-features - # Check that benchmarks of the cranelift project build - run: cargo check --benches -p cranelift-codegen - # Check that the bench-api compiles - - run: cargo check -p wasmtime-bench-api - # Check some feature combinations of the `wasmtime-c-api` crate - run: cargo check -p wasmtime-c-api --no-default-features - run: cargo check -p wasmtime-c-api --no-default-features --features wat @@ -367,7 +356,7 @@ jobs: # flags to rustc. - uses: ./.github/actions/install-rust with: - toolchain: nightly-2023-10-10 + toolchain: nightly-2023-07-02 - run: cargo install cargo-fuzz --vers "^0.11" # Install the OCaml packages necessary for fuzz targets that use the # `wasm-spec-interpreter`. @@ -394,9 +383,9 @@ jobs: name: ${{ matrix.name }} runs-on: ${{ matrix.os }} env: - QEMU_BUILD_VERSION: 8.1.1 + QEMU_BUILD_VERSION: 8.0.4 strategy: - fail-fast: false + fail-fast: true matrix: ${{ fromJson(needs.determine.outputs.test-matrix) }} steps: - uses: actions/checkout@v3 @@ -416,6 +405,8 @@ jobs: if: matrix.target == 'x86_64-pc-windows-gnu' - run: cargo fetch --locked + - run: cargo fetch --locked --manifest-path crates/test-programs/wasi-tests/Cargo.toml + - run: cargo fetch --locked --manifest-path crates/test-programs/wasi-http-tests/Cargo.toml - uses: actions/cache@v3 with: @@ -453,6 +444,7 @@ jobs: # quickly. curl https://download.qemu.org/qemu-$QEMU_BUILD_VERSION.tar.xz | tar xJf - cd qemu-$QEMU_BUILD_VERSION + patch -p1 < $GITHUB_WORKSPACE/ci/qemu-cpuinfo.patch ./configure --target-list=${{ matrix.qemu_target }} --prefix=${{ runner.tool_cache}}/qemu --disable-tools --disable-slirp --disable-fdt --disable-capstone --disable-docs ninja -C build install touch ${{ runner.tool_cache }}/qemu/built @@ -510,7 +502,7 @@ jobs: submodules: true - uses: ./.github/actions/install-rust - run: rustup target add wasm32-wasi - - uses: abrown/install-openvino-action@v7 + - uses: abrown/install-openvino-action@v6 with: version: 2022.3.0 apt: true @@ -648,7 +640,7 @@ jobs: submodules: true - uses: ./.github/actions/install-rust with: - toolchain: nightly-2023-10-10 + toolchain: nightly-2023-07-02 - run: rustup component add rust-src miri - uses: actions/cache@v3 with: @@ -674,28 +666,40 @@ jobs: # Perform release builds of `wasmtime` and `libwasmtime.so`. Builds a variety # of platforms and architectures and then uploads the release artifacts to # this workflow run's list of artifacts. - # - # Note that the full matrix is computed by `ci/build-build-matrix.js`. build: needs: determine if: needs.determine.outputs.run-full name: Release build for ${{ matrix.build }} runs-on: ${{ matrix.os }} strategy: - fail-fast: false - matrix: ${{ fromJson(needs.determine.outputs.build-matrix) }} + matrix: + include: + - build: x86_64-linux + os: ubuntu-latest + - build: x86_64-macos + os: macos-latest + - build: aarch64-macos + os: macos-latest + target: aarch64-apple-darwin + - build: x86_64-windows + os: windows-latest + - build: x86_64-mingw + os: windows-latest + target: x86_64-pc-windows-gnu + - build: aarch64-linux + os: ubuntu-latest + target: aarch64-unknown-linux-gnu + - build: s390x-linux + os: ubuntu-latest + target: s390x-unknown-linux-gnu + - build: riscv64gc-linux + os: ubuntu-latest + target: riscv64gc-unknown-linux-gnu steps: - uses: actions/checkout@v3 with: submodules: true - - uses: ./.github/actions/install-rust - with: - toolchain: ${{ matrix.rust }} - - run: | - rustup component add rust-src - rustup target add ${{ matrix.target }} - # On one builder produce the source tarball since there's no need to produce # it everywhere - run: ./ci/build-src-tarball.sh @@ -703,13 +707,21 @@ jobs: - uses: ./.github/actions/binary-compatible-builds with: name: ${{ matrix.build }} + - run: | + echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV + rustup target add ${{ matrix.target }} + if: matrix.target != '' + + # Build `wasmtime` and executables. Note that we include some non-default + # features so the # release artifacts can be maximally feature-ful. + - run: $CENTOS cargo build --release --bin wasmtime --features all-arch,component-model - - run: $CENTOS ./ci/build-release-artifacts.sh "${{ matrix.build }}" "${{ matrix.target }}" + # Build `libwasmtime.so` + - run: $CENTOS cargo build --release --manifest-path crates/c-api/Cargo.toml - # Assemble release artifacts appropriate for this platform, then upload them + # Assemble release artifats appropriate for this platform, then upload them # unconditionally to this workflow's files so we have a copy of them. - run: ./ci/build-tarballs.sh "${{ matrix.build }}" "${{ matrix.target }}" - - uses: actions/upload-artifact@v3 with: name: bins-${{ matrix.build }} diff --git a/.github/workflows/publish-artifacts.yml b/.github/workflows/publish-artifacts.yml index 8c149003dc91..e036474d24eb 100644 --- a/.github/workflows/publish-artifacts.yml +++ b/.github/workflows/publish-artifacts.yml @@ -28,8 +28,6 @@ jobs: env: GH_TOKEN: ${{ github.token }} - - run: ./ci/merge-artifacts.sh - # Deploy the `gh-pages.tar.gz` artifact to the `gh-pages` branch. - run: tar xf gh-pages.tar.gz working-directory: gh-pages @@ -43,6 +41,10 @@ jobs: - run: npm install --production working-directory: .github/actions/github-release + - run: | + mkdir dist + mv -t dist bins-*/*.tar.* + mv -t dist bins-*/*.{zip,msi,wasm} - name: Publish Release uses: ./.github/actions/github-release with: diff --git a/.gitignore b/.gitignore index 7790b83f8725..afb3ff15003f 100644 --- a/.gitignore +++ b/.gitignore @@ -21,5 +21,3 @@ foo publish vendor examples/build -examples/.cache -*.coredump diff --git a/Cargo.lock b/Cargo.lock index a0bdb3b5a96b..5aee586bfcfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,9 +106,9 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arbitrary" -version = "1.3.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" +checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" dependencies = [ "derive_arbitrary", ] @@ -194,9 +194,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "block-buffer" @@ -226,7 +226,7 @@ checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byte-array-literals" -version = "15.0.0" +version = "14.0.0" [[package]] name = "byteorder" @@ -257,7 +257,7 @@ checksum = "b779b2d0a001c125b4584ad586268fb4b92d957bff8d26d7fe0dd78283faa814" dependencies = [ "cap-primitives", "cap-std", - "io-lifetimes", + "io-lifetimes 2.0.2", "windows-sys", ] @@ -269,7 +269,7 @@ checksum = "6ffc30dee200c20b4dcb80572226f42658e1d9c4b668656d7cc59c33d50e396e" dependencies = [ "cap-primitives", "cap-std", - "rustix", + "rustix 0.38.8", "smallvec", ] @@ -282,10 +282,10 @@ dependencies = [ "ambient-authority", "fs-set-times", "io-extras", - "io-lifetimes", + "io-lifetimes 2.0.2", "ipnet", "maybe-owned", - "rustix", + "rustix 0.38.8", "windows-sys", "winx", ] @@ -308,8 +308,8 @@ checksum = "84bade423fa6403efeebeafe568fdb230e8c590a275fba2ba978dd112efcf6e9" dependencies = [ "cap-primitives", "io-extras", - "io-lifetimes", - "rustix", + "io-lifetimes 2.0.2", + "rustix 0.38.8", ] [[package]] @@ -320,7 +320,7 @@ checksum = "7b9e3348a3510c4619b4c7a7bcdef09a71221da18f266bda3ed6b9aea2c509e2" dependencies = [ "cap-std", "rand", - "rustix", + "rustix 0.38.8", "uuid", ] @@ -332,7 +332,7 @@ checksum = "f8f52b3c8f4abfe3252fd0a071f3004aaa3b18936ec97bdbd8763ce03aff6247" dependencies = [ "cap-primitives", "once_cell", - "rustix", + "rustix 0.38.8", "winx", ] @@ -484,6 +484,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "command-tests" +version = "0.0.0" +dependencies = [ + "anyhow", + "getrandom", + "wit-bindgen", +] + [[package]] name = "component-fuzz-util" version = "0.0.0" @@ -557,7 +566,7 @@ dependencies = [ [[package]] name = "cranelift" -version = "0.102.0" +version = "0.101.0" dependencies = [ "cranelift-codegen", "cranelift-frontend", @@ -565,14 +574,14 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.102.0" +version = "0.101.0" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.102.0" +version = "0.101.0" dependencies = [ "anyhow", "bincode", @@ -600,25 +609,25 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.102.0" +version = "0.101.0" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.102.0" +version = "0.101.0" [[package]] name = "cranelift-control" -version = "0.102.0" +version = "0.101.0" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.102.0" +version = "0.101.0" dependencies = [ "serde", "serde_derive", @@ -650,7 +659,6 @@ dependencies = [ "serde", "serde_derive", "similar", - "smallvec", "target-lexicon", "thiserror", "toml", @@ -660,7 +668,7 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.102.0" +version = "0.101.0" dependencies = [ "cranelift-codegen", "hashbrown 0.14.0", @@ -684,7 +692,7 @@ dependencies = [ [[package]] name = "cranelift-interpreter" -version = "0.102.0" +version = "0.101.0" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -698,7 +706,7 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.102.0" +version = "0.101.0" dependencies = [ "codespan-reporting", "log", @@ -707,7 +715,7 @@ dependencies = [ [[package]] name = "cranelift-jit" -version = "0.102.0" +version = "0.101.0" dependencies = [ "anyhow", "cranelift", @@ -728,7 +736,7 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.102.0" +version = "0.101.0" dependencies = [ "anyhow", "cranelift-codegen", @@ -740,7 +748,7 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.102.0" +version = "0.101.0" dependencies = [ "cranelift-codegen", "libc", @@ -749,7 +757,7 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.102.0" +version = "0.101.0" dependencies = [ "anyhow", "cranelift-codegen", @@ -764,7 +772,7 @@ dependencies = [ [[package]] name = "cranelift-reader" -version = "0.102.0" +version = "0.101.0" dependencies = [ "anyhow", "cranelift-codegen", @@ -774,7 +782,7 @@ dependencies = [ [[package]] name = "cranelift-serde" -version = "0.102.0" +version = "0.101.0" dependencies = [ "clap", "cranelift-codegen", @@ -821,7 +829,7 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.102.0" +version = "0.101.0" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1134,9 +1142,12 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fastrand" -version = "2.0.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] [[package]] name = "fd-lock" @@ -1145,7 +1156,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b0377f1edc77dbd1118507bc7a66e4ab64d2b90c66f90726dc801e73a8c68f9" dependencies = [ "cfg-if", - "rustix", + "rustix 0.38.8", "windows-sys", ] @@ -1208,8 +1219,8 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd738b84894214045e8414eaded76359b4a5773f0a0a56b16575110739cdcf39" dependencies = [ - "io-lifetimes", - "rustix", + "io-lifetimes 2.0.2", + "rustix 0.38.8", "windows-sys", ] @@ -1299,7 +1310,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.3.3", "debugid", "fxhash", "serde", @@ -1579,7 +1590,18 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d3c230ee517ee76b1cc593b52939ff68deda3fae9e41eca426c6b4993df51c4" dependencies = [ - "io-lifetimes", + "io-lifetimes 2.0.2", + "windows-sys", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.0", + "libc", "windows-sys", ] @@ -1597,12 +1619,13 @@ checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.0", - "rustix", + "io-lifetimes 1.0.10", + "rustix 0.37.13", "windows-sys", ] @@ -1642,9 +1665,9 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "ittapi" -version = "0.4.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b996fe614c41395cdaedf3cf408a9534851090959d90d54a535f675550b64b1" +checksum = "2e648c437172ce7d3ac35ca11a068755072054826fa455a916b43524fa4a62a7" dependencies = [ "anyhow", "ittapi-sys", @@ -1653,9 +1676,9 @@ dependencies = [ [[package]] name = "ittapi-sys" -version = "0.4.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5385394064fa2c886205dba02598013ce83d3e92d33dbdc0c52fe0e7bf4fc" +checksum = "a9b32a4d23f72548178dde54f3c12c6b6a08598e25575c0d0fa5bd861e0dc1a5" dependencies = [ "cc", ] @@ -1692,9 +1715,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libfuzzer-sys" @@ -1725,9 +1748,15 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "9b085a4f2cde5781fc4b1717f2e86c62f5cda49de7ba99a7c2eae02b61c9064c" + +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "listenfd" @@ -1781,11 +1810,11 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memfd" -version = "0.6.4" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" dependencies = [ - "rustix", + "rustix 0.37.13", ] [[package]] @@ -1826,16 +1855,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1947,12 +1966,6 @@ dependencies = [ "pretty_env_logger 0.4.0", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "paste" version = "1.0.7" @@ -2069,6 +2082,17 @@ dependencies = [ "cc", ] +[[package]] +name = "pulldown-cmark" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -2153,6 +2177,13 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "reactor-tests" +version = "0.1.0" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "redox_syscall" version = "0.2.13" @@ -2184,9 +2215,9 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.9.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +checksum = "5b4dcbd3a2ae7fb94b5813fa0e957c6ab51bf5d0a8ee1b69e0c2d0f1e6eb8485" dependencies = [ "hashbrown 0.13.2", "log", @@ -2281,15 +2312,29 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.21" +version = "0.37.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79bef90eb6d984c72722595b5b1348ab39275a5e5123faca6863bf07d75a4e0" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes 1.0.10", + "libc", + "linux-raw-sys 0.3.3", + "windows-sys", +] + +[[package]] +name = "rustix" +version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.3.3", "errno", "itoa", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.3", "once_cell", "windows-sys", ] @@ -2440,15 +2485,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "similar" version = "2.2.0" @@ -2577,12 +2613,12 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27ce32341b2c0b70c144bbf35627fdc1ef18c76ced5e5e7b3ee8b5ba6b2ab6a0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.3.3", "cap-fs-ext", "cap-std", "fd-lock", - "io-lifetimes", - "rustix", + "io-lifetimes 2.0.2", + "rustix 0.38.8", "windows-sys", "winx", ] @@ -2595,14 +2631,15 @@ checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix", + "rustix 0.37.13", "windows-sys", ] @@ -2641,22 +2678,27 @@ name = "test-programs" version = "0.0.0" dependencies = [ "anyhow", - "base64", - "futures", - "getrandom", - "libc", - "sha2", - "url", - "wasi", - "wit-bindgen", -] - -[[package]] -name = "test-programs-artifacts" -version = "0.0.0" -dependencies = [ + "cap-rand", + "cap-std", "cargo_metadata", + "cfg-if", "heck", + "http", + "http-body", + "http-body-util", + "hyper", + "is-terminal", + "lazy_static", + "tempfile", + "test-log", + "tokio", + "tracing", + "tracing-subscriber", + "wasi-cap-std-sync", + "wasi-common", + "wasmtime", + "wasmtime-wasi", + "wasmtime-wasi-http", "wit-component", ] @@ -2727,7 +2769,6 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", "windows-sys", @@ -2808,18 +2849,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", ] [[package]] @@ -2829,14 +2858,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", - "nu-ansi-term", "once_cell", "regex", "sharded-slab", "thread_local", "tracing", "tracing-core", - "tracing-log", ] [[package]] @@ -2851,6 +2878,15 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.8" @@ -2934,15 +2970,9 @@ dependencies = [ "which", ] -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "verify-component-adapter" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "wasmparser", @@ -2992,7 +3022,7 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi-cap-std-sync" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "async-trait", @@ -3002,9 +3032,10 @@ dependencies = [ "cap-time-ext", "fs-set-times", "io-extras", - "io-lifetimes", + "io-lifetimes 2.0.2", + "is-terminal", "once_cell", - "rustix", + "rustix 0.38.8", "system-interface", "tempfile", "tracing", @@ -3014,31 +3045,34 @@ dependencies = [ [[package]] name = "wasi-common" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", - "bitflags 2.4.1", + "bitflags 2.3.3", "cap-rand", "cap-std", "io-extras", "log", - "rustix", - "tempfile", - "test-log", - "test-programs-artifacts", + "rustix 0.38.8", "thiserror", - "tokio", "tracing", - "tracing-subscriber", "wasmtime", - "wasmtime-wasi", "wiggle", "windows-sys", ] +[[package]] +name = "wasi-http-tests" +version = "0.0.0" +dependencies = [ + "anyhow", + "tokio", + "wit-bindgen", +] + [[package]] name = "wasi-preview1-component-adapter" -version = "15.0.0" +version = "14.0.0" dependencies = [ "byte-array-literals", "object", @@ -3047,16 +3081,34 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasi-sockets-tests" +version = "0.0.0" +dependencies = [ + "anyhow", + "wit-bindgen", +] + +[[package]] +name = "wasi-tests" +version = "0.0.0" +dependencies = [ + "libc", + "once_cell", + "wasi", + "wit-bindgen", +] + [[package]] name = "wasi-tokio" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "cap-std", "cap-tempfile", "io-extras", - "io-lifetimes", - "rustix", + "io-lifetimes 2.0.2", + "rustix 0.38.8", "tempfile", "tokio", "wasi-cap-std-sync", @@ -3120,23 +3172,22 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-encoder" -version = "0.35.0" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca90ba1b5b0a70d3d49473c5579951f3bddc78d47b59256d2f9d4922b150aca" +checksum = "b39de0723a53d3c8f54bed106cfbc0d06b3e4d945c5c5022115a61e3b29183ae" dependencies = [ "leb128", ] [[package]] name = "wasm-metadata" -version = "0.10.9" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14abc161bfda5b519aa229758b68f2a52b45a12b993808665c857d1a9a00223c" +checksum = "9fab01638cbecc57afec7b53ce0e28620b44d7ae1dea53120c96dd08486c07ce" dependencies = [ "anyhow", "indexmap 2.0.0", "serde", - "serde_derive", "serde_json", "spdx", "wasm-encoder", @@ -3145,9 +3196,9 @@ dependencies = [ [[package]] name = "wasm-mutate" -version = "0.2.38" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1e04b0c049b0a0c42dd108a56c5c92500076747363d3bf1e83e7f0f8b4dfe4" +checksum = "730c1644f14f3dfa52d8c63bb26c6f3fe89ba80430f1ce29b0388e04825ec514" dependencies = [ "egg", "log", @@ -3159,9 +3210,9 @@ dependencies = [ [[package]] name = "wasm-smith" -version = "0.12.21" +version = "0.12.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef779c243bbf04d9f03333c2cb50b98047c6dcc2a1db0cc7d0691e4135064b4" +checksum = "154bb82cb9f17e5c0773e192e800094583767f752077d5116be376de747539eb" dependencies = [ "arbitrary", "flagset", @@ -3211,9 +3262,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.115.0" +version = "0.113.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e06c0641a4add879ba71ccb3a1e4278fd546f76f1eafb21d8f7b07733b547cd5" +checksum = "a128cea7b8516703ab41b10a0b1aa9ba18d0454cd3792341489947ddeee268db" dependencies = [ "indexmap 2.0.0", "semver", @@ -3230,9 +3281,9 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.2.70" +version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74458a9bc5cc9c7108abfa0fe4dc88d5abf1f3baf194df3264985f17d559b5e" +checksum = "ab2e5e818f88cee5311e9a5df15cba0a8f772978baf3109af97004bce6e8e3c6" dependencies = [ "anyhow", "wasmparser", @@ -3240,7 +3291,7 @@ dependencies = [ [[package]] name = "wasmtime" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "async-trait", @@ -3281,14 +3332,14 @@ dependencies = [ [[package]] name = "wasmtime-asm-macros" -version = "15.0.0" +version = "14.0.0" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-bench-api" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "cap-std", @@ -3305,22 +3356,12 @@ dependencies = [ [[package]] name = "wasmtime-c-api" -version = "15.0.0" -dependencies = [ - "wasmtime-c-api-impl", -] - -[[package]] -name = "wasmtime-c-api-impl" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "cap-std", "env_logger 0.10.0", - "futures", - "log", "once_cell", - "tracing", "wasi-cap-std-sync", "wasi-common", "wasmtime", @@ -3339,7 +3380,7 @@ dependencies = [ [[package]] name = "wasmtime-cache" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "base64", @@ -3349,7 +3390,7 @@ dependencies = [ "log", "once_cell", "pretty_env_logger 0.5.0", - "rustix", + "rustix 0.38.8", "serde", "serde_derive", "sha2", @@ -3361,12 +3402,11 @@ dependencies = [ [[package]] name = "wasmtime-cli" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "async-trait", "bstr", - "bytes", "clap", "component-macro-test", "component-test-util", @@ -3374,8 +3414,6 @@ dependencies = [ "env_logger 0.10.0", "expect-test", "filecheck", - "http-body-util", - "hyper", "libc", "listenfd", "log", @@ -3383,16 +3421,16 @@ dependencies = [ "num_cpus", "once_cell", "rayon", - "rustix", + "rustix 0.38.8", "serde", "serde_derive", "serde_json", "target-lexicon", "tempfile", - "test-programs-artifacts", + "test-programs", "tokio", - "tracing", "walkdir", + "wasm-encoder", "wasmparser", "wasmtime", "wasmtime-cache", @@ -3407,27 +3445,27 @@ dependencies = [ "wasmtime-wasi-nn", "wasmtime-wasi-threads", "wasmtime-wast", - "wast 66.0.2", + "wast 65.0.1", "wat", "windows-sys", ] [[package]] name = "wasmtime-cli-flags" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "clap", "file-per-thread-logger", "humantime 2.1.0", + "pretty_env_logger 0.5.0", "rayon", - "tracing-subscriber", "wasmtime", ] [[package]] name = "wasmtime-component-macro" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "component-macro-test-helpers", @@ -3443,11 +3481,11 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "15.0.0" +version = "14.0.0" [[package]] name = "wasmtime-cranelift" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "cfg-if", @@ -3470,7 +3508,7 @@ dependencies = [ [[package]] name = "wasmtime-cranelift-shared" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "cranelift-codegen", @@ -3484,9 +3522,10 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", + "atty", "clap", "cranelift-entity", "env_logger 0.10.0", @@ -3522,7 +3561,7 @@ dependencies = [ [[package]] name = "wasmtime-explorer" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "capstone", @@ -3536,13 +3575,12 @@ dependencies = [ [[package]] name = "wasmtime-fiber" -version = "15.0.0" +version = "14.0.0" dependencies = [ - "anyhow", "backtrace", "cc", "cfg-if", - "rustix", + "rustix 0.38.8", "wasmtime-asm-macros", "wasmtime-versioned-export-macros", "windows-sys", @@ -3605,7 +3643,7 @@ dependencies = [ [[package]] name = "wasmtime-jit" -version = "15.0.0" +version = "14.0.0" dependencies = [ "addr2line", "anyhow", @@ -3617,7 +3655,7 @@ dependencies = [ "log", "object", "rustc-demangle", - "rustix", + "rustix 0.38.8", "serde", "serde_derive", "target-lexicon", @@ -3630,17 +3668,17 @@ dependencies = [ [[package]] name = "wasmtime-jit-debug" -version = "15.0.0" +version = "14.0.0" dependencies = [ "object", "once_cell", - "rustix", + "rustix 0.38.8", "wasmtime-versioned-export-macros", ] [[package]] name = "wasmtime-jit-icache-coherence" -version = "15.0.0" +version = "14.0.0" dependencies = [ "cfg-if", "libc", @@ -3649,7 +3687,7 @@ dependencies = [ [[package]] name = "wasmtime-runtime" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "cc", @@ -3663,9 +3701,8 @@ dependencies = [ "memoffset", "once_cell", "paste", - "proptest", "rand", - "rustix", + "rustix 0.38.8", "sptr", "wasm-encoder", "wasmtime-asm-macros", @@ -3679,7 +3716,7 @@ dependencies = [ [[package]] name = "wasmtime-types" -version = "15.0.0" +version = "14.0.0" dependencies = [ "cranelift-entity", "serde", @@ -3690,7 +3727,7 @@ dependencies = [ [[package]] name = "wasmtime-versioned-export-macros" -version = "15.0.0" +version = "14.0.0" dependencies = [ "proc-macro2", "quote", @@ -3699,11 +3736,11 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "async-trait", - "bitflags 2.4.1", + "bitflags 2.3.3", "bytes", "cap-fs-ext", "cap-net-ext", @@ -3713,20 +3750,17 @@ dependencies = [ "fs-set-times", "futures", "io-extras", - "io-lifetimes", + "io-lifetimes 2.0.2", + "is-terminal", "libc", - "log", "once_cell", - "rustix", + "rustix 0.38.8", "system-interface", - "tempfile", "test-log", - "test-programs-artifacts", "thiserror", "tokio", "tracing", "tracing-subscriber", - "url", "wasi-cap-std-sync", "wasi-common", "wasi-tokio", @@ -3737,11 +3771,10 @@ dependencies = [ [[package]] name = "wasmtime-wasi-http" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "async-trait", - "base64", "bytes", "futures", "http", @@ -3749,13 +3782,10 @@ dependencies = [ "http-body-util", "hyper", "rustls", - "sha2", - "test-log", - "test-programs-artifacts", + "thiserror", "tokio", "tokio-rustls", "tracing", - "tracing-subscriber", "wasmtime", "wasmtime-wasi", "webpki-roots", @@ -3763,7 +3793,7 @@ dependencies = [ [[package]] name = "wasmtime-wasi-nn" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "openvino", @@ -3776,7 +3806,7 @@ dependencies = [ [[package]] name = "wasmtime-wasi-threads" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "log", @@ -3788,17 +3818,17 @@ dependencies = [ [[package]] name = "wasmtime-wast" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "log", "wasmtime", - "wast 66.0.2", + "wast 65.0.1", ] [[package]] name = "wasmtime-winch" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "cranelift-codegen", @@ -3813,7 +3843,7 @@ dependencies = [ [[package]] name = "wasmtime-wit-bindgen" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "heck", @@ -3823,7 +3853,7 @@ dependencies = [ [[package]] name = "wasmtime-wmemcheck" -version = "15.0.0" +version = "14.0.0" [[package]] name = "wast" @@ -3836,9 +3866,9 @@ dependencies = [ [[package]] name = "wast" -version = "66.0.2" +version = "65.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93cb43b0ac6dd156f2c375735ccfd72b012a7c0a6e6d09503499b8d3cb6e6072" +checksum = "5fd8c1cbadf94a0b0d1071c581d3cfea1b7ed5192c79808dd15406e508dd0afb" dependencies = [ "leb128", "memchr", @@ -3848,11 +3878,11 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.77" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e367582095d2903caeeea9acbb140e1db9c7677001efa4347c3687fd34fe7072" +checksum = "3209e35eeaf483714f4c6be93f4a03e69aad5f304e3fa66afa7cb90fe1c8051f" dependencies = [ - "wast 66.0.2", + "wast 65.0.1", ] [[package]] @@ -3884,11 +3914,11 @@ dependencies = [ [[package]] name = "wiggle" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "async-trait", - "bitflags 2.4.1", + "bitflags 2.3.3", "proptest", "thiserror", "tokio", @@ -3901,7 +3931,7 @@ dependencies = [ [[package]] name = "wiggle-generate" -version = "15.0.0" +version = "14.0.0" dependencies = [ "anyhow", "heck", @@ -3914,7 +3944,7 @@ dependencies = [ [[package]] name = "wiggle-macro" -version = "15.0.0" +version = "14.0.0" dependencies = [ "proc-macro2", "quote", @@ -3969,7 +3999,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winch-codegen" -version = "0.13.0" +version = "0.12.0" dependencies = [ "anyhow", "cranelift-codegen", @@ -4102,25 +4132,25 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4857cedf8371f690bb6782a3e2b065c54d1b6661be068aaf3eac8b45e813fdf8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.3.3", "windows-sys", ] [[package]] name = "wit-bindgen" -version = "0.13.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d92ce0ca6b6074059413a9581a637550c3a740581c854f9847ec293c8aed71" +checksum = "f8a3e8e965dc50e6eb4410d9a11720719fadc6a1713803ea5f3be390b81c8279" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.3.3", "wit-bindgen-rust-macro", ] [[package]] name = "wit-bindgen-core" -version = "0.13.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "565b945ae074886071eccf9cdaf8ccd7b959c2b0d624095bea5fe62003e8b3e0" +checksum = "77255512565dfbd0b61de466e854918041d1da53c7bc049d6188c6e02643dc1e" dependencies = [ "anyhow", "wit-component", @@ -4129,44 +4159,54 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.13.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5695ff4e41873ed9ce56d2787e6b5772bdad9e70e2c1d2d160621d1762257f4f" +checksum = "399c60e6ea8598d1380e792f13d557007834f0fb799fea6503408cbc5debb4ae" dependencies = [ "anyhow", "heck", "wasm-metadata", "wit-bindgen-core", + "wit-bindgen-rust-lib", "wit-component", ] +[[package]] +name = "wit-bindgen-rust-lib" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fb7a43c7dc28b0b727d6ae01bf369981229b7539e768fba2b7a4df13feeeb" +dependencies = [ + "heck", + "wit-bindgen-core", +] + [[package]] name = "wit-bindgen-rust-macro" -version = "0.13.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91835ea4231da1fe7971679d505ba14be7826e192b6357f08465866ef482e08" +checksum = "44cea5ed784da06da0e55836a6c160e7502dbe28771c2368a595e8606243bf22" dependencies = [ "anyhow", "proc-macro2", - "quote", "syn 2.0.29", "wit-bindgen-core", "wit-bindgen-rust", + "wit-bindgen-rust-lib", "wit-component", ] [[package]] name = "wit-component" -version = "0.16.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e87488b57a08e2cbbd076b325acbe7f8666965af174d69d5929cd373bd54547f" +checksum = "af872ef43ecb73cc49c7bd2dd19ef9117168e183c78cf70000dca0e14b6a5473" dependencies = [ "anyhow", - "bitflags 2.4.1", + "bitflags 2.3.3", "indexmap 2.0.0", "log", "serde", - "serde_derive", "serde_json", "wasm-encoder", "wasm-metadata", @@ -4176,19 +4216,20 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.12.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ace9943d89bbf3dbbc71b966da0e7302057b311f36a4ac3d65ddfef17b52cf" +checksum = "1dcd022610436a1873e60bfdd9b407763f2404adf7d1cb57912c7ae4059e57a5" dependencies = [ "anyhow", "id-arena", "indexmap 2.0.0", "log", + "pulldown-cmark", "semver", "serde", - "serde_derive", "serde_json", "unicode-xid", + "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 31a1ac788920..9c1fca098d05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,13 +22,13 @@ path = "src/bin/wasmtime.rs" doc = false [dependencies] -wasmtime = { workspace = true } -wasmtime-cache = { workspace = true, optional = true } +wasmtime = { workspace = true, features = ['cache', 'cranelift'] } +wasmtime-cache = { workspace = true } wasmtime-cli-flags = { workspace = true } -wasmtime-cranelift = { workspace = true, optional = true } +wasmtime-cranelift = { workspace = true } wasmtime-environ = { workspace = true } -wasmtime-explorer = { workspace = true, optional = true } -wasmtime-wast = { workspace = true, optional = true } +wasmtime-explorer = { workspace = true } +wasmtime-wast = { workspace = true } wasmtime-wasi = { workspace = true, default-features = true, features = [ "exit", ] } @@ -36,24 +36,17 @@ wasmtime-wasi-nn = { workspace = true, optional = true } wasmtime-wasi-threads = { workspace = true, optional = true } wasmtime-wasi-http = { workspace = true, optional = true } wasmtime-runtime = { workspace = true } -clap = { workspace = true } +clap = { workspace = true, features = ["color", "suggestions", "derive"] } anyhow = { workspace = true } target-lexicon = { workspace = true } once_cell = { workspace = true } listenfd = "1.0.0" -wat = { workspace = true, optional = true } +wat = { workspace = true } serde = { workspace = true } serde_derive = { workspace = true } serde_json = { workspace = true } wasmparser = { workspace = true } -tracing = { workspace = true } -log = { workspace = true } - -async-trait = { workspace = true } -bytes = { workspace = true } -tokio = { workspace = true, optional = true, features = [ "signal", "macros" ] } -hyper = { workspace = true, optional = true } -http-body-util = { workspace = true, optional = true } +wasm-encoder = { workspace = true } [target.'cfg(unix)'.dependencies] rustix = { workspace = true, features = ["mm", "param"] } @@ -66,8 +59,9 @@ log = { workspace = true } expect-test = { workspace = true } filecheck = { workspace = true } tempfile = { workspace = true } +test-programs = { path = "crates/test-programs" } wasmtime-runtime = { workspace = true } -tokio = { workspace = true, features = ["rt", "time", "macros", "rt-multi-thread"] } +tokio = { version = "1.8.0", features = ["rt", "time", "macros", "rt-multi-thread"] } wast = { workspace = true } criterion = "0.5.0" num_cpus = "1.13.0" @@ -84,7 +78,6 @@ libc = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } walkdir = { workspace = true } -test-programs-artifacts = { workspace = true } [target.'cfg(windows)'.dev-dependencies] windows-sys = { workspace = true, features = ["Win32_System_Memory"] } @@ -103,9 +96,16 @@ members = [ "cranelift/isle/islec", "cranelift/serde", "crates/bench-api", - "crates/c-api/artifact", + "crates/c-api", + "crates/cli-flags", "crates/environ/fuzz", - "crates/test-programs", + "crates/jit-icache-coherence", + "crates/test-programs/wasi-tests", + "crates/test-programs/wasi-http-tests", + "crates/test-programs/wasi-sockets-tests", + "crates/test-programs/command-tests", + "crates/test-programs/reactor-tests", + "crates/wmemcheck", "crates/wasi-preview1-component-adapter", "crates/wasi-preview1-component-adapter/verify", "crates/winch", @@ -122,68 +122,66 @@ exclude = [ ] [workspace.package] -version = "15.0.0" +version = "14.0.0" authors = ["The Wasmtime Project Developers"] edition = "2021" # Wasmtime's current policy is that this number can be no larger than the # current stable release of Rust minus 2. -rust-version = "1.71.0" +rust-version = "1.70.0" [workspace.dependencies] -arbitrary = { version = "1.3.1" } -wasmtime-wmemcheck = { path = "crates/wmemcheck", version = "=15.0.0" } -wasmtime = { path = "crates/wasmtime", version = "15.0.0", default-features = false } -wasmtime-cache = { path = "crates/cache", version = "=15.0.0" } -wasmtime-cli-flags = { path = "crates/cli-flags", version = "=15.0.0" } -wasmtime-cranelift = { path = "crates/cranelift", version = "=15.0.0" } -wasmtime-cranelift-shared = { path = "crates/cranelift-shared", version = "=15.0.0" } -wasmtime-winch = { path = "crates/winch", version = "=15.0.0" } -wasmtime-environ = { path = "crates/environ", version = "=15.0.0" } -wasmtime-explorer = { path = "crates/explorer", version = "=15.0.0" } -wasmtime-fiber = { path = "crates/fiber", version = "=15.0.0" } -wasmtime-types = { path = "crates/types", version = "15.0.0" } -wasmtime-jit = { path = "crates/jit", version = "=15.0.0" } -wasmtime-jit-debug = { path = "crates/jit-debug", version = "=15.0.0" } -wasmtime-runtime = { path = "crates/runtime", version = "=15.0.0" } -wasmtime-wast = { path = "crates/wast", version = "=15.0.0" } -wasmtime-wasi = { path = "crates/wasi", version = "15.0.0", default-features = false } -wasmtime-wasi-http = { path = "crates/wasi-http", version = "=15.0.0", default-features = false } -wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "15.0.0" } -wasmtime-wasi-threads = { path = "crates/wasi-threads", version = "15.0.0" } -wasmtime-component-util = { path = "crates/component-util", version = "=15.0.0" } -wasmtime-component-macro = { path = "crates/component-macro", version = "=15.0.0" } -wasmtime-asm-macros = { path = "crates/asm-macros", version = "=15.0.0" } -wasmtime-versioned-export-macros = { path = "crates/versioned-export-macros", version = "=15.0.0" } +wasmtime-wmemcheck = { path = "crates/wmemcheck", version = "=14.0.0" } +wasmtime = { path = "crates/wasmtime", version = "14.0.0", default-features = false } +wasmtime-cache = { path = "crates/cache", version = "=14.0.0" } +wasmtime-cli-flags = { path = "crates/cli-flags", version = "=14.0.0" } +wasmtime-cranelift = { path = "crates/cranelift", version = "=14.0.0" } +wasmtime-cranelift-shared = { path = "crates/cranelift-shared", version = "=14.0.0" } +wasmtime-winch = { path = "crates/winch", version = "=14.0.0" } +wasmtime-environ = { path = "crates/environ", version = "=14.0.0" } +wasmtime-explorer = { path = "crates/explorer", version = "=14.0.0" } +wasmtime-fiber = { path = "crates/fiber", version = "=14.0.0" } +wasmtime-types = { path = "crates/types", version = "14.0.0" } +wasmtime-jit = { path = "crates/jit", version = "=14.0.0" } +wasmtime-jit-debug = { path = "crates/jit-debug", version = "=14.0.0" } +wasmtime-runtime = { path = "crates/runtime", version = "=14.0.0" } +wasmtime-wast = { path = "crates/wast", version = "=14.0.0" } +wasmtime-wasi = { path = "crates/wasi", version = "14.0.0", default-features = false } +wasmtime-wasi-http = { path = "crates/wasi-http", version = "=14.0.0", default-features = false } +wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "14.0.0" } +wasmtime-wasi-threads = { path = "crates/wasi-threads", version = "14.0.0" } +wasmtime-component-util = { path = "crates/component-util", version = "=14.0.0" } +wasmtime-component-macro = { path = "crates/component-macro", version = "=14.0.0" } +wasmtime-asm-macros = { path = "crates/asm-macros", version = "=14.0.0" } +wasmtime-versioned-export-macros = { path = "crates/versioned-export-macros", version = "=14.0.0" } component-test-util = { path = "crates/misc/component-test-util" } component-fuzz-util = { path = "crates/misc/component-fuzz-util" } -wiggle = { path = "crates/wiggle", version = "=15.0.0", default-features = false } -wiggle-macro = { path = "crates/wiggle/macro", version = "=15.0.0" } -wiggle-generate = { path = "crates/wiggle/generate", version = "=15.0.0" } -wasi-common = { path = "crates/wasi-common", version = "=15.0.0" } -wasi-tokio = { path = "crates/wasi-common/tokio", version = "=15.0.0" } -wasi-cap-std-sync = { path = "crates/wasi-common/cap-std-sync", version = "=15.0.0" } +wiggle = { path = "crates/wiggle", version = "=14.0.0", default-features = false } +wiggle-macro = { path = "crates/wiggle/macro", version = "=14.0.0" } +wiggle-generate = { path = "crates/wiggle/generate", version = "=14.0.0" } +wasi-common = { path = "crates/wasi-common", version = "=14.0.0" } +wasi-tokio = { path = "crates/wasi-common/tokio", version = "=14.0.0" } +wasi-cap-std-sync = { path = "crates/wasi-common/cap-std-sync", version = "=14.0.0" } wasmtime-fuzzing = { path = "crates/fuzzing" } -wasmtime-jit-icache-coherence = { path = "crates/jit-icache-coherence", version = "=15.0.0" } -wasmtime-wit-bindgen = { path = "crates/wit-bindgen", version = "=15.0.0" } -test-programs-artifacts = { path = 'crates/test-programs/artifacts' } - -cranelift-wasm = { path = "cranelift/wasm", version = "0.102.0" } -cranelift-codegen = { path = "cranelift/codegen", version = "0.102.0", default-features = false, features = ["std", "unwind"] } -cranelift-frontend = { path = "cranelift/frontend", version = "0.102.0" } -cranelift-entity = { path = "cranelift/entity", version = "0.102.0" } -cranelift-native = { path = "cranelift/native", version = "0.102.0" } -cranelift-module = { path = "cranelift/module", version = "0.102.0" } -cranelift-interpreter = { path = "cranelift/interpreter", version = "0.102.0" } -cranelift-reader = { path = "cranelift/reader", version = "0.102.0" } +wasmtime-jit-icache-coherence = { path = "crates/jit-icache-coherence", version = "=14.0.0" } +wasmtime-wit-bindgen = { path = "crates/wit-bindgen", version = "=14.0.0" } + +cranelift-wasm = { path = "cranelift/wasm", version = "0.101.0" } +cranelift-codegen = { path = "cranelift/codegen", version = "0.101.0" } +cranelift-frontend = { path = "cranelift/frontend", version = "0.101.0" } +cranelift-entity = { path = "cranelift/entity", version = "0.101.0" } +cranelift-native = { path = "cranelift/native", version = "0.101.0" } +cranelift-module = { path = "cranelift/module", version = "0.101.0" } +cranelift-interpreter = { path = "cranelift/interpreter", version = "0.101.0" } +cranelift-reader = { path = "cranelift/reader", version = "0.101.0" } cranelift-filetests = { path = "cranelift/filetests" } -cranelift-object = { path = "cranelift/object", version = "0.102.0" } -cranelift-jit = { path = "cranelift/jit", version = "0.102.0" } +cranelift-object = { path = "cranelift/object", version = "0.101.0" } +cranelift-jit = { path = "cranelift/jit", version = "0.101.0" } cranelift-fuzzgen = { path = "cranelift/fuzzgen" } -cranelift-bforest = { path = "cranelift/bforest", version = "0.102.0" } -cranelift-control = { path = "cranelift/control", version = "0.102.0" } -cranelift = { path = "cranelift/umbrella", version = "0.102.0" } +cranelift-bforest = { path = "cranelift/bforest", version = "0.101.0" } +cranelift-control = { path = "cranelift/control", version = "0.101.0" } +cranelift = { path = "cranelift/umbrella", version = "0.101.0" } -winch-codegen = { path = "winch/codegen", version = "=0.13.0" } +winch-codegen = { path = "winch/codegen", version = "=0.12.0" } winch-filetests = { path = "winch/filetests" } winch-test-macros = { path = "winch/test-macros" } @@ -192,7 +190,7 @@ byte-array-literals = { path = "crates/wasi-preview1-component-adapter/byte-arra # Bytecode Alliance maintained dependencies: # --------------------------- -regalloc2 = "0.9.3" +regalloc2 = "0.9.2" # cap-std family: target-lexicon = { version = "0.12.3", default-features = false, features = ["std"] } @@ -209,18 +207,18 @@ io-extras = "0.18.0" rustix = "0.38.8" is-terminal = "0.4.0" # wit-bindgen: -wit-bindgen = { version = "0.13.0", default-features = false } +wit-bindgen = { version = "0.11.0", default-features = false } # wasm-tools family: -wasmparser = "0.115.0" -wat = "1.0.77" -wast = "66.0.2" -wasmprinter = "0.2.70" -wasm-encoder = "0.35.0" -wasm-smith = "0.12.21" -wasm-mutate = "0.2.38" -wit-parser = "0.12.1" -wit-component = "0.16.0" +wasmparser = "0.113.1" +wat = "1.0.73" +wast = "65.0.1" +wasmprinter = "0.2.66" +wasm-encoder = "0.33.1" +wasm-smith = "0.12.17" +wasm-mutate = "0.2.34" +wit-parser = "0.11.1" +wit-component = "0.14.2" # Non-Bytecode Alliance maintained dependencies: # -------------------------- @@ -231,7 +229,7 @@ windows-sys = "0.48.0" env_logger = "0.10" expect-test = "1.4.1" log = { version = "0.4.8", default-features = false } -clap = { version = "4.3.12", default-features = false, features = ["std", "derive"] } +clap = { version = "4.3.12", features = ["color", "suggestions", "derive"] } hashbrown = { version = "0.14", default-features = false } capstone = "0.9.0" once_cell = "1.12.0" @@ -255,108 +253,40 @@ tempfile = "3.1.0" filecheck = "0.5.0" libc = "0.2.60" file-per-thread-logger = "0.2.0" -tokio = { version = "1.26.0", features = [ "rt", "time" ] } -hyper = "=1.0.0-rc.3" -http = "0.2.9" -http-body = "=1.0.0-rc.2" -http-body-util = "=0.1.0-rc.2" +tokio = { version = "1.26.0" } bytes = "1.4" futures = { version = "0.3.27", default-features = false } indexmap = "2.0.0" pretty_env_logger = "0.5.0" syn = "2.0.25" test-log = { version = "0.2", default-features = false, features = ["trace"] } -tracing-subscriber = { version = "0.3.1", default-features = false, features = ['fmt', 'env-filter', 'ansi', 'tracing-log'] } -url = "2.3.1" +tracing-subscriber = { version = "0.3.1", default-features = false, features = ['fmt', 'env-filter'] } -# ============================================================================= -# -# Features for the Wasmtime CLI executable -# -# -# Note that many of these features are inherited from Wasmtime itself or -# otherwise configure the `wasmtime` crate's execution. Features are provided as -# compile-time switches to disable functionality primarily if one is interested -# in configuring binary size and or exploring the binary size implications of -# various features. Most features are enabled by default but most embeddings -# likely won't need all features. [features] default = [ - # All subcommands are included by default. - "compile", - "explore", - "serve", - "wast", - "config", - - # On-by-default WASI features + "jitdump", + "wasmtime/wat", + "wasmtime/parallel-compilation", + "vtune", "wasi-nn", "wasi-threads", "wasi-http", - - # Most features of Wasmtime are enabled by default. - "wat", - "parallel-compilation", "pooling-allocator", - "cache", - "logging", - "demangle", - "cranelift", - "profiling", - "coredump", - "addr2line", - "debug-builtins", - - # Enable some nice features of clap by default, but they come at a binary size - # cost, so allow disabling this through disabling of our own `default` - # feature. - "clap/default", ] - -# ======================================== -# Off-by-default features -# -# These features are off-by-default but may optionally be enabled. -all-arch = ["wasmtime/all-arch"] -winch = ["wasmtime/winch"] -wmemcheck = ["wasmtime/wmemcheck"] - -# This feature, when enabled, will statically compile out all logging statements -# throughout Wasmtime and its dependencies. -disable-logging = ["log/max_level_off", "tracing/max_level_off"] - -# ======================================== -# On-by-default features -# -# These features are all included in the `default` set above and this is -# the internal mapping for what they enable in Wasmtime itself. +jitdump = ["wasmtime/jitdump"] +vtune = ["wasmtime/vtune"] wasi-nn = ["dep:wasmtime-wasi-nn"] wasi-threads = ["dep:wasmtime-wasi-threads"] -wasi-http = ["component-model", "dep:wasmtime-wasi-http", "dep:tokio", "dep:hyper", "wasmtime-wasi-http?/sync"] +wasi-http = ["dep:wasmtime-wasi-http", "wasmtime-wasi-http?/sync"] pooling-allocator = ["wasmtime/pooling-allocator", "wasmtime-cli-flags/pooling-allocator"] +all-arch = ["wasmtime/all-arch"] component-model = [ "wasmtime/component-model", "wasmtime-wast/component-model", "wasmtime-cli-flags/component-model" ] -wat = ["dep:wat"] -cache = ["dep:wasmtime-cache", "wasmtime-cli-flags/cache"] -parallel-compilation = ["wasmtime-cli-flags/parallel-compilation"] -logging = ["wasmtime-cli-flags/logging"] -demangle = ["wasmtime/demangle"] -cranelift = ["wasmtime-cli-flags/cranelift", "dep:wasmtime-cranelift"] -profiling = ["wasmtime/profiling"] -coredump = ["wasmtime-cli-flags/coredump"] -addr2line = ["wasmtime/addr2line"] -debug-builtins = ["wasmtime/debug-builtins"] - -# CLI subcommands for the `wasmtime` executable. See `wasmtime $cmd --help` -# for more information on each subcommand. -serve = ["wasi-http", "component-model", "dep:http-body-util"] -explore = ["dep:wasmtime-explorer"] -wast = ["dep:wasmtime-wast"] -config = ["cache"] -compile = ["cranelift"] +winch = ["wasmtime/winch"] +wmemcheck = ["wasmtime/wmemcheck"] [[test]] name = "host_segfault" diff --git a/RELEASES.md b/RELEASES.md index 296ee1357d90..6d1ba437dda8 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,211 +1,13 @@ -------------------------------------------------------------------------------- -## 15.0.0 - -Unreleased. - -### Added - -### Changed - --------------------------------------------------------------------------------- - -## 14.0.2 - -Released 2023-10-26 - -### Fixed - -* Make the `wasmtime::unix` module accessible on macOS again. - [#7360](https://github.com/bytecodealliance/wasmtime/pull/7360) - -* Inter-crate dependencies between `cranelift-*` crates now disable the - `default` feature meaning that it's possible for embedders to depend on - `cranelift-codegen` as well without the `default` feature. - [#7369](https://github.com/bytecodealliance/wasmtime/pull/7369) - --------------------------------------------------------------------------------- - -## 14.0.1 - -Released 2023-10-23 - -### Fixed - -* Cranelift: preserve uext and sext flags for parameters on x86\_64 and apple - aarch64. Note that this does not affect Wasmtime and is only intended for - Cranelift embedders such as `rustc_codegen_cranelift`. - [#7333](https://github.com/bytecodealliance/wasmtime/pull/7333) - --------------------------------------------------------------------------------- - ## 14.0.0 -Released 2023-10-20 - -One of the larger changes in this release is a redesign of Wasmtime's CLI -arguments and where arguments are passed. This means that previous invocations -of the `wasmtime` CLI executable will need to be updated. No functionality was -removed but most of it is behind new flags. One major change is that Wasmtime -CLI flags are now grouped behind short options like `-O`. For example - - wasmtime run --opt-level 2 foo.wasm - -is now: - - wasmtime run -O opt-level=2 foo.wasm - -Additionally options prefixed with `--enable-*` or `--disable-*` now -consistently are considered boolean setters. For example: - - wasmtime run --disable-cache foo.wasm - -is now: - - wasmtime run -C cache=n foo.wasm - -Options can be explored with `wasmtime -C help` for example, and `wasmtime -h` -will show all option groups that can be expanded. - -Another major change in the CLI is that any CLI argument which positionally -comes after the wasm file specified will be passed as an argument to the guest -module. For example this invocations - - wasmtime run foo.wasm --epoch-interruption - -was previously accepted as enabling epoch interruption for the `foo.wasm` file. -This is now interpreted as if it were `./foo.wasm --epoch-interruption`, -however, passing the flag to the wasm file itself. Flags to Wasmtime must now -come after Wasmtime's subcommand (in this case `run`) and before the wasm file -that's being run, for example: - - wasmtime run -W epoch-interruption foo.wasm - -More information about this change can be found on -[#6925](https://github.com/bytecodealliance/wasmtime/pull/6925) and -[#6946](https://github.com/bytecodealliance/wasmtime/pull/6946). +Unreleased. ### Added -* Added the `wasmtime::FrameInfo::module` method, which returns the - `wasmtime::Module` associated with the stack frame. - -* The `wasmtime::component::Linker` type now implements `Clone`. - [#7032](https://github.com/bytecodealliance/wasmtime/pull/7032) - -* Wasmtime's `TypedFunc` API now supports the `v128` WebAssembly type on x86\_64 - and aarch64. - [#7010](https://github.com/bytecodealliance/wasmtime/pull/7010) - -* Support for resources exported from a WebAssembly guest has been added to the - component `bindgen!` macro. - [#7050](https://github.com/bytecodealliance/wasmtime/pull/7050) - -* The C API now supports learning about a module's `image_range`. - [#7064](https://github.com/bytecodealliance/wasmtime/pull/7064) - -* Passing values between components is now possible with a more complete - implementation of type-checking of values. - [#7065](https://github.com/bytecodealliance/wasmtime/pull/7065) - -* Types representing resources can now be customized with `bindgen!`. - [#7069](https://github.com/bytecodealliance/wasmtime/pull/7069) - -* Wasm-defined globals and memories are now included in core dumps, and the - `wasmtime::WasmCoreDump` type is now serializable. - [#6935](https://github.com/bytecodealliance/wasmtime/pull/6935) - [#7078](https://github.com/bytecodealliance/wasmtime/pull/7078) - -* Initial experimental support for Intel MPK has been added to support running - more instances concurrently. - [#7072](https://github.com/bytecodealliance/wasmtime/pull/7072) - -* The implementation of `wasi:http` now supports inbound requests in addition to - outbound requests. A new `wasmtime serve` command is an example way of - handling http requests with wasm files. - [#7091](https://github.com/bytecodealliance/wasmtime/pull/7091) - -* The C API now supports Wasmtime's "host memory creation" API to customize the - allocation of linear memories. - [#7115](https://github.com/bytecodealliance/wasmtime/pull/7115) - -* The C API now supports asynchronous invocation of WebAssembly programs. - [#7106](https://github.com/bytecodealliance/wasmtime/pull/7106) - -* The C API now supports Wasmtime's `InstancePre` type. - [#7140](https://github.com/bytecodealliance/wasmtime/pull/7140) - -* The `wasi:sockets/ip-name-lookup` interface is now implemented by Wasmtime. - [#7109](https://github.com/bytecodealliance/wasmtime/pull/7109) - ### Changed -* Wasmtime's CLI has been significantly overhauled. See the note above. - [#6925](https://github.com/bytecodealliance/wasmtime/pull/6925) - [#6946](https://github.com/bytecodealliance/wasmtime/pull/6946) - -* The `wasmtime::FrameInfo::module_name` has been removed, however you can now - get identical results by chaining `wasmtime::FrameInfo::module` and - `wasmtime::Module::name`: `my_frame.module().name()`. - -* WASI interfaces have seen significant work since the previous release. Streams - for example have a new backpressure and flushing design. Additionally WIT - `resource`s are now used ubiquitously throughout the specification and - implementation. - [#6877](https://github.com/bytecodealliance/wasmtime/pull/6877) - [#7029](https://github.com/bytecodealliance/wasmtime/pull/7029) - [#7090](https://github.com/bytecodealliance/wasmtime/pull/7090) - -* The implementation of `wasi:http` now uses `{input,output}-stream` from the - `wasi:io/streams` interface. - [#7056](https://github.com/bytecodealliance/wasmtime/pull/7056) - -* Lifting and lowering of the `list` component values has been significantly - optimized. - [#6971](https://github.com/bytecodealliance/wasmtime/pull/6971) - -* The `wasmtime-c-api` crate is now additionally built as an rlib as well as the - previous cdylib/staticlib combo. - [#6765](https://github.com/bytecodealliance/wasmtime/pull/6765) - -### Fixed - -* Support referencing stack slots in the DWARF debug info. - [#6960](https://github.com/bytecodealliance/wasmtime/pull/6960) - -* Printing unicode to stdio on Windows has been fixed. - [#6825](https://github.com/bytecodealliance/wasmtime/pull/6825) - -* Building for x86\_64-linux-android has been fixed. - [#7055](https://github.com/bytecodealliance/wasmtime/pull/7055) - -* Fixed stdout/stderr becoming nonblocking by accident with WASI preview2 on - macOS. - [#7058](https://github.com/bytecodealliance/wasmtime/pull/7058) - -* Fixed some character boundary-related panics in the preview2 implementation of - preview1. - [#7011](https://github.com/bytecodealliance/wasmtime/pull/7011) - -* Fixed an issue of guests sleeping for an incorrect amount of time with - preview2. - [#6993](https://github.com/bytecodealliance/wasmtime/pull/6993) - -* Cranelift will now return an error when running out of temporaries in a very - large function instead of panicking. - [#7114](https://github.com/bytecodealliance/wasmtime/pull/7114) - --------------------------------------------------------------------------------- - -## 13.0.1 - -Released 2023-10-26 - -### Fixed - -* Make the `wasmtime::unix` module accessible on macOS again. - [#7360](https://github.com/bytecodealliance/wasmtime/pull/7360) - -------------------------------------------------------------------------------- ## 13.0.0 diff --git a/build.rs b/build.rs index 64584ca886c4..b591af39d7cd 100644 --- a/build.rs +++ b/build.rs @@ -205,34 +205,13 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool { // We ignore tests that assert for traps on windows, given // that Winch doesn't encode unwind information for Windows, yet. if strategy == "Winch" { - let assert_trap = [ - "i32", - "i64", - "call_indirect", - "table_fill", - "table_init", - "table_copy", - "table_set", - "table_get", - ] - .contains(&testname); - - if assert_trap && env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() == "windows" { + if testsuite != "winch" { return true; } - if testsuite == "misc_testsuite" { - // The misc/call_indirect is fully supported by Winch. - if testname != "call_indirect" { - return true; - } - } - if testsuite == "spec_testsuite" { - // The official table init and table copy tests are now supported. - return !["table_init", "table_copy"].contains(&testname); - } + let assert_trap = ["i32", "i64"].contains(&testname); - if testsuite != "winch" { + if assert_trap && env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() == "windows" { return true; } } diff --git a/ci/build-build-matrix.js b/ci/build-build-matrix.js deleted file mode 100644 index 23c2b6ebb060..000000000000 --- a/ci/build-build-matrix.js +++ /dev/null @@ -1,68 +0,0 @@ -// Small script used to calculate the matrix of builds that are going to be -// done if CI decides to do a release build. -// -// This is a separate script primarily to write out all the release -// targets/platforms once and then duplicate them all with a "min" build. - -const array = [ - { - // The name of the build which shows up in the name of the artifact for - // Wasmtime's github releases. - "build": "x86_64-linux", - // The GitHub Actions platform that this build runs on - "os": "ubuntu-latest", - // The Rust target that will be used for the build. - "target": "x86_64-unknown-linux-gnu", - }, - { - "build": "aarch64-linux", - "os": "ubuntu-latest", - "target": "aarch64-unknown-linux-gnu", - }, - { - "build": "s390x-linux", - "os": "ubuntu-latest", - "target": "s390x-unknown-linux-gnu", - }, - { - "build": "riscv64gc-linux", - "os": "ubuntu-latest", - "target": "riscv64gc-unknown-linux-gnu", - }, - { - "build": "x86_64-macos", - "os": "macos-latest", - "target": "x86_64-apple-darwin", - }, - { - "build": "aarch64-macos", - "os": "macos-latest", - "target": "aarch64-apple-darwin", - }, - { - "build": "x86_64-windows", - "os": "windows-latest", - "target": "x86_64-pc-windows-msvc", - }, - { - "build": "x86_64-mingw", - "os": "windows-latest", - "target": "x86_64-pc-windows-gnu", - }, -]; - -const builds = []; -for (let build of array) { - // Perform a "deep clone" roundtripping through JSON for a copy of the build - // that's normal - build.rust = 'stable'; - builds.push(JSON.parse(JSON.stringify(build))); - - // Next generate a "min" build and add it to the builds list. Min builds - // require Nightly rust due to some nightly build options that are configured. - build.build += '-min'; - build.rust = 'nightly-2023-10-10'; - builds.push(build); -} - -console.log(JSON.stringify(builds)); diff --git a/ci/build-release-artifacts.sh b/ci/build-release-artifacts.sh deleted file mode 100755 index 71c7888395cd..000000000000 --- a/ci/build-release-artifacts.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# A script to build the release artifacts of Wasmtime into the `target` -# directory. For now this is the CLI and the C API. Note that this script only -# produces the artifacts through Cargo and doesn't package things up. That's -# intended for the `build-tarballs.sh` script. -# -# This script takes a Rust target as its first input and optionally a parameter -# afterwards which can be "-min" to indicate that a minimal build should be -# produced with as many features as possible stripped out. - -set -ex - -build=$1 -target=$2 - -# Default build flags for release artifacts. Leave debugging for -# builds-from-source which have richer information anyway, and additionally the -# CLI won't benefit from catching unwinds and neither will the C API so use -# panic=abort in both situations. -export CARGO_PROFILE_RELEASE_STRIP=debuginfo -export CARGO_PROFILE_RELEASE_PANIC=abort - -if [[ "$build" = *-min ]]; then - # Configure a whole bunch of compile-time options which help reduce the size - # of the binary artifact produced. - export CARGO_PROFILE_RELEASE_OPT_LEVEL=s - export RUSTFLAGS=-Zlocation-detail=none - export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 - export CARGO_PROFILE_RELEASE_LTO=true - flags="-Zbuild-std=std,panic_abort --no-default-features -Zbuild-std-features=std_detect_dlsym_getauxval" - flags="$flags --features disable-logging" -else - # For release builds the CLI is built a bit more feature-ful than the Cargo - # defaults to provide artifacts that can do as much as possible. - bin_flags="--features all-arch,component-model" -fi - -cargo build --release $flags --target $target -p wasmtime-cli $bin_flags -cargo build --release $flags --target $target -p wasmtime-c-api diff --git a/ci/build-src-tarball.sh b/ci/build-src-tarball.sh index c5d3c10fa9b7..571fcc47a3a7 100755 --- a/ci/build-src-tarball.sh +++ b/ci/build-src-tarball.sh @@ -18,5 +18,3 @@ cargo vendor > .cargo/config.toml tar -czf /tmp/$pkgname.tar.gz --transform "s/^\./$pkgname/S" --exclude=.git . mkdir -p dist mv /tmp/$pkgname.tar.gz dist/ - -rm .cargo/config.toml diff --git a/ci/build-tarballs.sh b/ci/build-tarballs.sh index d8a249f113b1..eb6197c2a5ac 100755 --- a/ci/build-tarballs.sh +++ b/ci/build-tarballs.sh @@ -1,18 +1,19 @@ #!/bin/bash # A small script used for assembling release tarballs for both the `wasmtime` -# binary and the C API. This is executed with two arguments, mostly coming -# from the CI matrix. +# binary and the C API. This is executed with two arguments, mostly coming from +# the CI matrix. # -# * The first argument is the name of the "build", used to name the release. -# * The second argument is the Rust target that the build was performed for. +# * The first argument is the name of the platform, used to name the release +# * The second argument is the "target", if present, currently only for +# cross-compiles # # This expects the build to already be done and will assemble release artifacts # in `dist/` set -ex -build=$1 +platform=$1 target=$2 rm -rf tmp @@ -24,15 +25,8 @@ if [[ $GITHUB_REF == refs/heads/release-* ]]; then tag=v$(./ci/print-current-version.sh) fi -# For *-min builds produce the same named artifacts as the normal build and -# they'll get unioned together in a later step in the CI. -build_pkgname=$build -if [[ $build == *-min ]]; then - build_pkgname=${build%-min} -fi - -bin_pkgname=wasmtime-$tag-$build_pkgname -api_pkgname=wasmtime-$tag-$build_pkgname-c-api +bin_pkgname=wasmtime-$tag-$platform +api_pkgname=wasmtime-$tag-$platform-c-api mkdir tmp/$api_pkgname mkdir tmp/$api_pkgname/lib @@ -43,61 +37,47 @@ cp LICENSE README.md tmp/$bin_pkgname cp -r crates/c-api/include tmp/$api_pkgname cp crates/c-api/wasm-c-api/include/wasm.h tmp/$api_pkgname/include -# For *-min builds rename artifacts with a `-min` suffix to avoid eventual -# clashes with the normal builds when the tarballs are unioned together. -if [[ $build == *-min ]]; then - min="-min" -fi - fmt=tar - -case $build in - x86_64-windows*) - cp target/$target/release/wasmtime.exe tmp/$bin_pkgname/wasmtime$min.exe - cp target/$target/release/wasmtime.dll tmp/$api_pkgname/lib/wasmtime$min.dll - cp target/$target/release/wasmtime.lib tmp/$api_pkgname/lib/wasmtime$min.lib - cp target/$target/release/wasmtime.dll.lib tmp/$api_pkgname/lib/wasmtime$min.dll.lib - fmt=zip - - if [ "$min" = "" ]; then - # Generate a `*.msi` installer for Windows as well - export WT_VERSION=`cat Cargo.toml | sed -n 's/^version = "\([^"]*\)".*/\1/p'` - "$WIX/bin/candle" -arch x64 -out target/wasmtime.wixobj ci/wasmtime.wxs - "$WIX/bin/light" -out dist/$bin_pkgname.msi target/wasmtime.wixobj -ext WixUtilExtension - rm dist/$bin_pkgname.wixpdb - fi - ;; - - x86_64-mingw*) - cp target/$target/release/wasmtime.exe tmp/$bin_pkgname/wasmtime$min.exe - cp target/$target/release/wasmtime.dll tmp/$api_pkgname/lib/wasmtime$min.dll - cp target/$target/release/libwasmtime.a tmp/$api_pkgname/lib/libwasmtime$min.a - cp target/$target/release/libwasmtime.dll.a tmp/$api_pkgname/lib/libwasmtime$min.dll.a - fmt=zip - ;; - - *-macos*) - # Postprocess the macOS dylib a bit to have a more reasonable `LC_ID_DYLIB` - # directive than the default one that comes out of the linker when typically - # doing `cargo build`. For more info see #984 - install_name_tool -id "@rpath/libwasmtime$min.dylib" target/$target/release/libwasmtime.dylib - cp target/$target/release/wasmtime tmp/$bin_pkgname/wasmtime$min - cp target/$target/release/libwasmtime.a tmp/$api_pkgname/lib/libwasmtime$min.a - cp target/$target/release/libwasmtime.dylib tmp/$api_pkgname/lib/libwasmtime$min.dylib - ;; - - *) - cp target/$target/release/wasmtime tmp/$bin_pkgname/wasmtime$min - cp target/$target/release/libwasmtime.a tmp/$api_pkgname/lib/libwasmtime$min.a - cp target/$target/release/libwasmtime.so tmp/$api_pkgname/lib/libwasmtime$min.so - ;; -esac +if [ "$platform" = "x86_64-windows" ]; then + cp target/release/wasmtime.exe tmp/$bin_pkgname + cp target/release/{wasmtime.dll,wasmtime.lib,wasmtime.dll.lib} tmp/$api_pkgname/lib + fmt=zip + + # Generate a `*.msi` installer for Windows as well + export WT_VERSION=`cat Cargo.toml | sed -n 's/^version = "\([^"]*\)".*/\1/p'` + "$WIX/bin/candle" -arch x64 -out target/wasmtime.wixobj ci/wasmtime.wxs + "$WIX/bin/light" -out dist/$bin_pkgname.msi target/wasmtime.wixobj -ext WixUtilExtension + rm dist/$bin_pkgname.wixpdb +elif [ "$platform" = "x86_64-mingw" ]; then + cp target/x86_64-pc-windows-gnu/release/wasmtime.exe tmp/$bin_pkgname + cp target/x86_64-pc-windows-gnu/release/{wasmtime.dll,libwasmtime.a,libwasmtime.dll.a} tmp/$api_pkgname/lib + fmt=zip +elif [ "$platform" = "x86_64-macos" ]; then + # Postprocess the macOS dylib a bit to have a more reasonable `LC_ID_DYLIB` + # directive than the default one that comes out of the linker when typically + # doing `cargo build`. For more info see #984 + install_name_tool -id "@rpath/libwasmtime.dylib" target/release/libwasmtime.dylib + cp target/release/wasmtime tmp/$bin_pkgname + cp target/release/libwasmtime.{a,dylib} tmp/$api_pkgname/lib +elif [ "$platform" = "aarch64-macos" ]; then + install_name_tool -id "@rpath/libwasmtime.dylib" target/aarch64-apple-darwin/release/libwasmtime.dylib + cp target/aarch64-apple-darwin/release/wasmtime tmp/$bin_pkgname + cp target/aarch64-apple-darwin/release/libwasmtime.{a,dylib} tmp/$api_pkgname/lib +elif [ "$target" = "" ]; then + cp target/release/wasmtime tmp/$bin_pkgname + cp target/release/libwasmtime.{a,so} tmp/$api_pkgname/lib +else + cp target/$target/release/wasmtime tmp/$bin_pkgname + cp target/$target/release/libwasmtime.{a,so} tmp/$api_pkgname/lib +fi mktarball() { dir=$1 if [ "$fmt" = "tar" ]; then - tar -czvf dist/$dir.tar.gz -C tmp $dir + # this is a bit wonky, but the goal is to use `xz` with threaded compression + # to ideally get better performance with the `-T0` flag. + tar -cvf - -C tmp $dir | xz -9 -T0 > dist/$dir.tar.xz else # Note that this runs on Windows, and it looks like GitHub Actions doesn't # have a `zip` tool there, so we use something else diff --git a/ci/build-test-matrix.js b/ci/build-test-matrix.js index 5fee846d6787..35c2c00efd57 100644 --- a/ci/build-test-matrix.js +++ b/ci/build-test-matrix.js @@ -91,11 +91,17 @@ const array = [ "target": "riscv64gc-unknown-linux-gnu", "gcc_package": "gcc-riscv64-linux-gnu", "gcc": "riscv64-linux-gnu-gcc", - "qemu": "qemu-riscv64 -cpu rv64,v=true,vlen=256,vext_spec=v1.0,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zcb=true -L /usr/riscv64-linux-gnu", + "qemu": "qemu-riscv64 -cpu rv64,v=true,vlen=256,vext_spec=v1.0,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true -L /usr/riscv64-linux-gnu", "qemu_target": "riscv64-linux-user", "name": "Test Linux riscv64", "filter": "linux-riscv64", "isa": "riscv64", + // There appears to be a miscompile in Rust 1.72 for riscv64 where + // wasmtime-wasi tests are segfaulting in CI with the stack pointing in + // Tokio. Updating rustc seems to do the trick, so without doing a full + // rigorous investigation this uses beta for now but Rust 1.73 should be + // good to go for this. + "rust": "beta-2023-09-10", } ]; diff --git a/ci/merge-artifacts.sh b/ci/merge-artifacts.sh deleted file mode 100755 index aece95e6c4ad..000000000000 --- a/ci/merge-artifacts.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -# Script to merge the outputs of a run on github actions to github releases. -# This is invoked from `.github/workflows/publish-artifacts.yml`. All previous -# artifacts from builds are located in `bins-*` folders. The main purpose of -# this script is to take the "min" build and merge it into the "normal" build to -# produce one final tarball. This means that the final artifacts will have both -# a normal and a min build in them for comparison and usage. - -set -ex - -# Prepare the upload folder and move all aritfacts that aren't being merged into -# this folder, e.g. the MSI installer and adapter wasm files. -rm -rf dist -mkdir dist -mv -t dist bins-*/*.{msi,wasm} - -# Merge tarballs and zips by searching for `*-min` builds, unpacking the -# min/normal builds, into the same destination, and then repacking into a -# tarball. -# -# Note that for now xz compression is used for the final artifact to try to get -# small artifacts, but it's left at the default level since a lot of artifacts -# are processed here and turning it up to the max 9 compression might take -# quite awhile on CI for this one builder to process. -for min in bins-*-min/*.tar.*; do - normal=${min/-min\//\/} - filename=$(basename $normal) - dir=${filename%.tar.gz} - - rm -rf tmp - mkdir tmp - tar xf $min -C tmp - tar xf $normal -C tmp - tar -cf - -C tmp $dir | xz -T0 > dist/$dir.tar.xz - rm $min $normal -done - -for min in bins-*-min/*.zip; do - normal=${min/-min\//\/} - filename=$(basename $normal) - dir=${filename%.zip} - - rm -rf tmp - mkdir tmp - (cd tmp && unzip -o ../$min) - (cd tmp && unzip -o ../$normal) - (cd tmp && 7z a ../dist/$dir.zip $dir/) - rm $min $normal -done - -# Copy over remaining source tarball into the dist folder -mv -t dist bins-*/*.tar.* diff --git a/ci/qemu-cpuinfo.patch b/ci/qemu-cpuinfo.patch new file mode 100644 index 000000000000..261bcb593409 --- /dev/null +++ b/ci/qemu-cpuinfo.patch @@ -0,0 +1,115 @@ +From 5d05b046efb079360d0175164ee04947f20f9e66 Mon Sep 17 00:00:00 2001 +From: Afonso Bordado +Date: Tue, 21 Mar 2023 18:45:20 +0000 +Subject: [PATCH] linux-user: Emulate /proc/cpuinfo output for riscv + +RISC-V does not expose all extensions via hwcaps, thus some userspace +applications may want to query these via /proc/cpuinfo. + +Currently when querying this file the host's file is shown instead +which is slightly confusing. Emulate a basic /proc/cpuinfo file +with mmu info and an ISA string. +--- + linux-user/syscall.c | 34 ++++++++++++++++++++++++++++++++-- + tests/tcg/riscv64/cpuinfo.c | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 62 insertions(+), 2 deletions(-) + create mode 100644 tests/tcg/riscv64/cpuinfo.c + +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 333e6b7026..e6d85e0e8a 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -8231,7 +8231,8 @@ void target_exception_dump(CPUArchState *env, const char *fmt, int code) + } + + #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \ +- defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) ++ defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) || \ ++ defined(TARGET_RISCV) + static int is_proc(const char *filename, const char *entry) + { + return strcmp(filename, entry) == 0; +@@ -8309,6 +8310,35 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd) + } + #endif + ++#if defined(TARGET_RISCV) ++static int open_cpuinfo(CPUArchState *cpu_env, int fd) ++{ ++ int i; ++ int num_cpus = sysconf(_SC_NPROCESSORS_ONLN); ++ RISCVCPU *cpu = env_archcpu(cpu_env); ++ const RISCVCPUConfig *cfg = riscv_cpu_cfg((CPURISCVState *) cpu_env); ++ char *isa_string = riscv_isa_string(cpu); ++ const char *mmu; ++ ++ if (cfg->mmu) { ++ mmu = (cpu_env->xl == MXL_RV32) ? "sv32" : "sv48"; ++ } else { ++ mmu = "none"; ++ } ++ ++ for (i = 0; i < num_cpus; i++) { ++ dprintf(fd, "processor\t: %d\n", i); ++ dprintf(fd, "hart\t\t: %d\n", i); ++ dprintf(fd, "isa\t\t: %s\n", isa_string); ++ dprintf(fd, "mmu\t\t: %s\n", mmu); ++ dprintf(fd, "uarch\t\t: qemu\n\n"); ++ } ++ ++ g_free(isa_string); ++ return 0; ++} ++#endif ++ + #if defined(TARGET_M68K) + static int open_hardware(CPUArchState *cpu_env, int fd) + { +@@ -8333,7 +8363,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int + #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN + { "/proc/net/route", open_net_route, is_proc }, + #endif +-#if defined(TARGET_SPARC) || defined(TARGET_HPPA) ++#if defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined(TARGET_RISCV) + { "/proc/cpuinfo", open_cpuinfo, is_proc }, + #endif + #if defined(TARGET_M68K) +diff --git a/tests/tcg/riscv64/cpuinfo.c b/tests/tcg/riscv64/cpuinfo.c +new file mode 100644 +index 0000000000..296abd0a8c +--- /dev/null ++++ b/tests/tcg/riscv64/cpuinfo.c +@@ -0,0 +1,30 @@ ++#include ++#include ++#include ++#include ++ ++#define BUFFER_SIZE 1024 ++ ++int main(void) ++{ ++ char buffer[BUFFER_SIZE]; ++ FILE *fp = fopen("/proc/cpuinfo", "r"); ++ assert(fp != NULL); ++ ++ while (fgets(buffer, BUFFER_SIZE, fp) != NULL) { ++ if (strstr(buffer, "processor") != NULL) { ++ assert(strstr(buffer, "processor\t: ") == buffer); ++ } else if (strstr(buffer, "hart") != NULL) { ++ assert(strstr(buffer, "hart\t\t: ") == buffer); ++ } else if (strstr(buffer, "isa") != NULL) { ++ assert(strcmp(buffer, "isa\t\t: rv64imafdc_zicsr_zifencei\n") == 0); ++ } else if (strstr(buffer, "mmu") != NULL) { ++ assert(strcmp(buffer, "mmu\t\t: sv48\n") == 0); ++ } else if (strstr(buffer, "uarch") != NULL) { ++ assert(strcmp(buffer, "uarch\t\t: qemu\n") == 0); ++ } ++ } ++ ++ fclose(fp); ++ return 0; ++} +-- +2.34.1 + diff --git a/ci/run-tests.sh b/ci/run-tests.sh index db338dc2409e..b29b6eb71d9b 100755 --- a/ci/run-tests.sh +++ b/ci/run-tests.sh @@ -1,10 +1,14 @@ #!/bin/bash cargo test \ + --features "test-programs/test_programs" \ --features wasi-threads \ --features wasi-http \ --features component-model \ - --features serve \ --workspace \ - --exclude test-programs \ + --exclude 'wasmtime-wasi-*' \ + --exclude wasi-tests \ + --exclude wasi-http-tests \ + --exclude command-tests \ + --exclude reactor-tests \ $@ diff --git a/ci/run-wasi-nn-example.sh b/ci/run-wasi-nn-example.sh index 6f433bc3eff2..74bab3bd30fc 100755 --- a/ci/run-wasi-nn-example.sh +++ b/ci/run-wasi-nn-example.sh @@ -39,7 +39,7 @@ pushd $WASMTIME_DIR/crates/wasi-nn/examples/classification-example cargo build --release --target=wasm32-wasi cp target/wasm32-wasi/release/wasi-nn-example.wasm $TMP_DIR popd -cargo run -- run --dir $TMP_DIR::fixture -S nn $TMP_DIR/wasi-nn-example.wasm +cargo run -- run --dir fixture::$TMP_DIR -S nn $TMP_DIR/wasi-nn-example.wasm # Build and run another example, this time using Wasmtime's graph flag to # preload the model. @@ -47,7 +47,7 @@ pushd $WASMTIME_DIR/crates/wasi-nn/examples/classification-example-named cargo build --release --target=wasm32-wasi cp target/wasm32-wasi/release/wasi-nn-example-named.wasm $TMP_DIR popd -cargo run -- run --dir $TMP_DIR::fixture -S nn,nn-graph=openvino::$TMP_DIR \ +cargo run -- run --dir fixture::$TMP_DIR -S nn,nn-graph=openvino::$TMP_DIR \ $TMP_DIR/wasi-nn-example-named.wasm # Clean up the temporary directory only if it was not specified (users may want diff --git a/ci/wasmtime.wxs b/ci/wasmtime.wxs index 0e947135d555..ec3a58f9aa13 100644 --- a/ci/wasmtime.wxs +++ b/ci/wasmtime.wxs @@ -62,7 +62,7 @@ - + diff --git a/cranelift/Cargo.toml b/cranelift/Cargo.toml index 24577ddc1c2e..f6b271112dbb 100644 --- a/cranelift/Cargo.toml +++ b/cranelift/Cargo.toml @@ -44,7 +44,7 @@ indicatif = "0.13.0" thiserror = { workspace = true } walkdir = { workspace = true } anyhow = { workspace = true } -clap = { workspace = true, features = ['default'] } +clap = { workspace = true } similar = { workspace = true } toml = { workspace = true } serde = { workspace = true } diff --git a/cranelift/bforest/Cargo.toml b/cranelift/bforest/Cargo.toml index f620eb757029..d55fdad495ee 100644 --- a/cranelift/bforest/Cargo.toml +++ b/cranelift/bforest/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["The Cranelift Project Developers"] name = "cranelift-bforest" -version = "0.102.0" +version = "0.101.0" description = "A forest of B+-trees" license = "Apache-2.0 WITH LLVM-exception" documentation = "https://docs.rs/cranelift-bforest" diff --git a/cranelift/codegen/Cargo.toml b/cranelift/codegen/Cargo.toml index 6697393e93af..05bb88bed4a9 100644 --- a/cranelift/codegen/Cargo.toml +++ b/cranelift/codegen/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["The Cranelift Project Developers"] name = "cranelift-codegen" -version = "0.102.0" +version = "0.101.0" description = "Low-level code generator library" license = "Apache-2.0 WITH LLVM-exception" documentation = "https://docs.rs/cranelift-codegen" @@ -16,7 +16,7 @@ edition.workspace = true anyhow = { workspace = true, optional = true } bumpalo = "3" capstone = { workspace = true, optional = true } -cranelift-codegen-shared = { path = "./shared", version = "0.102.0" } +cranelift-codegen-shared = { path = "./shared", version = "0.101.0" } cranelift-entity = { workspace = true } cranelift-bforest = { workspace = true } cranelift-control = { workspace = true } @@ -41,8 +41,8 @@ criterion = { version = "0.5.0", features = ["html_reports"] } similar = "2.1.0" [build-dependencies] -cranelift-codegen-meta = { path = "meta", version = "0.102.0" } -cranelift-isle = { path = "../isle/isle", version = "=0.102.0" } +cranelift-codegen-meta = { path = "meta", version = "0.101.0" } +cranelift-isle = { path = "../isle/isle", version = "=0.101.0" } [features] default = ["std", "unwind", "host-arch"] diff --git a/cranelift/codegen/meta/Cargo.toml b/cranelift/codegen/meta/Cargo.toml index f507cc873bbe..4b930571018d 100644 --- a/cranelift/codegen/meta/Cargo.toml +++ b/cranelift/codegen/meta/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cranelift-codegen-meta" authors = ["The Cranelift Project Developers"] -version = "0.102.0" +version = "0.101.0" description = "Metaprogram for cranelift-codegen code generator library" license = "Apache-2.0 WITH LLVM-exception" repository = "https://github.com/bytecodealliance/wasmtime" @@ -12,4 +12,4 @@ edition.workspace = true rustdoc-args = [ "--document-private-items" ] [dependencies] -cranelift-codegen-shared = { path = "../shared", version = "0.102.0" } +cranelift-codegen-shared = { path = "../shared", version = "0.101.0" } diff --git a/cranelift/codegen/meta/src/shared/immediates.rs b/cranelift/codegen/meta/src/shared/immediates.rs index 5584b5564bb9..9f908c93da48 100644 --- a/cranelift/codegen/meta/src/shared/immediates.rs +++ b/cranelift/codegen/meta/src/shared/immediates.rs @@ -181,7 +181,6 @@ impl Immediates { trapcode_values.insert("heap_oob", "HeapOutOfBounds"); trapcode_values.insert("int_ovf", "IntegerOverflow"); trapcode_values.insert("int_divz", "IntegerDivisionByZero"); - trapcode_values.insert("bad_toint", "BadConversionToInteger"); new_enum( "code", "ir::TrapCode", diff --git a/cranelift/codegen/meta/src/shared/settings.rs b/cranelift/codegen/meta/src/shared/settings.rs index f632280145c8..e4e511b5e8cb 100644 --- a/cranelift/codegen/meta/src/shared/settings.rs +++ b/cranelift/codegen/meta/src/shared/settings.rs @@ -63,20 +63,6 @@ pub(crate) fn define() -> SettingGroup { true, ); - settings.add_bool( - "enable_pcc", - "Enable proof-carrying code translation validation.", - r#" - This adds a proof-carrying-code mode. Proof-carrying code (PCC) is a strategy to verify - that the compiler preserves certain properties or invariants in the compiled code. - For example, a frontend that translates WebAssembly to CLIF can embed PCC facts in - the CLIF, and Cranelift will verify that the final machine code satisfies the stated - facts at each intermediate computed value. Loads and stores can be marked as "checked" - and their memory effects can be verified as safe. - "#, - false, - ); - // Note that Cranelift doesn't currently need an is_pie flag, because PIE is // just PIC where symbols can't be pre-empted, which can be expressed with the // `colocated` flag on external functions and global values. diff --git a/cranelift/codegen/shared/Cargo.toml b/cranelift/codegen/shared/Cargo.toml index d68f66091609..3575420fa117 100644 --- a/cranelift/codegen/shared/Cargo.toml +++ b/cranelift/codegen/shared/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["The Cranelift Project Developers"] name = "cranelift-codegen-shared" -version = "0.102.0" +version = "0.101.0" description = "For code shared between cranelift-codegen-meta and cranelift-codegen" license = "Apache-2.0 WITH LLVM-exception" repository = "https://github.com/bytecodealliance/wasmtime" diff --git a/cranelift/codegen/src/binemit/mod.rs b/cranelift/codegen/src/binemit/mod.rs index 9eed2905c4cd..d5582d87f3be 100644 --- a/cranelift/codegen/src/binemit/mod.rs +++ b/cranelift/codegen/src/binemit/mod.rs @@ -64,21 +64,15 @@ pub enum Reloc { /// Offset within page of TLVP slot. MachOAarch64TlsAdrPageOff12, - /// Aarch64 TLSDESC Adr Page21 - /// This is equivalent to `R_AARCH64_TLSDESC_ADR_PAGE21` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#57105thread-local-storage-descriptors) - Aarch64TlsDescAdrPage21, + /// Aarch64 TLS GD + /// Set an ADRP immediate field to the top 21 bits of the final address. Checks for overflow. + /// This is equivalent to `R_AARCH64_TLSGD_ADR_PAGE21` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#relocations-for-thread-local-storage) + Aarch64TlsGdAdrPage21, - /// Aarch64 TLSDESC Ld64 Lo12 - /// This is equivalent to `R_AARCH64_TLSDESC_LD64_LO12` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#57105thread-local-storage-descriptors) - Aarch64TlsDescLd64Lo12, - - /// Aarch64 TLSDESC Add Lo12 - /// This is equivalent to `R_AARCH64_TLSGD_ADD_LO12` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#57105thread-local-storage-descriptors) - Aarch64TlsDescAddLo12, - - /// Aarch64 TLSDESC Call - /// This is equivalent to `R_AARCH64_TLSDESC_CALL` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#57105thread-local-storage-descriptors) - Aarch64TlsDescCall, + /// Aarch64 TLS GD + /// Set the add immediate field to the low 12 bits of the final address. Does not check for overflow. + /// This is equivalent to `R_AARCH64_TLSGD_ADD_LO12_NC` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#relocations-for-thread-local-storage) + Aarch64TlsGdAddLo12Nc, /// AArch64 GOT Page /// Set the immediate value of an ADRP to bits 32:12 of X; check that –232 <= X < 232 @@ -91,14 +85,12 @@ pub enum Reloc { /// This is equivalent to `R_AARCH64_LD64_GOT_LO12_NC` (312) in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#static-aarch64-relocations) Aarch64Ld64GotLo12Nc, - /// RISC-V Call PLT: 32-bit PC-relative function call, macros call, tail (PIC) - /// - /// Despite having PLT in the name, this relocation is also used for normal calls. - /// The non-PLT version of this relocation has been deprecated. - /// - /// This is the `R_RISCV_CALL_PLT` relocation from the RISC-V ELF psABI document. - /// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#procedure-calls - RiscvCallPlt, + /// procedure call. + /// call symbol + /// expands to the following assembly and relocation: + /// auipc ra, 0 + /// jalr ra, ra, 0 + RiscvCall, /// RISC-V TLS GD: High 20 bits of 32-bit PC-relative TLS GD GOT reference, /// @@ -112,12 +104,6 @@ pub enum Reloc { /// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses RiscvPCRelLo12I, - /// High 20 bits of a 32-bit PC-relative GOT offset relocation - /// - /// This is the `R_RISCV_GOT_HI20` relocation from the RISC-V ELF psABI document. - /// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses - RiscvGotHi20, - /// s390x TLS GD64 - 64-bit offset of tls_index for GD symbol in GOT S390xTlsGd64, /// s390x TLS GDCall - marker to enable optimization of TLS calls @@ -139,18 +125,15 @@ impl fmt::Display for Reloc { Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"), Self::X86SecRel => write!(f, "SecRel"), Self::Arm32Call | Self::Arm64Call => write!(f, "Call"), - Self::RiscvCallPlt => write!(f, "RiscvCallPlt"), + Self::RiscvCall => write!(f, "RiscvCall"), Self::RiscvTlsGdHi20 => write!(f, "RiscvTlsGdHi20"), - Self::RiscvGotHi20 => write!(f, "RiscvGotHi20"), Self::RiscvPCRelLo12I => write!(f, "RiscvPCRelLo12I"), Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"), Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), Self::MachOAarch64TlsAdrPage21 => write!(f, "MachOAarch64TlsAdrPage21"), Self::MachOAarch64TlsAdrPageOff12 => write!(f, "MachOAarch64TlsAdrPageOff12"), - Self::Aarch64TlsDescAdrPage21 => write!(f, "Aarch64TlsDescAdrPage21"), - Self::Aarch64TlsDescLd64Lo12 => write!(f, "Aarch64TlsDescLd64Lo12"), - Self::Aarch64TlsDescAddLo12 => write!(f, "Aarch64TlsDescAddLo12"), - Self::Aarch64TlsDescCall => write!(f, "Aarch64TlsDescCall"), + Self::Aarch64TlsGdAdrPage21 => write!(f, "Aarch64TlsGdAdrPage21"), + Self::Aarch64TlsGdAddLo12Nc => write!(f, "Aarch64TlsGdAddLo12Nc"), Self::Aarch64AdrGotPage21 => write!(f, "Aarch64AdrGotPage21"), Self::Aarch64Ld64GotLo12Nc => write!(f, "Aarch64AdrGotLo12Nc"), Self::S390xTlsGd64 => write!(f, "TlsGd64"), diff --git a/cranelift/codegen/src/context.rs b/cranelift/codegen/src/context.rs index ca3d5fb73628..2dc62ee77fd5 100644 --- a/cranelift/codegen/src/context.rs +++ b/cranelift/codegen/src/context.rs @@ -237,8 +237,6 @@ impl Context { /// Run the verifier on the function. /// /// Also check that the dominator tree and control flow graph are consistent with the function. - /// - /// TODO: rename to "CLIF validate" or similar. pub fn verify<'a, FOI: Into>>(&self, fisa: FOI) -> VerifierResult<()> { let mut errors = VerifierErrors::default(); let _ = verify_context(&self.func, &self.cfg, &self.domtree, fisa, &mut errors); diff --git a/cranelift/codegen/src/egraph.rs b/cranelift/codegen/src/egraph.rs index b54c1e7b63d3..e12b6fed39f2 100644 --- a/cranelift/codegen/src/egraph.rs +++ b/cranelift/codegen/src/egraph.rs @@ -162,7 +162,6 @@ where let result = self.func.dfg.first_result(inst); self.value_to_opt_value[result] = orig_result; self.eclasses.union(result, orig_result); - self.func.dfg.merge_facts(result, orig_result); self.stats.union += 1; result } else { @@ -257,11 +256,6 @@ where // still works, but take *only* the subsuming // value, and break now. isle_ctx.ctx.eclasses.union(optimized_value, union_value); - isle_ctx - .ctx - .func - .dfg - .merge_facts(optimized_value, union_value); union_value = optimized_value; break; } @@ -279,11 +273,6 @@ where .ctx .eclasses .union(old_union_value, optimized_value); - isle_ctx - .ctx - .func - .dfg - .merge_facts(old_union_value, optimized_value); isle_ctx.ctx.eclasses.union(old_union_value, union_value); } @@ -353,7 +342,6 @@ where new_result ); self.value_to_opt_value[result] = new_result; - self.func.dfg.merge_facts(result, new_result); true } // Otherwise, generic side-effecting op -- always keep it, and @@ -670,7 +658,7 @@ pub(crate) struct Stats { pub(crate) elaborate_visit_node: u64, pub(crate) elaborate_memoize_hit: u64, pub(crate) elaborate_memoize_miss: u64, - pub(crate) elaborate_remat: u64, + pub(crate) elaborate_memoize_miss_remat: u64, pub(crate) elaborate_licm_hoist: u64, pub(crate) elaborate_func: u64, pub(crate) elaborate_func_pre_insts: u64, diff --git a/cranelift/codegen/src/egraph/cost.rs b/cranelift/codegen/src/egraph/cost.rs index bc807df02dd1..9cfb0894ca74 100644 --- a/cranelift/codegen/src/egraph/cost.rs +++ b/cranelift/codegen/src/egraph/cost.rs @@ -33,6 +33,12 @@ use crate::ir::Opcode; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub(crate) struct Cost(u32); impl Cost { + pub(crate) fn at_level(&self, loop_level: usize) -> Cost { + let loop_level = std::cmp::min(2, loop_level); + let multiplier = 1u32 << ((10 * loop_level) as u32); + Cost(self.0.saturating_mul(multiplier)).finite() + } + pub(crate) fn infinity() -> Cost { // 2^32 - 1 is, uh, pretty close to infinite... (we use `Cost` // only for heuristics and always saturate so this suffices!) diff --git a/cranelift/codegen/src/egraph/elaborate.rs b/cranelift/codegen/src/egraph/elaborate.rs index 26c7378b2c7f..6acf83cba9ae 100644 --- a/cranelift/codegen/src/egraph/elaborate.rs +++ b/cranelift/codegen/src/egraph/elaborate.rs @@ -5,10 +5,9 @@ use super::cost::{pure_op_cost, Cost}; use super::domtree::DomTreeWithChildren; use super::Stats; use crate::dominator_tree::DominatorTree; -use crate::fx::{FxHashMap, FxHashSet}; -use crate::hash_map::Entry as HashEntry; +use crate::fx::FxHashSet; use crate::ir::{Block, Function, Inst, Value, ValueDef}; -use crate::loop_analysis::{Loop, LoopAnalysis}; +use crate::loop_analysis::{Loop, LoopAnalysis, LoopLevel}; use crate::scoped_hash_map::ScopedHashMap; use crate::trace; use crate::unionfind::UnionFind; @@ -57,8 +56,6 @@ pub(crate) struct Elaborator<'a> { elab_result_stack: Vec, /// Explicitly-unrolled block elaboration stack. block_stack: Vec, - /// Copies of values that have been rematerialized. - remat_copies: FxHashMap<(Block, Value), Value>, /// Stats for various events during egraph processing, to help /// with optimization of this infrastructure. stats: &'a mut Stats, @@ -98,6 +95,7 @@ enum ElabStackEntry { inst: Inst, result_idx: usize, num_args: usize, + remat: bool, before: Inst, }, } @@ -136,7 +134,6 @@ impl<'a> Elaborator<'a> { elab_stack: vec![], elab_result_stack: vec![], block_stack: vec![], - remat_copies: FxHashMap::default(), stats, } } @@ -214,24 +211,26 @@ impl<'a> Elaborator<'a> { // at this point, only the side-effecting skeleton), // then it must be computed and thus we give it zero // cost. + ValueDef::Result(inst, _) if self.func.layout.inst_block(inst).is_some() => { + best[value] = (Cost::zero(), value); + } ValueDef::Result(inst, _) => { - if let Some(_) = self.func.layout.inst_block(inst) { - best[value] = (Cost::zero(), value); - } else { - trace!(" -> value {}: result, computing cost", value); - let inst_data = &self.func.dfg.insts[inst]; - // N.B.: at this point we know that the opcode is - // pure, so `pure_op_cost`'s precondition is - // satisfied. - let cost = self - .func - .dfg - .inst_values(inst) - .fold(pure_op_cost(inst_data.opcode()), |cost, value| { - cost + best[value].0 - }); - best[value] = (cost, value); - } + trace!(" -> value {}: result, computing cost", value); + let inst_data = &self.func.dfg.insts[inst]; + let loop_level = self + .func + .layout + .inst_block(inst) + .map(|block| self.loop_analysis.loop_level(block)) + .unwrap_or(LoopLevel::root()); + // N.B.: at this point we know that the opcode is + // pure, so `pure_op_cost`'s precondition is + // satisfied. + let cost = self.func.dfg.inst_values(inst).fold( + pure_op_cost(inst_data.opcode()).at_level(loop_level.level()), + |cost, value| cost + best[value].0, + ); + best[value] = (cost, value); } }; debug_assert_ne!(best[value].0, Cost::infinity()); @@ -259,49 +258,13 @@ impl<'a> Elaborator<'a> { self.elab_result_stack.pop().unwrap() } - /// Possibly rematerialize the instruction producing the value in - /// `arg` and rewrite `arg` to refer to it, if needed. Returns - /// `true` if a rewrite occurred. - fn maybe_remat_arg( - remat_values: &FxHashSet, - func: &mut Function, - remat_copies: &mut FxHashMap<(Block, Value), Value>, - insert_block: Block, - before: Inst, - arg: &mut ElaboratedValue, - stats: &mut Stats, - ) -> bool { - // TODO (#7313): we may want to consider recursive - // rematerialization as well. We could process the arguments of - // the rematerialized instruction up to a certain depth. This - // would affect, e.g., adds-with-one-constant-arg, which are - // currently rematerialized. Right now we don't do this, to - // avoid the need for another fixpoint loop here. - if arg.in_block != insert_block && remat_values.contains(&arg.value) { - let new_value = match remat_copies.entry((insert_block, arg.value)) { - HashEntry::Occupied(o) => *o.get(), - HashEntry::Vacant(v) => { - let inst = func.dfg.value_def(arg.value).inst().unwrap(); - debug_assert_eq!(func.dfg.inst_results(inst).len(), 1); - let new_inst = func.dfg.clone_inst(inst); - func.layout.insert_inst(new_inst, before); - let new_result = func.dfg.inst_results(new_inst)[0]; - *v.insert(new_result) - } - }; - trace!("rematerialized {} as {}", arg.value, new_value); - arg.value = new_value; - stats.elaborate_remat += 1; - true - } else { - false - } - } - fn process_elab_stack(&mut self) { - while let Some(entry) = self.elab_stack.pop() { + while let Some(entry) = self.elab_stack.last() { match entry { - ElabStackEntry::Start { value, before } => { + &ElabStackEntry::Start { value, before } => { + // We always replace the Start entry, so pop it now. + self.elab_stack.pop(); + debug_assert_ne!(value, Value::reserved_value()); let value = self.func.dfg.resolve_aliases(value); @@ -320,17 +283,39 @@ impl<'a> Elaborator<'a> { // eclass. trace!("looking up best value for {}", value); let (_, best_value) = self.value_to_best_value[value]; - trace!("elaborate: value {} -> best {}", value, best_value); debug_assert_ne!(best_value, Value::reserved_value()); + trace!("elaborate: value {} -> best {}", value, best_value); - if let Some(elab_val) = self.value_to_elaborated_value.get(&canonical_value) { - // Value is available; use it. - trace!("elaborate: value {} -> {:?}", value, elab_val); - self.stats.elaborate_memoize_hit += 1; - self.elab_result_stack.push(*elab_val); - continue; - } - + let remat = if let Some(elab_val) = + self.value_to_elaborated_value.get(&canonical_value) + { + // Value is available. Look at the defined + // block, and determine whether this node kind + // allows rematerialization if the value comes + // from another block. If so, ignore the hit + // and recompute below. + let remat = elab_val.in_block != self.cur_block + && self.remat_values.contains(&best_value); + if !remat { + trace!("elaborate: value {} -> {:?}", value, elab_val); + self.stats.elaborate_memoize_hit += 1; + self.elab_result_stack.push(*elab_val); + continue; + } + trace!("elaborate: value {} -> remat", canonical_value); + self.stats.elaborate_memoize_miss_remat += 1; + // The op is pure at this point, so it is always valid to + // remove from this map. + self.value_to_elaborated_value.remove(&canonical_value); + true + } else { + // Value not available; but still look up + // whether it's been flagged for remat because + // this affects placement. + let remat = self.remat_values.contains(&best_value); + trace!(" -> not present in map; remat = {}", remat); + remat + }; self.stats.elaborate_memoize_miss += 1; // Now resolve the value to its definition to see @@ -378,6 +363,7 @@ impl<'a> Elaborator<'a> { inst, result_idx, num_args, + remat, before, }); @@ -390,17 +376,21 @@ impl<'a> Elaborator<'a> { } } - ElabStackEntry::PendingInst { + &ElabStackEntry::PendingInst { inst, result_idx, num_args, + remat, before, } => { + self.elab_stack.pop(); + trace!( - "PendingInst: {} result {} args {} before {}", + "PendingInst: {} result {} args {} remat {} before {}", inst, result_idx, num_args, + remat, before ); @@ -408,7 +398,7 @@ impl<'a> Elaborator<'a> { // point. Grab them and drain them out, removing // them. let arg_idx = self.elab_result_stack.len() - num_args; - let arg_values = &mut self.elab_result_stack[arg_idx..]; + let arg_values = &self.elab_result_stack[arg_idx..]; // Compute max loop depth. // @@ -454,15 +444,16 @@ impl<'a> Elaborator<'a> { // We know that this is a pure inst, because // non-pure roots have already been placed in the - // value-to-elab'd-value map, so they will not - // reach this stage of processing. + // value-to-elab'd-value map and are never subject + // to remat, so they will not reach this stage of + // processing. // // We now must determine the location at which we // place the instruction. This is the current // block *unless* we hoist above a loop when all // args are loop-invariant (and this op is pure). let (scope_depth, before, insert_block) = - if loop_hoist_level == self.loop_stack.len() { + if loop_hoist_level == self.loop_stack.len() || remat { // Depends on some value at the current // loop depth, or remat forces it here: // place it at the current location. @@ -495,39 +486,16 @@ impl<'a> Elaborator<'a> { insert_block ); - // Now that we have the location for the - // instruction, check if any of its args are remat - // values. If so, and if we don't have a copy of - // the rematerializing instruction for this block - // yet, create one. - let mut remat_arg = false; - for arg_value in arg_values.iter_mut() { - if Self::maybe_remat_arg( - &self.remat_values, - &mut self.func, - &mut self.remat_copies, - insert_block, - before, - arg_value, - &mut self.stats, - ) { - remat_arg = true; - } - } - - // Now we need to place `inst` at the computed - // location (just before `before`). Note that - // `inst` may already have been placed somewhere - // else, because a pure node may be elaborated at - // more than one place. In this case, we need to - // duplicate the instruction (and return the - // `Value`s for that duplicated instance instead). - // - // Also clone if we rematerialized, because we - // don't want to rewrite the args in the original - // copy. + // Now we need to place `inst` at the computed + // location (just before `before`). Note that + // `inst` may already have been placed somewhere + // else, because a pure node may be elaborated at + // more than one place. In this case, we need to + // duplicate the instruction (and return the + // `Value`s for that duplicated instance + // instead). trace!("need inst {} before {}", inst, before); - let inst = if self.func.layout.inst_block(inst).is_some() || remat_arg { + let inst = if self.func.layout.inst_block(inst).is_some() { // Clone the inst! let new_inst = self.func.dfg.clone_inst(inst); trace!( @@ -644,16 +612,7 @@ impl<'a> Elaborator<'a> { // Elaborate the arg, placing any newly-inserted insts // before `before`. Get the updated value, which may // be different than the original. - let mut new_arg = self.elaborate_eclass_use(*arg, before); - Self::maybe_remat_arg( - &self.remat_values, - &mut self.func, - &mut self.remat_copies, - block, - inst, - &mut new_arg, - &mut self.stats, - ); + let new_arg = self.elaborate_eclass_use(*arg, before); trace!(" -> rewrote arg to {:?}", new_arg); *arg = new_arg.value; } diff --git a/cranelift/codegen/src/ir/dfg.rs b/cranelift/codegen/src/ir/dfg.rs index 501a7f0a4ef4..76b1b08cbeea 100644 --- a/cranelift/codegen/src/ir/dfg.rs +++ b/cranelift/codegen/src/ir/dfg.rs @@ -5,7 +5,6 @@ use crate::ir; use crate::ir::builder::ReplaceBuilder; use crate::ir::dynamic_type::{DynamicTypeData, DynamicTypes}; use crate::ir::instructions::{CallInfo, InstructionData}; -use crate::ir::pcc::Fact; use crate::ir::{ types, Block, BlockCall, ConstantData, ConstantPool, DynamicType, ExtFuncData, FuncRef, Immediate, Inst, JumpTables, RelSourceLoc, SigRef, Signature, Type, Value, @@ -126,9 +125,6 @@ pub struct DataFlowGraph { /// Primary value table with entries for all values. values: PrimaryMap, - /// Facts: proof-carrying-code assertions about values. - pub facts: SecondaryMap>, - /// Function signature table. These signatures are referenced by indirect call instructions as /// well as the external function references. pub signatures: PrimaryMap, @@ -162,7 +158,6 @@ impl DataFlowGraph { dynamic_types: DynamicTypes::new(), value_lists: ValueListPool::new(), values: PrimaryMap::new(), - facts: SecondaryMap::new(), signatures: PrimaryMap::new(), old_signatures: SecondaryMap::new(), ext_funcs: PrimaryMap::new(), @@ -188,7 +183,6 @@ impl DataFlowGraph { self.constants.clear(); self.immediates.clear(); self.jump_tables.clear(); - self.facts.clear(); } /// Get the total number of instructions created in this function, whether they are currently @@ -959,13 +953,7 @@ impl DataFlowGraph { // Get the controlling type variable. let ctrl_typevar = self.ctrl_typevar(inst); // Create new result values. - let num_results = self.make_inst_results(new_inst, ctrl_typevar); - // Copy over PCC facts, if any. - for i in 0..num_results { - let old_result = self.inst_results(inst)[i]; - let new_result = self.inst_results(new_inst)[i]; - self.facts[new_result] = self.facts[old_result].clone(); - } + self.make_inst_results(new_inst, ctrl_typevar); new_inst } @@ -1291,38 +1279,6 @@ impl DataFlowGraph { pub fn detach_block_params(&mut self, block: Block) -> ValueList { self.blocks[block].params.take() } - - /// Merge the facts for two values. If both values have facts and - /// they differ, both values get a special "conflict" fact that is - /// never satisfied. - pub fn merge_facts(&mut self, a: Value, b: Value) { - let a = self.resolve_aliases(a); - let b = self.resolve_aliases(b); - match (&self.facts[a], &self.facts[b]) { - (Some(a), Some(b)) if a == b => { /* nothing */ } - (None, None) => { /* nothing */ } - (Some(a), None) => { - self.facts[b] = Some(a.clone()); - } - (None, Some(b)) => { - self.facts[a] = Some(b.clone()); - } - (Some(a_fact), Some(b_fact)) => { - assert_eq!(self.value_type(a), self.value_type(b)); - let merged = Fact::intersect(a_fact, b_fact); - crate::trace!( - "facts merge on {} and {}: {:?}, {:?} -> {:?}", - a, - b, - a_fact, - b_fact, - merged, - ); - self.facts[a] = Some(merged.clone()); - self.facts[b] = Some(merged); - } - } - } } /// Contents of a basic block. diff --git a/cranelift/codegen/src/ir/entities.rs b/cranelift/codegen/src/ir/entities.rs index af2b0efc9488..f33e198c0936 100644 --- a/cranelift/codegen/src/ir/entities.rs +++ b/cranelift/codegen/src/ir/entities.rs @@ -209,29 +209,6 @@ impl GlobalValue { } } -/// An opaque reference to a memory type. -/// -/// A `MemoryType` is a descriptor of a struct layout in memory, with -/// types and proof-carrying-code facts optionally attached to the -/// fields. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub struct MemoryType(u32); -entity_impl!(MemoryType, "mt"); - -impl MemoryType { - /// Create a new memory type reference from its number. - /// - /// This method is for use by the parser. - pub fn with_number(n: u32) -> Option { - if n < u32::MAX { - Some(Self(n)) - } else { - None - } - } -} - /// An opaque reference to a constant. /// /// You can store [`ConstantData`](super::ConstantData) in a @@ -435,8 +412,6 @@ pub enum AnyEntity { DynamicType(DynamicType), /// A Global value. GlobalValue(GlobalValue), - /// A memory type. - MemoryType(MemoryType), /// A jump table. JumpTable(JumpTable), /// A constant. @@ -462,7 +437,6 @@ impl fmt::Display for AnyEntity { Self::DynamicStackSlot(r) => r.fmt(f), Self::DynamicType(r) => r.fmt(f), Self::GlobalValue(r) => r.fmt(f), - Self::MemoryType(r) => r.fmt(f), Self::JumpTable(r) => r.fmt(f), Self::Constant(r) => r.fmt(f), Self::FuncRef(r) => r.fmt(f), @@ -521,12 +495,6 @@ impl From for AnyEntity { } } -impl From for AnyEntity { - fn from(r: MemoryType) -> Self { - Self::MemoryType(r) - } -} - impl From for AnyEntity { fn from(r: JumpTable) -> Self { Self::JumpTable(r) diff --git a/cranelift/codegen/src/ir/function.rs b/cranelift/codegen/src/ir/function.rs index 5d91e705e9eb..f5b85c50af80 100644 --- a/cranelift/codegen/src/ir/function.rs +++ b/cranelift/codegen/src/ir/function.rs @@ -5,10 +5,10 @@ use crate::entity::{PrimaryMap, SecondaryMap}; use crate::ir::{ - self, pcc::Fact, Block, DataFlowGraph, DynamicStackSlot, DynamicStackSlotData, - DynamicStackSlots, DynamicType, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Inst, - JumpTable, JumpTableData, Layout, MemoryType, MemoryTypeData, Opcode, SigRef, Signature, - SourceLocs, StackSlot, StackSlotData, StackSlots, Table, TableData, Type, + self, Block, DataFlowGraph, DynamicStackSlot, DynamicStackSlotData, DynamicStackSlots, + DynamicType, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Inst, JumpTable, + JumpTableData, Layout, Opcode, SigRef, Signature, SourceLocs, StackSlot, StackSlotData, + StackSlots, Table, TableData, Type, }; use crate::isa::CallConv; use crate::write::write_function; @@ -172,12 +172,6 @@ pub struct FunctionStencil { /// Global values referenced. pub global_values: PrimaryMap, - /// Global value proof-carrying-code facts. - pub global_value_facts: SecondaryMap>, - - /// Memory types for proof-carrying code. - pub memory_types: PrimaryMap, - /// Tables referenced. pub tables: PrimaryMap, @@ -207,8 +201,6 @@ impl FunctionStencil { self.sized_stack_slots.clear(); self.dynamic_stack_slots.clear(); self.global_values.clear(); - self.global_value_facts.clear(); - self.memory_types.clear(); self.tables.clear(); self.dfg.clear(); self.layout.clear(); @@ -243,11 +235,6 @@ impl FunctionStencil { self.global_values.push(data) } - /// Declares a memory type for use by the function. - pub fn create_memory_type(&mut self, data: MemoryTypeData) -> MemoryType { - self.memory_types.push(data) - } - /// Find the global dyn_scale value associated with given DynamicType. pub fn get_dyn_scale(&self, ty: DynamicType) -> GlobalValue { self.dfg.dynamic_types.get(ty).unwrap().dynamic_scale @@ -327,17 +314,7 @@ impl FunctionStencil { pub fn is_leaf(&self) -> bool { // Conservative result: if there's at least one function signature referenced in this // function, assume it is not a leaf. - let has_signatures = !self.dfg.signatures.is_empty(); - - // Under some TLS models, retrieving the address of a TLS variable requires calling a - // function. Conservatively assume that any function that references a tls global value - // is not a leaf. - let has_tls = self.global_values.values().any(|gv| match gv { - GlobalValueData::Symbol { tls, .. } => *tls, - _ => false, - }); - - !has_signatures && !has_tls + self.dfg.signatures.is_empty() } /// Replace the `dst` instruction's data with the `src` instruction's data @@ -421,8 +398,6 @@ impl Function { sized_stack_slots: StackSlots::new(), dynamic_stack_slots: DynamicStackSlots::new(), global_values: PrimaryMap::new(), - global_value_facts: SecondaryMap::new(), - memory_types: PrimaryMap::new(), tables: PrimaryMap::new(), dfg: DataFlowGraph::new(), layout: Layout::new(), diff --git a/cranelift/codegen/src/ir/globalvalue.rs b/cranelift/codegen/src/ir/globalvalue.rs index 438a13e50119..530875641e43 100644 --- a/cranelift/codegen/src/ir/globalvalue.rs +++ b/cranelift/codegen/src/ir/globalvalue.rs @@ -1,7 +1,7 @@ //! Global values. use crate::ir::immediates::{Imm64, Offset32}; -use crate::ir::{ExternalName, GlobalValue, MemFlags, Type}; +use crate::ir::{ExternalName, GlobalValue, Type}; use crate::isa::TargetIsa; use core::fmt; @@ -31,8 +31,9 @@ pub enum GlobalValueData { /// Type of the loaded value. global_type: Type, - /// Specifies the memory flags to be used by the load. Guaranteed to be notrap and aligned. - flags: MemFlags, + /// Specifies whether the memory that this refers to is readonly, allowing for the + /// elimination of redundant loads. + readonly: bool, }, /// Value is an offset from another global value. @@ -110,8 +111,15 @@ impl fmt::Display for GlobalValueData { base, offset, global_type, - flags, - } => write!(f, "load.{}{} {}{}", global_type, flags, base, offset), + readonly, + } => write!( + f, + "load.{} notrap aligned {}{}{}", + global_type, + if readonly { "readonly " } else { "" }, + base, + offset + ), Self::IAddImm { global_type, base, diff --git a/cranelift/codegen/src/ir/memflags.rs b/cranelift/codegen/src/ir/memflags.rs index 546e11fa3703..87165ba69117 100644 --- a/cranelift/codegen/src/ir/memflags.rs +++ b/cranelift/codegen/src/ir/memflags.rs @@ -6,19 +6,10 @@ use core::fmt; use serde_derive::{Deserialize, Serialize}; enum FlagBit { - /// Guaranteed not to trap. This may enable additional - /// optimizations to be performed. Notrap, - /// Guaranteed to use "natural alignment" for the given type. This - /// may enable better instruction selection. Aligned, - /// A load that reads data in memory that does not change for the - /// duration of the function's execution. This may enable - /// additional optimizations to be performed. Readonly, - /// Load multi-byte values from memory in a little-endian format. LittleEndian, - /// Load multi-byte values from memory in a big-endian format. BigEndian, /// Accesses only the "heap" part of abstract state. Used for /// alias analysis. Mutually exclusive with "table" and "vmctx". @@ -29,15 +20,10 @@ enum FlagBit { /// Accesses only the "vmctx" part of abstract state. Used for /// alias analysis. Mutually exclusive with "heap" and "table". Vmctx, - /// Check this load or store for safety when using the - /// proof-carrying-code framework. The address must have a - /// `PointsTo` fact attached with a sufficiently large valid range - /// for the accessed size. - Checked, } -const NAMES: [&str; 9] = [ - "notrap", "aligned", "readonly", "little", "big", "heap", "table", "vmctx", "checked", +const NAMES: [&str; 8] = [ + "notrap", "aligned", "readonly", "little", "big", "heap", "table", "vmctx", ]; /// Endianness of a memory access. @@ -62,7 +48,7 @@ pub enum Endianness { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct MemFlags { - bits: u16, + bits: u8, } impl MemFlags { @@ -279,32 +265,6 @@ impl MemFlags { self.set_vmctx(); self } - - /// Test if the `checked` bit is set. - /// - /// Loads and stores with this flag are verified to access - /// pointers only with a validated `PointsTo` fact attached, and - /// with that fact validated, when using the proof-carrying-code - /// framework. If initial facts on program inputs are correct - /// (i.e., correctly denote the shape and types of data structures - /// in memory), and if PCC validates the compiled output, then all - /// `checked`-marked memory accesses are guaranteed (up to the - /// checker's correctness) to access valid memory. This can be - /// used to ensure memory safety and sandboxing. - pub fn checked(self) -> bool { - self.read(FlagBit::Checked) - } - - /// Set the `checked` bit. - pub fn set_checked(&mut self) { - self.set(FlagBit::Checked); - } - - /// Set the `checked` bit, returning new flags. - pub fn with_checked(mut self) -> Self { - self.set_checked(); - self - } } impl fmt::Display for MemFlags { diff --git a/cranelift/codegen/src/ir/memtype.rs b/cranelift/codegen/src/ir/memtype.rs deleted file mode 100644 index 403661d89c82..000000000000 --- a/cranelift/codegen/src/ir/memtype.rs +++ /dev/null @@ -1,181 +0,0 @@ -//! Definitions for "memory types" in CLIF. -//! -//! A memory type is a struct-like definition -- fields with offsets, -//! each field having a type and possibly an attached fact -- that we -//! can use in proof-carrying code to validate accesses to structs and -//! propagate facts onto the loaded values as well. -//! -//! Memory types are meant to be rich enough to describe the *layout* -//! of values in memory, but do not necessarily need to embody -//! higher-level features such as subtyping directly. Rather, they -//! should encode an implementation of a type or object system. -//! -//! Note also that it is a non-goal for now for this type system to be -//! "complete" or fully orthogonal: we have some restrictions now -//! (e.g., struct fields are only primitives) because this is all we -//! need for existing PCC applications, and it keeps the -//! implementation simpler. -//! -//! There are a few basic kinds of types: -//! -//! - A struct is an aggregate of fields and an overall size. Each -//! field has a *primitive Cranelift type*. This is for simplicity's -//! sake: we do not allow nested memory types because to do so -//! invites cycles, requires recursive computation of sizes, creates -//! complicated questions when field types are dynamically-sized, -//! and in general is more complexity than we need. -//! -//! The expectation (validated by PCC) is that when a checked load -//! or store accesses memory typed by a memory type, accesses will -//! only be to fields at offsets named in the type, and will be via -//! the given Cranelift type -- i.e., no type-punning occurs in -//! memory. -//! -//! The overall size of the struct may be larger than that implied -//! by the fields because (i) we may not want or need to name all -//! the actually-existing fields in the memory type, and (ii) there -//! may be alignment padding that we also don't want or need to -//! represent explicitly. -//! -//! - A static memory is an untyped blob of storage with a static -//! size. This is memory that can be accessed with any type of load -//! or store at any valid offset. -//! -//! Note that this is *distinct* from an "array of u8" kind of -//! representation of memory, if/when we can represent such a thing, -//! because the expectation with memory types' fields (including -//! array elements) is that they are strongly typed, only accessed -//! via that type, and not type-punned. We don't want to imply any -//! restriction on load/store size, or any actual structure, with -//! untyped memory; it's just a blob. -//! -//! Eventually we plan to also have: -//! -//! - A dynamic memory is an untyped blob of storage with a size given -//! by a global value (GV). This is otherwise just like the "static -//! memory" variant described above. -//! -//! - A dynamic array is a sequence of struct memory types, with a -//! length given by a global value (GV). This is useful to model, -//! e.g., tables. -//! -//! - A discriminated union is a union of several memory types -//! together with a tag field. This will be useful to model and -//! verify subtyping/downcasting for Wasm GC, among other uses. -//! -//! - Nullability on pointer fields: the fact will hold only if the -//! field is not null (all zero bits). - -use crate::ir::pcc::Fact; -use crate::ir::Type; -use alloc::vec::Vec; - -#[cfg(feature = "enable-serde")] -use serde_derive::{Deserialize, Serialize}; - -/// Data defining a memory type. -/// -/// A memory type corresponds to a layout of data in memory. It may -/// have a statically-known or dynamically-known size. -#[derive(Clone, PartialEq, Hash)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub enum MemoryTypeData { - /// An aggregate consisting of certain fields at certain offsets. - /// - /// Fields must be sorted by offset, must be within the struct's - /// overall size, and must not overlap. These conditions are - /// checked by the CLIF verifier. - Struct { - /// Size of this type. - size: u64, - - /// Fields in this type. Sorted by offset. - fields: Vec, - }, - - /// A statically-sized untyped blob of memory. - Memory { - /// Accessible size. - size: u64, - }, - - /// A type with no size. - Empty, -} - -impl std::default::Default for MemoryTypeData { - fn default() -> Self { - Self::Empty - } -} - -impl std::fmt::Display for MemoryTypeData { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - Self::Struct { size, fields } => { - write!(f, "struct {size} {{")?; - let mut first = true; - for field in fields { - if first { - first = false; - } else { - write!(f, ",")?; - } - write!(f, " {}: {}", field.offset, field.ty)?; - if field.readonly { - write!(f, " readonly")?; - } - if let Some(fact) = &field.fact { - write!(f, " ! {}", fact)?; - } - } - write!(f, " }}")?; - Ok(()) - } - Self::Memory { size } => { - write!(f, "memory {size:#x}") - } - Self::Empty => { - write!(f, "empty") - } - } - } -} - -/// One field in a memory type. -#[derive(Clone, PartialEq, Hash)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub struct MemoryTypeField { - /// The offset of this field in the memory type. - pub offset: u64, - /// The primitive type of the value in this field. Accesses to the - /// field must use this type (i.e., cannot bitcast/type-pun in - /// memory). - pub ty: Type, - /// A proof-carrying-code fact about this value, if any. - pub fact: Option, - /// Whether this field is read-only, i.e., stores should be - /// disallowed. - pub readonly: bool, -} - -impl MemoryTypeField { - /// Get the fact, if any, on a field. - pub fn fact(&self) -> Option<&Fact> { - self.fact.as_ref() - } -} - -impl MemoryTypeData { - /// Provide the static size of this type, if known. - /// - /// (The size may not be known for dynamically-sized arrays or - /// memories, when those memtype kinds are added.) - pub fn static_size(&self) -> Option { - match self { - Self::Struct { size, .. } => Some(*size), - Self::Memory { size } => Some(*size), - Self::Empty => Some(0), - } - } -} diff --git a/cranelift/codegen/src/ir/mod.rs b/cranelift/codegen/src/ir/mod.rs index e2ec87d67205..986f8003722c 100644 --- a/cranelift/codegen/src/ir/mod.rs +++ b/cranelift/codegen/src/ir/mod.rs @@ -18,8 +18,6 @@ pub(crate) mod known_symbol; pub mod layout; pub(crate) mod libcall; mod memflags; -mod memtype; -pub mod pcc; mod progpoint; mod sourceloc; pub mod stackslot; @@ -39,7 +37,7 @@ pub use crate::ir::dfg::{BlockData, DataFlowGraph, ValueDef}; pub use crate::ir::dynamic_type::{dynamic_to_fixed, DynamicTypeData, DynamicTypes}; pub use crate::ir::entities::{ Block, Constant, DynamicStackSlot, DynamicType, FuncRef, GlobalValue, Immediate, Inst, - JumpTable, MemoryType, SigRef, StackSlot, Table, UserExternalNameRef, Value, + JumpTable, SigRef, StackSlot, Table, UserExternalNameRef, Value, }; pub use crate::ir::extfunc::{ AbiParam, ArgumentExtension, ArgumentPurpose, ExtFuncData, Signature, @@ -55,7 +53,6 @@ pub use crate::ir::known_symbol::KnownSymbol; pub use crate::ir::layout::Layout; pub use crate::ir::libcall::{get_probestack_funcref, LibCall}; pub use crate::ir::memflags::{Endianness, MemFlags}; -pub use crate::ir::memtype::{MemoryTypeData, MemoryTypeField}; pub use crate::ir::progpoint::ProgramPoint; pub use crate::ir::sourceloc::RelSourceLoc; pub use crate::ir::sourceloc::SourceLoc; diff --git a/cranelift/codegen/src/ir/pcc.rs b/cranelift/codegen/src/ir/pcc.rs deleted file mode 100644 index fe7f08c96cdb..000000000000 --- a/cranelift/codegen/src/ir/pcc.rs +++ /dev/null @@ -1,809 +0,0 @@ -//! Proof-carrying code. We attach "facts" to values and then check -//! that they remain true after compilation. -//! -//! A few key design principle of this approach are: -//! -//! - The producer of the IR provides the axioms. All "ground truth", -//! such as what memory is accessible -- is meant to come by way of -//! facts on the function arguments and global values. In some -//! sense, all we are doing here is validating the "internal -//! consistency" of the facts that are provided on values, and the -//! actions performed on those values. -//! -//! - We do not derive and forward-propagate facts eagerly. Rather, -//! the producer needs to provide breadcrumbs -- a "proof witness" -//! of sorts -- to allow the checking to complete. That means that -//! as an address is computed, or pointer chains are dereferenced, -//! each intermediate value will likely have some fact attached. -//! -//! This does create more verbose IR, but a significant positive -//! benefit is that it avoids unnecessary work: we do not build up a -//! knowledge base that effectively encodes the integer ranges of -//! many or most values in the program. Rather, we only check -//! specifically the memory-access sequences. In practice, each such -//! sequence is likely to be a carefully-controlled sequence of IR -//! operations from, e.g., a sandboxing compiler (such as -//! `cranelift-wasm`) so adding annotations here to communicate -//! intent (ranges, bounds-checks, and the like) is no problem. -//! -//! Facts are attached to SSA values in CLIF, and are maintained -//! through optimizations and through lowering. They are thus also -//! present on VRegs in the VCode. In theory, facts could be checked -//! at either level, though in practice it is most useful to check -//! them at the VCode level if the goal is an end-to-end verification -//! of certain properties (e.g., memory sandboxing). -//! -//! Checking facts entails visiting each instruction that defines a -//! value with a fact, and checking the result's fact against the -//! facts on arguments and the operand. For VCode, this is -//! fundamentally a question of the target ISA's semantics, so we call -//! into the `LowerBackend` for this. Note that during checking there -//! is also limited forward propagation / inference, but only within -//! an instruction: for example, an addressing mode commonly can -//! include an addition, multiplication/shift, or extend operation, -//! and there is no way to attach facts to the intermediate values -//! "inside" the instruction, so instead the backend can use -//! `FactContext::add()` and friends to forward-propagate facts. -//! -//! TODO: -//! -//! Completeness: -//! - Propagate facts through optimization (egraph layer). -//! - Generate facts in cranelift-wasm frontend when lowering memory ops. -//! - Support bounds-checking-type operations for dynamic memories and -//! tables. -//! -//! More checks: -//! - Check that facts on `vmctx` GVs are subsumed by the actual facts -//! on the vmctx arg in block0 (function arg). -//! -//! Generality: -//! - facts on outputs (in func signature)? -//! - Implement checking at the CLIF level as well. -//! - Check instructions that can trap as well? -//! -//! Nicer errors: -//! - attach instruction index or some other identifier to errors -//! -//! Refactoring: -//! - avoid the "default fact" infra everywhere we fetch facts, -//! instead doing it in the subsume check (and take the type with -//! subsume)? -//! -//! Text format cleanup: -//! - make the bitwidth on `max` facts optional in the CLIF text -//! format? -//! - make offset in `mem` fact optional in the text format? -//! -//! Bikeshed colors (syntax): -//! - Put fact bang-annotations after types? -//! `v0: i64 ! fact(..)` vs. `v0 ! fact(..): i64` - -use crate::ir; -use crate::ir::types::*; -use crate::isa::TargetIsa; -use crate::machinst::{BlockIndex, LowerBackend, VCode}; -use crate::trace; -use regalloc2::Function as _; -use std::fmt; - -#[cfg(feature = "enable-serde")] -use serde_derive::{Deserialize, Serialize}; - -/// The result of checking proof-carrying-code facts. -pub type PccResult = std::result::Result; - -/// An error or inconsistency discovered when checking proof-carrying -/// code. -#[derive(Debug, Clone)] -pub enum PccError { - /// An operation wraps around, invalidating the stated value - /// range. - Overflow, - /// An input to an operator that produces a fact-annotated value - /// does not have a fact describing it, and one is needed. - MissingFact, - /// A derivation of an output fact is unsupported (incorrect or - /// not derivable). - UnsupportedFact, - /// A block parameter claims a fact that one of its predecessors - /// does not support. - UnsupportedBlockparam, - /// A memory access is out of bounds. - OutOfBounds, - /// Proof-carrying-code checking is not implemented for a - /// particular compiler backend. - UnimplementedBackend, - /// Proof-carrying-code checking is not implemented for a - /// particular instruction that instruction-selection chose. This - /// is an internal compiler error. - UnimplementedInst, - /// Access to an invalid or undefined field offset in a struct. - InvalidFieldOffset, - /// Access to a field via the wrong type. - BadFieldType, - /// Store to a read-only field. - WriteToReadOnlyField, - /// Store of data to a field with a fact that does not subsume the - /// field's fact. - InvalidStoredFact, -} - -/// A fact on a value. -#[derive(Clone, Debug, Hash, PartialEq, Eq)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub enum Fact { - /// A bitslice of a value (up to a bitwidth) is within the given - /// integer range. - /// - /// The slicing behavior is needed because this fact can describe - /// both an SSA `Value`, whose entire value is well-defined, and a - /// `VReg` in VCode, whose bits beyond the type stored in that - /// register are don't-care (undefined). - Range { - /// The bitwidth of bits we care about, from the LSB upward. - bit_width: u16, - /// The minimum value that the bitslice can take - /// (inclusive). The range is unsigned: the specified bits of - /// the actual value will be greater than or equal to this - /// value, as evaluated by an unsigned integer comparison. - min: u64, - /// The maximum value that the bitslice can take - /// (inclusive). The range is unsigned: the specified bits of - /// the actual value will be less than or equal to this value, - /// as evaluated by an unsigned integer comparison. - max: u64, - }, - - /// A pointer to a memory type. - Mem { - /// The memory type. - ty: ir::MemoryType, - /// The minimum offset into the memory type, inclusive. - min_offset: u64, - /// The maximum offset into the memory type, inclusive. - max_offset: u64, - }, - - /// A "conflict fact": this fact results from merging two other - /// facts, and it can never be satisfied -- checking any value - /// against this fact will fail. - Conflict, -} - -impl fmt::Display for Fact { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Fact::Range { - bit_width, - min, - max, - } => write!(f, "range({}, {:#x}, {:#x})", bit_width, min, max), - Fact::Mem { - ty, - min_offset, - max_offset, - } => write!(f, "mem({}, {:#x}, {:#x})", ty, min_offset, max_offset), - Fact::Conflict => write!(f, "conflict"), - } - } -} - -impl Fact { - /// Create a range fact that specifies a single known constant value. - pub fn constant(bit_width: u16, value: u64) -> Self { - debug_assert!(value <= max_value_for_width(bit_width)); - // `min` and `max` are inclusive, so this specifies a range of - // exactly one value. - Fact::Range { - bit_width, - min: value, - max: value, - } - } - - /// Create a range fact that specifies the maximum range for a - /// value of the given bit-width. - pub const fn max_range_for_width(bit_width: u16) -> Self { - match bit_width { - bit_width if bit_width < 64 => Fact::Range { - bit_width, - min: 0, - max: (1u64 << bit_width) - 1, - }, - 64 => Fact::Range { - bit_width: 64, - min: 0, - max: u64::MAX, - }, - _ => panic!("bit width too large!"), - } - } - - /// Create a range fact that specifies the maximum range for a - /// value of the given bit-width, zero-extended into a wider - /// width. - pub const fn max_range_for_width_extended(from_width: u16, to_width: u16) -> Self { - debug_assert!(from_width <= to_width); - match from_width { - from_width if from_width < 64 => Fact::Range { - bit_width: to_width, - min: 0, - max: (1u64 << from_width) - 1, - }, - 64 => Fact::Range { - bit_width: to_width, - min: 0, - max: u64::MAX, - }, - _ => panic!("bit width too large!"), - } - } - - /// Try to infer a minimal fact for a value of the given IR type. - pub fn infer_from_type(ty: ir::Type) -> Option<&'static Self> { - static FACTS: [Fact; 4] = [ - Fact::max_range_for_width(8), - Fact::max_range_for_width(16), - Fact::max_range_for_width(32), - Fact::max_range_for_width(64), - ]; - match ty { - I8 => Some(&FACTS[0]), - I16 => Some(&FACTS[1]), - I32 => Some(&FACTS[2]), - I64 => Some(&FACTS[3]), - _ => None, - } - } - - /// Does this fact "propagate" automatically, i.e., cause - /// instructions that process it to infer their own output facts? - /// Not all facts propagate automatically; otherwise, verification - /// would be much slower. - pub fn propagates(&self) -> bool { - match self { - Fact::Mem { .. } => true, - _ => false, - } - } - - /// Is this a constant value of the given bitwidth? Return it as a - /// `Some(value)` if so. - pub fn as_const(&self, bits: u16) -> Option { - match self { - Fact::Range { - bit_width, - min, - max, - } if *bit_width == bits && min == max => Some(*min), - _ => None, - } - } - - /// Merge two facts. We take the *intersection*: that is, we know - /// both facts to be true, so we can intersect ranges. (This - /// differs from the usual static analysis approach, where we are - /// merging multiple possibilities into a generalized / widened - /// fact. We want to narrow here.) - pub fn intersect(a: &Fact, b: &Fact) -> Fact { - match (a, b) { - ( - Fact::Range { - bit_width: bw_lhs, - min: min_lhs, - max: max_lhs, - }, - Fact::Range { - bit_width: bw_rhs, - min: min_rhs, - max: max_rhs, - }, - ) if bw_lhs == bw_rhs && max_lhs >= min_rhs && max_rhs >= min_lhs => Fact::Range { - bit_width: *bw_lhs, - min: std::cmp::max(*min_lhs, *min_rhs), - max: std::cmp::min(*max_lhs, *max_rhs), - }, - - ( - Fact::Mem { - ty: ty_lhs, - min_offset: min_offset_lhs, - max_offset: max_offset_lhs, - }, - Fact::Mem { - ty: ty_rhs, - min_offset: min_offset_rhs, - max_offset: max_offset_rhs, - }, - ) if ty_lhs == ty_rhs - && max_offset_lhs >= min_offset_rhs - && max_offset_rhs >= min_offset_lhs => - { - Fact::Mem { - ty: *ty_lhs, - min_offset: std::cmp::max(*min_offset_lhs, *min_offset_rhs), - max_offset: std::cmp::min(*max_offset_lhs, *max_offset_rhs), - } - } - - _ => Fact::Conflict, - } - } -} - -macro_rules! ensure { - ( $condition:expr, $err:tt $(,)? ) => { - if !$condition { - return Err(PccError::$err); - } - }; -} - -macro_rules! bail { - ( $err:tt ) => {{ - return Err(PccError::$err); - }}; -} - -/// A "context" in which we can evaluate and derive facts. This -/// context carries environment/global properties, such as the machine -/// pointer width. -pub struct FactContext<'a> { - function: &'a ir::Function, - pointer_width: u16, -} - -impl<'a> FactContext<'a> { - /// Create a new "fact context" in which to evaluate facts. - pub fn new(function: &'a ir::Function, pointer_width: u16) -> Self { - FactContext { - function, - pointer_width, - } - } - - /// Computes whether `lhs` "subsumes" (implies) `rhs`. - pub fn subsumes(&self, lhs: &Fact, rhs: &Fact) -> bool { - match (lhs, rhs) { - // Reflexivity. - (l, r) if l == r => true, - - ( - Fact::Range { - bit_width: bw_lhs, - min: min_lhs, - max: max_lhs, - }, - Fact::Range { - bit_width: bw_rhs, - min: min_rhs, - max: max_rhs, - }, - ) => { - // If the bitwidths we're claiming facts about are the - // same, or the left-hand-side makes a claim about a - // wider bitwidth, and if the right-hand-side range is - // larger than the left-hand-side range, than the LHS - // subsumes the RHS. - // - // In other words, we can always expand the claimed - // possible value range. - bw_lhs >= bw_rhs && max_lhs <= max_rhs && min_lhs >= min_rhs - } - - ( - Fact::Mem { - ty: ty_lhs, - min_offset: min_offset_lhs, - max_offset: max_offset_lhs, - }, - Fact::Mem { - ty: ty_rhs, - min_offset: min_offset_rhs, - max_offset: max_offset_rhs, - }, - ) => { - ty_lhs == ty_rhs - && max_offset_lhs <= max_offset_rhs - && min_offset_lhs >= min_offset_rhs - } - - _ => false, - } - } - - /// Computes whether the optional fact `lhs` subsumes (implies) - /// the optional fact `lhs`. A `None` never subsumes any fact, and - /// is always subsumed by any fact at all (or no fact). - pub fn subsumes_fact_optionals(&self, lhs: Option<&Fact>, rhs: Option<&Fact>) -> bool { - match (lhs, rhs) { - (None, None) => true, - (Some(_), None) => true, - (None, Some(_)) => false, - (Some(lhs), Some(rhs)) => self.subsumes(lhs, rhs), - } - } - - /// Computes whatever fact can be known about the sum of two - /// values with attached facts. The add is performed to the given - /// bit-width. Note that this is distinct from the machine or - /// pointer width: e.g., many 64-bit machines can still do 32-bit - /// adds that wrap at 2^32. - pub fn add(&self, lhs: &Fact, rhs: &Fact, add_width: u16) -> Option { - match (lhs, rhs) { - ( - Fact::Range { - bit_width: bw_lhs, - min: min_lhs, - max: max_lhs, - }, - Fact::Range { - bit_width: bw_rhs, - min: min_rhs, - max: max_rhs, - }, - ) if bw_lhs == bw_rhs && add_width >= *bw_lhs => { - let computed_min = min_lhs.checked_add(*min_rhs)?; - let computed_max = max_lhs.checked_add(*max_rhs)?; - let computed_max = std::cmp::min(max_value_for_width(add_width), computed_max); - Some(Fact::Range { - bit_width: *bw_lhs, - min: computed_min, - max: computed_max, - }) - } - - ( - Fact::Range { - bit_width: bw_max, - min, - max, - }, - Fact::Mem { - ty, - min_offset, - max_offset, - }, - ) - | ( - Fact::Mem { - ty, - min_offset, - max_offset, - }, - Fact::Range { - bit_width: bw_max, - min, - max, - }, - ) if *bw_max >= self.pointer_width && add_width >= *bw_max => { - let min_offset = min_offset.checked_add(*min)?; - let max_offset = max_offset.checked_add(*max)?; - Some(Fact::Mem { - ty: *ty, - min_offset, - max_offset, - }) - } - - _ => None, - } - } - - /// Computes the `uextend` of a value with the given facts. - pub fn uextend(&self, fact: &Fact, from_width: u16, to_width: u16) -> Option { - trace!( - "uextend: fact {:?} from {} to {}", - fact, - from_width, - to_width - ); - if from_width == to_width { - return Some(fact.clone()); - } - - match fact { - // If the claim is already for a same-or-wider value and the min - // and max are within range of the narrower value, we can - // claim the same range. - Fact::Range { - bit_width, - min, - max, - } if *bit_width >= from_width - && *min <= max_value_for_width(from_width) - && *max <= max_value_for_width(from_width) => - { - Some(Fact::Range { - bit_width: to_width, - min: *min, - max: *max, - }) - } - // Otherwise, we can at least claim that the value is - // within the range of `from_width`. - Fact::Range { .. } => Some(Fact::max_range_for_width_extended(from_width, to_width)), - - _ => None, - } - } - - /// Computes the `sextend` of a value with the given facts. - pub fn sextend(&self, fact: &Fact, from_width: u16, to_width: u16) -> Option { - match fact { - // If we have a defined value in bits 0..bit_width, and - // the MSB w.r.t. `from_width` is *not* set, then we can - // do the same as `uextend`. - Fact::Range { - bit_width, - // We can ignore `min`: it is always <= max in - // unsigned terms, and we check max's LSB below. - min: _, - max, - } if *bit_width == from_width && (*max & (1 << (*bit_width - 1)) == 0) => { - self.uextend(fact, from_width, to_width) - } - _ => None, - } - } - - /// Computes the bit-truncation of a value with the given fact. - pub fn truncate(&self, fact: &Fact, from_width: u16, to_width: u16) -> Option { - if from_width == to_width { - return Some(fact.clone()); - } - - trace!( - "truncate: fact {:?} from {} to {}", - fact, - from_width, - to_width - ); - - match fact { - Fact::Range { - bit_width, - min, - max, - } if *bit_width == from_width => { - let max_val = (1u64 << to_width) - 1; - if *min <= max_val && *max <= max_val { - Some(Fact::Range { - bit_width: to_width, - min: *min, - max: *max, - }) - } else { - Some(Fact::Range { - bit_width: to_width, - min: 0, - max: max_val, - }) - } - } - _ => None, - } - } - - /// Scales a value with a fact by a known constant. - pub fn scale(&self, fact: &Fact, width: u16, factor: u32) -> Option { - match fact { - Fact::Range { - bit_width, - min, - max, - } if *bit_width == width => { - let min = min.checked_mul(u64::from(factor))?; - let max = max.checked_mul(u64::from(factor))?; - if *bit_width < 64 && max > max_value_for_width(width) { - return None; - } - Some(Fact::Range { - bit_width: *bit_width, - min, - max, - }) - } - _ => None, - } - } - - /// Left-shifts a value with a fact by a known constant. - pub fn shl(&self, fact: &Fact, width: u16, amount: u16) -> Option { - if amount >= 32 { - return None; - } - let factor: u32 = 1 << amount; - self.scale(fact, width, factor) - } - - /// Offsets a value with a fact by a known amount. - pub fn offset(&self, fact: &Fact, width: u16, offset: i64) -> Option { - trace!( - "FactContext::offset: {:?} + {} in width {}", - fact, - offset, - width - ); - - let compute_offset = |base: u64| -> Option { - if offset >= 0 { - base.checked_add(u64::try_from(offset).unwrap()) - } else { - base.checked_sub(u64::try_from(-offset).unwrap()) - } - }; - - match fact { - Fact::Range { - bit_width, - min, - max, - } if *bit_width == width => { - let min = compute_offset(*min)?; - let max = compute_offset(*max)?; - - Some(Fact::Range { - bit_width: *bit_width, - min, - max, - }) - } - Fact::Mem { - ty, - min_offset: mem_min_offset, - max_offset: mem_max_offset, - } => { - let min_offset = compute_offset(*mem_min_offset)?; - let max_offset = compute_offset(*mem_max_offset)?; - Some(Fact::Mem { - ty: *ty, - min_offset, - max_offset, - }) - } - _ => None, - } - } - - /// Check that accessing memory via a pointer with this fact, with - /// a memory access of the given size, is valid. - /// - /// If valid, returns the memory type and offset into that type - /// that this address accesses, if known, or `None` if the range - /// doesn't constrain the access to exactly one location. - fn check_address(&self, fact: &Fact, size: u32) -> PccResult> { - trace!("check_address: fact {:?} size {}", fact, size); - match fact { - Fact::Mem { - ty, - min_offset, - max_offset, - } => { - let end_offset: u64 = max_offset - .checked_add(u64::from(size)) - .ok_or(PccError::Overflow)?; - match &self.function.memory_types[*ty] { - ir::MemoryTypeData::Struct { size, .. } - | ir::MemoryTypeData::Memory { size } => { - ensure!(end_offset <= *size, OutOfBounds) - } - ir::MemoryTypeData::Empty => bail!(OutOfBounds), - } - let specific_ty_and_offset = if min_offset == max_offset { - Some((*ty, *min_offset)) - } else { - None - }; - Ok(specific_ty_and_offset) - } - _ => bail!(OutOfBounds), - } - } - - /// Get the access struct field, if any, by a pointer with the - /// given fact and an access of the given type. - pub fn struct_field<'b>( - &'b self, - fact: &Fact, - access_ty: ir::Type, - ) -> PccResult> { - let (ty, offset) = match self.check_address(fact, access_ty.bytes())? { - Some((ty, offset)) => (ty, offset), - None => return Ok(None), - }; - - if let ir::MemoryTypeData::Struct { fields, .. } = &self.function.memory_types[ty] { - let field = fields - .iter() - .find(|field| field.offset == offset) - .ok_or(PccError::InvalidFieldOffset)?; - if field.ty != access_ty { - bail!(BadFieldType); - } - Ok(Some(field)) - } else { - // Access to valid memory, but not a struct: no facts can be attached to the result. - Ok(None) - } - } - - /// Check a load, and determine what fact, if any, the result of the load might have. - pub fn load<'b>(&'b self, fact: &Fact, access_ty: ir::Type) -> PccResult> { - Ok(self - .struct_field(fact, access_ty)? - .and_then(|field| field.fact())) - } - - /// Check a store. - pub fn store( - &self, - fact: &Fact, - access_ty: ir::Type, - data_fact: Option<&Fact>, - ) -> PccResult<()> { - if let Some(field) = self.struct_field(fact, access_ty)? { - // If it's a read-only field, disallow. - if field.readonly { - bail!(WriteToReadOnlyField); - } - // Check that the fact on the stored data subsumes the field's fact. - if !self.subsumes_fact_optionals(data_fact, field.fact()) { - bail!(InvalidStoredFact); - } - } - Ok(()) - } -} - -fn max_value_for_width(bits: u16) -> u64 { - assert!(bits <= 64); - if bits == 64 { - u64::MAX - } else { - (1u64 << bits) - 1 - } -} - -/// Top-level entry point after compilation: this checks the facts in -/// VCode. -pub fn check_vcode_facts( - f: &ir::Function, - vcode: &mut VCode, - backend: &B, -) -> PccResult<()> { - let ctx = FactContext::new(f, backend.triple().pointer_width().unwrap().bits().into()); - - // Check that individual instructions are valid according to input - // facts, and support the stated output facts. - for block in 0..vcode.num_blocks() { - let block = BlockIndex::new(block); - for inst in vcode.block_insns(block).iter() { - // Check any output facts on this inst. - if let Err(e) = backend.check_fact(&ctx, vcode, inst) { - log::error!("Error checking instruction: {:?}", vcode[inst]); - return Err(e); - } - - // If this is a branch, check that all block arguments subsume - // the assumed facts on the blockparams of successors. - if vcode.is_branch(inst) { - for (succ_idx, succ) in vcode.block_succs(block).iter().enumerate() { - for (arg, param) in vcode - .branch_blockparams(block, inst, succ_idx) - .iter() - .zip(vcode.block_params(*succ).iter()) - { - let arg_fact = vcode.vreg_fact(*arg); - let param_fact = vcode.vreg_fact(*param); - if !ctx.subsumes_fact_optionals(arg_fact, param_fact) { - return Err(PccError::UnsupportedBlockparam); - } - } - } - } - } - } - Ok(()) -} diff --git a/cranelift/codegen/src/isa/aarch64/abi.rs b/cranelift/codegen/src/isa/aarch64/abi.rs index b5d6e56fcd9f..bcf865d2603f 100644 --- a/cranelift/codegen/src/isa/aarch64/abi.rs +++ b/cranelift/codegen/src/isa/aarch64/abi.rs @@ -1148,14 +1148,10 @@ impl ABIMachineSpec for AArch64MachineDeps { } fn get_ext_mode( - call_conv: isa::CallConv, - specified: ir::ArgumentExtension, + _call_conv: isa::CallConv, + _specified: ir::ArgumentExtension, ) -> ir::ArgumentExtension { - if call_conv == isa::CallConv::AppleAarch64 { - specified - } else { - ir::ArgumentExtension::None - } + ir::ArgumentExtension::None } fn compute_frame_layout( diff --git a/cranelift/codegen/src/isa/aarch64/inst.isle b/cranelift/codegen/src/isa/aarch64/inst.isle index 90c0911185c5..624a5c9d987b 100644 --- a/cranelift/codegen/src/isa/aarch64/inst.isle +++ b/cranelift/codegen/src/isa/aarch64/inst.isle @@ -883,8 +883,7 @@ ;; Jump-table sequence, as one compound instruction (see note in lower_inst.rs for rationale). (JTSequence - (default MachLabel) - (targets BoxVecMachLabel) + (info BoxJTSequenceInfo) (ridx Reg) (rtmp1 WritableReg) (rtmp2 WritableReg)) @@ -947,9 +946,8 @@ ;; A call to the `ElfTlsGetAddr` libcall. Returns address of TLS symbol in x0. (ElfTlsGetAddr - (symbol BoxExternalName) - (rd WritableReg) - (tmp WritableReg)) + (symbol ExternalName) + (rd WritableReg)) (MachOTlsGetAddr (symbol ExternalName) @@ -1719,13 +1717,18 @@ (decl u64_into_imm_logic (Type u64) ImmLogic) (extern constructor u64_into_imm_logic u64_into_imm_logic) -(decl branch_target (MachLabel) BranchTarget) +(decl branch_target (VecMachLabel u8) BranchTarget) (extern constructor branch_target branch_target) -(convert MachLabel BranchTarget branch_target) -(decl targets_jt_space (BoxVecMachLabel) CodeOffset) +(decl targets_jt_size (VecMachLabel) u32) +(extern constructor targets_jt_size targets_jt_size) + +(decl targets_jt_space (VecMachLabel) CodeOffset) (extern constructor targets_jt_space targets_jt_space) +(decl targets_jt_info (VecMachLabel) BoxJTSequenceInfo) +(extern constructor targets_jt_info targets_jt_info) + ;; Calculate the minimum floating-point bound for a conversion to floating ;; point from an integer type. ;; Accepts whether the output is signed, the size of the input @@ -2705,9 +2708,6 @@ (rule (and_vec x y size) (vec_rrr (VecALUOp.And) x y size)) ;; Helpers for generating `eor` instructions. -(decl eor (Type Reg Reg) Reg) -(rule (eor ty x y) (alu_rrr (ALUOp.Eor) ty x y)) - (decl eor_vec (Reg Reg VectorSize) Reg) (rule (eor_vec x y size) (vec_rrr (VecALUOp.Eor) x y size)) @@ -3312,6 +3312,17 @@ (rule (splat_const n size) (vec_dup (imm $I64 (ImmExtend.Zero) n) size)) +;; Each of these extractors tests whether the upper half of the input equals the +;; lower half of the input +(decl u128_replicated_u64 (u64) u128) +(extern extractor u128_replicated_u64 u128_replicated_u64) +(decl u64_replicated_u32 (u64) u64) +(extern extractor u64_replicated_u32 u64_replicated_u32) +(decl u32_replicated_u16 (u64) u64) +(extern extractor u32_replicated_u16 u32_replicated_u16) +(decl u16_replicated_u8 (u64) u64) +(extern extractor u16_replicated_u8 u16_replicated_u8) + ;; Lower a FloatCC to a Cond. (decl fp_cond_code (FloatCC) Cond) ;; TODO: Port lower_fp_condcode() to ISLE. @@ -3765,8 +3776,7 @@ (decl elf_tls_get_addr (ExternalName) Reg) (rule (elf_tls_get_addr name) (let ((dst WritableReg (temp_writable_reg $I64)) - (tmp WritableReg (temp_writable_reg $I64)) - (_ Unit (emit (MInst.ElfTlsGetAddr (box_external_name name) dst tmp)))) + (_ Unit (emit (MInst.ElfTlsGetAddr name dst)))) dst)) (decl macho_tls_get_addr (ExternalName) Reg) @@ -4066,12 +4076,12 @@ ;; PC-rel offset to the jumptable would be incorrect. ;; (The alternative is to introduce a relocation pass ;; for inlined jumptables, which is much worse, IMHO.) -(decl jt_sequence (Reg MachLabel BoxVecMachLabel) ConsumesFlags) -(rule (jt_sequence ridx default targets) +(decl jt_sequence (Reg BoxJTSequenceInfo) ConsumesFlags) +(rule (jt_sequence ridx info) (let ((rtmp1 WritableReg (temp_writable_reg $I64)) (rtmp2 WritableReg (temp_writable_reg $I64))) (ConsumesFlags.ConsumesFlagsSideEffect - (MInst.JTSequence default targets ridx rtmp1 rtmp2)))) + (MInst.JTSequence info ridx rtmp1 rtmp2)))) ;; Helper for emitting `MInst.CondBr` instructions. (decl cond_br (BranchTarget BranchTarget CondBrKind) ConsumesFlags) @@ -4092,16 +4102,18 @@ (MInst.EmitIsland needed_space))) ;; Helper for emitting `br_table` sequences. -(decl br_table_impl (u64 Reg MachLabel BoxVecMachLabel) Unit) -(rule (br_table_impl (imm12_from_u64 jt_size) ridx default targets) - (emit_side_effect (with_flags_side_effect - (cmp_imm (OperandSize.Size32) ridx jt_size) - (jt_sequence ridx default targets)))) -(rule -1 (br_table_impl jt_size ridx default targets) - (let ((jt_size Reg (imm $I64 (ImmExtend.Zero) jt_size))) +(decl br_table_impl (u64 Reg VecMachLabel) Unit) +(rule (br_table_impl (imm12_from_u64 jt_size) ridx targets) + (let ((jt_info BoxJTSequenceInfo (targets_jt_info targets))) + (emit_side_effect (with_flags_side_effect + (cmp_imm (OperandSize.Size32) ridx jt_size) + (jt_sequence ridx jt_info))))) +(rule -1 (br_table_impl jt_size ridx targets) + (let ((jt_size Reg (imm $I64 (ImmExtend.Zero) jt_size)) + (jt_info BoxJTSequenceInfo (targets_jt_info targets))) (emit_side_effect (with_flags_side_effect (cmp (OperandSize.Size32) ridx jt_size) - (jt_sequence ridx default targets))))) + (jt_sequence ridx jt_info))))) ;; Helper for emitting the `uzp1` instruction (decl vec_uzp1 (Reg Reg VectorSize) Reg) diff --git a/cranelift/codegen/src/isa/aarch64/inst/args.rs b/cranelift/codegen/src/isa/aarch64/inst/args.rs index c6394e6596f3..cf1d6d05a671 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/args.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/args.rs @@ -11,7 +11,7 @@ use std::string::String; // Instruction sub-components: shift and extend descriptors /// A shift operator for a register or immediate. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug)] #[repr(u8)] pub enum ShiftOp { /// Logical shift left. @@ -580,14 +580,6 @@ impl OperandSize { OperandSize::Size64 => 1, } } - - /// The maximum unsigned value representable in a value of this size. - pub fn max_value(&self) -> u64 { - match self { - OperandSize::Size32 => u32::MAX as u64, - OperandSize::Size64 => u64::MAX, - } - } } /// Type used to communicate the size of a scalar SIMD & FP operand. @@ -647,17 +639,6 @@ impl ScalarSize { ScalarSize::Size128 => ScalarSize::Size64, } } - - /// Return a type with the same size as this scalar. - pub fn ty(&self) -> Type { - match self { - ScalarSize::Size8 => I8, - ScalarSize::Size16 => I16, - ScalarSize::Size32 => I32, - ScalarSize::Size64 => I64, - ScalarSize::Size128 => I128, - } - } } /// Type used to communicate the size of a vector operand. diff --git a/cranelift/codegen/src/isa/aarch64/inst/emit.rs b/cranelift/codegen/src/isa/aarch64/inst/emit.rs index 39a49dfdd275..43bdd4a3e981 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/emit.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/emit.rs @@ -4,7 +4,7 @@ use cranelift_control::ControlPlane; use regalloc2::Allocation; use crate::binemit::{Reloc, StackMap}; -use crate::ir::{self, types::*, MemFlags, RelSourceLoc, TrapCode}; +use crate::ir::{self, types::*, LibCall, MemFlags, RelSourceLoc, TrapCode}; use crate::isa::aarch64::inst::*; use crate::machinst::{ty_bits, Reg, RegClass, Writable}; use crate::trace; @@ -3275,8 +3275,7 @@ impl MachInstEmit for Inst { ridx, rtmp1, rtmp2, - default, - ref targets, + ref info, .. } => { let ridx = allocs.next(ridx); @@ -3288,7 +3287,7 @@ impl MachInstEmit for Inst { // Branch to default when condition code from prior comparison indicates. let br = enc_conditional_br( - BranchTarget::Label(default), + info.default_target, CondBrKind::Cond(Cond::Hs), &mut AllocationConsumer::default(), ); @@ -3297,7 +3296,9 @@ impl MachInstEmit for Inst { // will not be merged with any other branch, flipped, or elided (it is not preceded // or succeeded by any other branch). Just emit it with the label use. let default_br_offset = sink.cur_offset(); - sink.use_label_at_offset(default_br_offset, default, LabelUse::Branch19); + if let BranchTarget::Label(l) = info.default_target { + sink.use_label_at_offset(default_br_offset, l, LabelUse::Branch19); + } sink.put4(br); // Overwrite the index with a zero when the above @@ -3346,14 +3347,18 @@ impl MachInstEmit for Inst { inst.emit(&[], sink, emit_info, state); // Emit jump table (table of 32-bit offsets). let jt_off = sink.cur_offset(); - for &target in targets.iter() { + for &target in info.targets.iter() { let word_off = sink.cur_offset(); // off_into_table is an addend here embedded in the label to be later patched // at the end of codegen. The offset is initially relative to this jump table // entry; with the extra addend, it'll be relative to the jump table's start, // after patching. let off_into_table = word_off - jt_off; - sink.use_label_at_offset(word_off, target, LabelUse::PCRel32); + sink.use_label_at_offset( + word_off, + target.as_label().unwrap(), + LabelUse::PCRel32, + ); sink.put4(off_into_table); } @@ -3537,81 +3542,32 @@ impl MachInstEmit for Inst { } } - &Inst::ElfTlsGetAddr { - ref symbol, - rd, - tmp, - } => { + &Inst::ElfTlsGetAddr { ref symbol, rd } => { let rd = allocs.next_writable(rd); - let tmp = allocs.next_writable(tmp); assert_eq!(xreg(0), rd.to_reg()); - // See the original proposal for TLSDESC. - // http://www.fsfla.org/~lxoliva/writeups/TLS/paper-lk2006.pdf - // - // Implement the TLSDESC instruction sequence: - // adrp x0, :tlsdesc:tlsvar - // ldr tmp, [x0, :tlsdesc_lo12:tlsvar] - // add x0, x0, :tlsdesc_lo12:tlsvar - // blr tmp - // mrs tmp, tpidr_el0 - // add x0, x0, tmp - // // This is the instruction sequence that GCC emits for ELF GD TLS Relocations in aarch64 - // See: https://gcc.godbolt.org/z/e4j7MdErh - - // adrp x0, :tlsdesc:tlsvar - sink.add_reloc(Reloc::Aarch64TlsDescAdrPage21, &**symbol, 0); - Inst::Adrp { rd, off: 0 }.emit(&[], sink, emit_info, state); - - // ldr tmp, [x0, :tlsdesc_lo12:tlsvar] - sink.add_reloc(Reloc::Aarch64TlsDescLd64Lo12, &**symbol, 0); - Inst::ULoad64 { - rd: tmp, - mem: AMode::reg(rd.to_reg()), - flags: MemFlags::trusted(), - } - .emit(&[], sink, emit_info, state); + // See: https://gcc.godbolt.org/z/KhMh5Gvra - // add x0, x0, :tlsdesc_lo12:tlsvar - sink.add_reloc(Reloc::Aarch64TlsDescAddLo12, &**symbol, 0); - Inst::AluRRImm12 { - alu_op: ALUOp::Add, - size: OperandSize::Size64, - rd, - rn: rd.to_reg(), - imm12: Imm12::maybe_from_u64(0).unwrap(), - } - .emit(&[], sink, emit_info, state); + // adrp x0,