aarch64: call_indirect (§4.4.8 traps) + globals + param homing (#851)… #1134
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Fuzz smoke — short cargo-fuzz run (~60s / target) on every PR + push to main. | |
| # | |
| # Catches new panics / unencodable instructions / silent op drops in the | |
| # WASM → IR → ARM lowering pipeline. Long-budget runs (1h / target with | |
| # corpus persistence) are out of scope for #82; this is the smoke gate. | |
| # | |
| # Target list mirrors fuzz/Cargo.toml `[[bin]]` entries. Add a new | |
| # fuzz_target there → add the binary name to `matrix.target` here. | |
| # | |
| # Refs: issue #82, issue #93 (silent-drop class). | |
| name: Fuzz Smoke | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'crates/**' | |
| - 'fuzz/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - '.github/workflows/fuzz-smoke.yml' | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'crates/**' | |
| - 'fuzz/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - '.github/workflows/fuzz-smoke.yml' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| fuzz: | |
| name: "${{ matrix.target }} (60s)" | |
| # Match ci.yml: rust-cpu self-hosted pool, with ubuntu-latest fallback if | |
| # the pool is unavailable (cargo-fuzz needs Linux for libfuzzer-sys ASan). | |
| runs-on: [self-hosted, linux, x64, rust-cpu] | |
| timeout-minutes: 10 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Each entry: `target` + `gating`. Gating harnesses pass clean today | |
| # and block PR merge on regression. Exploration harnesses keep finding | |
| # new bugs at a rate faster than we close them in one cycle; they | |
| # report (crash artifacts uploaded) but don't block — `continue-on- | |
| # error` is taken from the `gating` flag. Promote an exploration | |
| # harness to gating once its bug-list stabilises. | |
| include: | |
| # `wasm_ops_lower_or_error` is gating again. It was demoted in | |
| # PR #117 because wasm_to_ir's inst_id-as-vreg-slot model crashed | |
| # on Drop / LocalSet / Store / Block shapes; the slot_stack | |
| # refactor (issue #121) closed those. The last panic site in the | |
| # optimized path was `ir_to_arm`'s defensive `get_arm_reg`, which | |
| # now returns `Result` instead of `panic!`-ing — the whole | |
| # `optimize_full` + `ir_to_arm` path is panic-free, so this | |
| # harness (contract: "lower or Err, never panic") gates again. | |
| - target: wasm_ops_lower_or_error | |
| gating: true | |
| - target: wasm_to_ir_roundtrip_op_coverage | |
| gating: true | |
| - target: i64_lowering_doesnt_clobber_params | |
| gating: false # finds real bugs faster than we fix them; tracked as follow-up issues | |
| - target: encoder_no_panic | |
| gating: false # encoder-level corner cases; not silicon-blocking | |
| # When gating == false, treat job failure as a non-blocking warning. The | |
| # matrix value is plain JSON (bool), not untrusted user input, so this is | |
| # safe to interpolate. | |
| continue-on-error: ${{ matrix.gating == false }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install nightly Rust | |
| uses: dtolnay/rust-toolchain@nightly | |
| - uses: actions/cache@v6 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| fuzz/target | |
| key: fuzz-${{ runner.os }}-${{ hashFiles('Cargo.lock', 'fuzz/Cargo.toml') }} | |
| restore-keys: fuzz-${{ runner.os }}- | |
| - name: Install cargo-fuzz | |
| uses: taiki-e/install-action@v2.85.5 | |
| with: | |
| tool: cargo-fuzz | |
| - name: Run fuzz target for 60s | |
| env: | |
| TARGET: ${{ matrix.target }} | |
| # Force the GNU target — cargo-fuzz defaults to musl on Linux, | |
| # whose statically-linked libc is incompatible with ASan | |
| # (libfuzzer-sys turns ASan on by default). The GNU target has | |
| # a dynamic libc and works correctly. | |
| # | |
| # We seed the corpus from `fuzz/seed_corpus/<target>/` (checked into | |
| # git) so known-crash inputs are always replayed — see PR #117 which | |
| # introduced `seed_corpus/wasm_ops_lower_or_error/seed-pr117-i32divs- | |
| # empty-stack`. Without seeding, a regression that re-introduces the | |
| # panic might be missed if libfuzzer doesn't rediscover the exact | |
| # input within 60s. | |
| run: | | |
| mkdir -p fuzz/artifacts fuzz/corpus "fuzz/corpus/${TARGET}" | |
| if [ -d "fuzz/seed_corpus/${TARGET}" ]; then | |
| cp -n fuzz/seed_corpus/"${TARGET}"/* "fuzz/corpus/${TARGET}/" || true | |
| fi | |
| cargo +nightly fuzz run "${TARGET}" \ | |
| --target x86_64-unknown-linux-gnu \ | |
| -- -max_total_time=60 -print_final_stats=1 | |
| - name: Upload crash artifacts | |
| if: failure() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: fuzz-crash-${{ matrix.target }} | |
| path: | | |
| fuzz/artifacts/${{ matrix.target }}/ | |
| fuzz/corpus/${{ matrix.target }}/ | |
| retention-days: 30 | |
| if-no-files-found: ignore |