diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24bc7be2..a6432ee9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,128 +3,128 @@ name: CI on: push: branches: - - main + - main paths-ignore: - - '*.md' + - "*.md" pull_request: paths-ignore: - - '*.md' + - "*.md" env: - CARGO_MAKE_TOOLCHAIN: nightly-2024-03-10 + CARGO_MAKE_TOOLCHAIN: nightly-2024-05-07 jobs: compiler: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }} - override: true - - name: Cache Cargo - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.CARGO_MAKE_TOOLCHAIN }} - - name: Install cargo-make - uses: actions-rs/cargo@v1 - with: - command: install - args: cargo-make - - name: Build - uses: actions-rs/cargo@v1 - with: - command: make - args: build - - name: Test - uses: actions-rs/cargo@v1 - with: - command: make - args: test + - uses: actions/checkout@v2 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }} + override: true + - name: Cache Cargo + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.CARGO_MAKE_TOOLCHAIN }} + - name: Install cargo-make + uses: actions-rs/cargo@v1 + with: + command: install + args: cargo-make + - name: Build + uses: actions-rs/cargo@v1 + with: + command: make + args: build + - name: Test + uses: actions-rs/cargo@v1 + with: + command: make + args: test cargo_miden_test_clean_env: # Run cargo-miden test in the clean env to simulate user's first run. # To test the installation of the required dependencies (e.g. rust-src, wasm target, etc.) - name: cargo-miden tests + name: cargo-miden tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }} - override: true - - name: Cache Cargo - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.CARGO_MAKE_TOOLCHAIN }} - - name: Test - uses: actions-rs/cargo@v1 - with: - command: test - args: -p cargo-miden --test integration + - uses: actions/checkout@v2 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }} + override: true + - name: Cache Cargo + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.CARGO_MAKE_TOOLCHAIN }} + - name: Test + uses: actions-rs/cargo@v1 + with: + command: test + args: -p cargo-miden --test integration clippy: name: clippy runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }} - override: true - - name: Cache Cargo - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.CARGO_MAKE_TOOLCHAIN }} - - name: Install cargo-make - uses: actions-rs/cargo@v1 - with: - command: install - args: cargo-make - - name: Test - uses: actions-rs/cargo@v1 - with: - command: make - args: clippy + - uses: actions/checkout@v2 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }} + override: true + - name: Cache Cargo + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.CARGO_MAKE_TOOLCHAIN }} + - name: Install cargo-make + uses: actions-rs/cargo@v1 + with: + command: install + args: cargo-make + - name: Test + uses: actions-rs/cargo@v1 + with: + command: make + args: clippy rustfmt: name: rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }} - override: true - - name: Cache Cargo - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.CARGO_MAKE_TOOLCHAIN }} - - name: Install cargo-make - uses: actions-rs/cargo@v1 - with: - command: install - args: cargo-make - - name: rustfmt - uses: actions-rs/cargo@v1 - with: - command: make - args: check-format + - uses: actions/checkout@v2 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }} + override: true + - name: Cache Cargo + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.CARGO_MAKE_TOOLCHAIN }} + - name: Install cargo-make + uses: actions-rs/cargo@v1 + with: + command: install + args: cargo-make + - name: rustfmt + uses: actions-rs/cargo@v1 + with: + command: make + args: check-format diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e49ad591..98c26129 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ on: - main env: - CARGO_MAKE_TOOLCHAIN: nightly-2024-03-10 + CARGO_MAKE_TOOLCHAIN: nightly-2024-05-07 jobs: release-plz: diff --git a/Cargo.lock b/Cargo.lock index a67f13bb..983a9e4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,11 +14,27 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ - "gimli", + "gimli 0.29.0", +] + +[[package]] +name = "addr2line" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +dependencies = [ + "cpp_demangle", + "fallible-iterator", + "gimli 0.31.0", + "memmap2", + "object", + "rustc-demangle", + "smallvec", + "typed-arena", ] [[package]] @@ -29,14 +45,13 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aes" -version = "0.7.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", "cpufeatures", - "opaque-debug", ] [[package]] @@ -66,22 +81,28 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "aligned" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80a21b9440a626c7fc8573a9e3d3a06b75c7c97754c2949bc7857b90353ca655" +checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" dependencies = [ "as-slice", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -99,47 +120,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -147,9 +169,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "anymap2" @@ -159,9 +181,9 @@ checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -199,12 +221,11 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.1.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 4.0.3", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -212,15 +233,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.8.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ - "async-lock 3.3.0", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.2.0", + "fastrand 2.1.0", + "futures-lite 2.3.0", "slab", ] @@ -258,18 +278,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb41eb19024a91746eba0773aa5e16036045bbf45733766661099e182ea6a744" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "parking", - "polling 3.3.2", - "rustix 0.38.32", + "polling 3.7.2", + "rustix 0.38.34", "slab", "tracing", "windows-sys 0.52.0", @@ -286,11 +306,11 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.3.1", "event-listener-strategy", "pin-project-lite", ] @@ -308,54 +328,54 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] [[package]] name = "async-recursion" -version = "1.0.5" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "async-signal" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" dependencies = [ - "async-io 2.3.0", - "async-lock 2.8.0", + "async-io 2.3.3", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.32", + "rustix 0.38.34", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "async-task" -version = "4.7.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -377,9 +397,9 @@ dependencies = [ [[package]] name = "auth-git2" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e7771d4ab6635cbd685ce8db215b29c78a468098126de77c57f3b2e6eb3757" +checksum = "e51bd0e4592409df8631ca807716dc1e5caafae5d01ce0157c966c71c7e49c3c" dependencies = [ "dirs", "git2", @@ -388,17 +408,17 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ - "addr2line", + "addr2line 0.22.0", "cc", "cfg-if", "libc", @@ -434,6 +454,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -446,6 +472,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -469,15 +504,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "blake3" -version = "1.5.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" dependencies = [ "arrayref", "arrayvec", @@ -496,53 +531,43 @@ dependencies = [ ] [[package]] -name = "block-modes" -version = "0.8.1" +name = "block-padding" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" dependencies = [ - "block-padding", - "cipher", + "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ "async-channel", - "async-lock 3.3.0", "async-task", - "fastrand 2.0.1", "futures-io", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] name = "bstr" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata", + "regex-automata 0.4.7", "serde", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" @@ -552,15 +577,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] @@ -579,7 +604,7 @@ dependencies = [ "clap", "futures", "heck 0.4.1", - "indexmap 2.1.0", + "indexmap 2.2.6", "libc", "log", "p256", @@ -587,12 +612,12 @@ dependencies = [ "pretty_env_logger", "rand_core", "rpassword", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "tokio", "tokio-util", - "toml_edit 0.21.0", + "toml_edit 0.21.1", "url", "warg-client", "warg-crypto", @@ -614,15 +639,15 @@ dependencies = [ "anyhow", "clap", "futures", - "indexmap 2.1.0", + "indexmap 2.2.6", "keyring", "libc", "log", "owo-colors", - "semver 1.0.21", + "semver 1.0.23", "serde", "tokio", - "toml_edit 0.21.0", + "toml_edit 0.21.1", "unicode-width", "url", "warg-client", @@ -635,14 +660,14 @@ dependencies = [ [[package]] name = "cargo-config2" -version = "0.1.18" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a283792e857b3ca787f26db6b8164d6ee61eca69b4fa5daa5fa51b24d59917" +checksum = "d83ce0be8bd1479e5de6202def660e6c7e27e4e0599bffa4fed05bd380ec2ede" dependencies = [ "home", "serde", "serde_derive", - "toml_edit 0.21.0", + "toml_edit 0.22.18", ] [[package]] @@ -656,14 +681,14 @@ dependencies = [ "clap", "console", "dialoguer", - "env_logger 0.11.2", + "env_logger 0.11.5", "fs-err", "git2", "gix-config", "heck 0.5.0", "home", "ignore", - "indexmap 2.1.0", + "indexmap 2.2.6", "indicatif", "liquid", "liquid-core", @@ -677,7 +702,7 @@ dependencies = [ "remove_dir_all", "rhai", "sanitize-filename", - "semver 1.0.21", + "semver 1.0.23", "serde", "tempfile", "thiserror", @@ -695,30 +720,29 @@ dependencies = [ "cargo-generate", "cargo_metadata", "clap", - "env_logger 0.11.2", + "env_logger 0.11.5", "log", - "miden-diagnostics", "midenc-compile", "midenc-session", "parse_arg", "path-absolutize", - "semver 1.0.21", + "semver 1.0.23", ] [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] [[package]] name = "cargo-util" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2d9a9a8d3e0b61b1110c49ab8f6ed7a76ce4f2b1d53ae48a83152d3d5e8f5b" +checksum = "14104698cb1694d43c2ff73492468ccf2bb0b047071a9838d999eeba9e984ffa" dependencies = [ "anyhow", "core-foundation", @@ -745,17 +769,41 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "thiserror", ] +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "castaway" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" +dependencies = [ + "rustversion", +] + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" -version = "1.0.83" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", @@ -767,33 +815,40 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" -version = "0.4.32" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41daef31d7a747c5c847246f36de49ced6f7403b4cdabc807a97b5cc184cda7a" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] name = "cipher" -version = "0.3.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "generic-array", + "crypto-common", + "inout", ] [[package]] name = "clap" -version = "4.5.4" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" dependencies = [ "clap_builder", "clap_derive", @@ -801,33 +856,33 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", + "strsim", ] [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "codespan" @@ -850,9 +905,23 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "compact_str" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] [[package]] name = "concat-idents" @@ -861,14 +930,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d" dependencies = [ "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -894,9 +963,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-random" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaf16c9c2c612020bcfd042e170f6e32de9b9d75adb5277cdbbd2e2c8c8299a" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" dependencies = [ "const-random-macro", ] @@ -940,6 +1009,15 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cpp_demangle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +dependencies = [ + "cfg-if", +] + [[package]] name = "cpufeatures" version = "0.2.12" @@ -964,6 +1042,15 @@ version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7eabb8d36b0ca8906bec93c78ea516741cac2d7e6b266fa7b0ffddcc09004990" +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -985,9 +1072,35 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crossterm" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.6.0", + "crossterm_winapi", + "futures-core", + "mio", + "parking_lot", + "rustix 0.38.34", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] [[package]] name = "crunchy" @@ -1028,9 +1141,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -1038,34 +1151,34 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 2.0.48", + "strsim", + "syn 2.0.72", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -1095,15 +1208,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -1181,9 +1294,9 @@ dependencies = [ [[package]] name = "dissimilar" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" +checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" [[package]] name = "doc-comment" @@ -1207,9 +1320,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -1233,9 +1346,9 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] @@ -1248,18 +1361,18 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "enumflags2" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", "serde", @@ -1267,20 +1380,20 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", "regex", @@ -1301,9 +1414,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", @@ -1320,9 +1433,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1347,9 +1460,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "4.0.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -1358,19 +1471,19 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.3.1", "pin-project-lite", ] [[package]] name = "expect-test" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d9eafeadd538e68fb28016364c9732d78e420b9ff8853fa5e4058861e9f8d3" +checksum = "9e0be0a561335815e06dab7c62e50353134c796e7a6155402a64bcff66b6a5e0" dependencies = [ "dissimilar", "once_cell", @@ -1399,9 +1512,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "ff" @@ -1421,7 +1534,7 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] @@ -1431,6 +1544,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "flurry" version = "0.4.0" @@ -1484,16 +1607,16 @@ dependencies = [ [[package]] name = "fs_at" -version = "0.1.10" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982f82cc75107eef84f417ad6c53ae89bf65b561937ca4a3b3b0fd04d0aa2425" +checksum = "14af6c9694ea25db25baa2a1788703b9e7c6648dcaeeebeb98f7561b5384c036" dependencies = [ "aligned", "cfg-if", "cvt", "libc", - "nix", - "windows-sys 0.48.0", + "nix 0.29.0", + "windows-sys 0.52.0", ] [[package]] @@ -1561,11 +1684,11 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.1", + "fastrand 2.1.0", "futures-core", "futures-io", "parking", @@ -1580,7 +1703,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1613,6 +1736,19 @@ dependencies = [ "slab", ] +[[package]] +name = "generator" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "979f00864edc7516466d6b3157706e06c032f22715700ddd878228a91d02bc56" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1626,9 +1762,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1637,9 +1773,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "gimli" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" dependencies = [ "fallible-iterator", "stable_deref_trait", @@ -1647,11 +1789,11 @@ dependencies = [ [[package]] name = "git2" -version = "0.18.1" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf97ba92db08df386e10c8ede66a2a0369bd277090afd8710e19e38de9ec0cd" +checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "libc", "libgit2-sys", "log", @@ -1662,23 +1804,23 @@ dependencies = [ [[package]] name = "gix-actor" -version = "0.31.1" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3a3bde455ad2ee8ba8a195745241ce0b770a8a26faae59fcf409d01b28c46" +checksum = "a0e454357e34b833cc3a00b6efbbd3dd4d18b24b9fb0c023876ec2645e8aa3f2" dependencies = [ "bstr", "gix-date", "gix-utils", "itoa", "thiserror", - "winnow 0.6.5", + "winnow 0.6.16", ] [[package]] name = "gix-config" -version = "0.36.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62129c75e4b6229fe15fb9838cdc00c655e87105b651e4edd7c183fc5288b5d1" +checksum = "7580e05996e893347ad04e1eaceb92e1c0e6a3ffe517171af99bf6b6df0ca6e5" dependencies = [ "bstr", "gix-config-value", @@ -1692,16 +1834,16 @@ dependencies = [ "smallvec", "thiserror", "unicode-bom", - "winnow 0.6.5", + "winnow 0.6.16", ] [[package]] name = "gix-config-value" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd06203b1a9b33a78c88252a625031b094d9e1b647260070c25b09910c0a804" +checksum = "b328997d74dd15dc71b2773b162cb4af9a25c424105e4876e6d0686ab41c383e" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "bstr", "gix-path", "libc", @@ -1710,9 +1852,9 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180b130a4a41870edfbd36ce4169c7090bca70e195da783dea088dd973daa59c" +checksum = "9eed6931f21491ee0aeb922751bd7ec97b4b2fe8fbfedcb678e2a2dce5f3b8c0" dependencies = [ "bstr", "itoa", @@ -1722,9 +1864,9 @@ dependencies = [ [[package]] name = "gix-features" -version = "0.38.1" +version = "0.38.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4254037d20a247a0367aa79333750146a369719f0c6617fec4f5752cc62b37" +checksum = "ac7045ac9fe5f9c727f38799d002a7ed3583cd777e3322a7c4b43e3cf437dc69" dependencies = [ "gix-hash", "gix-trace", @@ -1737,9 +1879,9 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634b8a743b0aae03c1a74ee0ea24e8c5136895efac64ce52b3ea106e1c6f0613" +checksum = "e2184c40e7910529677831c8b481acf788ffd92427ed21fad65b6aa637e631b8" dependencies = [ "gix-features", "gix-utils", @@ -1747,11 +1889,11 @@ dependencies = [ [[package]] name = "gix-glob" -version = "0.16.2" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "682bdc43cb3c00dbedfcc366de2a849b582efd8d886215dbad2ea662ec156bb5" +checksum = "fa7df15afa265cc8abe92813cd354d522f1ac06b29ec6dfa163ad320575cb447" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "bstr", "gix-features", "gix-path", @@ -1780,9 +1922,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.42.1" +version = "0.42.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4f8efae72030df1c4a81d02dbe2348e748d9b9a11e108ed6efbd846326e051" +checksum = "25da2f46b4e7c2fa7b413ce4dffb87f69eaf89c2057e386491f4c55cadbfe386" dependencies = [ "bstr", "gix-actor", @@ -1794,14 +1936,14 @@ dependencies = [ "itoa", "smallvec", "thiserror", - "winnow 0.6.5", + "winnow 0.6.16", ] [[package]] name = "gix-path" -version = "0.10.7" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23623cf0f475691a6d943f898c4d0b89f5c1a2a64d0f92bce0e0322ee6528783" +checksum = "8d23d5bbda31344d8abc8de7c075b3cf26e5873feba7c4a15d916bce67382bd9" dependencies = [ "bstr", "gix-trace", @@ -1829,16 +1971,16 @@ dependencies = [ "gix-validate", "memmap2", "thiserror", - "winnow 0.6.5", + "winnow 0.6.16", ] [[package]] name = "gix-sec" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fddc27984a643b20dd03e97790555804f98cf07404e0e552c0ad8133266a79a1" +checksum = "1547d26fa5693a7f34f05b4a3b59a90890972922172653bcb891ab3f09f436df" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "gix-path", "libc", "windows-sys 0.52.0", @@ -1859,25 +2001,25 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b838b2db8f62c9447d483a4c28d251b67fee32741a82cb4d35e9eb4e9fdc5ab" +checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" [[package]] name = "gix-utils" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066432d4c277f9877f091279a597ea5331f68ca410efc874f0bdfb1cd348f92" +checksum = "35192df7fd0fa112263bad8021e2df7167df4cc2a6e6d15892e1e55621d3d4dc" dependencies = [ - "fastrand 2.0.1", + "fastrand 2.1.0", "unicode-normalization", ] [[package]] name = "gix-validate" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e39fc6e06044985eac19dd34d474909e517307582e462b2eb4c8fa51b6241545" +checksum = "82c27dd34a49b1addf193c92070bcbf3beaf6e10f16a78544de6372e146a0acf" dependencies = [ "bstr", "thiserror", @@ -1898,8 +2040,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -1915,9 +2057,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -1925,7 +2067,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1940,9 +2082,14 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash 0.8.11", + "allocator-api2", + "serde", +] [[package]] name = "heck" @@ -1970,9 +2117,15 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -2009,9 +2162,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -2031,9 +2184,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -2043,9 +2196,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "human-panic" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c5d0e9120f6bca6120d142c7ede1ba376dd6bf276d69dd3dbe6cbeb7824179" +checksum = "1c5a08ed290eac04006e21e63d32e90086b6182c7cd0452d10f4264def1fec9a" dependencies = [ "anstream", "anstyle", @@ -2065,9 +2218,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -2080,7 +2233,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.5.7", "tokio", "tower-service", "tracing", @@ -2102,16 +2255,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -2155,7 +2308,7 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata", + "regex-automata 0.4.7", "same-file", "walkdir", "winapi-util", @@ -2180,20 +2333,20 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "serde", ] [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", @@ -2202,11 +2355,31 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "instability" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" +dependencies = [ + "quote", + "syn 2.0.72", +] + [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2217,14 +2390,14 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b694dc9f70c3bda874626d2aed13b780f137aab435f4e9814121955cf706122e" dependencies = [ - "memoffset 0.9.0", + "memoffset 0.9.1", ] [[package]] name = "inventory" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8573b2b1fb643a372c73b23f4da5f888677feef3305146d68a539250a9bccc7" +checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" [[package]] name = "io-lifetimes" @@ -2232,7 +2405,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.4", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -2245,12 +2418,12 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.4", - "rustix 0.38.32", + "hermit-abi 0.3.9", + "libc", "windows-sys 0.52.0", ] @@ -2260,6 +2433,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.10.5" @@ -2278,26 +2457,35 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -2313,9 +2501,9 @@ dependencies = [ [[package]] name = "keyring" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b479dcf9eae65481044dfda57af7fe2da6c1401180360f6898801fe9ed4db9" +checksum = "363387f0019d714aa60cc30ab4fe501a747f4c08fc58f069dd14be971bd495a0" dependencies = [ "byteorder", "lazy_static", @@ -2327,9 +2515,9 @@ dependencies = [ [[package]] name = "kstring" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" dependencies = [ "serde", "static_assertions", @@ -2337,37 +2525,39 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", "bit-set", - "diff", "ena", - "is-terminal", - "itertools 0.10.5", + "itertools 0.11.0", "lalrpop-util", "petgraph", "regex", - "regex-syntax 0.7.5", + "regex-syntax 0.8.4", "string_cache", "term", "tiny-keccak", "unicode-xid", + "walkdir", ] [[package]] name = "lalrpop-util" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata 0.4.7", +] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -2377,15 +2567,15 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libgit2-sys" -version = "0.16.1+1.7.1" +version = "0.16.2+1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c" +checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" dependencies = [ "cc", "libc", @@ -2403,13 +2593,12 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "libc", - "redox_syscall", ] [[package]] @@ -2428,9 +2617,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.14" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "libc", @@ -2438,13 +2627,19 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-keyutils" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "libc", ] @@ -2456,15 +2651,15 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "liquid" -version = "0.26.4" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f68ae1011499ae2ef879f631891f21c78e309755f4a5e483c4a8f12e10b609" +checksum = "4e9338405fdbc0bce9b01695b2a2ef6b20eca5363f385d47bce48ddf8323cc25" dependencies = [ "doc-comment", "liquid-core", @@ -2475,12 +2670,12 @@ dependencies = [ [[package]] name = "liquid-core" -version = "0.26.4" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e0724dfcaad5cfb7965ea0f178ca0870b8d7315178f4a7179f5696f7f04d5f" +checksum = "feb8fed70857010ed9016ed2ce5a7f34e7cc51d5d7255c9c9dc2e3243e490b42" dependencies = [ "anymap2", - "itertools 0.10.5", + "itertools 0.13.0", "kstring", "liquid-derive", "num-traits", @@ -2493,22 +2688,22 @@ dependencies = [ [[package]] name = "liquid-derive" -version = "0.26.4" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2fb41a9bb4257a3803154bdf7e2df7d45197d1941c9b1a90ad815231630721" +checksum = "77a5aa659a76b649f0d639ef0b9c067a9499c42a9d7f3e7832e279f791704966" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "liquid-lib" -version = "0.26.4" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a17e273a6fb1fb6268f7a5867ddfd0bd4683c7e19b51084f3d567fad4348c0" +checksum = "ee1794b5605e9f8864a8a4f41aa97976b42512cc81093f8c885d29fb94c6c556" dependencies = [ - "itertools 0.10.5", + "itertools 0.13.0", "liquid-core", "once_cell", "percent-encoding", @@ -2519,9 +2714,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2529,9 +2724,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logos" @@ -2553,7 +2748,7 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax 0.6.29", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -2565,11 +2760,42 @@ dependencies = [ "logos-codegen", ] +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -2591,58 +2817,76 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] [[package]] name = "miden-air" -version = "0.10.0" -source = "git+https://github.com/0xPolygonMiden/miden-vm?rev=a993b72e3fd5d209e017461b62ef2054d9120f01#a993b72e3fd5d209e017461b62ef2054d9120f01" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e396af383ee2a38ca41f188173672cd70e221985eec4afcb854fe37d18fd1b" dependencies = [ "miden-core", + "miden-thiserror", "winter-air", "winter-prover", ] [[package]] name = "miden-assembly" -version = "0.10.0" -source = "git+https://github.com/0xPolygonMiden/miden-vm?rev=a993b72e3fd5d209e017461b62ef2054d9120f01#a993b72e3fd5d209e017461b62ef2054d9120f01" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3aefae8d99d66c3f8666e917cb3ef976edb39247099311f695e5ba57305616d" dependencies = [ "aho-corasick", "lalrpop", "lalrpop-util", "miden-core", - "miette 7.1.0", - "rustc_version 0.2.3", + "miden-miette", + "miden-thiserror", + "rustc_version 0.4.0", "smallvec", - "thiserror", "tracing", "unicode-width", ] +[[package]] +name = "miden-base-sys" +version = "0.0.0" +dependencies = [ + "miden-assembly", + "miden-stdlib-sys", +] + [[package]] name = "miden-core" -version = "0.10.0" -source = "git+https://github.com/0xPolygonMiden/miden-vm?rev=a993b72e3fd5d209e017461b62ef2054d9120f01#a993b72e3fd5d209e017461b62ef2054d9120f01" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e46df4105dc2ec15aa14182ce6de299720991bfb83a9b6aa9293c6ee2b12b18" dependencies = [ + "lock_api", + "loom", + "memchr", "miden-crypto", "miden-formatting", + "miden-miette", + "miden-thiserror", "num-derive", "num-traits", - "thiserror", + "parking_lot", "winter-math", "winter-utils", ] [[package]] name = "miden-crypto" -version = "0.9.3" -source = "git+https://github.com/0xPolygonMiden/crypto?branch=next#b06cfa3c035ada8122a405a72d2e4b2ad1a89b47" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6fad06fc3af260ed3c4235821daa2132813d993f96d446856036ae97e9606dd" dependencies = [ "blake3", "cc", @@ -2703,25 +2947,25 @@ dependencies = [ "cargo_metadata", "concat-idents", "derive_more", - "env_logger 0.11.2", + "env_logger 0.11.5", "expect-test", "filetime", "glob", "log", "miden-assembly", "miden-core", - "miden-diagnostics", "miden-integration-tests-rust-fib", "miden-processor", "miden-stdlib", "midenc-codegen-masm", "midenc-compile", + "midenc-debug", + "midenc-driver", "midenc-frontend-wasm", "midenc-hir", "midenc-hir-transform", "midenc-session", "proptest", - "rustc-demangle", "sha2", "walkdir", "wasmprinter", @@ -2731,6 +2975,48 @@ dependencies = [ name = "miden-integration-tests-rust-fib" version = "0.0.0" +[[package]] +name = "miden-miette" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c532250422d933f15b148fb81e4522a5d649c178ab420d0d596c86228da35570" +dependencies = [ + "backtrace", + "backtrace-ext", + "cfg-if", + "futures", + "indenter", + "lazy_static", + "miden-miette-derive", + "miden-thiserror", + "owo-colors", + "regex", + "rustc_version 0.2.3", + "rustversion", + "serde_json", + "spin", + "strip-ansi-escapes", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "syn 2.0.72", + "terminal_size", + "textwrap", + "trybuild", + "unicode-width", +] + +[[package]] +name = "miden-miette-derive" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cc759f0a2947acae217a2f32f722105cacc57d17d5f93bc16362142943a4edd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "miden-parsing" version = "0.1.0" @@ -2743,8 +3029,9 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.10.0" -source = "git+https://github.com/0xPolygonMiden/miden-vm?rev=a993b72e3fd5d209e017461b62ef2054d9120f01#a993b72e3fd5d209e017461b62ef2054d9120f01" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afc2ccde2a0d6dc1580a6515b130700484042bee810d84fd3cf3e4616cac632" dependencies = [ "miden-air", "miden-core", @@ -2754,18 +3041,42 @@ dependencies = [ [[package]] name = "miden-stdlib" -version = "0.10.0" -source = "git+https://github.com/0xPolygonMiden/miden-vm?rev=a993b72e3fd5d209e017461b62ef2054d9120f01#a993b72e3fd5d209e017461b62ef2054d9120f01" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9314d34d66a677f819aaf9912b2110b29a24a28db66e9bf1be687b6f29389d9e" dependencies = [ "miden-assembly", ] +[[package]] +name = "miden-stdlib-sys" +version = "0.0.1" + +[[package]] +name = "miden-thiserror" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183ff8de338956ecfde3a38573241eb7a6f3d44d73866c210e5629c07fa00253" +dependencies = [ + "miden-thiserror-impl", +] + +[[package]] +name = "miden-thiserror-impl" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee4176a0f2e7d29d2a8ee7e60b6deb14ce67a20e94c3e2c7275cdb8804e1862" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "midenc" version = "0.0.1" dependencies = [ - "anyhow", - "env_logger 0.11.2", + "env_logger 0.11.5", "human-panic", "midenc-driver", ] @@ -2776,14 +3087,15 @@ version = "0.0.1" dependencies = [ "anyhow", "cranelift-entity", - "env_logger 0.11.2", + "env_logger 0.11.5", "intrusive-collections", "inventory", "log", "miden-assembly", "miden-core", - "miden-diagnostics", + "miden-processor", "miden-stdlib", + "miden-thiserror", "midenc-hir", "midenc-hir-analysis", "midenc-hir-transform", @@ -2793,62 +3105,88 @@ dependencies = [ "proptest", "rustc-hash", "smallvec", - "thiserror", ] [[package]] name = "midenc-compile" version = "0.0.1" dependencies = [ - "anyhow", "clap", + "either", + "intrusive-collections", "inventory", "log", "miden-assembly", "miden-diagnostics", + "miden-thiserror", "midenc-codegen-masm", "midenc-frontend-wasm", "midenc-hir", "midenc-hir-analysis", "midenc-hir-transform", "midenc-session", - "rustc-hash", - "thiserror", "wat", ] +[[package]] +name = "midenc-debug" +version = "0.0.1" +dependencies = [ + "clap", + "crossterm", + "futures", + "glob", + "log", + "miden-assembly", + "miden-core", + "miden-processor", + "miden-stdlib", + "miden-thiserror", + "midenc-codegen-masm", + "midenc-hir", + "midenc-session", + "proptest", + "ratatui", + "signal-hook", + "syntect", + "tokio", + "tokio-util", + "tui-input", +] + [[package]] name = "midenc-driver" version = "0.0.1" dependencies = [ - "anyhow", "clap", - "miden-diagnostics", + "log", + "miden-thiserror", "midenc-compile", + "midenc-debug", "midenc-hir", "midenc-session", - "thiserror", ] [[package]] name = "midenc-frontend-wasm" version = "0.0.1" dependencies = [ + "addr2line 0.24.1", "anyhow", "derive_more", "expect-test", - "gimli", - "indexmap 2.1.0", + "gimli 0.31.0", + "indexmap 2.2.6", "log", "miden-core", - "miden-diagnostics", "miden-integration-tests", + "miden-thiserror", "midenc-hir", "midenc-hir-type", + "midenc-session", "rustc-hash", "smallvec", - "thiserror", - "wasmparser 0.118.1", + "wasmparser 0.214.0", "wat", ] @@ -2860,15 +3198,16 @@ dependencies = [ "cranelift-entity", "derive_more", "either", - "indexmap 2.1.0", + "indexmap 2.2.6", "intrusive-collections", "inventory", "lalrpop", "lalrpop-util", + "log", "miden-assembly", "miden-core", - "miden-diagnostics", "miden-parsing", + "miden-thiserror", "midenc-hir-macros", "midenc-hir-symbol", "midenc-hir-type", @@ -2878,9 +3217,9 @@ dependencies = [ "paste", "petgraph", "pretty_assertions", + "rustc-demangle", "rustc-hash", "smallvec", - "thiserror", "typed-arena", "unicode-width", ] @@ -2894,13 +3233,12 @@ dependencies = [ "cranelift-entity", "intrusive-collections", "inventory", - "miden-diagnostics", + "miden-thiserror", "midenc-hir", "midenc-session", "pretty_assertions", "rustc-hash", "smallvec", - "thiserror", ] [[package]] @@ -2910,7 +3248,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -2951,10 +3289,14 @@ dependencies = [ "atty", "clap", "inventory", + "miden-assembly", + "miden-base-sys", + "miden-core", "miden-diagnostics", + "miden-stdlib", + "miden-thiserror", + "midenc-hir-macros", "midenc-hir-symbol", - "rustc-hash", - "thiserror", ] [[package]] @@ -2963,42 +3305,12 @@ version = "5.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" dependencies = [ - "miette-derive 5.10.0", + "miette-derive", "once_cell", "thiserror", "unicode-width", ] -[[package]] -name = "miette" -version = "7.1.0" -source = "git+https://github.com/bitwalker/miette?branch=no-std#e918fbde6c9853fe5e0db8e8e05bf7fbc8d2cc15" -dependencies = [ - "backtrace", - "backtrace-ext", - "cfg-if", - "futures", - "indenter", - "lazy_static", - "miette-derive 7.1.0", - "owo-colors", - "regex", - "rustc_version 0.2.3", - "rustversion", - "serde_json", - "spin", - "strip-ansi-escapes", - "supports-color", - "supports-hyperlinks", - "supports-unicode", - "syn 2.0.48", - "terminal_size", - "textwrap", - "thiserror", - "trybuild", - "unicode-width", -] - [[package]] name = "miette-derive" version = "5.10.0" @@ -3007,17 +3319,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", -] - -[[package]] -name = "miette-derive" -version = "7.1.0" -source = "git+https://github.com/bitwalker/miette?branch=no-std#e918fbde6c9853fe5e0db8e8e05bf7fbc8d2cc15" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -3028,22 +3330,24 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.10" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi 0.3.9", "libc", + "log", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3072,11 +3376,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -3090,9 +3393,9 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" @@ -3106,20 +3409,42 @@ dependencies = [ "memoffset 0.7.1", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "normpath" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", +] + +[[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" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", @@ -3131,24 +3456,29 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.4.2" @@ -3157,24 +3487,23 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -3183,11 +3512,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -3195,9 +3523,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -3209,15 +3537,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.4", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "num_threads" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" dependencies = [ "libc", ] @@ -3230,11 +3558,13 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.2" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" dependencies = [ + "flate2", "memchr", + "ruzstd", ] [[package]] @@ -3244,18 +3574,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] -name = "opaque-debug" -version = "0.3.0" +name = "onig" +version = "6.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" +dependencies = [ + "bitflags 1.3.2", + "libc", + "once_cell", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7" +dependencies = [ + "cc", + "pkg-config", +] [[package]] name = "openssl" -version = "0.10.63" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -3272,7 +3618,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -3283,9 +3629,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.99" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -3311,15 +3657,21 @@ dependencies = [ [[package]] name = "os_info" -version = "3.7.0" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" dependencies = [ "log", "serde", - "winapi", + "windows-sys 0.52.0", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "owo-colors" version = "4.0.0" @@ -3346,9 +3698,9 @@ checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -3356,15 +3708,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -3375,9 +3727,9 @@ checksum = "14248cc8eced350e20122a291613de29e4fa129ba2731818c4cdbb44fccd3e55" [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "path-absolutize" @@ -3457,9 +3809,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -3468,9 +3820,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -3478,22 +3830,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -3502,12 +3854,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.2.6", ] [[package]] @@ -3521,9 +3873,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -3533,12 +3885,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand 2.1.0", "futures-io", ] @@ -3554,9 +3906,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "polling" @@ -3576,23 +3928,24 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.2" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.32", + "rustix 0.38.34", "tracing", "windows-sys 0.52.0", ] [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" [[package]] name = "powerfmt" @@ -3602,9 +3955,13 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "2288c0e17cc8d342c712bb43a257a80ebffce59cdb33d5000d8348f3ec02528b" +dependencies = [ + "zerocopy", + "zerocopy-derive", +] [[package]] name = "precomputed-hash" @@ -3663,9 +4020,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -3678,19 +4035,19 @@ checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.2", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", "rusty-fork", "tempfile", "unarray", @@ -3748,7 +4105,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b823de344848e011658ac981009100818b322421676740546f8b52ed5249428" dependencies = [ "logos", - "miette 5.10.0", + "miette", "once_cell", "prost", "prost-types", @@ -3770,7 +4127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06a5aacd1f6147ceac5e3896e0c766187dc6a9645f3b93ec821fabbaf821b887" dependencies = [ "bytes", - "miette 5.10.0", + "miette", "prost", "prost-reflect", "prost-types", @@ -3785,7 +4142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30fc6d0af2dec2c39da31eb02cc78cbc05b843b04f30ad78ccc6e8a342ec5518" dependencies = [ "logos", - "miette 5.10.0", + "miette", "prost-types", "thiserror", ] @@ -3798,9 +4155,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3844,6 +4201,27 @@ dependencies = [ "rand_core", ] +[[package]] +name = "ratatui" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ba6a365afbe5615999275bea2446b970b10a41102500e27ce7678d50d978303" +dependencies = [ + "bitflags 2.6.0", + "cassowary", + "compact_str", + "crossterm", + "instability", + "itertools 0.13.0", + "lru", + "paste", + "strum", + "strum_macros", + "unicode-segmentation", + "unicode-truncate", + "unicode-width", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -3853,11 +4231,20 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -3866,25 +4253,34 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] name = "regex-automata" -version = "0.4.4" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] [[package]] @@ -3895,37 +4291,29 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "remove_dir_all" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23895cfadc1917fed9c6ed76a8c2903615fa3704f7493ff82b364c6540acc02b" +checksum = "c914caef075f03e9d5c568e2e71b3d3cf17dc61a5481ff379bb744721be0a75a" dependencies = [ - "aligned", "cfg-if", "cvt", "fs_at", - "lazy_static", "libc", "normpath", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -3945,9 +4333,11 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -3978,7 +4368,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6273372244d04a8a4b0bec080ea1e710403e88c5d9d83f9808b2bfa64f0982a" dependencies = [ "ahash 0.8.11", - "bitflags 2.4.2", + "bitflags 2.6.0", "instant", "num-traits", "once_cell", @@ -3990,13 +4380,13 @@ dependencies = [ [[package]] name = "rhai_codegen" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9db7f8dc4c9d48183a17ce550574c42995252b82d267eaca3fcd1b979159856c" +checksum = "a5a11a05ee1ce44058fa3d5961d05194fdbe3ad6b40f904af764d81b86450e6b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4022,9 +4412,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -4047,7 +4437,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.21", + "semver 1.0.23", ] [[package]] @@ -4066,22 +4456,31 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" @@ -4095,11 +4494,21 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "ruzstd" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5022b253619b1ba797f243056276bed8ed1a73b0f5a7ce7225d524067644bf8f" +dependencies = [ + "byteorder", + "twox-hash", +] + [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -4129,6 +4538,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -4160,12 +4575,12 @@ dependencies = [ [[package]] name = "secret-service" -version = "3.0.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da1a5ad4d28c03536f82f77d9f36603f5e37d8869ac98f0a750d5b5686d8d95" +checksum = "b5204d39df37f06d1944935232fd2dfe05008def7ca599bf28c0800366c8a8f9" dependencies = [ "aes", - "block-modes", + "cbc", "futures-util", "generic-array", "hkdf", @@ -4179,11 +4594,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -4192,9 +4607,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -4221,9 +4636,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -4236,51 +4651,52 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_repr" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -4299,16 +4715,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.5.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58c3a1b3e418f61c25b2aeb43fc6c95eaa252b8cecdda67f401943e9e08d33f" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -4316,14 +4733,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.5.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2068b437a31fc68f25dd7edc296b078f04b45145c199d8eed9866e45f1ff274" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4339,9 +4756,9 @@ dependencies = [ [[package]] name = "sha1_smol" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" @@ -4364,6 +4781,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shell-escape" version = "0.1.5" @@ -4376,11 +4802,32 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -4412,9 +4859,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smartstring" @@ -4445,19 +4892,19 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "spdx" -version = "0.10.3" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bde1398b09b9f93fc2fc9b9da86e362693e999d3a54a8ac47a99a5a73f638b" +checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc" dependencies = [ "smallvec", ] @@ -4514,21 +4961,37 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "strsim" -version = "0.11.1" +name = "strum" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.72", +] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "supports-color" @@ -4564,15 +5027,42 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "syntect" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" +dependencies = [ + "bincode", + "bitflags 1.3.2", + "flate2", + "fnv", + "once_cell", + "onig", + "regex-syntax 0.8.4", + "serde", + "serde_derive", + "serde_json", + "thiserror", + "walkdir", + "yaml-rust", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -4601,8 +5091,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "rustix 0.38.32", + "fastrand 2.1.0", + "rustix 0.38.34", "windows-sys 0.52.0", ] @@ -4642,7 +5132,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -4665,31 +5155,44 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.59" -source = "git+https://github.com/bitwalker/thiserror?branch=no-std#444c920234c683b73e1da67ba371a7084ae11725" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" -source = "git+https://github.com/bitwalker/thiserror?branch=no-std#444c920234c683b73e1da67ba371a7084ae11725" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", ] [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", "libc", + "num-conv", "num_threads", "powerfmt", "serde", @@ -4705,10 +5208,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -4723,9 +5227,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4738,32 +5242,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2 0.5.7", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4778,36 +5281,35 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.8" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "7a44eede9b727419af8095cb2d72fab15487a541f54647ad4414b34096ee4631" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.22.18", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -4818,22 +5320,35 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", "toml_datetime", - "winnow 0.5.34", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.22.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "1490595c74d930da779e944f5ba2ecdf538af67df1a9848cbd156af43c1b7cf0" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.5.34", + "winnow 0.6.16", ] [[package]] @@ -4861,7 +5376,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4871,6 +5386,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -4881,13 +5426,12 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.90" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aa6f84ec205ebf87fb7a0abdbcd1467fa5af0e86878eb6d888b78ecbb10b6d5" +checksum = "b55265878356bdd85c9baa15859c87de93b2bf1f33acf752040a561e4a228f62" dependencies = [ "dissimilar", "glob", - "once_cell", "serde", "serde_derive", "serde_json", @@ -4895,6 +5439,26 @@ dependencies = [ "toml", ] +[[package]] +name = "tui-input" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68699e8bb4ca025ab41fcc602d3d53a5714a56b0cf2d6e93c98aaf4231e3d937" +dependencies = [ + "ratatui", + "unicode-width", +] + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + [[package]] name = "typed-arena" version = "2.0.2" @@ -4919,7 +5483,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "memoffset 0.9.0", + "memoffset 0.9.1", "tempfile", "winapi", ] @@ -4956,24 +5520,35 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-truncate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +dependencies = [ + "itertools 0.13.0", + "unicode-segmentation", + "unicode-width", +] [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -4983,9 +5558,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -4995,19 +5570,25 @@ dependencies = [ [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" @@ -5016,9 +5597,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vte" @@ -5032,9 +5613,9 @@ dependencies = [ [[package]] name = "vte_generate_state_changes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" dependencies = [ "proc-macro2", "quote", @@ -5051,9 +5632,9 @@ dependencies = [ [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" @@ -5171,11 +5752,11 @@ dependencies = [ "anyhow", "base64 0.21.7", "hex", - "indexmap 2.1.0", + "indexmap 2.2.6", "pbjson-types", "prost", "prost-types", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_with", "thiserror", @@ -5206,9 +5787,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5216,24 +5797,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -5243,9 +5824,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5253,22 +5834,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-encoder" @@ -5288,27 +5869,45 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.41.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "972f97a5d8318f908dded23594188a90bcd09365986b1163e66d70170e5287ae" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-encoder" +version = "0.214.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff694f02a8d7a50b6922b197ae03883fbf18cdb2ae9fbee7b6148456f5f44041" +dependencies = [ + "leb128", +] + [[package]] name = "wasm-metadata" -version = "0.10.15" +version = "0.10.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818931c85b1d197909699d36c509fa89550ccfa0d66932ba3c1726faddb4d0c7" +checksum = "18ebaa7bd0f9e7a5e5dd29b9a998acf21c4abed74265524dd7e85934597bfb10" dependencies = [ "anyhow", - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", "serde_derive", "serde_json", "spdx", - "wasm-encoder 0.39.0", - "wasmparser 0.119.0", + "wasm-encoder 0.41.2", + "wasmparser 0.121.2", ] [[package]] name = "wasm-streams" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" dependencies = [ "futures-util", "js-sys", @@ -5323,18 +5922,18 @@ version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76c956109dcb41436a39391139d9b6e2d0a5e0b158e1293ef352ec977e5e36c5" dependencies = [ - "indexmap 2.1.0", - "semver 1.0.21", + "indexmap 2.2.6", + "semver 1.0.23", ] [[package]] name = "wasmparser" -version = "0.118.1" +version = "0.118.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" +checksum = "77f1154f1ab868e2a01d9834a805faca7bf8b50d041b4ca714d005d0dab1c50c" dependencies = [ - "indexmap 2.1.0", - "semver 1.0.21", + "indexmap 2.2.6", + "semver 1.0.23", ] [[package]] @@ -5343,47 +5942,73 @@ version = "0.119.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c35daf77afb4f9b14016625144a391085ec2ca99ca9cc53ed291bb53ab5278d" dependencies = [ - "bitflags 2.4.2", - "indexmap 2.1.0", - "semver 1.0.21", + "bitflags 2.6.0", + "indexmap 2.2.6", + "semver 1.0.23", +] + +[[package]] +name = "wasmparser" +version = "0.121.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" +dependencies = [ + "bitflags 2.6.0", + "indexmap 2.2.6", + "semver 1.0.23", +] + +[[package]] +name = "wasmparser" +version = "0.214.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5309c1090e3e84dad0d382f42064e9933fdaedb87e468cc239f0eabea73ddcb6" +dependencies = [ + "ahash 0.8.11", + "bitflags 2.6.0", + "hashbrown 0.14.5", + "indexmap 2.2.6", + "semver 1.0.23", + "serde", ] [[package]] name = "wasmprinter" -version = "0.2.76" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac2a7745372074e5573e365e17100f5a26058740576313784ef03fb900ea8d2" +checksum = "60e73986a6b7fdfedb7c5bf9e7eb71135486507c8fbc4c0c42cffcb6532988b7" dependencies = [ "anyhow", - "wasmparser 0.119.0", + "wasmparser 0.121.2", ] [[package]] name = "wast" -version = "70.0.0" +version = "214.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee4bc54bbe1c6924160b9f75e374a1d07532e7580eb632c0ee6cdd109bb217e" +checksum = "694bcdb24c49c8709bd8713768b71301a11e823923eee355d530f1d8d0a7f8e9" dependencies = [ + "bumpalo", "leb128", "memchr", "unicode-width", - "wasm-encoder 0.39.0", + "wasm-encoder 0.214.0", ] [[package]] name = "wat" -version = "1.0.83" +version = "1.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f0dce8cdc288c717cf01e461a1e451a7b8445d53451123536ba576e423a101a" +checksum = "347249eb56773fa728df2656cfe3a8c19437ded61a922a0b5e0839d9790e278e" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -5398,7 +6023,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] @@ -5410,7 +6035,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -5432,11 +6057,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -5445,22 +6070,77 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] -name = "windows-sys" -version = "0.45.0" +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-targets 0.42.2", + "windows-result", + "windows-targets 0.52.6", ] [[package]] @@ -5478,22 +6158,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.6", ] [[package]] @@ -5513,25 +6178,20 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5540,15 +6200,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -5558,15 +6212,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -5576,15 +6224,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -5594,15 +6242,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5612,15 +6254,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5630,15 +6266,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5648,24 +6278,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "b480ae9340fc261e6be3e95a1ba86d54ae3f9171132a73ce8d4bbaf68339507c" dependencies = [ "memchr", ] @@ -5733,7 +6363,7 @@ checksum = "7ce0f4161cdde50de809b3869c1cb083a09e92e949428ea28f04c0d64045875c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -5788,15 +6418,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2" dependencies = [ "anyhow", - "bitflags 2.4.2", - "indexmap 2.1.0", + "bitflags 2.6.0", + "indexmap 2.2.6", "log", "serde", "serde_derive", "serde_json", "wasm-encoder 0.38.1", "wasm-metadata", - "wasmparser 0.118.1", + "wasmparser 0.118.2", "wit-parser", ] @@ -5807,8 +6437,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "429e3c06fba3a7566aab724ae3ffff3152ede5399d44789e7dd11f5421292859" dependencies = [ "anyhow", - "bitflags 2.4.2", - "indexmap 2.1.0", + "bitflags 2.6.0", + "indexmap 2.2.6", "log", "serde", "serde_derive", @@ -5821,15 +6451,15 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df4913a2219096373fd6512adead1fb77ecdaa59d7fc517972a7d30b12f625be" +checksum = "316b36a9f0005f5aa4b03c39bc3728d045df136f8c13a73b7db4510dec725e08" dependencies = [ "anyhow", "id-arena", - "indexmap 2.1.0", + "indexmap 2.2.6", "log", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_derive", "serde_json", @@ -5838,12 +6468,21 @@ dependencies = [ [[package]] name = "xdg-home" -version = "1.0.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd" +checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" dependencies = [ - "nix", - "winapi", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", ] [[package]] @@ -5854,9 +6493,9 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zbus" -version = "3.14.1" +version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31de390a2d872e4cd04edd71b425e29853f786dc99317ed72d73d6fcf5ebb948" +checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" dependencies = [ "async-broadcast", "async-executor", @@ -5876,7 +6515,7 @@ dependencies = [ "futures-sink", "futures-util", "hex", - "nix", + "nix 0.26.4", "once_cell", "ordered-stream", "rand", @@ -5895,9 +6534,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "3.14.1" +version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1794a946878c0e807f55a397187c11fc7a038ba5d868e7db4f3bd7760bc9d" +checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5909,9 +6548,9 @@ dependencies = [ [[package]] name = "zbus_names" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb80bb776dbda6e23d705cf0123c3b95df99c4ebeaec6c2599d4a5419902b4a9" +checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" dependencies = [ "serde", "static_assertions", @@ -5920,35 +6559,36 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zvariant" -version = "3.15.0" +version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44b291bee0d960c53170780af148dca5fa260a63cdd24f1962fa82e03e53338c" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" dependencies = [ "byteorder", "enumflags2", @@ -5960,9 +6600,9 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "3.15.0" +version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934d7a7dfc310d6ee06c87ffe88ef4eca7d3e37bb251dece2ef93da8f17d8ecd" +checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" dependencies = [ "proc-macro-crate", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 8f33f7bc..faab6405 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,14 +10,19 @@ members = [ "hir-type", "midenc", "midenc-compile", + "midenc-debug", "midenc-driver", "midenc-session", + "sdk/base-sys", "tools/*", "frontend-wasm", - "tests/rust-apps/*", "tests/integration", ] -exclude = ["tests/rust-apps-wasm", "cargo-ext/tests/data"] +exclude = [ + "tests/rust-apps/fib", + "tests/rust-apps-wasm", + "cargo-ext/tests/data", +] [workspace.package] version = "0.0.0" @@ -42,11 +47,13 @@ cranelift-entity = "0.108" cranelift-bforest = "0.108" env_logger = "0.11" either = { version = "1.10", default-features = false } +expect-test = "1.4.1" Inflector = "0.11" intrusive-collections = "0.9" inventory = "0.3" log = "0.4" -miette = { version = "7.1.0", git = "https://github.com/bitwalker/miette", branch = "no-std" } +miette = { package = "miden-miette", version = "7.1.1" } +#miette = { version = "7.1", git = "https://github.com/bitwalker/miette", branch = "no-std" } paste = "1.0" parking_lot = "0.12" parking_lot_core = "0.9" @@ -61,17 +68,20 @@ smallvec = { version = "1.13", features = [ "drain_filter", ] } smallstr = { version = "0.3", features = ["union"] } -thiserror = { version = "1.0", git = "https://github.com/bitwalker/thiserror", branch = "no-std" } +thiserror = { package = "miden-thiserror", version = "1.0" } +#thiserror = { version = "1.0", git = "https://github.com/bitwalker/thiserror", branch = "no-std" } toml = { version = "0.8", features = ["preserve_order"] } derive_more = "0.99" -indexmap = "2.1" -# a993b72e3fd5d209e017461b62ef2054d9120f01 is the commit that sets the `v0.10.0` -# version to all the VM crates in the 'next' branch -miden-assembly = { version = "0.10", git = "https://github.com/0xPolygonMiden/miden-vm", rev = "a993b72e3fd5d209e017461b62ef2054d9120f01" } -miden-core = { version = "0.10", git = "https://github.com/0xPolygonMiden/miden-vm", rev = "a993b72e3fd5d209e017461b62ef2054d9120f01" } -miden-processor = { version = "0.10", git = "https://github.com/0xPolygonMiden/miden-vm", rev = "a993b72e3fd5d209e017461b62ef2054d9120f01" } -miden-stdlib = { version = "0.10", git = "https://github.com/0xPolygonMiden/miden-vm", rev = "a993b72e3fd5d209e017461b62ef2054d9120f01" } -midenc-codegen-masm = { version = "0.0.1", path = "codegen/masm" } +indexmap = "2.2" +miden-assembly = { version = "0.10.3" } +miden-core = { version = "0.10.3" } +miden-processor = { version = "0.10.3" } +miden-stdlib = { version = "0.10.3" } +#miden-assembly = { git = "https://github.com/0xPolygonMiden/miden-vm", rev = "828557c28ca1d159bfe42195e7ea73256ce4aa06" } +#miden-core = { git = "https://github.com/0xPolygonMiden/miden-vm", rev = "828557c28ca1d159bfe42195e7ea73256ce4aa06" } +#miden-processor = { git = "https://github.com/0xPolygonMiden/miden-vm", rev = "828557c28ca1d159bfe42195e7ea73256ce4aa06" } +#miden-stdlib = { git = "https://github.com/0xPolygonMiden/miden-vm", rev = "828557c28ca1d159bfe42195e7ea73256ce4aa06" } +midenc-codegen-masm = { path = "codegen/masm" } miden-diagnostics = "0.1" midenc-hir = { version = "0.0.1", path = "hir" } midenc-hir-analysis = { version = "0.0.1", path = "hir-analysis" } @@ -83,15 +93,12 @@ miden-parsing = "0.1" midenc-frontend-wasm = { version = "0.0.1", path = "frontend-wasm" } midenc-compile = { version = "0.0.1", path = "midenc-compile" } midenc-driver = { version = "0.0.1", path = "midenc-driver" } +midenc-debug = { version = "0.0.1", path = "midenc-debug" } midenc-session = { version = "0.0.1", path = "midenc-session" } miden-integration-tests = { version = "0.0.0", path = "tests/integration" } wat = "1.0.69" blake3 = "1.5" -[patch.crates-io] -thiserror = { git = "https://github.com/bitwalker/thiserror", branch = "no-std" } -miette = { git = "https://github.com/bitwalker/miette", branch = "no-std" } - [profile.dev] lto = false # Needed for 'inventory' to work @@ -103,16 +110,21 @@ debug = true codegen-units = 1 lto = "thin" +# The following crates are always built with optimizations [profile.test.package.proptest] opt-level = 3 [profile.test.package.rand_chacha] opt-level = 3 -# Build `expect-test` with release optimizations even in dev mode to speed up the diffing [profile.dev.package.expect-test] opt-level = 3 -# Build `dissimilar` with release optimizations even in dev mode to speed up the diffing [profile.dev.package.dissimilar] opt-level = 3 + +[profile.dev.package.regex-syntax] +opt-level = 3 + +[profile.dev.package.onig] +opt-level = 3 diff --git a/Makefile.toml b/Makefile.toml index c5fdaf7b..dbd8d942 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -183,10 +183,12 @@ category = "Install" description = "Builds midenc and installs it globally via the cargo bin directory" command = "cargo" args = [ - "cargo", "install", "--path", "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/midenc", + "--debug", + "--force", + "--bin", "midenc", ] @@ -200,7 +202,9 @@ args = ["target", "add", "wasm32-unknown-unknown"] category = "Test" description = "Install wasm32-wasi target" command = "rustup" -args = ["target", "add", "wasm32-wasi"] +# `wasm32-wasi` target is renamed to `wasm32-wasip1` +# https://blog.rust-lang.org/2024/04/09/updates-to-rusts-wasi-targets.html +args = ["target", "add", "wasm32-wasip1"] [tasks.install-rust-src] category = "Test" @@ -212,14 +216,15 @@ args = ["component", "add", "rust-src"] category = "Test" description = "Install cargo-component extension" command = "cargo" -args = ["install", "cargo-component@0.7.0"] +args = ["install", "cargo-component@0.14.0"] [tasks.test-rust] category = "Test" description = "Runs tests written in Rust" command = "cargo" args = [ - "test", + "nextest", + "run", "@@remove-empty(CARGO_MAKE_CARGO_VERBOSE_FLAGS)", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )", "${@}", @@ -285,11 +290,11 @@ args = ["serve", "--open", "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/docs"] description = "Runs clippy on the workspace" category = "Development" command = "cargo" -args = ["clippy" , "--all", "--", "-D", "clippy::all", "-D", "warnings"] +args = ["clippy", "--all", "--", "-D", "clippy::all", "-D", "warnings"] dependencies = ["install-clippy"] [tasks.install-clippy] category = "Development" description = "Installs cargo clippy plugin." command = "rustup" -args = ["component", "add", "clippy"] \ No newline at end of file +args = ["component", "add", "clippy"] diff --git a/codegen/masm/Cargo.toml b/codegen/masm/Cargo.toml index 465a029b..0a0257a0 100644 --- a/codegen/masm/Cargo.toml +++ b/codegen/masm/Cargo.toml @@ -19,7 +19,7 @@ inventory.workspace = true log.workspace = true miden-assembly.workspace = true miden-core.workspace = true -miden-diagnostics.workspace = true +miden-processor.workspace = true miden-stdlib.workspace = true midenc-hir.workspace = true midenc-hir-analysis.workspace = true diff --git a/codegen/masm/intrinsics/mem.masm b/codegen/masm/intrinsics/mem.masm index d53b845b..0486981d 100644 --- a/codegen/masm/intrinsics/mem.masm +++ b/codegen/masm/intrinsics/mem.masm @@ -1,3 +1,95 @@ +# The location where we store information about the dynamic heap +const.HEAP_INFO_ADDR=0x80000000 # (address in words) +# The address beyond which the dynamic heap cannot be allowed to grow +const.HEAP_END=0x10000000 # 2^30 / 4 (i.e. byte address, not word) +# The assertion error code used when intrinsics are used without calling heap_init +const.HEAP_ERR=0x68656170 # b"heap" +const.NEG1=4294967295 # u32::MAX +# The magic bytes used to verify that the heap was properly initialized +const.MAGIC=0xDEADBEEF +const.PAGE_SIZE=65536 + +# Checks the HEAP_INFO magic to ensure heap initialization has taken place +# +# This consumes the input element. +proc.verify_heap_magic # [input] + u32assert.err=HEAP_ERR + push.MAGIC + assert_eq.err=HEAP_ERR +end + +# Intrinsic used to initialize the heap globals manipulated by memory intrinsics +# +# This must be called before any other heap intrinsics are called. This is checked +# by each intrinsic +export.heap_init # [heap_base] + push.MAGIC swap.1 push.0 dup.1 # [heap_top, heap_size, heap_base, MAGIC] + mem_storew.HEAP_INFO_ADDR + dropw +end + +# Get the (byte) address where the base of the heap starts +export.heap_base + padw mem_loadw.HEAP_INFO_ADDR + drop drop swap.1 exec.verify_heap_magic +end + +# Get the (byte) address of the top of the heap +export.heap_top_unchecked + mem_load.HEAP_INFO_ADDR +end + +# Get the (byte) address of the top of the heap +export.heap_top + padw mem_loadw.HEAP_INFO_ADDR + movdn.3 drop drop exec.verify_heap_magic +end + +# Intrinsic corresponding to the `memory_size` instruction +export.memory_size + padw mem_loadw.HEAP_INFO_ADDR + drop movdn.2 drop exec.verify_heap_magic +end + +# Intrinsic corresponding to the `memory_grow` instruction +export.memory_grow # [num_pages] + padw mem_loadw.HEAP_INFO_ADDR # [heap_top, heap_size, heap_base, MAGIC, num_pages] + dup.3 exec.verify_heap_magic + drop # [heap_size, heap_base, MAGIC, num_pages] + dup.0 movdn.4 # [heap_size, heap_base, MAGIC, num_pages, heap_size] + movup.3 # [num_pages, heap_size, heap_base, MAGIC0, heap_size] + u32overflowing_add # [overflowed, heap_size + num_pages, heap_base, MAGIC0, heap_size] + if.true # [new_heap_size, heap_base, MAGIC0, heap_size] + # Cannot grow the memory, return -1 + dropw # [] + push.NEG1 + else + # Success, recompute the heap_top, and make sure it doesn't exceed HEAP_END + dup.0 # [new_heap_size, new_heap_size, heap_base, MAGIC0, heap_size] + push.PAGE_SIZE # [PAGE_SIZE, new_heap_size, new_heap_size, heap_base, MAGIC0, heap_size] + dup.3 # [heap_base, PAGE_SIZE, new_heap_size, new_heap_size, heap_base, MAGIC0, heap_size] + movdn.2 # [PAGE_SIZE, new_heap_size, heap_base, ..] + u32overflowing_madd # [overflow, PAGE_SIZE * new_heap_size + heap_base, ..] + if.true # [new_heap_top, new_heap_size, heap_base, MAGIC, heap_size] + # Overflow, drop the changes and return -1 + dropw drop + push.NEG1 + else + # Ensure the new heap_top is <= HEAP_END + dup.0 u32lte.HEAP_END + if.true + # Write updated heap information, and return the old heap size (in pages) + mem_storew.HEAP_INFO_ADDR + dropw + else + # Overflow, drop the changes and return -1 + dropw drop + push.NEG1 + end + end + end +end + # Given an element index, and a word, in that order, drop the elements of the # word other than the at the specified index. # diff --git a/codegen/masm/src/codegen/emit/binary.rs b/codegen/masm/src/codegen/emit/binary.rs index 87c0a5da..eea74de6 100644 --- a/codegen/masm/src/codegen/emit/binary.rs +++ b/codegen/masm/src/codegen/emit/binary.rs @@ -1,20 +1,20 @@ -use midenc_hir::{assert_matches, Felt, Immediate, Overflow, Type}; +use midenc_hir::{assert_matches, Felt, Immediate, Overflow, SourceSpan, Type}; use super::OpEmitter; use crate::masm::Op; impl<'a> OpEmitter<'a> { - pub fn eq(&mut self) { + pub fn eq(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected eq operands to be the same type"); match &ty { Type::I128 | Type::U128 => { - self.eq_i128(); + self.eq_i128(span); } Type::I64 | Type::U64 => { - self.eq_int64(); + self.eq_int64(span); } Type::Felt | Type::Ptr(_) @@ -25,47 +25,47 @@ impl<'a> OpEmitter<'a> { | Type::I8 | Type::U8 | Type::I1 => { - self.emit(Op::Eq); + self.emit(Op::Eq, span); } ty => unimplemented!("eq is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn eq_imm(&mut self, imm: Immediate) { + pub fn eq_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected eq operands to be the same type"); match &ty { Type::I128 | Type::U128 => { - self.push_immediate(imm); - self.eq_i128(); + self.push_immediate(imm, span); + self.eq_i128(span); } Type::I64 | Type::U64 => { - self.push_immediate(imm); - self.eq_int64(); + self.push_immediate(imm, span); + self.eq_int64(span); } Type::Felt | Type::Ptr(_) | Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit(Op::EqImm(imm.as_felt().unwrap())); + self.emit(Op::EqImm(imm.as_felt().unwrap()), span); } Type::I32 | Type::I16 | Type::I8 => { - self.emit(Op::EqImm(Felt::new(imm.as_i32().unwrap() as u32 as u64))); + self.emit(Op::EqImm(Felt::new(imm.as_i32().unwrap() as u32 as u64)), span); } ty => unimplemented!("eq is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn neq(&mut self) { + pub fn neq(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected neq operands to be the same type"); match &ty { Type::I128 | Type::U128 => { - self.neq_i128(); + self.neq_i128(span); } - Type::I64 | Type::U64 => self.neq_int64(), + Type::I64 | Type::U64 => self.neq_int64(span), Type::Felt | Type::Ptr(_) | Type::U32 @@ -75,276 +75,288 @@ impl<'a> OpEmitter<'a> { | Type::I8 | Type::U8 | Type::I1 => { - self.emit(Op::Neq); + self.emit(Op::Neq, span); } ty => unimplemented!("neq is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn neq_imm(&mut self, imm: Immediate) { + pub fn neq_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected neq operands to be the same type"); match &ty { Type::I128 | Type::U128 => { - self.push_immediate(imm); - self.neq_i128(); + self.push_immediate(imm, span); + self.neq_i128(span); } Type::I64 | Type::U64 => { - self.push_immediate(imm); - self.neq_int64() + self.push_immediate(imm, span); + self.neq_int64(span) } Type::Felt | Type::Ptr(_) | Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit(Op::NeqImm(imm.as_felt().unwrap())); + self.emit(Op::NeqImm(imm.as_felt().unwrap()), span); } Type::I32 | Type::I16 | Type::I8 => { - self.emit(Op::NeqImm(Felt::new(imm.as_i32().unwrap() as u32 as u64))); + self.emit(Op::NeqImm(Felt::new(imm.as_i32().unwrap() as u32 as u64)), span); } ty => unimplemented!("neq is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn gt(&mut self) { + pub fn gt(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected gt operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Gt); + self.emit(Op::Gt, span); } Type::U64 => { - self.gt_u64(); + self.gt_u64(span); } Type::I64 => { - self.gt_i64(); + self.gt_i64(span); } Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit(Op::U32Gt); + self.emit(Op::U32Gt, span); } - Type::I32 => self.emit(Op::Exec("intrinsics::i32::is_gt".parse().unwrap())), + Type::I32 => self.emit(Op::Exec("intrinsics::i32::is_gt".parse().unwrap()), span), ty => unimplemented!("gt is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn gt_imm(&mut self, imm: Immediate) { + pub fn gt_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected gt operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::GtImm(imm.as_felt().unwrap())); + self.emit(Op::GtImm(imm.as_felt().unwrap()), span); } Type::U64 => { - self.push_u64(imm.as_u64().unwrap()); - self.gt_u64(); + self.push_u64(imm.as_u64().unwrap(), span); + self.gt_u64(span); } Type::I64 => { - self.push_i64(imm.as_i64().unwrap()); - self.gt_i64(); + self.push_i64(imm.as_i64().unwrap(), span); + self.gt_i64(span); } Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit_all(&[Op::PushU32(imm.as_u32().unwrap()), Op::U32Gt]); + self.emit_all(&[Op::PushU32(imm.as_u32().unwrap()), Op::U32Gt], span); } Type::I32 => { - self.emit_all(&[ - Op::PushU32(imm.as_i32().unwrap() as u32), - Op::Exec("intrinsics::i32::is_gt".parse().unwrap()), - ]); + self.emit_all( + &[ + Op::PushU32(imm.as_i32().unwrap() as u32), + Op::Exec("intrinsics::i32::is_gt".parse().unwrap()), + ], + span, + ); } ty => unimplemented!("gt is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn gte(&mut self) { + pub fn gte(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected gte operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Gte); + self.emit(Op::Gte, span); } Type::U64 => { - self.gte_u64(); + self.gte_u64(span); } Type::I64 => { - self.gte_i64(); + self.gte_i64(span); } Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit(Op::U32Gte); + self.emit(Op::U32Gte, span); } - Type::I32 => self.emit(Op::Exec("intrinsics::i32::is_gte".parse().unwrap())), + Type::I32 => self.emit(Op::Exec("intrinsics::i32::is_gte".parse().unwrap()), span), ty => unimplemented!("gte is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn gte_imm(&mut self, imm: Immediate) { + pub fn gte_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected gte operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::GteImm(imm.as_felt().unwrap())); + self.emit(Op::GteImm(imm.as_felt().unwrap()), span); } Type::U64 => { - self.push_u64(imm.as_u64().unwrap()); - self.gte_u64(); + self.push_u64(imm.as_u64().unwrap(), span); + self.gte_u64(span); } Type::I64 => { - self.push_i64(imm.as_i64().unwrap()); - self.gte_i64(); + self.push_i64(imm.as_i64().unwrap(), span); + self.gte_i64(span); } Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit_all(&[Op::PushU32(imm.as_u32().unwrap()), Op::U32Gte]); + self.emit_all(&[Op::PushU32(imm.as_u32().unwrap()), Op::U32Gte], span); } Type::I32 => { - self.emit_all(&[ - Op::PushU32(imm.as_i32().unwrap() as u32), - Op::Exec("intrinsics::i32::is_gte".parse().unwrap()), - ]); + self.emit_all( + &[ + Op::PushU32(imm.as_i32().unwrap() as u32), + Op::Exec("intrinsics::i32::is_gte".parse().unwrap()), + ], + span, + ); } ty => unimplemented!("gte is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn lt(&mut self) { + pub fn lt(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected lt operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Lt); + self.emit(Op::Lt, span); } Type::U64 => { - self.lt_u64(); + self.lt_u64(span); } Type::I64 => { - self.lt_i64(); + self.lt_i64(span); } Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit(Op::U32Lt); + self.emit(Op::U32Lt, span); } - Type::I32 => self.emit(Op::Exec("intrinsics::i32::is_lt".parse().unwrap())), + Type::I32 => self.emit(Op::Exec("intrinsics::i32::is_lt".parse().unwrap()), span), ty => unimplemented!("lt is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn lt_imm(&mut self, imm: Immediate) { + pub fn lt_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected lt operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::LtImm(imm.as_felt().unwrap())); + self.emit(Op::LtImm(imm.as_felt().unwrap()), span); } Type::U64 => { - self.push_u64(imm.as_u64().unwrap()); - self.lt_u64(); + self.push_u64(imm.as_u64().unwrap(), span); + self.lt_u64(span); } Type::I64 => { - self.push_i64(imm.as_i64().unwrap()); - self.lt_i64(); + self.push_i64(imm.as_i64().unwrap(), span); + self.lt_i64(span); } Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit_all(&[Op::PushU32(imm.as_u32().unwrap()), Op::U32Lt]); + self.emit_all(&[Op::PushU32(imm.as_u32().unwrap()), Op::U32Lt], span); } Type::I32 => { - self.emit_all(&[ - Op::PushU32(imm.as_i32().unwrap() as u32), - Op::Exec("intrinsics::i32::is_lt".parse().unwrap()), - ]); + self.emit_all( + &[ + Op::PushU32(imm.as_i32().unwrap() as u32), + Op::Exec("intrinsics::i32::is_lt".parse().unwrap()), + ], + span, + ); } ty => unimplemented!("lt is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn lte(&mut self) { + pub fn lte(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected lte operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Lte); + self.emit(Op::Lte, span); } Type::U64 => { - self.lte_u64(); + self.lte_u64(span); } Type::I64 => { - self.lte_i64(); + self.lte_i64(span); } Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit(Op::U32Lte); + self.emit(Op::U32Lte, span); } - Type::I32 => self.emit(Op::Exec("intrinsics::i32::is_lte".parse().unwrap())), + Type::I32 => self.emit(Op::Exec("intrinsics::i32::is_lte".parse().unwrap()), span), ty => unimplemented!("lte is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn lte_imm(&mut self, imm: Immediate) { + pub fn lte_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected lte operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::LteImm(imm.as_felt().unwrap())); + self.emit(Op::LteImm(imm.as_felt().unwrap()), span); } Type::U64 => { - self.push_u64(imm.as_u64().unwrap()); - self.lte_u64(); + self.push_u64(imm.as_u64().unwrap(), span); + self.lte_u64(span); } Type::I64 => { - self.push_i64(imm.as_i64().unwrap()); - self.lte_i64(); + self.push_i64(imm.as_i64().unwrap(), span); + self.lte_i64(span); } Type::U32 | Type::U16 | Type::U8 | Type::I1 => { - self.emit_all(&[Op::PushU32(imm.as_u32().unwrap()), Op::U32Lte]); + self.emit_all(&[Op::PushU32(imm.as_u32().unwrap()), Op::U32Lte], span); } Type::I32 => { - self.emit_all(&[ - Op::PushU32(imm.as_i32().unwrap() as u32), - Op::Exec("intrinsics::i32::is_lte".parse().unwrap()), - ]); + self.emit_all( + &[ + Op::PushU32(imm.as_i32().unwrap() as u32), + Op::Exec("intrinsics::i32::is_lte".parse().unwrap()), + ], + span, + ); } ty => unimplemented!("lte is not yet implemented for {ty}"), } self.push(Type::I1); } - pub fn add(&mut self, overflow: Overflow) { + pub fn add(&mut self, overflow: Overflow, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected add operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Add); + self.emit(Op::Add, span); } Type::U64 => { - self.add_u64(overflow); + self.add_u64(overflow, span); } Type::I64 => { - self.add_i64(overflow); + self.add_i64(overflow, span); } Type::U32 => { - self.add_u32(overflow); + self.add_u32(overflow, span); } Type::I32 => { - self.add_i32(overflow); + self.add_i32(overflow, span); } ty @ (Type::U16 | Type::U8 | Type::I1) => { - self.add_uint(ty.size_in_bits() as u32, overflow); + self.add_uint(ty.size_in_bits() as u32, overflow, span); } ty => unimplemented!("add is not yet implemented for {ty}"), } @@ -354,30 +366,30 @@ impl<'a> OpEmitter<'a> { } } - pub fn add_imm(&mut self, imm: Immediate, overflow: Overflow) { + pub fn add_imm(&mut self, imm: Immediate, overflow: Overflow, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected add operands to be the same type"); match &ty { - Type::Felt if imm == 1 => self.emit(Op::Incr), + Type::Felt if imm == 1 => self.emit(Op::Incr, span), Type::Felt => { - self.emit(Op::AddImm(imm.as_felt().unwrap())); + self.emit(Op::AddImm(imm.as_felt().unwrap()), span); } Type::U64 => { - self.push_immediate(imm); - self.add_u64(overflow); + self.push_immediate(imm, span); + self.add_u64(overflow, span); } Type::I64 => { - self.add_imm_i64(imm.as_i64().unwrap(), overflow); + self.add_imm_i64(imm.as_i64().unwrap(), overflow, span); } Type::U32 => { - self.add_imm_u32(imm.as_u32().unwrap(), overflow); + self.add_imm_u32(imm.as_u32().unwrap(), overflow, span); } Type::I32 => { - self.add_imm_i32(imm.as_i32().unwrap(), overflow); + self.add_imm_i32(imm.as_i32().unwrap(), overflow, span); } ty @ (Type::U16 | Type::U8 | Type::I1) => { - self.add_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, overflow); + self.add_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, overflow, span); } ty => unimplemented!("add is not yet implemented for {ty}"), } @@ -387,29 +399,29 @@ impl<'a> OpEmitter<'a> { } } - pub fn sub(&mut self, overflow: Overflow) { + pub fn sub(&mut self, overflow: Overflow, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected sub operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Sub); + self.emit(Op::Sub, span); } Type::U64 => { - self.sub_u64(overflow); + self.sub_u64(overflow, span); } Type::I64 => { - self.sub_i64(overflow); + self.sub_i64(overflow, span); } Type::U32 => { - self.sub_u32(overflow); + self.sub_u32(overflow, span); } Type::I32 => { - self.sub_i32(overflow); + self.sub_i32(overflow, span); } ty @ (Type::U16 | Type::U8 | Type::I1) => { - self.sub_uint(ty.size_in_bits() as u32, overflow); + self.sub_uint(ty.size_in_bits() as u32, overflow, span); } ty => unimplemented!("sub is not yet implemented for {ty}"), } @@ -419,29 +431,29 @@ impl<'a> OpEmitter<'a> { } } - pub fn sub_imm(&mut self, imm: Immediate, overflow: Overflow) { + pub fn sub_imm(&mut self, imm: Immediate, overflow: Overflow, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected sub operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::SubImm(imm.as_felt().unwrap())); + self.emit(Op::SubImm(imm.as_felt().unwrap()), span); } Type::U64 => { - self.push_immediate(imm); - self.sub_u64(overflow); + self.push_immediate(imm, span); + self.sub_u64(overflow, span); } Type::I64 => { - self.sub_imm_i64(imm.as_i64().unwrap(), overflow); + self.sub_imm_i64(imm.as_i64().unwrap(), overflow, span); } Type::U32 => { - self.sub_imm_u32(imm.as_u32().unwrap(), overflow); + self.sub_imm_u32(imm.as_u32().unwrap(), overflow, span); } Type::I32 => { - self.sub_imm_i32(imm.as_i32().unwrap(), overflow); + self.sub_imm_i32(imm.as_i32().unwrap(), overflow, span); } ty @ (Type::U16 | Type::U8 | Type::I1) => { - self.sub_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, overflow); + self.sub_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, overflow, span); } ty => unimplemented!("sub is not yet implemented for {ty}"), } @@ -451,7 +463,7 @@ impl<'a> OpEmitter<'a> { } } - pub fn mul(&mut self, overflow: Overflow) { + pub fn mul(&mut self, overflow: Overflow, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); @@ -479,14 +491,14 @@ impl<'a> OpEmitter<'a> { Overflow::Unchecked | Overflow::Wrapping, "only unchecked or wrapping semantics are supported for felt" ); - self.emit(Op::Mul); + self.emit(Op::Mul, span); } - Type::U64 => self.mul_u64(overflow), - Type::I64 => self.mul_i64(overflow), - Type::U32 => self.mul_u32(overflow), - Type::I32 => self.mul_i32(overflow), + Type::U64 => self.mul_u64(overflow, span), + Type::I64 => self.mul_i64(overflow, span), + Type::U32 => self.mul_u32(overflow, span), + Type::I32 => self.mul_i32(overflow, span), ty @ (Type::U16 | Type::U8) => { - self.mul_uint(ty.size_in_bits() as u32, overflow); + self.mul_uint(ty.size_in_bits() as u32, overflow, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: mul expects integer operands, got {ty}") @@ -499,7 +511,7 @@ impl<'a> OpEmitter<'a> { } } - pub fn mul_imm(&mut self, imm: Immediate, overflow: Overflow) { + pub fn mul_imm(&mut self, imm: Immediate, overflow: Overflow, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected mul operands to be the same type"); @@ -510,17 +522,17 @@ impl<'a> OpEmitter<'a> { Overflow::Unchecked | Overflow::Wrapping, "only unchecked or wrapping semantics are supported for felt" ); - self.emit(Op::MulImm(imm.as_felt().unwrap())); + self.emit(Op::MulImm(imm.as_felt().unwrap()), span); } Type::U64 => { - self.push_immediate(imm); - self.mul_u64(overflow); + self.push_immediate(imm, span); + self.mul_u64(overflow, span); } - Type::I64 => self.mul_imm_i64(imm.as_i64().unwrap(), overflow), - Type::U32 => self.mul_imm_u32(imm.as_u32().unwrap(), overflow), - Type::I32 => self.mul_imm_i32(imm.as_i32().unwrap(), overflow), + Type::I64 => self.mul_imm_i64(imm.as_i64().unwrap(), overflow, span), + Type::U32 => self.mul_imm_u32(imm.as_u32().unwrap(), overflow, span), + Type::I32 => self.mul_imm_i32(imm.as_i32().unwrap(), overflow, span), ty @ (Type::U16 | Type::U8) => { - self.mul_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, overflow); + self.mul_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, overflow, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: mul expects integer operands, got {ty}") @@ -533,21 +545,21 @@ impl<'a> OpEmitter<'a> { } } - pub fn checked_div(&mut self) { + pub fn checked_div(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected div operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Div); + self.emit(Op::Div, span); } - Type::U64 => self.checked_div_u64(), - Type::I64 => self.checked_div_i64(), - Type::U32 => self.checked_div_u32(), - Type::I32 => self.checked_div_i32(), + Type::U64 => self.checked_div_u64(span), + Type::I64 => self.checked_div_i64(span), + Type::U32 => self.checked_div_u32(span), + Type::I32 => self.checked_div_i32(span), ty @ (Type::U16 | Type::U8) => { - self.checked_div_uint(ty.size_in_bits() as u32); + self.checked_div_uint(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: div expects integer operands, got {ty}") @@ -557,24 +569,24 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn checked_div_imm(&mut self, imm: Immediate) { + pub fn checked_div_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected div operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Div); + self.emit(Op::Div, span); } Type::U64 => { assert_ne!(imm.as_u64().unwrap(), 0, "invalid division by zero"); - self.push_immediate(imm); - self.checked_div_u64(); + self.push_immediate(imm, span); + self.checked_div_u64(span); } - Type::I64 => self.checked_div_imm_i64(imm.as_i64().unwrap()), - Type::U32 => self.checked_div_imm_u32(imm.as_u32().unwrap()), - Type::I32 => self.checked_div_imm_i32(imm.as_i32().unwrap()), + Type::I64 => self.checked_div_imm_i64(imm.as_i64().unwrap(), span), + Type::U32 => self.checked_div_imm_u32(imm.as_u32().unwrap(), span), + Type::I32 => self.checked_div_imm_i32(imm.as_i32().unwrap(), span), ty @ (Type::U16 | Type::U8) => { - self.checked_div_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32); + self.checked_div_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: div expects integer operands, got {ty}") @@ -584,19 +596,19 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn unchecked_div(&mut self) { + pub fn unchecked_div(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected div operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Div); + self.emit(Op::Div, span); } - Type::U64 => self.unchecked_div_u64(), - Type::I64 => self.checked_div_i64(), - Type::U32 | Type::U16 | Type::U8 => self.unchecked_div_u32(), - Type::I32 => self.checked_div_i32(), + Type::U64 => self.unchecked_div_u64(span), + Type::I64 => self.checked_div_i64(span), + Type::U32 | Type::U16 | Type::U8 => self.unchecked_div_u32(span), + Type::I32 => self.checked_div_i32(span), ty if !ty.is_integer() => { panic!("invalid binary operand: div expects integer operands, got {ty}") } @@ -605,24 +617,24 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn unchecked_div_imm(&mut self, imm: Immediate) { + pub fn unchecked_div_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected div operands to be the same type"); match &ty { Type::Felt => { - self.emit(Op::Div); + self.emit(Op::Div, span); } Type::U64 => { assert_ne!(imm.as_u64().unwrap(), 0, "invalid division by zero"); - self.push_immediate(imm); - self.unchecked_div_u64(); + self.push_immediate(imm, span); + self.unchecked_div_u64(span); } - Type::I64 => self.checked_div_imm_i64(imm.as_i64().unwrap()), - Type::U32 => self.unchecked_div_imm_u32(imm.as_u32().unwrap()), - Type::I32 => self.checked_div_imm_i32(imm.as_i32().unwrap()), + Type::I64 => self.checked_div_imm_i64(imm.as_i64().unwrap(), span), + Type::U32 => self.unchecked_div_imm_u32(imm.as_u32().unwrap(), span), + Type::I32 => self.checked_div_imm_i32(imm.as_i32().unwrap(), span), ty @ (Type::U16 | Type::U8) => { - self.unchecked_div_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32); + self.unchecked_div_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: div expects integer operands, got {ty}") @@ -632,16 +644,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn checked_mod(&mut self) { + pub fn checked_mod(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected mod operands to be the same type"); match &ty { - Type::U64 => self.checked_mod_u64(), - Type::U32 => self.checked_mod_u32(), + Type::U64 => self.checked_mod_u64(span), + Type::U32 => self.checked_mod_u32(span), ty @ (Type::U16 | Type::U8) => { - self.checked_mod_uint(ty.size_in_bits() as u32); + self.checked_mod_uint(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: mod expects integer operands, got {ty}") @@ -651,19 +663,19 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn checked_mod_imm(&mut self, imm: Immediate) { + pub fn checked_mod_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected mod operands to be the same type"); match &ty { Type::U64 => { assert_ne!(imm.as_u64().unwrap(), 0, "invalid division by zero"); - self.push_immediate(imm); - self.checked_mod_u64(); + self.push_immediate(imm, span); + self.checked_mod_u64(span); } - Type::U32 => self.checked_mod_imm_u32(imm.as_u32().unwrap()), + Type::U32 => self.checked_mod_imm_u32(imm.as_u32().unwrap(), span), ty @ (Type::U16 | Type::U8) => { - self.checked_mod_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32); + self.checked_mod_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: mod expects integer operands, got {ty}") @@ -673,16 +685,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn unchecked_mod(&mut self) { + pub fn unchecked_mod(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected mod operands to be the same type"); match &ty { - Type::U64 => self.unchecked_mod_u64(), - Type::U32 => self.unchecked_mod_u32(), + Type::U64 => self.unchecked_mod_u64(span), + Type::U32 => self.unchecked_mod_u32(span), ty @ (Type::U16 | Type::U8) => { - self.unchecked_mod_uint(ty.size_in_bits() as u32); + self.unchecked_mod_uint(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: mod expects integer operands, got {ty}") @@ -692,19 +704,19 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn unchecked_mod_imm(&mut self, imm: Immediate) { + pub fn unchecked_mod_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected mod operands to be the same type"); match &ty { Type::U64 => { assert_ne!(imm.as_u64().unwrap(), 0, "invalid division by zero"); - self.push_immediate(imm); - self.unchecked_mod_u64(); + self.push_immediate(imm, span); + self.unchecked_mod_u64(span); } - Type::U32 => self.unchecked_mod_imm_u32(imm.as_u32().unwrap()), + Type::U32 => self.unchecked_mod_imm_u32(imm.as_u32().unwrap(), span), ty @ (Type::U16 | Type::U8) => { - self.unchecked_mod_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32); + self.unchecked_mod_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: mod expects integer operands, got {ty}") @@ -714,16 +726,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn checked_divmod(&mut self) { + pub fn checked_divmod(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected divmod operands to be the same type"); match &ty { - Type::U64 => self.checked_divmod_u64(), - Type::U32 => self.checked_divmod_u32(), + Type::U64 => self.checked_divmod_u64(span), + Type::U32 => self.checked_divmod_u32(span), ty @ (Type::U16 | Type::U8) => { - self.checked_divmod_uint(ty.size_in_bits() as u32); + self.checked_divmod_uint(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: divmod expects integer operands, got {ty}") @@ -734,19 +746,19 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn checked_divmod_imm(&mut self, imm: Immediate) { + pub fn checked_divmod_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected divmod operands to be the same type"); match &ty { Type::U64 => { assert_ne!(imm.as_u64().unwrap(), 0, "invalid division by zero"); - self.push_immediate(imm); - self.checked_divmod_u64(); + self.push_immediate(imm, span); + self.checked_divmod_u64(span); } - Type::U32 => self.checked_divmod_imm_u32(imm.as_u32().unwrap()), + Type::U32 => self.checked_divmod_imm_u32(imm.as_u32().unwrap(), span), ty @ (Type::U16 | Type::U8) => { - self.checked_divmod_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32); + self.checked_divmod_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: divmod expects integer operands, got {ty}") @@ -757,16 +769,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn unchecked_divmod(&mut self) { + pub fn unchecked_divmod(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected divmod operands to be the same type"); match &ty { - Type::U64 => self.unchecked_divmod_u64(), - Type::U32 => self.unchecked_divmod_u32(), + Type::U64 => self.unchecked_divmod_u64(span), + Type::U32 => self.unchecked_divmod_u32(span), ty @ (Type::U16 | Type::U8) => { - self.unchecked_divmod_uint(ty.size_in_bits() as u32); + self.unchecked_divmod_uint(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: divmod expects integer operands, got {ty}") @@ -777,19 +789,23 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn unchecked_divmod_imm(&mut self, imm: Immediate) { + pub fn unchecked_divmod_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected divmod operands to be the same type"); match &ty { Type::U64 => { assert_ne!(imm.as_u64().unwrap(), 0, "invalid division by zero"); - self.push_immediate(imm); - self.unchecked_divmod_u64(); + self.push_immediate(imm, span); + self.unchecked_divmod_u64(span); } - Type::U32 => self.unchecked_divmod_imm_u32(imm.as_u32().unwrap()), + Type::U32 => self.unchecked_divmod_imm_u32(imm.as_u32().unwrap(), span), ty @ (Type::U16 | Type::U8) => { - self.unchecked_divmod_imm_uint(imm.as_u32().unwrap(), ty.size_in_bits() as u32); + self.unchecked_divmod_imm_uint( + imm.as_u32().unwrap(), + ty.size_in_bits() as u32, + span, + ); } ty if !ty.is_integer() => { panic!("invalid binary operand: divmod expects integer operands, got {ty}") @@ -800,7 +816,7 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn exp(&mut self) { + pub fn exp(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); @@ -808,17 +824,17 @@ impl<'a> OpEmitter<'a> { match &ty { Type::U64 => todo!("exponentiation by squaring"), Type::Felt => { - self.emit(Op::Exp); + self.emit(Op::Exp, span); } Type::U32 => { - self.emit_all(&[Op::Exp, Op::U32Assert]); + self.emit_all(&[Op::Exp, Op::U32Assert], span); } Type::I32 => { - self.emit(Op::Exec("intrinsics::i32::ipow".parse().unwrap())); + self.emit(Op::Exec("intrinsics::i32::ipow".parse().unwrap()), span); } ty @ (Type::U16 | Type::U8) => { - self.emit_all(&[Op::Exp, Op::U32Assert]); - self.int32_to_uint(ty.size_in_bits() as u32); + self.emit_all(&[Op::Exp, Op::U32Assert], span); + self.int32_to_uint(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: exp expects integer operands, got {ty}") @@ -828,7 +844,7 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn exp_imm(&mut self, imm: Immediate) { + pub fn exp_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected exp operands to be the same type"); @@ -837,20 +853,20 @@ impl<'a> OpEmitter<'a> { match &ty { Type::U64 => todo!("exponentiation by squaring"), Type::Felt => { - self.emit(Op::ExpImm(exp)); + self.emit(Op::ExpImm(exp), span); } Type::U32 => { - self.emit_all(&[Op::ExpImm(exp), Op::U32Assert]); + self.emit_all(&[Op::ExpImm(exp), Op::U32Assert], span); } Type::I32 => { - self.emit_all(&[ - Op::PushU8(exp), - Op::Exec("intrinsics::i32::ipow".parse().unwrap()), - ]); + self.emit_all( + &[Op::PushU8(exp), Op::Exec("intrinsics::i32::ipow".parse().unwrap())], + span, + ); } ty @ (Type::U16 | Type::U8) => { - self.emit_all(&[Op::ExpImm(exp), Op::U32Assert]); - self.int32_to_uint(ty.size_in_bits() as u32); + self.emit_all(&[Op::ExpImm(exp), Op::U32Assert], span); + self.int32_to_uint(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: exp expects integer operands, got {ty}") @@ -860,64 +876,64 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn and(&mut self) { + pub fn and(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected and operands to be the same type"); assert_eq!(ty, Type::I1, "expected and operands to be of boolean type"); - self.emit(Op::And); + self.emit(Op::And, span); self.push(ty); } - pub fn and_imm(&mut self, imm: Immediate) { + pub fn and_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected and operands to be the same type"); assert_eq!(ty, Type::I1, "expected and operands to be of boolean type"); - self.emit(Op::AndImm(imm.as_bool().unwrap())); + self.emit(Op::AndImm(imm.as_bool().unwrap()), span); self.push(ty); } - pub fn or(&mut self) { + pub fn or(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected or operands to be the same type"); assert_eq!(ty, Type::I1, "expected or operands to be of boolean type"); - self.emit(Op::Or); + self.emit(Op::Or, span); self.push(ty); } - pub fn or_imm(&mut self, imm: Immediate) { + pub fn or_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected or operands to be the same type"); assert_eq!(ty, Type::I1, "expected or operands to be of boolean type"); - self.emit(Op::OrImm(imm.as_bool().unwrap())); + self.emit(Op::OrImm(imm.as_bool().unwrap()), span); self.push(ty); } - pub fn xor(&mut self) { + pub fn xor(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected xor operands to be the same type"); assert_eq!(ty, Type::I1, "expected xor operands to be of boolean type"); - self.emit(Op::Xor); + self.emit(Op::Xor, span); self.push(ty); } - pub fn xor_imm(&mut self, imm: Immediate) { + pub fn xor_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected xor operands to be the same type"); assert_eq!(ty, Type::I1, "expected xor operands to be of boolean type"); - self.emit(Op::XorImm(imm.as_bool().unwrap())); + self.emit(Op::XorImm(imm.as_bool().unwrap()), span); self.push(ty); } - pub fn band(&mut self) { + pub fn band(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); @@ -927,28 +943,39 @@ impl<'a> OpEmitter<'a> { // AND the high bits // // [b_hi_hi, b_hi_lo, b_lo_hi, b_lo_lo, a_hi_hi, ..] - self.emit_all(&[ - // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] - Op::Movup(5), - Op::Movup(5), - ]); - self.band_int64(); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] - // AND the low bits - self.emit_all(&[ - // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] - Op::Movdn(5), - Op::Movdn(5), - ]); - self.band_int64(); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] - self.emit_all(&[ - // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] - Op::Movup(3), - Op::Movup(3), - ]); - } - Type::U64 | Type::I64 => self.band_int64(), - Type::U32 | Type::I32 | Type::U16 | Type::I16 | Type::U8 | Type::I8 => self.band_u32(), - Type::I1 => self.emit(Op::And), + self.emit_all( + &[ + // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] + Op::Movup(5), + Op::Movup(5), + ], + span, + ); + self.band_int64(span); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] + // AND the low bits + self.emit_all( + &[ + // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] + Op::Movdn(5), + Op::Movdn(5), + ], + span, + ); + self.band_int64(span); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] + self.emit_all( + &[ + // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] + Op::Movup(3), + Op::Movup(3), + ], + span, + ); + } + Type::U64 | Type::I64 => self.band_int64(span), + Type::U32 | Type::I32 | Type::U16 | Type::I16 | Type::U8 | Type::I8 => { + self.band_u32(span) + } + Type::I1 => self.emit(Op::And, span), ty if !ty.is_integer() => { panic!("invalid binary operand: band expects integer operands, got {ty}") } @@ -957,44 +984,53 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn band_imm(&mut self, imm: Immediate) { + pub fn band_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected band operands to be the same type"); match &ty { Type::U128 | Type::I128 => { - self.push_immediate(imm); + self.push_immediate(imm, span); // AND the high bits // // [b_hi_hi, b_hi_lo, b_lo_hi, b_lo_lo, a_hi_hi, ..] - self.emit_all(&[ - // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] - Op::Movup(5), - Op::Movup(5), - ]); - self.band_int64(); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] - // AND the low bits - self.emit_all(&[ - // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] - Op::Movdn(5), - Op::Movdn(5), - ]); - self.band_int64(); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] - self.emit_all(&[ - // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] - Op::Movup(3), - Op::Movup(3), - ]); + self.emit_all( + &[ + // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] + Op::Movup(5), + Op::Movup(5), + ], + span, + ); + self.band_int64(span); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] + // AND the low bits + self.emit_all( + &[ + // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] + Op::Movdn(5), + Op::Movdn(5), + ], + span, + ); + self.band_int64(span); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] + self.emit_all( + &[ + // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] + Op::Movup(3), + Op::Movup(3), + ], + span, + ); } Type::U64 | Type::I64 => { - self.push_immediate(imm); - self.band_int64(); + self.push_immediate(imm, span); + self.band_int64(span); } - Type::U32 | Type::U16 | Type::U8 => self.band_imm_u32(imm.as_u32().unwrap()), + Type::U32 | Type::U16 | Type::U8 => self.band_imm_u32(imm.as_u32().unwrap(), span), Type::I32 | Type::I16 | Type::I8 => { - self.band_imm_u32(imm.as_i64().unwrap() as u64 as u32) + self.band_imm_u32(imm.as_i64().unwrap() as u64 as u32, span) } - Type::I1 => self.emit(Op::AndImm(imm.as_bool().unwrap())), + Type::I1 => self.emit(Op::AndImm(imm.as_bool().unwrap()), span), ty if !ty.is_integer() => { panic!("invalid binary operand: band expects integer operands, got {ty}") } @@ -1003,7 +1039,7 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn bor(&mut self) { + pub fn bor(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); @@ -1013,28 +1049,39 @@ impl<'a> OpEmitter<'a> { // OR the high bits // // [b_hi_hi, b_hi_lo, b_lo_hi, b_lo_lo, a_hi_hi, ..] - self.emit_all(&[ - // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] - Op::Movup(5), - Op::Movup(5), - ]); - self.bor_int64(); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] - // OR the low bits - self.emit_all(&[ - // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] - Op::Movdn(5), - Op::Movdn(5), - ]); - self.bor_int64(); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] - self.emit_all(&[ - // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] - Op::Movup(3), - Op::Movup(3), - ]); - } - Type::U64 | Type::I64 => self.bor_int64(), - Type::U32 | Type::I32 | Type::U16 | Type::I16 | Type::U8 | Type::I8 => self.bor_u32(), - Type::I1 => self.emit(Op::Or), + self.emit_all( + &[ + // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] + Op::Movup(5), + Op::Movup(5), + ], + span, + ); + self.bor_int64(span); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] + // OR the low bits + self.emit_all( + &[ + // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] + Op::Movdn(5), + Op::Movdn(5), + ], + span, + ); + self.bor_int64(span); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] + self.emit_all( + &[ + // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] + Op::Movup(3), + Op::Movup(3), + ], + span, + ); + } + Type::U64 | Type::I64 => self.bor_int64(span), + Type::U32 | Type::I32 | Type::U16 | Type::I16 | Type::U8 | Type::I8 => { + self.bor_u32(span) + } + Type::I1 => self.emit(Op::Or, span), ty if !ty.is_integer() => { panic!("invalid binary operand: bor expects integer operands, got {ty}") } @@ -1043,44 +1090,53 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn bor_imm(&mut self, imm: Immediate) { + pub fn bor_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected bor operands to be the same type"); match &ty { Type::U128 | Type::I128 => { - self.push_immediate(imm); + self.push_immediate(imm, span); // OR the high bits // // [b_hi_hi, b_hi_lo, b_lo_hi, b_lo_lo, a_hi_hi, ..] - self.emit_all(&[ - // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] - Op::Movup(5), - Op::Movup(5), - ]); - self.bor_int64(); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] - // OR the low bits - self.emit_all(&[ - // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] - Op::Movdn(5), - Op::Movdn(5), - ]); - self.bor_int64(); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] - self.emit_all(&[ - // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] - Op::Movup(3), - Op::Movup(3), - ]); + self.emit_all( + &[ + // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] + Op::Movup(5), + Op::Movup(5), + ], + span, + ); + self.bor_int64(span); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] + // OR the low bits + self.emit_all( + &[ + // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] + Op::Movdn(5), + Op::Movdn(5), + ], + span, + ); + self.bor_int64(span); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] + self.emit_all( + &[ + // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] + Op::Movup(3), + Op::Movup(3), + ], + span, + ); } Type::U64 | Type::I64 => { - self.push_immediate(imm); - self.bor_int64(); + self.push_immediate(imm, span); + self.bor_int64(span); } - Type::U32 | Type::U16 | Type::U8 => self.bor_imm_u32(imm.as_u32().unwrap()), + Type::U32 | Type::U16 | Type::U8 => self.bor_imm_u32(imm.as_u32().unwrap(), span), Type::I32 | Type::I16 | Type::I8 => { - self.bor_imm_u32(imm.as_i64().unwrap() as u64 as u32) + self.bor_imm_u32(imm.as_i64().unwrap() as u64 as u32, span) } - Type::I1 => self.emit(Op::AndImm(imm.as_bool().unwrap())), + Type::I1 => self.emit(Op::AndImm(imm.as_bool().unwrap()), span), ty if !ty.is_integer() => { panic!("invalid binary operand: bor expects integer operands, got {ty}") } @@ -1089,7 +1145,7 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn bxor(&mut self) { + pub fn bxor(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); @@ -1099,32 +1155,41 @@ impl<'a> OpEmitter<'a> { // XOR the high bits // // [b_hi_hi, b_hi_lo, b_lo_hi, b_lo_lo, a_hi_hi, ..] - self.emit_all(&[ - // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] - Op::Movup(5), - Op::Movup(5), - ]); - self.bxor_int64(); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] - // XOR the low bits - self.emit_all(&[ - // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] - Op::Movdn(5), - Op::Movdn(5), - ]); - self.bxor_int64(); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] - self.emit_all(&[ - // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] - Op::Movup(3), - Op::Movup(3), - ]); - } - Type::U64 | Type::I64 => self.bxor_int64(), - Type::U32 | Type::I32 => self.bxor_u32(), + self.emit_all( + &[ + // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] + Op::Movup(5), + Op::Movup(5), + ], + span, + ); + self.bxor_int64(span); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] + // XOR the low bits + self.emit_all( + &[ + // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] + Op::Movdn(5), + Op::Movdn(5), + ], + span, + ); + self.bxor_int64(span); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] + self.emit_all( + &[ + // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] + Op::Movup(3), + Op::Movup(3), + ], + span, + ); + } + Type::U64 | Type::I64 => self.bxor_int64(span), + Type::U32 | Type::I32 => self.bxor_u32(span), ty @ (Type::U16 | Type::I16 | Type::U8 | Type::I8) => { - self.bxor_u32(); - self.trunc_int32(ty.size_in_bits() as u32); + self.bxor_u32(span); + self.trunc_int32(ty.size_in_bits() as u32, span); } - Type::I1 => self.emit(Op::Xor), + Type::I1 => self.emit(Op::Xor, span), ty if !ty.is_integer() => { panic!("invalid binary operand: bxor expects integer operands, got {ty}") } @@ -1133,50 +1198,59 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn bxor_imm(&mut self, imm: Immediate) { + pub fn bxor_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected bxor operands to be the same type"); match &ty { Type::U128 | Type::I128 => { - self.push_immediate(imm); + self.push_immediate(imm, span); // XOR the high bits // // [b_hi_hi, b_hi_lo, b_lo_hi, b_lo_lo, a_hi_hi, ..] - self.emit_all(&[ - // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] - Op::Movup(5), - Op::Movup(5), - ]); - self.bxor_int64(); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] - // XOR the low bits - self.emit_all(&[ - // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] - Op::Movdn(5), - Op::Movdn(5), - ]); - self.bxor_int64(); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] - self.emit_all(&[ - // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] - Op::Movup(3), - Op::Movup(3), - ]); + self.emit_all( + &[ + // [a_hi_hi, a_hi_lo, b_hi_hi, b_hi_lo, ..] + Op::Movup(5), + Op::Movup(5), + ], + span, + ); + self.bxor_int64(span); // [band_hi_hi, band_hi_lo, b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo] + // XOR the low bits + self.emit_all( + &[ + // [b_lo_hi, b_lo_lo, a_lo_hi, a_lo_lo, band_hi_hi, band_hi_lo] + Op::Movdn(5), + Op::Movdn(5), + ], + span, + ); + self.bxor_int64(span); // [band_lo_hi, band_lo_lo, band_hi_hi, band_hi_lo] + self.emit_all( + &[ + // [band_hi_hi, band_hi_lo, band_lo_hi, band_lo_lo] + Op::Movup(3), + Op::Movup(3), + ], + span, + ); } Type::U64 | Type::I64 => { - self.push_immediate(imm); - self.bxor_int64(); + self.push_immediate(imm, span); + self.bxor_int64(span); } - Type::U32 => self.bxor_imm_u32(imm.as_u32().unwrap()), - Type::I32 => self.bxor_imm_u32(imm.as_i64().unwrap() as u64 as u32), + Type::U32 => self.bxor_imm_u32(imm.as_u32().unwrap(), span), + Type::I32 => self.bxor_imm_u32(imm.as_i64().unwrap() as u64 as u32, span), ty @ (Type::U16 | Type::U8) => { - self.bxor_imm_u32(imm.as_u32().unwrap()); - self.trunc_int32(ty.size_in_bits() as u32); + self.bxor_imm_u32(imm.as_u32().unwrap(), span); + self.trunc_int32(ty.size_in_bits() as u32, span); } ty @ (Type::I16 | Type::I8) => { - self.bxor_imm_u32(imm.as_i64().unwrap() as u64 as u32); - self.trunc_int32(ty.size_in_bits() as u32); + self.bxor_imm_u32(imm.as_i64().unwrap() as u64 as u32, span); + self.trunc_int32(ty.size_in_bits() as u32, span); } - Type::I1 => self.emit(Op::XorImm(imm.as_bool().unwrap())), + Type::I1 => self.emit(Op::XorImm(imm.as_bool().unwrap()), span), ty if !ty.is_integer() => { panic!("invalid binary operand: bxor expects integer operands, got {ty}") } @@ -1185,17 +1259,17 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn shl(&mut self) { + pub fn shl(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(rhs.ty(), Type::U32, "expected shift operand to be u32"); match &ty { - Type::U64 | Type::I64 => self.shl_u64(), - Type::U32 | Type::I32 => self.shl_u32(), + Type::U64 | Type::I64 => self.shl_u64(span), + Type::U32 | Type::I32 => self.shl_u32(span), ty @ (Type::U16 | Type::I16 | Type::U8 | Type::I8) => { - self.shl_u32(); - self.trunc_int32(ty.size_in_bits() as u32); + self.shl_u32(span); + self.trunc_int32(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: shl expects integer operands, got {ty}") @@ -1205,21 +1279,21 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn shl_imm(&mut self, imm: Immediate) { + pub fn shl_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(imm.ty(), Type::U32, "expected shift operand to be u32"); match &ty { Type::U64 | Type::I64 => { assert!(imm.as_u32().unwrap() < 64, "invalid shift value: must be < 64"); - self.push_immediate(imm); - self.shl_u64(); + self.push_immediate(imm, span); + self.shl_u64(span); } - Type::U32 => self.shl_imm_u32(imm.as_u32().unwrap()), - Type::I32 => self.shl_imm_u32(imm.as_u32().unwrap()), + Type::U32 => self.shl_imm_u32(imm.as_u32().unwrap(), span), + Type::I32 => self.shl_imm_u32(imm.as_u32().unwrap(), span), ty @ (Type::U16 | Type::I16 | Type::U8 | Type::I8) => { - self.shl_imm_u32(imm.as_u32().unwrap()); - self.trunc_int32(ty.size_in_bits() as u32); + self.shl_imm_u32(imm.as_u32().unwrap(), span); + self.trunc_int32(ty.size_in_bits() as u32, span); } ty if !ty.is_integer() => { panic!("invalid binary operand: shl expects integer operands, got {ty}") @@ -1229,16 +1303,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn shr(&mut self) { + pub fn shr(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(rhs.ty(), Type::U32, "expected shift operand to be u32"); match &ty { - Type::U64 => self.shr_u64(), - Type::I64 => self.shr_i64(), - Type::U32 | Type::U16 | Type::U8 => self.shr_u32(), - Type::I32 => self.shr_i32(), + Type::U64 => self.shr_u64(span), + Type::I64 => self.shr_i64(span), + Type::U32 | Type::U16 | Type::U8 => self.shr_u32(span), + Type::I32 => self.shr_i32(span), ty if !ty.is_integer() => { panic!("invalid binary operand: shr expects integer operands, got {ty}") } @@ -1247,7 +1321,7 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn shr_imm(&mut self, imm: Immediate) { + pub fn shr_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(imm.ty(), Type::U32, "expected shift operand to be u32"); @@ -1255,12 +1329,12 @@ impl<'a> OpEmitter<'a> { Type::U64 => { let shift = imm.as_u32().unwrap(); assert!(shift < 64, "invalid shift value: must be < 64, got {shift}"); - self.push_immediate(imm); - self.shr_u64(); + self.push_immediate(imm, span); + self.shr_u64(span); } - Type::I64 => self.shr_imm_i64(imm.as_u32().unwrap()), - Type::U32 | Type::U16 | Type::U8 => self.shr_imm_u32(imm.as_u32().unwrap()), - Type::I32 => self.shr_imm_i32(imm.as_u32().unwrap()), + Type::I64 => self.shr_imm_i64(imm.as_u32().unwrap(), span), + Type::U32 | Type::U16 | Type::U8 => self.shr_imm_u32(imm.as_u32().unwrap(), span), + Type::I32 => self.shr_imm_i32(imm.as_u32().unwrap(), span), ty if !ty.is_integer() => { panic!("invalid binary operand: shr expects integer operands, got {ty}") } @@ -1269,14 +1343,14 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn rotl(&mut self) { + pub fn rotl(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(rhs.ty(), Type::U32, "expected shift operand to be u32"); match &ty { - Type::U64 | Type::I64 => self.rotl_u64(), - Type::U32 | Type::I32 => self.rotl_u32(), + Type::U64 | Type::I64 => self.rotl_u64(span), + Type::U32 | Type::I32 => self.rotl_u32(span), ty if !ty.is_integer() => { panic!("invalid binary operand: rotl expects integer operands, got {ty}") } @@ -1285,16 +1359,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn rotl_imm(&mut self, imm: Immediate) { + pub fn rotl_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(imm.ty(), Type::U32, "expected shift operand to be u32"); match &ty { Type::U64 | Type::I64 => { - self.push_immediate(imm); - self.rotl_u64(); + self.push_immediate(imm, span); + self.rotl_u64(span); } - Type::U32 | Type::I32 => self.rotl_imm_u32(imm.as_u32().unwrap()), + Type::U32 | Type::I32 => self.rotl_imm_u32(imm.as_u32().unwrap(), span), ty if !ty.is_integer() => { panic!("invalid binary operand: rotl expects integer operands, got {ty}") } @@ -1303,14 +1377,14 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn rotr(&mut self) { + pub fn rotr(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(rhs.ty(), Type::U32, "expected shift operand to be u32"); match &ty { - Type::U64 | Type::I64 => self.rotr_u64(), - Type::U32 | Type::I32 => self.rotr_u32(), + Type::U64 | Type::I64 => self.rotr_u64(span), + Type::U32 | Type::I32 => self.rotr_u32(span), ty if !ty.is_integer() => { panic!("invalid binary operand: rotr expects integer operands, got {ty}") } @@ -1319,16 +1393,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn rotr_imm(&mut self, imm: Immediate) { + pub fn rotr_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(imm.ty(), Type::U32, "expected shift operand to be u32"); match &ty { Type::U64 | Type::I64 => { - self.push_immediate(imm); - self.rotr_u64(); + self.push_immediate(imm, span); + self.rotr_u64(span); } - Type::U32 | Type::I32 => self.rotr_imm_u32(imm.as_u32().unwrap()), + Type::U32 | Type::I32 => self.rotr_imm_u32(imm.as_u32().unwrap(), span), ty if !ty.is_integer() => { panic!("invalid binary operand: rotr expects integer operands, got {ty}") } @@ -1337,16 +1411,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn min(&mut self) { + pub fn min(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected min operands to be the same type"); match &ty { - Type::U64 => self.min_u64(), - Type::I64 => self.min_i64(), - Type::U32 | Type::U16 | Type::U8 | Type::I1 => self.min_u32(), - Type::I32 => self.min_i32(), + Type::U64 => self.min_u64(span), + Type::I64 => self.min_i64(span), + Type::U32 | Type::U16 | Type::U8 | Type::I1 => self.min_u32(span), + Type::I32 => self.min_i32(span), ty if !ty.is_integer() => { panic!("invalid binary operand: min expects integer operands, got {ty}") } @@ -1355,18 +1429,20 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn min_imm(&mut self, imm: Immediate) { + pub fn min_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected min operands to be the same type"); match &ty { Type::U64 => { - self.push_immediate(imm); - self.min_u64(); + self.push_immediate(imm, span); + self.min_u64(span); } - Type::I64 => self.min_imm_i64(imm.as_i64().unwrap()), - Type::U32 | Type::U16 | Type::U8 | Type::I1 => self.min_imm_u32(imm.as_u32().unwrap()), - Type::I32 => self.min_imm_i32(imm.as_i32().unwrap()), + Type::I64 => self.min_imm_i64(imm.as_i64().unwrap(), span), + Type::U32 | Type::U16 | Type::U8 | Type::I1 => { + self.min_imm_u32(imm.as_u32().unwrap(), span) + } + Type::I32 => self.min_imm_i32(imm.as_i32().unwrap(), span), ty if !ty.is_integer() => { panic!("invalid binary operand: min expects integer operands, got {ty}") } @@ -1375,16 +1451,16 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn max(&mut self) { + pub fn max(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, rhs.ty(), "expected max operands to be the same type"); match &ty { - Type::U64 => self.max_u64(), - Type::I64 => self.max_i64(), - Type::U32 | Type::U16 | Type::U8 | Type::I1 => self.max_u32(), - Type::I32 => self.max_i32(), + Type::U64 => self.max_u64(span), + Type::I64 => self.max_i64(span), + Type::U32 | Type::U16 | Type::U8 | Type::I1 => self.max_u32(span), + Type::I32 => self.max_i32(span), ty if !ty.is_integer() => { panic!("invalid binary operand: max expects integer operands, got {ty}") } @@ -1393,18 +1469,20 @@ impl<'a> OpEmitter<'a> { self.push(ty); } - pub fn max_imm(&mut self, imm: Immediate) { + pub fn max_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected max operands to be the same type"); match &ty { Type::U64 => { - self.push_immediate(imm); - self.max_u64(); + self.push_immediate(imm, span); + self.max_u64(span); + } + Type::I64 => self.max_imm_i64(imm.as_i64().unwrap(), span), + Type::U32 | Type::U16 | Type::U8 | Type::I1 => { + self.max_imm_u32(imm.as_u32().unwrap(), span) } - Type::I64 => self.max_imm_i64(imm.as_i64().unwrap()), - Type::U32 | Type::U16 | Type::U8 | Type::I1 => self.max_imm_u32(imm.as_u32().unwrap()), - Type::I32 => self.max_imm_i32(imm.as_i32().unwrap()), + Type::I32 => self.max_imm_i32(imm.as_i32().unwrap(), span), ty if !ty.is_integer() => { panic!("invalid binary operand: max expects integer operands, got {ty}") } diff --git a/codegen/masm/src/codegen/emit/felt.rs b/codegen/masm/src/codegen/emit/felt.rs index 3e25c15e..886bc39e 100644 --- a/codegen/masm/src/codegen/emit/felt.rs +++ b/codegen/masm/src/codegen/emit/felt.rs @@ -1,4 +1,4 @@ -use midenc_hir::{Felt, FieldElement}; +use midenc_hir::{Felt, FieldElement, SourceSpan}; use super::OpEmitter; use crate::masm::Op; @@ -19,8 +19,8 @@ impl<'a> OpEmitter<'a> { /// /// `[a, ..] => [a == 0, a, ..]` #[inline(always)] - pub fn felt_is_zero(&mut self) { - self.emit_all(&[Op::Dup(0), Op::EqImm(ZERO)]); + pub fn felt_is_zero(&mut self, span: SourceSpan) { + self.emit_all(&[Op::Dup(0), Op::EqImm(ZERO)], span); } /// This operation asserts the field element on top of the stack is zero. @@ -31,8 +31,8 @@ impl<'a> OpEmitter<'a> { /// /// `[a, ..] => [a, ..]` #[inline(always)] - pub fn assert_felt_is_zero(&mut self) { - self.emit_all(&[Op::Dup(0), Op::Assertz]); + pub fn assert_felt_is_zero(&mut self, span: SourceSpan) { + self.emit_all(&[Op::Dup(0), Op::Assertz], span); } /// Convert a field element to i128 by zero-extension. @@ -43,8 +43,8 @@ impl<'a> OpEmitter<'a> { /// /// `[a, ..] => [0, 0, a_hi, a_lo]` #[inline] - pub fn felt_to_i128(&mut self) { - self.emit_all(&[Op::U32Split, Op::Push2([ZERO, ZERO])]); + pub fn felt_to_i128(&mut self, span: SourceSpan) { + self.emit_all(&[Op::U32Split, Op::Push2([ZERO, ZERO])], span); } /// Convert a field element to u64 by zero-extension. @@ -55,8 +55,8 @@ impl<'a> OpEmitter<'a> { /// /// `[a, ..] => [a_hi, a_lo]` #[inline(always)] - pub fn felt_to_u64(&mut self) { - self.emit(Op::U32Split); + pub fn felt_to_u64(&mut self, span: SourceSpan) { + self.emit(Op::U32Split, span); } /// Convert a field element to i64 by zero-extension. @@ -69,58 +69,64 @@ impl<'a> OpEmitter<'a> { /// /// `[a, ..] => [a_hi, a_lo]` #[inline(always)] - pub fn felt_to_i64(&mut self) { - self.felt_to_u64(); + pub fn felt_to_i64(&mut self, span: SourceSpan) { + self.felt_to_u64(span); } /// Convert a field element value to an unsigned N-bit integer, where N <= 32 /// /// Conversion will trap if the input value is too large to fit in an unsigned N-bit integer. - pub fn felt_to_uint(&mut self, n: u32) { + pub fn felt_to_uint(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); - self.emit_all(&[ - // Split into u32 limbs - Op::U32Split, - // Assert most significant 32 bits are unused - Op::Assertz, - ]); + self.emit_all( + &[ + // Split into u32 limbs + Op::U32Split, + // Assert most significant 32 bits are unused + Op::Assertz, + ], + span, + ); if n < 32 { // Convert to N-bit integer - self.int32_to_uint(n); + self.int32_to_uint(n, span); } } /// Convert a field element value to a signed N-bit integer, where N <= 32 /// /// Conversion will trap if the input value is too large to fit in a signed N-bit integer. - pub fn felt_to_int(&mut self, n: u32) { + pub fn felt_to_int(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); - self.emit_all(&[ - // Split into u32 limbs - Op::U32Split, - // Assert most significant 32 bits are unused - Op::Assertz, - ]); + self.emit_all( + &[ + // Split into u32 limbs + Op::U32Split, + // Assert most significant 32 bits are unused + Op::Assertz, + ], + span, + ); // Assert the sign bit isn't set - self.assert_unsigned_int32(); + self.assert_unsigned_int32(span); if n < 32 { // Convert to signed N-bit integer - self.int32_to_int(n); + self.int32_to_int(n, span); } } /// Zero-extend a field element value to N-bits, where N >= 64 /// /// N must be a power of two, or this function will panic. - pub fn zext_felt(&mut self, n: u32) { + pub fn zext_felt(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 64, 256); match n { - 64 => self.felt_to_u64(), - 128 => self.felt_to_i128(), + 64 => self.felt_to_u64(span), + 128 => self.felt_to_i128(span), n => { // Convert to u64 and zero-extend - self.felt_to_u64(); - self.zext_int64(n); + self.felt_to_u64(span); + self.zext_int64(n, span); } } } @@ -131,15 +137,15 @@ impl<'a> OpEmitter<'a> { /// integer type is a signed type, so we have one less bit available to use. /// /// N must be a power of two, or this function will panic. - pub fn sext_felt(&mut self, n: u32) { + pub fn sext_felt(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 64, 256); match n { - 64 => self.felt_to_i64(), - 128 => self.felt_to_i128(), + 64 => self.felt_to_i64(span), + 128 => self.felt_to_i128(span), n => { // Convert to i64 and sign-extend - self.felt_to_i64(); - self.sext_int64(n); + self.felt_to_i64(span); + self.sext_int64(n, span); } } } @@ -154,17 +160,17 @@ impl<'a> OpEmitter<'a> { /// This should produce outputs which are identical to equivalent u64 values, i.e. the same /// value in both u64 and felt representation will be truncated to the same u32 value. #[inline] - pub fn trunc_felt(&mut self, n: u32) { + pub fn trunc_felt(&mut self, n: u32, span: SourceSpan) { // Apply a field modulus of 2^32, i.e. `a mod 2^32`, converting // the field element into the u32 range. Miden defines values in // this range as having a standard unsigned binary representation. - self.emit(Op::U32Cast); - self.trunc_int32(n); + self.emit(Op::U32Cast, span); + self.trunc_int32(n, span); } /// Make `n` copies of the element on top of the stack #[inline(always)] - pub fn dup_felt(&mut self, count: u8) { - self.emit_n(count as usize, Op::Dup(0)); + pub fn dup_felt(&mut self, count: u8, span: SourceSpan) { + self.emit_n(count as usize, Op::Dup(0), span); } } diff --git a/codegen/masm/src/codegen/emit/int128.rs b/codegen/masm/src/codegen/emit/int128.rs index a3427822..16f44940 100644 --- a/codegen/masm/src/codegen/emit/int128.rs +++ b/codegen/masm/src/codegen/emit/int128.rs @@ -1,3 +1,5 @@ +use midenc_hir::SourceSpan; + use super::OpEmitter; use crate::masm::Op; @@ -5,21 +7,21 @@ use crate::masm::Op; impl<'a> OpEmitter<'a> { /// Checks if the i128 value on the stack has its sign bit set. #[inline(always)] - pub fn is_signed_int128(&mut self) { - self.is_signed_int32() + pub fn is_signed_int128(&mut self, span: SourceSpan) { + self.is_signed_int32(span) } /// Assert that the i128 value on the stack does not have its sign bit set. #[inline(always)] - pub fn assert_unsigned_int128(&mut self) { + pub fn assert_unsigned_int128(&mut self, span: SourceSpan) { // Assert that the sign bit is unset - self.assert_unsigned_int32() + self.assert_unsigned_int32(span) } /// Push a u128 value on the operand stack /// /// An u128 value consists of 4 32-bit limbs - pub fn push_u128(&mut self, value: u128) { + pub fn push_u128(&mut self, value: u128, span: SourceSpan) { let bytes = value.to_le_bytes(); let hi = u64::from_le_bytes([ bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], @@ -27,14 +29,14 @@ impl<'a> OpEmitter<'a> { let lo = u64::from_le_bytes([ bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15], ]); - self.push_u64(lo); - self.push_u64(hi); + self.push_u64(lo, span); + self.push_u64(hi, span); } /// Push an i128 value on the operand stack /// /// An i128 value consists of 4 32-bit limbs - pub fn push_i128(&mut self, value: i128) { + pub fn push_i128(&mut self, value: i128, span: SourceSpan) { let bytes = value.to_le_bytes(); let hi = u64::from_le_bytes([ bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], @@ -42,8 +44,8 @@ impl<'a> OpEmitter<'a> { let lo = u64::from_le_bytes([ bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15], ]); - self.push_u64(lo); - self.push_u64(hi); + self.push_u64(lo, span); + self.push_u64(hi, span); } /// Convert an i128 value to a field element value. @@ -56,11 +58,11 @@ impl<'a> OpEmitter<'a> { /// /// NOTE: This function does not validate the i128, the caller is expected to /// have already validated that the top of the stack holds a valid i128. - pub fn int128_to_felt(&mut self) { + pub fn int128_to_felt(&mut self, span: SourceSpan) { // First, convert to u64 - self.int128_to_u64(); + self.int128_to_u64(span); // Then convert the u64 to felt - self.u64_to_felt(); + self.u64_to_felt(span); } /// Convert a 128-bit value to u64 @@ -72,12 +74,12 @@ impl<'a> OpEmitter<'a> { /// /// NOTE: This function does not validate the i128, the caller is expected to /// have already validated that the top of the stack holds a valid i128. - pub fn int128_to_u64(&mut self) { + pub fn int128_to_u64(&mut self, span: SourceSpan) { // Assert the first two limbs are equal to 0 // // What remains on the stack at this point are the low 64-bits, // which is also our result. - self.emit_n(2, Op::Assertz); + self.emit_n(2, Op::Assertz, span); } /// Convert a 128-bit value to u32 @@ -89,12 +91,12 @@ impl<'a> OpEmitter<'a> { /// /// NOTE: This function does not validate the i128, the caller is expected to /// have already validated that the top of the stack holds a valid i128. - pub fn int128_to_u32(&mut self) { + pub fn int128_to_u32(&mut self, span: SourceSpan) { // Assert the first three limbs are equal to 0 // // What remains on the stack at this point are the low 32-bits, // which is also our result. - self.emit_n(3, Op::Assertz); + self.emit_n(3, Op::Assertz, span); } /// Convert a unsigned 128-bit value to i64 @@ -106,11 +108,11 @@ impl<'a> OpEmitter<'a> { /// /// NOTE: This function does not validate the i128, the caller is expected to /// have already validated that the top of the stack holds a valid i128. - pub fn u128_to_i64(&mut self) { + pub fn u128_to_i64(&mut self, span: SourceSpan) { // Truncate the first 64-bits, so long as those bits are zero - self.int128_to_u64(); + self.int128_to_u64(span); // Ensure that the remaining 64 bits are a valid non-negative i64 value - self.assert_unsigned_int64(); + self.assert_unsigned_int64(span); } /// Convert an i128 value to i64 @@ -122,39 +124,45 @@ impl<'a> OpEmitter<'a> { /// /// NOTE: This function does not validate the i128, the caller is expected to /// have already validated that the top of the stack holds a valid i128. - pub fn i128_to_i64(&mut self) { + pub fn i128_to_i64(&mut self, span: SourceSpan) { // Determine if this value is signed or not - self.is_signed_int32(); + self.is_signed_int32(span); // Preserving the is_signed flag, select the expected hi bits value - self.emit(Op::Dup(0)); - self.select_int32(u32::MAX, 0); + self.emit(Op::Dup(0), span); + self.select_int32(u32::MAX, 0, span); // Move the most significant 64 bits to top of stack - self.move_int64_up(2); + self.move_int64_up(2, span); // Move expected value to top of stack - self.emit(Op::Movup(2)); + self.emit(Op::Movup(2), span); // Assert the most significant 32 bits match, without consuming them - self.assert_eq_u32(); - self.emit_all(&[ - // Assert that both 32-bit limbs of the most significant 64 bits match, - // consuming them in the process - Op::AssertEq, - // At this point, the stack is: [is_signed, x1, x0] - // - // Select an expected value for the sign bit based on the is_signed flag - Op::Swap(1), - ]); + self.assert_eq_u32(span); + self.emit_all( + &[ + // Assert that both 32-bit limbs of the most significant 64 bits match, + // consuming them in the process + Op::AssertEq, + // At this point, the stack is: [is_signed, x1, x0] + // + // Select an expected value for the sign bit based on the is_signed flag + Op::Swap(1), + ], + span, + ); // [is_sign_bit_set, x1, is_signed, x0] - self.is_const_flag_set_u32(1 << 31); - self.emit_all(&[ - // [is_signed, is_sign_bit_set, x1, x0] - Op::Movup(2), - // Assert that the flags are equal: either the input was signed and the - // sign bit was set, or the input was unsigned, and the sign bit was unset, - // any other combination will trap. - // - // [x1, x0] - Op::AssertEq, - ]); + self.is_const_flag_set_u32(1 << 31, span); + self.emit_all( + &[ + // [is_signed, is_sign_bit_set, x1, x0] + Op::Movup(2), + // Assert that the flags are equal: either the input was signed and the + // sign bit was set, or the input was unsigned, and the sign bit was unset, + // any other combination will trap. + // + // [x1, x0] + Op::AssertEq, + ], + span, + ); } /// Truncate this i128 value to a felt value @@ -163,9 +171,9 @@ impl<'a> OpEmitter<'a> { /// /// NOTE: This function does not validate the i128, that is left up to the caller. #[inline] - pub fn trunc_i128_to_felt(&mut self) { - self.emit_n(2, Op::Drop); - self.trunc_int64_to_felt(); + pub fn trunc_i128_to_felt(&mut self, span: SourceSpan) { + self.emit_n(2, Op::Drop, span); + self.trunc_int64_to_felt(span); } /// Truncate this i128 value to N bits, where N is <= 64 @@ -177,17 +185,17 @@ impl<'a> OpEmitter<'a> { /// /// NOTE: This function does not validate the i128 value, that is left up to the caller. #[inline] - pub fn trunc_i128(&mut self, n: u32) { + pub fn trunc_i128(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 64); match n { 64 => { - self.emit_n(2, Op::Drop); + self.emit_n(2, Op::Drop, span); } 32 => { - self.emit_n(3, Op::Drop); + self.emit_n(3, Op::Drop, span); } n => { - self.trunc_int32(n); + self.trunc_int32(n, span); } } } @@ -195,22 +203,25 @@ impl<'a> OpEmitter<'a> { /// Pop two i128 values, `b` and `a`, off the operand stack, and place the result of `a == b` on /// the stack. #[inline] - pub fn eq_i128(&mut self) { - self.emit_all(&[ - Op::Eqw, - // Move the boolean below the elements we're going to drop - Op::Movdn(8), - // Drop both i128 values - Op::Dropw, - Op::Dropw, - ]); + pub fn eq_i128(&mut self, span: SourceSpan) { + self.emit_all( + &[ + Op::Eqw, + // Move the boolean below the elements we're going to drop + Op::Movdn(8), + // Drop both i128 values + Op::Dropw, + Op::Dropw, + ], + span, + ); } /// Pop two i128 values, `b` and `a`, off the operand stack, and place the result of `a == b` on /// the stack. #[inline] - pub fn neq_i128(&mut self) { - self.eq_i128(); - self.emit(Op::Not); + pub fn neq_i128(&mut self, span: SourceSpan) { + self.eq_i128(span); + self.emit(Op::Not, span); } } diff --git a/codegen/masm/src/codegen/emit/int32.rs b/codegen/masm/src/codegen/emit/int32.rs index 233fe0d3..3fcf06ff 100644 --- a/codegen/masm/src/codegen/emit/int32.rs +++ b/codegen/masm/src/codegen/emit/int32.rs @@ -1,4 +1,4 @@ -use midenc_hir::{Felt, FieldElement, Overflow}; +use midenc_hir::{Felt, FieldElement, Overflow, SourceSpan}; use super::{felt, OpEmitter}; use crate::masm::Op; @@ -18,8 +18,8 @@ impl<'a> OpEmitter<'a> { /// /// `[a, ..] => [a & mask, ..]` #[inline] - pub fn const_mask_u32(&mut self, mask: u32) { - self.emit_all(&[Op::PushU32(mask), Op::U32And]); + pub fn const_mask_u32(&mut self, mask: u32, span: SourceSpan) { + self.emit_all(&[Op::PushU32(mask), Op::U32And], span); } /// Emits code to apply a 32-bit mask, `mask`, to a u32 value, `input`. @@ -34,8 +34,8 @@ impl<'a> OpEmitter<'a> { /// /// `[mask, input, ..] => [input & mask, input]` #[inline] - pub fn mask_u32(&mut self) { - self.emit_all(&[Op::Dup(1), Op::U32And]); + pub fn mask_u32(&mut self, span: SourceSpan) { + self.emit_all(&[Op::Dup(1), Op::U32And], span); } /// Emits code to check if all bits of `flags` are set in the u32 value on top of the stack. @@ -49,10 +49,10 @@ impl<'a> OpEmitter<'a> { /// /// `[a, ..] => [a & flags == flags, a]` #[inline] - pub fn is_const_flag_set_u32(&mut self, flags: u32) { - self.emit(Op::Dup(0)); - self.const_mask_u32(flags); - self.emit(Op::EqImm(Felt::new(flags as u64))); + pub fn is_const_flag_set_u32(&mut self, flags: u32, span: SourceSpan) { + self.emit(Op::Dup(0), span); + self.const_mask_u32(flags, span); + self.emit(Op::EqImm(Felt::new(flags as u64)), span); } /// Emits code to check if all bits of `mask` are set in `input`. @@ -67,13 +67,16 @@ impl<'a> OpEmitter<'a> { /// /// `[mask, input, ..] => [input & mask == mask, input]` #[inline] - pub fn is_flag_set_u32(&mut self) { - self.emit_all(&[ - Op::Dup(1), // [input, mask, input] - Op::Dup(1), // [mask, input, mask, input] - Op::U32And, // [input & mask, mask, input] - Op::Eq, // [input & mask == mask, input] - ]); + pub fn is_flag_set_u32(&mut self, span: SourceSpan) { + self.emit_all( + &[ + Op::Dup(1), // [input, mask, input] + Op::Dup(1), // [mask, input, mask, input] + Op::U32And, // [input & mask, mask, input] + Op::Eq, // [input & mask == mask, input] + ], + span, + ); } /// Check if a 32-bit integer value on the operand stack has its sign bit set. @@ -82,17 +85,17 @@ impl<'a> OpEmitter<'a> { /// /// See `is_const_flag_set` for semantics and stack effects. #[inline] - pub fn is_signed_int32(&mut self) { - self.is_const_flag_set_u32(SIGN_BIT); + pub fn is_signed_int32(&mut self, span: SourceSpan) { + self.is_const_flag_set_u32(SIGN_BIT, span); } /// Check if a 32-bit integer value on the operand stack does not have its sign bit set. /// /// The value on top of the stack IS NOT consumed. #[inline(always)] - pub fn is_unsigned_int32(&mut self) { - self.is_signed_int32(); - self.emit(Op::Not); + pub fn is_unsigned_int32(&mut self, span: SourceSpan) { + self.is_signed_int32(span); + self.emit(Op::Not, span); } /// Emits code to assert that a 32-bit value on the operand stack has the i32 sign bit set. @@ -101,9 +104,9 @@ impl<'a> OpEmitter<'a> { /// /// See `is_signed` for semantics and stack effects of the signedness check. #[inline] - pub fn assert_signed_int32(&mut self) { - self.is_signed_int32(); - self.emit(Op::Assert); + pub fn assert_signed_int32(&mut self, span: SourceSpan) { + self.is_signed_int32(span); + self.emit(Op::Assert, span); } /// Emits code to assert that a 32-bit value on the operand stack does not have the i32 sign bit @@ -113,21 +116,21 @@ impl<'a> OpEmitter<'a> { /// /// See `is_signed` for semantics and stack effects of the signedness check. #[inline] - pub fn assert_unsigned_int32(&mut self) { - self.is_signed_int32(); - self.emit(Op::Assertz); + pub fn assert_unsigned_int32(&mut self, span: SourceSpan) { + self.is_signed_int32(span); + self.emit(Op::Assertz, span); } /// Assert that the 32-bit value on the stack is a valid i32 value - pub fn assert_i32(&mut self) { + pub fn assert_i32(&mut self, span: SourceSpan) { // Copy the value on top of the stack - self.emit(Op::Dup(0)); + self.emit(Op::Dup(0), span); // Assert the value does not overflow i32::MAX or underflow i32::MIN // This can be checked by validating that when interpreted as a u32, // the value is <= i32::MIN, which is 1 more than i32::MAX. - self.push_i32(i32::MIN); - self.emit(Op::U32Lte); - self.emit(Op::Assert); + self.push_i32(i32::MIN, span); + self.emit(Op::U32Lte, span); + self.emit(Op::Assert, span); } /// Emits code to assert that a 32-bit value on the operand stack is equal to the given constant @@ -139,8 +142,8 @@ impl<'a> OpEmitter<'a> { /// /// `[input, ..] => [input, ..]` #[inline] - pub fn assert_eq_imm_u32(&mut self, value: u32) { - self.emit_all(&[Op::Dup(0), Op::EqImm(Felt::new(value as u64)), Op::Assert]); + pub fn assert_eq_imm_u32(&mut self, value: u32, span: SourceSpan) { + self.emit_all(&[Op::Dup(0), Op::EqImm(Felt::new(value as u64)), Op::Assert], span); } /// Emits code to assert that two 32-bit values, `expected` and `value`, on top of the operand @@ -152,8 +155,8 @@ impl<'a> OpEmitter<'a> { /// /// `[expected, input, ..] => [input, ..]` #[inline] - pub fn assert_eq_u32(&mut self) { - self.emit_all(&[Op::Dup(1), Op::AssertEq]); + pub fn assert_eq_u32(&mut self, span: SourceSpan) { + self.emit_all(&[Op::Dup(1), Op::AssertEq], span); } /// Emits code to select a constant u32 value, using the `n`th value on the operand @@ -164,15 +167,15 @@ impl<'a> OpEmitter<'a> { /// all three operands, placing only a single value back on the operand stack; the /// selected value, either `a` or `b`. Use `dup_select` if you would rather copy /// the conditional rather than move it. - pub fn mov_select_int32(&mut self, a: u32, b: u32, n: u8) { + pub fn mov_select_int32(&mut self, a: u32, b: u32, n: u8, span: SourceSpan) { assert_valid_stack_index!(n); // If the value we need will get pushed off the end of the stack, // bring it closer first, and adjust our `n` accordingly if n > 13 { - self.emit(Op::Movup(n)); - self.select_int32(a, b); + self.emit(Op::Movup(n), span); + self.select_int32(a, b, span); } else { - self.emit_all(&[Op::PushU32(b), Op::PushU32(a), Op::Movup(n + 2), Op::Cdrop]); + self.emit_all(&[Op::PushU32(b), Op::PushU32(a), Op::Movup(n + 2), Op::Cdrop], span); } } @@ -183,15 +186,15 @@ impl<'a> OpEmitter<'a> { /// /// Moves `c` to the top of the stack, where `c` is the `n`th value on the operand stack, /// then applies `select`. - pub fn dup_select_int32(&mut self, a: u32, b: u32, n: u8) { + pub fn dup_select_int32(&mut self, a: u32, b: u32, n: u8, span: SourceSpan) { assert_valid_stack_index!(n); // If the value we need will get pushed off the end of the stack, // bring it closer first, and adjust our `n` accordingly if n > 13 { - self.emit(Op::Dup(n)); - self.select_int32(a, b); + self.emit(Op::Dup(n), span); + self.select_int32(a, b, span); } else { - self.emit_all(&[Op::PushU32(b), Op::PushU32(a), Op::Dup(n + 2), Op::Cdrop]); + self.emit_all(&[Op::PushU32(b), Op::PushU32(a), Op::Dup(n + 2), Op::Cdrop], span); } } @@ -200,98 +203,110 @@ impl<'a> OpEmitter<'a> { /// # Stack Effects /// /// `[c, a, b, ..] => [d, ..] where d is c == 1 ? a : b` - pub fn select_int32(&mut self, a: u32, b: u32) { - self.emit_all(&[Op::PushU32(b), Op::PushU32(a), Op::Movup(2), Op::Cdrop]); + pub fn select_int32(&mut self, a: u32, b: u32, span: SourceSpan) { + self.emit_all(&[Op::PushU32(b), Op::PushU32(a), Op::Movup(2), Op::Cdrop], span); } /// Convert an i32/u32 value on the stack to a signed N-bit integer value /// /// Execution traps if the value cannot fit in the signed N-bit range. - pub fn int32_to_int(&mut self, n: u32) { + pub fn int32_to_int(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); // Push is_signed on the stack - self.is_signed_int32(); + self.is_signed_int32(span); // Pop the is_signed flag, and replace it with a selected mask // for the upper reserved bits of the N-bit range let reserved = 32 - n; // Add one bit to the reserved bits to represent the sign bit, // and subtract it from the shift to account for the loss let mask = (2u32.pow(reserved + 1) - 1) << (n - 1); - self.select_int32(mask, 0); - self.emit_all(&[ - // Copy the input to the top of the stack for the masking op - Op::Dup(1), - // Copy the mask value for the masking op - Op::Dup(1), - // Apply the mask - Op::U32And, - // Assert that the masked bits and the mask are equal - Op::AssertEq, - ]); + self.select_int32(mask, 0, span); + self.emit_all( + &[ + // Copy the input to the top of the stack for the masking op + Op::Dup(1), + // Copy the mask value for the masking op + Op::Dup(1), + // Apply the mask + Op::U32And, + // Assert that the masked bits and the mask are equal + Op::AssertEq, + ], + span, + ); } /// Convert an i32/u32 value on the stack to a signed N-bit integer value /// /// Places a boolean on top of the stack indicating if the conversion was successful - pub fn try_int32_to_int(&mut self, n: u32) { + pub fn try_int32_to_int(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); // Push is_signed on the stack - self.is_signed_int32(); + self.is_signed_int32(span); // Pop the is_signed flag, and replace it with a selected mask // for the upper reserved bits of the N-bit range let reserved = 32 - n; // Add one bit to the reserved bits to represent the sign bit, // and subtract it from the shift to account for the loss let mask = (2u32.pow(reserved + 1) - 1) << (n - 1); - self.select_int32(mask, 0); - self.emit_all(&[ - // Copy the input to the top of the stack for the masking op - Op::Dup(1), - // Copy the mask value for the masking op - Op::Dup(1), - // Apply the mask - Op::U32And, - // Assert that the masked bits and the mask are equal - Op::Eq, - ]); + self.select_int32(mask, 0, span); + self.emit_all( + &[ + // Copy the input to the top of the stack for the masking op + Op::Dup(1), + // Copy the mask value for the masking op + Op::Dup(1), + // Apply the mask + Op::U32And, + // Assert that the masked bits and the mask are equal + Op::Eq, + ], + span, + ); } /// Convert an i32/u32 value on the stack to an unsigned N-bit integer value /// /// Execution traps if the value cannot fit in the unsigned N-bit range. - pub fn int32_to_uint(&mut self, n: u32) { + pub fn int32_to_uint(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); // Mask the value and ensure that the unused bits above the N-bit range are 0 let reserved = 32 - n; let mask = (2u32.pow(reserved) - 1) << n; - self.emit_all(&[ - // Copy the input - Op::Dup(1), - // Apply the mask - Op::PushU32(mask), - Op::U32And, - // Assert the masked value is all 0s - Op::Assertz, - ]); + self.emit_all( + &[ + // Copy the input + Op::Dup(1), + // Apply the mask + Op::PushU32(mask), + Op::U32And, + // Assert the masked value is all 0s + Op::Assertz, + ], + span, + ); } /// Convert an i32/u32 value on the stack to an unsigned N-bit integer value /// /// Places a boolean on top of the stack indicating if the conversion was successful - pub fn try_int32_to_uint(&mut self, n: u32) { + pub fn try_int32_to_uint(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); // Mask the value and ensure that the unused bits above the N-bit range are 0 let reserved = 32 - n; let mask = (2u32.pow(reserved) - 1) << n; - self.emit_all(&[ - // Copy the input - Op::Dup(1), - // Apply the mask - Op::PushU32(mask), - Op::U32And, - // Assert the masked value is all 0s - Op::EqImm(Felt::ZERO), - ]); + self.emit_all( + &[ + // Copy the input + Op::Dup(1), + // Apply the mask + Op::PushU32(mask), + Op::U32And, + // Assert the masked value is all 0s + Op::EqImm(Felt::ZERO), + ], + span, + ); } /// Emit code to truncate a 32-bit value on top of the operand stack, to N bits, where N is <= @@ -302,12 +317,12 @@ impl<'a> OpEmitter<'a> { /// NOTE: This function does not validate the input as < 2^32, the caller is expected to /// validate this. #[inline] - pub fn trunc_int32(&mut self, n: u32) { + pub fn trunc_int32(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); // Mask out any bits between N and 32. let unused_bits = 32 - n; if unused_bits > 0 { - self.const_mask_u32(1 << ((32 - unused_bits) - 1)); + self.const_mask_u32(1 << ((32 - unused_bits) - 1), span); } } @@ -318,7 +333,7 @@ impl<'a> OpEmitter<'a> { /// NOTE: This operation does not check the sign bit, it is assumed the value is /// either an unsigned integer, or a non-negative signed integer. #[inline] - pub fn zext_int32(&mut self, n: u32) { + pub fn zext_int32(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 32); // Only values larger than 32 bits require padding if n <= 32 { @@ -327,7 +342,7 @@ impl<'a> OpEmitter<'a> { let num_bits = n % 32; let num_elements = (n / 32) + (num_bits > 0) as u32; let needed = num_elements - 1; - self.emit_n(needed as usize, Op::PushU32(0)); + self.emit_n(needed as usize, Op::PushU32(0), span); } /// Emit code to sign-extend a signed 32-bit value to N bits, where N <= 128 @@ -338,11 +353,11 @@ impl<'a> OpEmitter<'a> { /// assumed the value is an i32, it is up to the caller to ensure this is a valid /// operation to perform on the input. #[inline] - pub fn sext_int32(&mut self, n: u32) { + pub fn sext_int32(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 32); - self.is_signed_int32(); - self.select_int32(u32::MAX, 0); - self.pad_int32(n); + self.is_signed_int32(span); + self.select_int32(u32::MAX, 0, span); + self.pad_int32(n, span); } /// Emit code to pad a 32-bit value out to N bits, where N >= 32. @@ -356,26 +371,26 @@ impl<'a> OpEmitter<'a> { /// The padding value will be duplicated for each additional 32-bit limb needed to /// ensure that there are enough limbs on the stack to represent an N-bit integer. #[inline] - pub fn pad_int32(&mut self, n: u32) { + pub fn pad_int32(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 32); // We need one element for each 32-bit limb let num_elements = n / 32; // We already have the input u32, as well as the pad value, so deduct // those elements from the number needed. let needed = num_elements.saturating_sub(2); - self.emit_n(needed as usize, Op::Dup(0)); + self.emit_n(needed as usize, Op::Dup(0), span); } /// Push a u32 value on the stack #[inline(always)] - pub fn push_u32(&mut self, i: u32) { - self.emit(Op::PushU32(i)); + pub fn push_u32(&mut self, i: u32, span: SourceSpan) { + self.emit(Op::PushU32(i), span); } /// Push a i32 value on the stack #[inline(always)] - pub fn push_i32(&mut self, i: i32) { - self.emit(Op::PushU32(i as u32)); + pub fn push_i32(&mut self, i: i32, span: SourceSpan) { + self.emit(Op::PushU32(i as u32), span); } /// This is the inverse operation of the Miden VM `u32split` instruction. @@ -383,33 +398,41 @@ impl<'a> OpEmitter<'a> { /// This takes two 32-bit limbs, and produces a felt. /// /// NOTE: It is expected that the caller has validated that the limbs are valid u32 values. - pub fn u32unsplit(&mut self) { - self.emit_all(&[Op::MulImm(felt::U32_FIELD_MODULUS), Op::Add]); + pub fn u32unsplit(&mut self, span: SourceSpan) { + self.emit_all(&[Op::MulImm(felt::U32_FIELD_MODULUS), Op::Add], span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a + b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. #[inline(always)] - pub fn add_u32(&mut self, overflow: Overflow) { - self.emit(match overflow { - Overflow::Unchecked => Op::Add, - Overflow::Checked => return self.emit_all(&[Op::Add, Op::U32Assert]), - Overflow::Wrapping => Op::U32WrappingAdd, - Overflow::Overflowing => Op::U32OverflowingAdd, - }); + pub fn add_u32(&mut self, overflow: Overflow, span: SourceSpan) { + self.emit( + match overflow { + Overflow::Unchecked => Op::Add, + Overflow::Checked => return self.emit_all(&[Op::Add, Op::U32Assert], span), + Overflow::Wrapping => Op::U32WrappingAdd, + Overflow::Overflowing => Op::U32OverflowingAdd, + }, + span, + ); } /// Pops two i32 values off the stack, `b` and `a`, and performs `a + b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. #[inline(always)] - pub fn add_i32(&mut self, overflow: Overflow) { - self.emit(match overflow { - Overflow::Unchecked | Overflow::Wrapping => Op::U32WrappingAdd, - Overflow::Checked => Op::Exec("intrinsics::i32::checked_add".parse().unwrap()), - Overflow::Overflowing => Op::Exec("intrinsics::i32::overflowing_add".parse().unwrap()), - }) + pub fn add_i32(&mut self, overflow: Overflow, span: SourceSpan) { + self.emit( + match overflow { + Overflow::Unchecked | Overflow::Wrapping => Op::U32WrappingAdd, + Overflow::Checked => Op::Exec("intrinsics::i32::checked_add".parse().unwrap()), + Overflow::Overflowing => { + Op::Exec("intrinsics::i32::overflowing_add".parse().unwrap()) + } + }, + span, + ) } /// Pops a u32 value off the stack, `a`, and performs `a + `. @@ -418,19 +441,23 @@ impl<'a> OpEmitter<'a> { /// /// Adding zero is a no-op. #[inline] - pub fn add_imm_u32(&mut self, imm: u32, overflow: Overflow) { + pub fn add_imm_u32(&mut self, imm: u32, overflow: Overflow, span: SourceSpan) { if imm == 0 { return; } - self.emit(match overflow { - Overflow::Unchecked if imm == 1 => Op::Incr, - Overflow::Unchecked => Op::AddImm(Felt::new(imm as u64)), - Overflow::Checked => { - return self.emit_all(&[Op::AddImm(Felt::new(imm as u64)), Op::U32Assert]); - } - Overflow::Wrapping => Op::U32WrappingAddImm(imm), - Overflow::Overflowing => Op::U32OverflowingAddImm(imm), - }); + self.emit( + match overflow { + Overflow::Unchecked if imm == 1 => Op::Incr, + Overflow::Unchecked => Op::AddImm(Felt::new(imm as u64)), + Overflow::Checked => { + return self + .emit_all(&[Op::AddImm(Felt::new(imm as u64)), Op::U32Assert], span); + } + Overflow::Wrapping => Op::U32WrappingAddImm(imm), + Overflow::Overflowing => Op::U32OverflowingAddImm(imm), + }, + span, + ); } /// Pops a i32 value off the stack, `a`, and performs `a + `. @@ -439,50 +466,61 @@ impl<'a> OpEmitter<'a> { /// /// Adding zero is a no-op. #[inline] - pub fn add_imm_i32(&mut self, imm: i32, overflow: Overflow) { + pub fn add_imm_i32(&mut self, imm: i32, overflow: Overflow, span: SourceSpan) { if imm == 0 { return; } match overflow { - Overflow::Unchecked | Overflow::Wrapping => self.add_imm_u32(imm as u32, overflow), + Overflow::Unchecked | Overflow::Wrapping => { + self.add_imm_u32(imm as u32, overflow, span) + } Overflow::Checked => { - self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::checked_add".parse().unwrap()), - ]); + self.emit_all( + &[ + Op::PushU32(imm as u32), + Op::Exec("intrinsics::i32::checked_add".parse().unwrap()), + ], + span, + ); } - Overflow::Overflowing => self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::overflowing_add".parse().unwrap()), - ]), + Overflow::Overflowing => self.emit_all( + &[ + Op::PushU32(imm as u32), + Op::Exec("intrinsics::i32::overflowing_add".parse().unwrap()), + ], + span, + ), } } /// Pops two u32 values off the stack, `b` and `a`, and performs `a - b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. - pub fn sub_u32(&mut self, overflow: Overflow) { - self.emit(match overflow { - Overflow::Unchecked => Op::Sub, - Overflow::Checked => { - return self.emit_all(&[Op::Sub, Op::U32Assert]); - } - Overflow::Wrapping => Op::U32WrappingSub, - Overflow::Overflowing => Op::U32OverflowingSub, - }); + pub fn sub_u32(&mut self, overflow: Overflow, span: SourceSpan) { + self.emit( + match overflow { + Overflow::Unchecked => Op::Sub, + Overflow::Checked => { + return self.emit_all(&[Op::Sub, Op::U32Assert], span); + } + Overflow::Wrapping => Op::U32WrappingSub, + Overflow::Overflowing => Op::U32OverflowingSub, + }, + span, + ); } /// Pops two i32 values off the stack, `b` and `a`, and performs `a - b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. - pub fn sub_i32(&mut self, overflow: Overflow) { + pub fn sub_i32(&mut self, overflow: Overflow, span: SourceSpan) { match overflow { - Overflow::Unchecked | Overflow::Wrapping => self.sub_u32(overflow), + Overflow::Unchecked | Overflow::Wrapping => self.sub_u32(overflow, span), Overflow::Checked => { - self.emit(Op::Exec("intrinsics::i32::checked_sub".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i32::checked_sub".parse().unwrap()), span) } Overflow::Overflowing => { - self.emit(Op::Exec("intrinsics::i32::overflowing_sub".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i32::overflowing_sub".parse().unwrap()), span) } } } @@ -493,18 +531,21 @@ impl<'a> OpEmitter<'a> { /// /// Subtracting zero is a no-op. #[inline] - pub fn sub_imm_u32(&mut self, imm: u32, overflow: Overflow) { + pub fn sub_imm_u32(&mut self, imm: u32, overflow: Overflow, span: SourceSpan) { if imm == 0 { return; } - self.emit(match overflow { - Overflow::Unchecked => Op::SubImm(Felt::new(imm as u64)), - Overflow::Checked => { - return self.emit_all(&[Op::SubImm(Felt::new(imm as u64)), Op::U32Assert]) - } - Overflow::Wrapping => Op::U32WrappingSubImm(imm), - Overflow::Overflowing => Op::U32OverflowingSubImm(imm), - }); + self.emit( + match overflow { + Overflow::Unchecked => Op::SubImm(Felt::new(imm as u64)), + Overflow::Checked => { + return self.emit_all(&[Op::SubImm(Felt::new(imm as u64)), Op::U32Assert], span) + } + Overflow::Wrapping => Op::U32WrappingSubImm(imm), + Overflow::Overflowing => Op::U32OverflowingSubImm(imm), + }, + span, + ); } /// Pops a i32 value off the stack, `a`, and performs `a - `. @@ -513,48 +554,59 @@ impl<'a> OpEmitter<'a> { /// /// Subtracting zero is a no-op. #[inline] - pub fn sub_imm_i32(&mut self, imm: i32, overflow: Overflow) { + pub fn sub_imm_i32(&mut self, imm: i32, overflow: Overflow, span: SourceSpan) { if imm == 0 { return; } match overflow { - Overflow::Unchecked | Overflow::Wrapping => self.sub_imm_u32(imm as u32, overflow), - Overflow::Checked => self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::checked_sub".parse().unwrap()), - ]), - Overflow::Overflowing => self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::overflowing_sub".parse().unwrap()), - ]), + Overflow::Unchecked | Overflow::Wrapping => { + self.sub_imm_u32(imm as u32, overflow, span) + } + Overflow::Checked => self.emit_all( + &[ + Op::PushU32(imm as u32), + Op::Exec("intrinsics::i32::checked_sub".parse().unwrap()), + ], + span, + ), + Overflow::Overflowing => self.emit_all( + &[ + Op::PushU32(imm as u32), + Op::Exec("intrinsics::i32::overflowing_sub".parse().unwrap()), + ], + span, + ), } } /// Pops two u32 values off the stack, `b` and `a`, and performs `a * b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. - pub fn mul_u32(&mut self, overflow: Overflow) { - self.emit(match overflow { - Overflow::Unchecked => Op::Mul, - Overflow::Checked => return self.emit_all(&[Op::Mul, Op::U32Assert]), - Overflow::Wrapping => Op::U32WrappingMul, - Overflow::Overflowing => Op::U32OverflowingMul, - }); + pub fn mul_u32(&mut self, overflow: Overflow, span: SourceSpan) { + self.emit( + match overflow { + Overflow::Unchecked => Op::Mul, + Overflow::Checked => return self.emit_all(&[Op::Mul, Op::U32Assert], span), + Overflow::Wrapping => Op::U32WrappingMul, + Overflow::Overflowing => Op::U32OverflowingMul, + }, + span, + ); } /// Pops two i32 values off the stack, `b` and `a`, and performs `a * b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. - pub fn mul_i32(&mut self, overflow: Overflow) { + pub fn mul_i32(&mut self, overflow: Overflow, span: SourceSpan) { match overflow { Overflow::Unchecked | Overflow::Wrapping => { - self.emit(Op::Exec("intrinsics::i32::wrapping_mul".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i32::wrapping_mul".parse().unwrap()), span) } Overflow::Checked => { - self.emit(Op::Exec("intrinsics::i32::checked_mul".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i32::checked_mul".parse().unwrap()), span) } Overflow::Overflowing => { - self.emit(Op::Exec("intrinsics::i32::overflowing_mul".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i32::overflowing_mul".parse().unwrap()), span) } } } @@ -568,21 +620,27 @@ impl<'a> OpEmitter<'a> { /// /// Multiplying by one is a no-op. #[inline] - pub fn mul_imm_u32(&mut self, imm: u32, overflow: Overflow) { + pub fn mul_imm_u32(&mut self, imm: u32, overflow: Overflow, span: SourceSpan) { match imm { 0 => { - self.emit_all(&[Op::Drop, Op::PushU32(0)]); + self.emit_all(&[Op::Drop, Op::PushU32(0)], span); } 1 => (), imm => { - self.emit(match overflow { - Overflow::Unchecked => Op::MulImm(Felt::new(imm as u64)), - Overflow::Checked => { - return self.emit_all(&[Op::MulImm(Felt::new(imm as u64)), Op::U32Assert]) - } - Overflow::Wrapping => Op::U32WrappingMulImm(imm), - Overflow::Overflowing => Op::U32OverflowingMulImm(imm), - }); + self.emit( + match overflow { + Overflow::Unchecked => Op::MulImm(Felt::new(imm as u64)), + Overflow::Checked => { + return self.emit_all( + &[Op::MulImm(Felt::new(imm as u64)), Op::U32Assert], + span, + ) + } + Overflow::Wrapping => Op::U32WrappingMulImm(imm), + Overflow::Overflowing => Op::U32OverflowingMulImm(imm), + }, + span, + ); } } } @@ -596,25 +654,34 @@ impl<'a> OpEmitter<'a> { /// /// Multiplying by one is a no-op. #[inline] - pub fn mul_imm_i32(&mut self, imm: i32, overflow: Overflow) { + pub fn mul_imm_i32(&mut self, imm: i32, overflow: Overflow, span: SourceSpan) { match imm { 0 => { - self.emit_all(&[Op::Drop, Op::PushU32(0)]); + self.emit_all(&[Op::Drop, Op::PushU32(0)], span); } 1 => (), imm => match overflow { - Overflow::Unchecked | Overflow::Wrapping => self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::wrapping_mul".parse().unwrap()), - ]), - Overflow::Checked => self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::checked_mul".parse().unwrap()), - ]), - Overflow::Overflowing => self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::overflowing_mul".parse().unwrap()), - ]), + Overflow::Unchecked | Overflow::Wrapping => self.emit_all( + &[ + Op::PushU32(imm as u32), + Op::Exec("intrinsics::i32::wrapping_mul".parse().unwrap()), + ], + span, + ), + Overflow::Checked => self.emit_all( + &[ + Op::PushU32(imm as u32), + Op::Exec("intrinsics::i32::checked_mul".parse().unwrap()), + ], + span, + ), + Overflow::Overflowing => self.emit_all( + &[ + Op::PushU32(imm as u32), + Op::Exec("intrinsics::i32::overflowing_mul".parse().unwrap()), + ], + span, + ), }, } } @@ -622,15 +689,15 @@ impl<'a> OpEmitter<'a> { /// Pops two u32 values off the stack, `b` and `a`, and performs `a / b`. /// /// This operation is checked, so if the operands or result are not valid u32, execution traps. - pub fn checked_div_u32(&mut self) { - self.emit_all(&[Op::U32Div, Op::U32Assert]); + pub fn checked_div_u32(&mut self, span: SourceSpan) { + self.emit_all(&[Op::U32Div, Op::U32Assert], span); } /// Pops two i32 values off the stack, `b` and `a`, and performs `a / b`. /// /// This operation is checked, so if the operands or result are not valid i32, execution traps. - pub fn checked_div_i32(&mut self) { - self.emit(Op::Exec("intrinsics::i32::checked_div".parse().unwrap())); + pub fn checked_div_i32(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i32::checked_div".parse().unwrap()), span); } /// Pops a u32 value off the stack, `a`, and performs `a / `. @@ -638,9 +705,9 @@ impl<'a> OpEmitter<'a> { /// This function will panic if the divisor is zero. /// /// This operation is checked, so if the operand or result are not valid u32, execution traps. - pub fn checked_div_imm_u32(&mut self, imm: u32) { + pub fn checked_div_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert_ne!(imm, 0, "division by zero is not allowed"); - self.emit_all(&[Op::U32DivImm(imm), Op::U32Assert]); + self.emit_all(&[Op::U32DivImm(imm), Op::U32Assert], span); } /// Pops a i32 value off the stack, `a`, and performs `a / `. @@ -648,34 +715,37 @@ impl<'a> OpEmitter<'a> { /// This function will panic if the divisor is zero. /// /// This operation is checked, so if the operand or result are not valid i32, execution traps. - pub fn checked_div_imm_i32(&mut self, imm: i32) { + pub fn checked_div_imm_i32(&mut self, imm: i32, span: SourceSpan) { assert_ne!(imm, 0, "division by zero is not allowed"); - self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::checked_div".parse().unwrap()), - ]); + self.emit_all( + &[ + Op::PushU32(imm as u32), + Op::Exec("intrinsics::i32::checked_div".parse().unwrap()), + ], + span, + ); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a / b`. /// /// This operation is unchecked, so the result is not guaranteed to be a valid u32 - pub fn unchecked_div_u32(&mut self) { - self.emit(Op::U32Div); + pub fn unchecked_div_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Div, span); } /// Pops a u32 value off the stack, `a`, and performs `a / `. /// /// This function will panic if the divisor is zero. - pub fn unchecked_div_imm_u32(&mut self, imm: u32) { + pub fn unchecked_div_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert_ne!(imm, 0, "division by zero is not allowed"); - self.emit(Op::U32DivImm(imm)); + self.emit(Op::U32DivImm(imm), span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a % b`. /// /// This operation is checked, so if the operands or result are not valid u32, execution traps. - pub fn checked_mod_u32(&mut self) { - self.emit_all(&[Op::U32Mod, Op::U32Assert]); + pub fn checked_mod_u32(&mut self, span: SourceSpan) { + self.emit_all(&[Op::U32Mod, Op::U32Assert], span); } /// Pops a u32 value off the stack, `a`, and performs `a % `. @@ -683,105 +753,105 @@ impl<'a> OpEmitter<'a> { /// This function will panic if the divisor is zero. /// /// This operation is checked, so if the operand or result are not valid u32, execution traps. - pub fn checked_mod_imm_u32(&mut self, imm: u32) { + pub fn checked_mod_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert_ne!(imm, 0, "division by zero is not allowed"); - self.emit_all(&[Op::U32ModImm(imm), Op::U32Assert]); + self.emit_all(&[Op::U32ModImm(imm), Op::U32Assert], span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a % b`. /// /// This operation is unchecked, so the result is not guaranteed to be a valid u32 - pub fn unchecked_mod_u32(&mut self) { - self.emit(Op::U32Mod); + pub fn unchecked_mod_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Mod, span); } /// Pops a u32 value off the stack, `a`, and performs `a % `. /// /// This function will panic if the divisor is zero. - pub fn unchecked_mod_imm_u32(&mut self, imm: u32) { + pub fn unchecked_mod_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert_ne!(imm, 0, "division by zero is not allowed"); - self.emit(Op::U32ModImm(imm)); + self.emit(Op::U32ModImm(imm), span); } /// Pops two u32 values off the stack, `b` and `a`, and pushes `a / b`, then `a % b` on the /// stack. /// /// This operation is checked, so if the operands or result are not valid u32, execution traps. - pub fn checked_divmod_u32(&mut self) { - self.emit_all(&[Op::U32DivMod, Op::U32Assert]); + pub fn checked_divmod_u32(&mut self, span: SourceSpan) { + self.emit_all(&[Op::U32DivMod, Op::U32Assert], span); } /// Pops a u32 value off the stack, `a`, and pushes `a / `, then `a % ` on the stack. /// /// This operation is checked, so if the operands or result are not valid u32, execution traps. - pub fn checked_divmod_imm_u32(&mut self, imm: u32) { + pub fn checked_divmod_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert_ne!(imm, 0, "division by zero is not allowed"); - self.emit_all(&[Op::U32DivModImm(imm), Op::U32Assert]); + self.emit_all(&[Op::U32DivModImm(imm), Op::U32Assert], span); } /// Pops two u32 values off the stack, `b` and `a`, and pushes `a / b`, then `a % b` on the /// stack. /// /// This operation is unchecked, so the result is not guaranteed to be a valid u32 - pub fn unchecked_divmod_u32(&mut self) { - self.emit(Op::U32DivMod); + pub fn unchecked_divmod_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32DivMod, span); } /// Pops a u32 value off the stack, `a`, and pushes `a / `, then `a % ` on the stack. /// /// This operation is unchecked, so the result is not guaranteed to be a valid u32 - pub fn unchecked_divmod_imm_u32(&mut self, imm: u32) { + pub fn unchecked_divmod_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert_ne!(imm, 0, "division by zero is not allowed"); - self.emit(Op::U32DivModImm(imm)); + self.emit(Op::U32DivModImm(imm), span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a & b` /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn band_u32(&mut self) { - self.emit(Op::U32And); + pub fn band_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32And, span); } /// Pops a u32 value off the stack, `a`, and performs `a & ` /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn band_imm_u32(&mut self, imm: u32) { - self.emit_all(&[Op::PushU32(imm), Op::U32And]); + pub fn band_imm_u32(&mut self, imm: u32, span: SourceSpan) { + self.emit_all(&[Op::PushU32(imm), Op::U32And], span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a | b` /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn bor_u32(&mut self) { - self.emit(Op::U32Or); + pub fn bor_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Or, span); } /// Pops a u32 value off the stack, `a`, and performs `a | ` /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn bor_imm_u32(&mut self, imm: u32) { - self.emit_all(&[Op::PushU32(imm), Op::U32Or]); + pub fn bor_imm_u32(&mut self, imm: u32, span: SourceSpan) { + self.emit_all(&[Op::PushU32(imm), Op::U32Or], span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a ^ b` /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn bxor_u32(&mut self) { - self.emit(Op::U32Xor); + pub fn bxor_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Xor, span); } /// Pops a u32 value off the stack, `a`, and performs `a ^ ` /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn bxor_imm_u32(&mut self, imm: u32) { - self.emit_all(&[Op::PushU32(imm), Op::U32Xor]); + pub fn bxor_imm_u32(&mut self, imm: u32, span: SourceSpan) { + self.emit_all(&[Op::PushU32(imm), Op::U32Xor], span); } /// Pops a u32 value off the stack, `a`, and performs `!a` /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn bnot_u32(&mut self) { - self.emit(Op::U32WrappingSubImm(-1i32 as u32)); + pub fn bnot_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32WrappingSubImm(-1i32 as u32), span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a << b` @@ -789,16 +859,16 @@ impl<'a> OpEmitter<'a> { /// Execution traps if `b` > 31. /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn shl_u32(&mut self) { - self.emit(Op::U32Shl); + pub fn shl_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Shl, span); } /// Pops a u32 value off the stack, `a`, and performs `a << ` /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn shl_imm_u32(&mut self, imm: u32) { + pub fn shl_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert!(imm < 32, "invalid shift value: must be < 32, got {imm}"); - self.emit(Op::U32ShlImm(imm)); + self.emit(Op::U32ShlImm(imm), span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a >> b` @@ -806,8 +876,8 @@ impl<'a> OpEmitter<'a> { /// Execution traps if `b` > 31. /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn shr_u32(&mut self) { - self.emit(Op::U32Shr); + pub fn shr_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Shr, span); } /// Pops two i32 values off the stack, `b` and `a`, and performs `a >> b` @@ -815,27 +885,27 @@ impl<'a> OpEmitter<'a> { /// Execution traps if `b` > 31. /// /// This operation is checked, if the operands or result are not valid i32, execution traps. - pub fn shr_i32(&mut self) { - self.emit(Op::Exec("intrinsics::i32::checked_shr".parse().unwrap())); + pub fn shr_i32(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i32::checked_shr".parse().unwrap()), span); } /// Pops a u32 value off the stack, `a`, and performs `a >> ` /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn shr_imm_u32(&mut self, imm: u32) { + pub fn shr_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert!(imm < 32, "invalid shift value: must be < 32, got {imm}"); - self.emit(Op::U32ShrImm(imm)); + self.emit(Op::U32ShrImm(imm), span); } /// Pops a i32 value off the stack, `a`, and performs `a >> ` /// /// This operation is checked, if the operand or result are not valid i32, execution traps. - pub fn shr_imm_i32(&mut self, imm: u32) { + pub fn shr_imm_i32(&mut self, imm: u32, span: SourceSpan) { assert!(imm < 32, "invalid shift value: must be < 32, got {imm}"); - self.emit_all(&[ - Op::PushU32(imm), - Op::Exec("intrinsics::i32::checked_shr".parse().unwrap()), - ]); + self.emit_all( + &[Op::PushU32(imm), Op::Exec("intrinsics::i32::checked_shr".parse().unwrap())], + span, + ); } /// Pops two u32 values off the stack, `b` and `a`, and rotates the bits of `a` left by `b` bits @@ -843,16 +913,16 @@ impl<'a> OpEmitter<'a> { /// Execution traps if `b` > 31. /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn rotl_u32(&mut self) { - self.emit(Op::U32Rotl); + pub fn rotl_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Rotl, span); } /// Pops a u32 value off the stack, `a`, and rotates the bits of `a` left by `imm` bits /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn rotl_imm_u32(&mut self, imm: u32) { + pub fn rotl_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert!(imm < 32, "invalid rotation value: must be < 32, got {imm}"); - self.emit(Op::U32RotlImm(imm)); + self.emit(Op::U32RotlImm(imm), span); } /// Pops two u32 values off the stack, `b` and `a`, and rotates the bits of `a` right by `b` @@ -861,81 +931,81 @@ impl<'a> OpEmitter<'a> { /// Execution traps if `b` > 31. /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn rotr_u32(&mut self) { - self.emit(Op::U32Rotr); + pub fn rotr_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Rotr, span); } /// Pops a u32 value off the stack, `a`, and rotates the bits of `a` right by `imm` bits /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn rotr_imm_u32(&mut self, imm: u32) { + pub fn rotr_imm_u32(&mut self, imm: u32, span: SourceSpan) { assert!(imm < 32, "invalid rotation value: must be < 32, got {imm}"); - self.emit(Op::U32RotrImm(imm)); + self.emit(Op::U32RotrImm(imm), span); } /// Pops two u32 values off the stack, `b` and `a`, and puts the result of `min(a, b)` on the /// stack /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn min_u32(&mut self) { - self.emit(Op::U32Min); + pub fn min_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Min, span); } /// Pops two i32 values off the stack, `b` and `a`, and puts the result of `min(a, b)` on the /// stack /// /// This operation is checked, if the operands or result are not valid i32, execution traps. - pub fn min_i32(&mut self) { - self.emit(Op::Exec("intrinsics::i32::min".parse().unwrap())); + pub fn min_i32(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i32::min".parse().unwrap()), span); } /// Pops a u32 value off the stack, `a`, and puts the result of `min(a, imm)` on the stack /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn min_imm_u32(&mut self, imm: u32) { - self.emit_all(&[Op::PushU32(imm), Op::U32Min]); + pub fn min_imm_u32(&mut self, imm: u32, span: SourceSpan) { + self.emit_all(&[Op::PushU32(imm), Op::U32Min], span); } /// Pops a i32 value off the stack, `a`, and puts the result of `min(a, imm)` on the stack /// /// This operation is checked, if the operand or result are not valid i32, execution traps. - pub fn min_imm_i32(&mut self, imm: i32) { - self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::min".parse().unwrap()), - ]); + pub fn min_imm_i32(&mut self, imm: i32, span: SourceSpan) { + self.emit_all( + &[Op::PushU32(imm as u32), Op::Exec("intrinsics::i32::min".parse().unwrap())], + span, + ); } /// Pops two u32 values off the stack, `b` and `a`, and puts the result of `max(a, b)` on the /// stack /// /// This operation is checked, if the operands or result are not valid u32, execution traps. - pub fn max_u32(&mut self) { - self.emit(Op::U32Max); + pub fn max_u32(&mut self, span: SourceSpan) { + self.emit(Op::U32Max, span); } /// Pops two i32 values off the stack, `b` and `a`, and puts the result of `max(a, b)` on the /// stack /// /// This operation is checked, if the operands or result are not valid i32, execution traps. - pub fn max_i32(&mut self) { - self.emit(Op::Exec("intrinsics::i32::max".parse().unwrap())); + pub fn max_i32(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i32::max".parse().unwrap()), span); } /// Pops a u32 value off the stack, `a`, and puts the result of `max(a, imm)` on the stack /// /// This operation is checked, if the operand or result are not valid u32, execution traps. - pub fn max_imm_u32(&mut self, imm: u32) { - self.emit_all(&[Op::PushU32(imm), Op::U32Max]); + pub fn max_imm_u32(&mut self, imm: u32, span: SourceSpan) { + self.emit_all(&[Op::PushU32(imm), Op::U32Max], span); } /// Pops a i32 value off the stack, `a`, and puts the result of `max(a, imm)` on the stack /// /// This operation is checked, if the operand or result are not valid i32, execution traps. - pub fn max_imm_i32(&mut self, imm: i32) { - self.emit_all(&[ - Op::PushU32(imm as u32), - Op::Exec("intrinsics::i32::max".parse().unwrap()), - ]); + pub fn max_imm_i32(&mut self, imm: i32, span: SourceSpan) { + self.emit_all( + &[Op::PushU32(imm as u32), Op::Exec("intrinsics::i32::max".parse().unwrap())], + span, + ); } } diff --git a/codegen/masm/src/codegen/emit/int64.rs b/codegen/masm/src/codegen/emit/int64.rs index 2de91cca..7bde1cc4 100644 --- a/codegen/masm/src/codegen/emit/int64.rs +++ b/codegen/masm/src/codegen/emit/int64.rs @@ -1,4 +1,4 @@ -use midenc_hir::{Felt, FieldElement, Overflow}; +use midenc_hir::{Felt, FieldElement, Overflow, SourceSpan}; use super::{OpEmitter, P}; use crate::masm::{self as masm, Op}; @@ -8,14 +8,14 @@ impl<'a> OpEmitter<'a> { /// Convert a u64 value to felt. /// /// This operation will assert at runtime if the value is larger than the felt field. - pub fn u64_to_felt(&mut self) { + pub fn u64_to_felt(&mut self, span: SourceSpan) { // Copy the input operand for the check - self.copy_int64(); + self.copy_int64(span); // Assert that value is <= P, then unsplit the limbs to get a felt - self.push_u64(P); - self.lt_u64(); - self.emit(Op::Assert); - self.u32unsplit(); + self.push_u64(P, span); + self.lt_u64(span); + self.emit(Op::Assert, span); + self.u32unsplit(span); } /// Convert a i64 value to felt. @@ -23,49 +23,58 @@ impl<'a> OpEmitter<'a> { /// This operation will assert at runtime if the value is negative, or larger than the felt /// field. #[inline] - pub fn i64_to_felt(&mut self) { - self.u64_to_felt(); + pub fn i64_to_felt(&mut self, span: SourceSpan) { + self.u64_to_felt(span); } /// Convert a u64 value to an unsigned N-bit integer, where N <= 32 /// /// Conversion will trap if the input value is too large to fit in an N-bit integer. - pub fn u64_to_uint(&mut self, n: u32) { - self.emit_all(&[ - // Assert hi bits are zero - Op::Assertz, - // Check that the remaining bits fit in range - Op::Dup(0), - Op::Push(Felt::new(2u64.pow(n) - 1)), - Op::U32Lte, - Op::Assert, - ]); + pub fn u64_to_uint(&mut self, n: u32, span: SourceSpan) { + self.emit_all( + &[ + // Assert hi bits are zero + Op::Assertz, + // Check that the remaining bits fit in range + Op::Dup(0), + Op::Push(Felt::new(2u64.pow(n) - 1)), + Op::U32Lte, + Op::Assert, + ], + span, + ); } /// Convert an i64 value to a signed N-bit integer, where N <= 32 /// /// Conversion will trap if the input value is too large to fit in an N-bit integer. - pub fn i64_to_int(&mut self, n: u32) { - self.emit_all(&[ - // Assert hi bits are all zero or all one - // [x_hi, x_hi, x_lo] - Op::Dup(0), - // [is_unsigned, x_hi, x_lo] - Op::EqImm(Felt::ZERO), - // [is_unsigned, is_unsigned, ..] - Op::Dup(0), - // [is_unsigned, x_hi, is_unsigned, x_lo] - Op::Movdn(2), - ]); + pub fn i64_to_int(&mut self, n: u32, span: SourceSpan) { + self.emit_all( + &[ + // Assert hi bits are all zero or all one + // [x_hi, x_hi, x_lo] + Op::Dup(0), + // [is_unsigned, x_hi, x_lo] + Op::EqImm(Felt::ZERO), + // [is_unsigned, is_unsigned, ..] + Op::Dup(0), + // [is_unsigned, x_hi, is_unsigned, x_lo] + Op::Movdn(2), + ], + span, + ); // Select all 0s if is_unsigned is true, else all 1s // [mask, x_hi, is_unsigned, x_lo] - self.select_int32(0, u32::MAX); - self.emit_all(&[ - // [is_unsigned, x_lo] - Op::AssertEq, - // [x_lo, is_unsigned, x_lo] - Op::Dup(1), - ]); + self.select_int32(0, u32::MAX, span); + self.emit_all( + &[ + // [is_unsigned, x_lo] + Op::AssertEq, + // [x_lo, is_unsigned, x_lo] + Op::Dup(1), + ], + span, + ); // Select mask for remaining sign bits // // The mask should cover the u64 bits which must be set to 1 if @@ -77,19 +86,22 @@ impl<'a> OpEmitter<'a> { // integer, there are N-1 such bits. let value_bits = (2u64.pow(n - 1) - 1) as u32; // [sign_bits, is_unsigned, x_lo] - self.const_mask_u32(!value_bits); - self.emit_all(&[ - // [sign_bits, sign_bits, ..] - Op::Dup(0), - // [0, sign_bits, sign_bits, is_unsigned, x_lo] - Op::PushU32(0), - // [is_unsigned, 0, sign_bits, sign_bits, x_lo] - Op::Movup(3), - // [expected_sign_bits, sign_bits, x_lo] - Op::Cdrop, - // [x_lo] - Op::AssertEq, - ]); + self.const_mask_u32(!value_bits, span); + self.emit_all( + &[ + // [sign_bits, sign_bits, ..] + Op::Dup(0), + // [0, sign_bits, sign_bits, is_unsigned, x_lo] + Op::PushU32(0), + // [is_unsigned, 0, sign_bits, sign_bits, x_lo] + Op::Movup(3), + // [expected_sign_bits, sign_bits, x_lo] + Op::Cdrop, + // [x_lo] + Op::AssertEq, + ], + span, + ); } /// Truncate a i64/u64 value to a felt value @@ -108,9 +120,9 @@ impl<'a> OpEmitter<'a> { /// /// NOTE: This function does not validate the i64/u64, the caller is expected to /// have already validated that the top of the stack holds a valid value of this type. - #[inline] - pub fn trunc_int64_to_felt(&mut self) { - self.u32unsplit() + #[inline(always)] + pub fn trunc_int64_to_felt(&mut self, span: SourceSpan) { + self.u32unsplit(span) } /// Truncate this 64-bit value to N bits, where N is <= 32 @@ -120,69 +132,70 @@ impl<'a> OpEmitter<'a> { /// NOTE: This function does not validate the i64/u64, the caller is expected to /// have already validated that the top of the stack holds a valid value of that type. #[inline] - pub fn trunc_int64(&mut self, n: u32) { + pub fn trunc_int64(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); - self.emit(Op::Drop); + self.emit(Op::Drop, span); match n { 32 => (), - n => self.trunc_int32(n), + n => self.trunc_int32(n, span), } } /// Sign-extend a 64-bit value to an signed N-bit integer, where N >= 128 - pub fn sext_int64(&mut self, n: u32) { + pub fn sext_int64(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 128, 256); - self.is_signed_int64(); + self.is_signed_int64(span); // Select the extension bits - self.select_int32(u32::MAX, 0); + self.select_int32(u32::MAX, 0, span); // Pad out the missing bits // // Deduct 32 bits to account for the difference between u32 and u64 - self.pad_int32(n - 32); + self.pad_int32(n - 32, span); } /// Zero-extend a 64-bit value to N-bits, where N >= 64 - pub fn zext_int64(&mut self, n: u32) { + pub fn zext_int64(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 128, 256); // Pad out the missing bits // // Deduct 32 bits to account for the difference between u32 and u64 - self.zext_int32(n - 32); + self.zext_int32(n - 32, span); } /// Assert that there is a valid 64-bit integer value on the operand stack - pub fn assert_int64(&mut self) { - self.emit(Op::U32Assert2); + pub fn assert_int64(&mut self, span: SourceSpan) { + self.emit(Op::U32Assert2, span); } /// Checks if the 64-bit value on the stack has its sign bit set. - #[inline] - pub fn is_signed_int64(&mut self) { - self.is_signed_int32() + #[inline(always)] + pub fn is_signed_int64(&mut self, span: SourceSpan) { + self.is_signed_int32(span) } /// Assert that the 64-bit value on the stack does not have its sign bit set. - pub fn assert_unsigned_int64(&mut self) { + #[inline(always)] + pub fn assert_unsigned_int64(&mut self, span: SourceSpan) { // Assert that the sign bit is unset - self.assert_unsigned_int32() + self.assert_unsigned_int32(span) } /// Assert that the 64-bit value on the stack is a valid i64 value - pub fn assert_i64(&mut self) { + pub fn assert_i64(&mut self, span: SourceSpan) { // Copy the value on top of the stack - self.copy_int64(); + self.copy_int64(span); // Assert the value does not overflow i64::MAX or underflow i64::MIN // This can be checked by validating that when interpreted as a u64, // the value is <= i64::MIN, which is 1 more than i64::MAX. - self.push_i64(i64::MIN); - self.lte_u64(); - self.emit(Op::Assert); + self.push_i64(i64::MIN, span); + self.lte_u64(span); + self.emit(Op::Assert, span); } /// Duplicate the i64/u64 value on top of the stack #[inline(always)] - pub fn copy_int64(&mut self) { - self.copy_int64_from(0) + pub fn copy_int64(&mut self, span: SourceSpan) { + self.copy_int64_from(0, span) } /// Duplicate a i64/u64 value to the top of the stack @@ -190,10 +203,10 @@ impl<'a> OpEmitter<'a> { /// The value `n` must be a valid stack index, and may not reference the last stack slot, /// or this function will panic. #[inline(always)] - pub fn copy_int64_from(&mut self, n: u8) { + pub fn copy_int64_from(&mut self, n: u8, span: SourceSpan) { assert_valid_stack_index!(n + 1); // copy limbs such that the order is preserved - self.emit_n(2, Op::Dup(n + 1)); + self.emit_n(2, Op::Dup(n + 1), span); } /// Move a 64-bit value to the top of the stack, i.e. `movup(N)` for 64-bit values @@ -203,164 +216,167 @@ impl<'a> OpEmitter<'a> { /// /// A value of `0` has no effect. #[inline] - pub fn move_int64_up(&mut self, n: u8) { + pub fn move_int64_up(&mut self, n: u8, span: SourceSpan) { assert_valid_stack_index!(n + 1); match n { 0 => (), 1 => { // Move the top of the stack past the 64 bit value - self.emit(Op::Movdn(2)); + self.emit(Op::Movdn(2), span); } n => { - self.emit_all(&[ - // Move the low 32 bits to the top - Op::Movup(n + 1), - // Move the high 32 bits to the top - Op::Movup(n + 1), - ]); + self.emit_all( + &[ + // Move the low 32 bits to the top + Op::Movup(n + 1), + // Move the high 32 bits to the top + Op::Movup(n + 1), + ], + span, + ); } } } /// Pushes a literal i64 value on the operand stack #[inline(always)] - pub fn push_i64(&mut self, value: i64) { - self.push_u64(value as u64); + pub fn push_i64(&mut self, value: i64, span: SourceSpan) { + self.push_u64(value as u64, span); } /// Pushes a literal u64 value on the operand stack #[inline] - pub fn push_u64(&mut self, value: u64) { + pub fn push_u64(&mut self, value: u64, span: SourceSpan) { let (hi, lo) = to_raw_parts(value); - from_raw_parts(lo, hi, self.current_block()); + from_raw_parts(lo, hi, self.current_block(), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `a < b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn lt_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::lt".parse().unwrap())); + pub fn lt_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::lt".parse().unwrap()), span); } /// Pops two i64 values off the stack, `b` and `a`, and pushes `a < b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn lt_i64(&mut self) { - self.emit(Op::Exec("intrinsics::i64::lt".parse().unwrap())); + pub fn lt_i64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i64::lt".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `a <= b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn lte_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::lte".parse().unwrap())); + pub fn lte_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::lte".parse().unwrap()), span); } /// Pops two i64 values off the stack, `b` and `a`, and pushes `a <= b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn lte_i64(&mut self) { - self.emit(Op::Exec("intrinsics::i64::lte".parse().unwrap())); + pub fn lte_i64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i64::lte".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `a > b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn gt_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::gt".parse().unwrap())); + pub fn gt_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::gt".parse().unwrap()), span); } /// Pops two i64 values off the stack, `b` and `a`, and pushes `a > b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn gt_i64(&mut self) { - self.emit(Op::Exec("intrinsics::i64::gt".parse().unwrap())); + pub fn gt_i64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i64::gt".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `a >= b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn gte_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::gte".parse().unwrap())); + pub fn gte_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::gte".parse().unwrap()), span); } /// Pops two i64 values off the stack, `b` and `a`, and pushes `a >= b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn gte_i64(&mut self) { - self.emit(Op::Exec("intrinsics::i64::gte".parse().unwrap())); + pub fn gte_i64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i64::gte".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `a == b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn eq_int64(&mut self) { - self.emit(Op::Exec("std::math::u64::eq".parse().unwrap())); + pub fn eq_int64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::eq".parse().unwrap()), span); } /// Pops a u64 value off the stack, `a`, and pushes `a == 0` on the stack. /// /// This operation is checked, so if the value is not a valid u64, execution will trap. #[inline] - pub fn is_zero_int64(&mut self) { - self.emit(Op::Exec("std::math::u64::eqz".parse().unwrap())); + pub fn is_zero_int64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::eqz".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `min(a, b)` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn min_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::min".parse().unwrap())); + pub fn min_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::min".parse().unwrap()), span); } /// Pops two i64 values off the stack, `b` and `a`, and pushes `min(a, b)` on the stack. /// /// This operation is checked, so if the values are not valid i64, execution will trap. - pub fn min_i64(&mut self) { - self.emit(Op::Exec("intrinsics::i64::min".parse().unwrap())); + pub fn min_i64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i64::min".parse().unwrap()), span); } - pub fn min_imm_i64(&mut self, imm: i64) { - self.push_i64(imm); - self.emit(Op::Exec("intrinsics::i64::min".parse().unwrap())); + pub fn min_imm_i64(&mut self, imm: i64, span: SourceSpan) { + self.push_i64(imm, span); + self.emit(Op::Exec("intrinsics::i64::min".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `max(a, b)` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn max_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::max".parse().unwrap())); + pub fn max_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::max".parse().unwrap()), span); } /// Pops two i64 values off the stack, `b` and `a`, and pushes `max(a, b)` on the stack. /// /// This operation is checked, so if the values are not valid i64, execution will trap. - pub fn max_i64(&mut self) { - self.emit(Op::Exec("intrinsics::i64::max".parse().unwrap())); + pub fn max_i64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i64::max".parse().unwrap()), span); } - pub fn max_imm_i64(&mut self, imm: i64) { - self.push_i64(imm); - self.emit(Op::Exec("intrinsics::i64::max".parse().unwrap())); + pub fn max_imm_i64(&mut self, imm: i64, span: SourceSpan) { + self.push_i64(imm, span); + self.emit(Op::Exec("intrinsics::i64::max".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `a != b` on the stack. /// /// This operation is checked, so if the values are not valid u64, execution will trap. #[inline] - pub fn neq_int64(&mut self) { - self.emit(Op::Exec("std::math::u64::neq".parse().unwrap())); + pub fn neq_int64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::neq".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and performs `a + b`. @@ -377,19 +393,19 @@ impl<'a> OpEmitter<'a> { /// The caller is assumed to know that different `overflow` settings can /// produce different results, and that those differences are handled. #[inline] - pub fn add_u64(&mut self, overflow: Overflow) { + pub fn add_u64(&mut self, overflow: Overflow, span: SourceSpan) { match overflow { Overflow::Checked => { - self.emit_all(&[ - Op::Exec("std::math::u64::overflowing_add".parse().unwrap()), - Op::Assertz, - ]); + self.emit_all( + &[Op::Exec("std::math::u64::overflowing_add".parse().unwrap()), Op::Assertz], + span, + ); } Overflow::Unchecked | Overflow::Wrapping => { - self.emit(Op::Exec("std::math::u64::wrapping_add".parse().unwrap())); + self.emit(Op::Exec("std::math::u64::wrapping_add".parse().unwrap()), span); } Overflow::Overflowing => { - self.emit(Op::Exec("std::math::u64::overflowing_add".parse().unwrap())); + self.emit(Op::Exec("std::math::u64::overflowing_add".parse().unwrap()), span); } } } @@ -398,14 +414,19 @@ impl<'a> OpEmitter<'a> { /// /// See the [Overflow] type for how overflow semantics can change the operation. #[inline(always)] - pub fn add_i64(&mut self, overflow: Overflow) { - self.emit(match overflow { - Overflow::Unchecked | Overflow::Wrapping => { - Op::Exec("std::math::u64::wrapping_add".parse().unwrap()) - } - Overflow::Checked => Op::Exec("intrinsics::i64::checked_add".parse().unwrap()), - Overflow::Overflowing => Op::Exec("intrinsics::i64::overflowing_add".parse().unwrap()), - }) + pub fn add_i64(&mut self, overflow: Overflow, span: SourceSpan) { + self.emit( + match overflow { + Overflow::Unchecked | Overflow::Wrapping => { + Op::Exec("std::math::u64::wrapping_add".parse().unwrap()) + } + Overflow::Checked => Op::Exec("intrinsics::i64::checked_add".parse().unwrap()), + Overflow::Overflowing => { + Op::Exec("intrinsics::i64::overflowing_add".parse().unwrap()) + } + }, + span, + ) } /// Pops a i64 value off the stack, `a`, and performs `a + `. @@ -414,18 +435,18 @@ impl<'a> OpEmitter<'a> { /// /// Adding zero is a no-op. #[inline] - pub fn add_imm_i64(&mut self, imm: i64, overflow: Overflow) { + pub fn add_imm_i64(&mut self, imm: i64, overflow: Overflow, span: SourceSpan) { if imm == 0 { return; } - self.push_i64(imm); + self.push_i64(imm, span); match overflow { - Overflow::Unchecked | Overflow::Wrapping => self.add_u64(overflow), + Overflow::Unchecked | Overflow::Wrapping => self.add_u64(overflow, span), Overflow::Checked => { - self.emit(Op::Exec("intrinsics::i64::checked_add".parse().unwrap())); + self.emit(Op::Exec("intrinsics::i64::checked_add".parse().unwrap()), span); } Overflow::Overflowing => { - self.emit(Op::Exec("intrinsics::i64::overflowing_add".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i64::overflowing_add".parse().unwrap()), span) } } } @@ -444,19 +465,19 @@ impl<'a> OpEmitter<'a> { /// The caller is assumed to know that different `overflow` settings can /// produce different results, and that those differences are handled. #[inline] - pub fn sub_u64(&mut self, overflow: Overflow) { + pub fn sub_u64(&mut self, overflow: Overflow, span: SourceSpan) { match overflow { Overflow::Checked => { - self.emit_all(&[ - Op::Exec("std::math::u64::overflowing_sub".parse().unwrap()), - Op::Assertz, - ]); + self.emit_all( + &[Op::Exec("std::math::u64::overflowing_sub".parse().unwrap()), Op::Assertz], + span, + ); } Overflow::Unchecked | Overflow::Wrapping => { - self.emit(Op::Exec("std::math::u64::wrapping_sub".parse().unwrap())); + self.emit(Op::Exec("std::math::u64::wrapping_sub".parse().unwrap()), span); } Overflow::Overflowing => { - self.emit(Op::Exec("std::math::u64::overflowing_sub".parse().unwrap())); + self.emit(Op::Exec("std::math::u64::overflowing_sub".parse().unwrap()), span); } } } @@ -464,14 +485,14 @@ impl<'a> OpEmitter<'a> { /// Pops two i64 values off the stack, `b` and `a`, and performs `a - b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. - pub fn sub_i64(&mut self, overflow: Overflow) { + pub fn sub_i64(&mut self, overflow: Overflow, span: SourceSpan) { match overflow { - Overflow::Unchecked | Overflow::Wrapping => self.sub_u64(overflow), + Overflow::Unchecked | Overflow::Wrapping => self.sub_u64(overflow, span), Overflow::Checked => { - self.emit(Op::Exec("intrinsics::i64::checked_sub".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i64::checked_sub".parse().unwrap()), span) } Overflow::Overflowing => { - self.emit(Op::Exec("intrinsics::i64::overflowing_sub".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i64::overflowing_sub".parse().unwrap()), span) } } } @@ -482,18 +503,18 @@ impl<'a> OpEmitter<'a> { /// /// Subtracting zero is a no-op. #[inline] - pub fn sub_imm_i64(&mut self, imm: i64, overflow: Overflow) { + pub fn sub_imm_i64(&mut self, imm: i64, overflow: Overflow, span: SourceSpan) { if imm == 0 { return; } - self.push_i64(imm); + self.push_i64(imm, span); match overflow { - Overflow::Unchecked | Overflow::Wrapping => self.sub_u64(overflow), + Overflow::Unchecked | Overflow::Wrapping => self.sub_u64(overflow, span), Overflow::Checked => { - self.emit(Op::Exec("intrinsics::i64::checked_sub".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i64::checked_sub".parse().unwrap()), span) } Overflow::Overflowing => { - self.emit(Op::Exec("intrinsics::i64::overflowing_sub".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i64::overflowing_sub".parse().unwrap()), span) } } } @@ -512,23 +533,29 @@ impl<'a> OpEmitter<'a> { /// The caller is assumed to know that different `overflow` settings can /// produce different results, and that those differences are handled. #[inline] - pub fn mul_u64(&mut self, overflow: Overflow) { + pub fn mul_u64(&mut self, overflow: Overflow, span: SourceSpan) { match overflow { Overflow::Checked => { - self.emit_all(&[ - Op::Exec("std::math::u64::overflowing_mul".parse().unwrap()), - Op::Exec("std::math::u64::overflowing_eqz".parse().unwrap()), - Op::Assertz, - ]); + self.emit_all( + &[ + Op::Exec("std::math::u64::overflowing_mul".parse().unwrap()), + Op::Exec("std::math::u64::overflowing_eqz".parse().unwrap()), + Op::Assertz, + ], + span, + ); } Overflow::Unchecked | Overflow::Wrapping => { - self.emit(Op::Exec("std::math::u64::wrapping_mul".parse().unwrap())); + self.emit(Op::Exec("std::math::u64::wrapping_mul".parse().unwrap()), span); } Overflow::Overflowing => { - self.emit_all(&[ - Op::Exec("std::math::u64::overflowing_mul".parse().unwrap()), - Op::Exec("std::math::u64::overflowing_eqz".parse().unwrap()), - ]); + self.emit_all( + &[ + Op::Exec("std::math::u64::overflowing_mul".parse().unwrap()), + Op::Exec("std::math::u64::overflowing_eqz".parse().unwrap()), + ], + span, + ); } } } @@ -536,16 +563,16 @@ impl<'a> OpEmitter<'a> { /// Pops two i64 values off the stack, `b` and `a`, and performs `a * b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. - pub fn mul_i64(&mut self, overflow: Overflow) { + pub fn mul_i64(&mut self, overflow: Overflow, span: SourceSpan) { match overflow { Overflow::Unchecked | Overflow::Wrapping => { - self.emit(Op::Exec("intrinsics::i64::wrapping_mul".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i64::wrapping_mul".parse().unwrap()), span) } Overflow::Checked => { - self.emit(Op::Exec("intrinsics::i64::checked_mul".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i64::checked_mul".parse().unwrap()), span) } Overflow::Overflowing => { - self.emit(Op::Exec("intrinsics::i64::overflowing_mul".parse().unwrap())) + self.emit(Op::Exec("intrinsics::i64::overflowing_mul".parse().unwrap()), span) } } } @@ -559,24 +586,24 @@ impl<'a> OpEmitter<'a> { /// /// Multiplying by one is a no-op. #[inline] - pub fn mul_imm_i64(&mut self, imm: i64, overflow: Overflow) { + pub fn mul_imm_i64(&mut self, imm: i64, overflow: Overflow, span: SourceSpan) { match imm { 0 => { - self.emit_all(&[Op::Drop, Op::Drop, Op::PushU32(0), Op::PushU32(0)]); + self.emit_all(&[Op::Drop, Op::Drop, Op::PushU32(0), Op::PushU32(0)], span); } 1 => (), imm => match overflow { Overflow::Unchecked | Overflow::Wrapping => { - self.push_i64(imm); - self.emit(Op::Exec("intrinsics::i64::wrapping_mul".parse().unwrap())); + self.push_i64(imm, span); + self.emit(Op::Exec("intrinsics::i64::wrapping_mul".parse().unwrap()), span); } Overflow::Checked => { - self.push_i64(imm); - self.emit(Op::Exec("intrinsics::i64::checked_mul".parse().unwrap())); + self.push_i64(imm, span); + self.emit(Op::Exec("intrinsics::i64::checked_mul".parse().unwrap()), span); } Overflow::Overflowing => { - self.push_i64(imm); - self.emit(Op::Exec("intrinsics::i64::overflowing_mul".parse().unwrap())); + self.push_i64(imm, span); + self.emit(Op::Exec("intrinsics::i64::overflowing_mul".parse().unwrap()), span); } }, } @@ -587,8 +614,8 @@ impl<'a> OpEmitter<'a> { /// /// Both the operands and result are validated to ensure they are valid u64 values. #[inline] - pub fn checked_div_u64(&mut self) { - self.emit_all(&[Op::U32Assertw, Op::Exec("std::math::u64::div".parse().unwrap())]); + pub fn checked_div_u64(&mut self, span: SourceSpan) { + self.emit_all(&[Op::U32Assertw, Op::Exec("std::math::u64::div".parse().unwrap())], span); } /// Pops two i64 values off the stack, `b` and `a`, and pushes the result of `a / b` on the @@ -596,8 +623,8 @@ impl<'a> OpEmitter<'a> { /// /// Both the operands and result are validated to ensure they are valid u64 values. #[inline] - pub fn checked_div_i64(&mut self) { - self.emit(Op::Exec("intrinsics::i64::checked_div".parse().unwrap())); + pub fn checked_div_i64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i64::checked_div".parse().unwrap()), span); } /// Pops a i64 value off the stack, `a`, and performs `a / `. @@ -605,10 +632,10 @@ impl<'a> OpEmitter<'a> { /// This function will panic if the divisor is zero. /// /// This operation is checked, so if the operand or result are not valid i32, execution traps. - pub fn checked_div_imm_i64(&mut self, imm: i64) { + pub fn checked_div_imm_i64(&mut self, imm: i64, span: SourceSpan) { assert_ne!(imm, 0, "division by zero is not allowed"); - self.push_i64(imm); - self.emit(Op::Exec("intrinsics::i64::checked_div".parse().unwrap())); + self.push_i64(imm, span); + self.emit(Op::Exec("intrinsics::i64::checked_div".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes the result of `a / b` on the @@ -616,8 +643,8 @@ impl<'a> OpEmitter<'a> { /// /// This operation is unchecked, it is up to the caller to ensure validity of the operands. #[inline] - pub fn unchecked_div_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::div".parse().unwrap())); + pub fn unchecked_div_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::div".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes the result of `a % b` on the @@ -625,8 +652,8 @@ impl<'a> OpEmitter<'a> { /// /// Both the operands and result are validated to ensure they are valid u64 values. #[inline] - pub fn checked_mod_u64(&mut self) { - self.emit_all(&[Op::U32Assertw, Op::Exec("std::math::u64::mod".parse().unwrap())]); + pub fn checked_mod_u64(&mut self, span: SourceSpan) { + self.emit_all(&[Op::U32Assertw, Op::Exec("std::math::u64::mod".parse().unwrap())], span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes the result of `a % b` on the @@ -634,8 +661,8 @@ impl<'a> OpEmitter<'a> { /// /// This operation is unchecked, it is up to the caller to ensure validity of the operands. #[inline] - pub fn unchecked_mod_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::mod".parse().unwrap())); + pub fn unchecked_mod_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::mod".parse().unwrap()), span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `a / b`, then `a % b` on the @@ -643,8 +670,8 @@ impl<'a> OpEmitter<'a> { /// /// Both the operands and result are validated to ensure they are valid u64 values. #[inline] - pub fn checked_divmod_u64(&mut self) { - self.emit_all(&[Op::U32Assertw, Op::Exec("std::math::u64::divmod".parse().unwrap())]); + pub fn checked_divmod_u64(&mut self, span: SourceSpan) { + self.emit_all(&[Op::U32Assertw, Op::Exec("std::math::u64::divmod".parse().unwrap())], span); } /// Pops two u64 values off the stack, `b` and `a`, and pushes `a / b`, then `a % b` on the @@ -652,32 +679,32 @@ impl<'a> OpEmitter<'a> { /// /// This operation is unchecked, it is up to the caller to ensure validity of the operands. #[inline] - pub fn unchecked_divmod_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::divmod".parse().unwrap())); + pub fn unchecked_divmod_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::divmod".parse().unwrap()), span); } /// Pops two 64-bit values off the stack, `b` and `a`, and pushes `a & b` on the stack. /// /// Both the operands and result are validated to ensure they are valid int64 values. #[inline] - pub fn band_int64(&mut self) { - self.emit(Op::Exec("std::math::u64::and".parse().unwrap())); + pub fn band_int64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::and".parse().unwrap()), span); } /// Pops two 64-bit values off the stack, `b` and `a`, and pushes `a | b` on the stack. /// /// Both the operands and result are validated to ensure they are valid int64 values. #[inline] - pub fn bor_int64(&mut self) { - self.emit(Op::Exec("std::math::u64::or".parse().unwrap())); + pub fn bor_int64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::or".parse().unwrap()), span); } /// Pops two 64-bit values off the stack, `b` and `a`, and pushes `a ^ b` on the stack. /// /// Both the operands and result are validated to ensure they are valid int64 values. #[inline] - pub fn bxor_int64(&mut self) { - self.emit(Op::Exec("std::math::u64::xor".parse().unwrap())); + pub fn bxor_int64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::xor".parse().unwrap()), span); } /// Pops a u32 value, `b`, and a u64 value, `a`, off the stack and pushes `a << b` on the stack. @@ -686,8 +713,8 @@ impl<'a> OpEmitter<'a> { /// /// The operation will trap if the shift value is > 63. #[inline] - pub fn shl_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::shl".parse().unwrap())); + pub fn shl_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::shl".parse().unwrap()), span); } /// Pops a u32 value, `b`, and a u64 value, `a`, off the stack and pushes `a >> b` on the stack. @@ -696,8 +723,8 @@ impl<'a> OpEmitter<'a> { /// /// The operation will trap if the shift value is > 63. #[inline] - pub fn shr_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::shr".parse().unwrap())); + pub fn shr_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::shr".parse().unwrap()), span); } /// Arithmetic shift right (i.e. signedness is preserved) @@ -708,19 +735,19 @@ impl<'a> OpEmitter<'a> { /// /// The operation will trap if the shift value is > 63. #[inline] - pub fn shr_i64(&mut self) { - self.emit(Op::Exec("intrinsics::i64::checked_shr".parse().unwrap())); + pub fn shr_i64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::i64::checked_shr".parse().unwrap()), span); } /// Pops a i64 value off the stack, `a`, and performs `a >> ` /// /// This operation is checked, if the operand or result are not valid i64, execution traps. - pub fn shr_imm_i64(&mut self, imm: u32) { + pub fn shr_imm_i64(&mut self, imm: u32, span: SourceSpan) { assert!(imm < 63, "invalid shift value: must be < 63, got {imm}"); - self.emit_all(&[ - Op::PushU32(imm), - Op::Exec("intrinsics::i64::checked_shr".parse().unwrap()), - ]); + self.emit_all( + &[Op::PushU32(imm), Op::Exec("intrinsics::i64::checked_shr".parse().unwrap())], + span, + ); } /// Pops a u32 value, `b`, and a u64 value, `a`, off the stack and rotates the bitwise @@ -729,8 +756,8 @@ impl<'a> OpEmitter<'a> { /// /// The operation will trap if the rotation value is > 63. #[inline] - pub fn rotl_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::rotl".parse().unwrap())); + pub fn rotl_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::rotl".parse().unwrap()), span); } /// Pops a u32 value, `b`, and a u64 value, `a`, off the stack and rotates the bitwise @@ -739,8 +766,8 @@ impl<'a> OpEmitter<'a> { /// /// The operation will trap if the rotation value is > 63. #[inline] - pub fn rotr_u64(&mut self) { - self.emit(Op::Exec("std::math::u64::rotr".parse().unwrap())); + pub fn rotr_u64(&mut self, span: SourceSpan) { + self.emit(Op::Exec("std::math::u64::rotr".parse().unwrap()), span); } } @@ -758,6 +785,6 @@ pub fn to_raw_parts(value: u64) -> (u32, u32) { /// Construct a u64/i64 constant from raw parts, i.e. two 32-bit little-endian limbs #[inline] -pub fn from_raw_parts(lo: u32, hi: u32, block: &mut masm::Block) { - block.push(Op::Push2([Felt::new(lo as u64), Felt::new(hi as u64)])); +pub fn from_raw_parts(lo: u32, hi: u32, block: &mut masm::Block, span: SourceSpan) { + block.push(Op::Push2([Felt::new(lo as u64), Felt::new(hi as u64)]), span); } diff --git a/codegen/masm/src/codegen/emit/mem.rs b/codegen/masm/src/codegen/emit/mem.rs index 178b0f49..87402327 100644 --- a/codegen/masm/src/codegen/emit/mem.rs +++ b/codegen/masm/src/codegen/emit/mem.rs @@ -1,9 +1,9 @@ -use midenc_hir::{self as hir, Felt, FieldElement, StructType, Type}; +use midenc_hir::{self as hir, Felt, FieldElement, SourceSpan, StructType, Type}; use super::OpEmitter; use crate::masm::{NativePtr, Op}; -const PAGE_SIZE: u32 = 64 * 1024; +pub(crate) const PAGE_SIZE: u32 = 64 * 1024; /// Allocation impl<'a> OpEmitter<'a> { @@ -12,28 +12,42 @@ impl<'a> OpEmitter<'a> { /// amount of memory allocated. /// /// The address of that slot is placed on the operand stack. - pub fn alloca(&mut self, ptr: &Type) { + pub fn alloca(&mut self, ptr: &Type, span: SourceSpan) { match ptr { Type::Ptr(pointee) => { let local = self.function.alloc_local(pointee.as_ref().clone()); - self.emit(Op::LocAddr(local)); + self.emit(Op::LocAddr(local), span); self.stack.push(ptr.clone()); } ty => panic!("expected a pointer type, got {ty}"), } } - /// TODO(pauls): For now, we simply return -1 as if the heap cannot be grown any further - pub fn mem_grow(&mut self) { - let _size = self.stack.pop().expect("operand stack is empty"); - self.emit(Op::PushU32(-1i32 as u32)); + /// Return the base address of the heap + #[allow(unused)] + pub fn heap_base(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::mem::heap_base".parse().unwrap()), span); + self.stack.push(Type::Ptr(Box::new(Type::U8))); + } + + /// Return the address of the top of the heap + #[allow(unused)] + pub fn heap_top(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::mem::heap_top".parse().unwrap()), span); + self.stack.push(Type::Ptr(Box::new(Type::U8))); + } + + /// Grow the heap (from the perspective of Wasm programs) by N pages, returning the previous + /// size of the heap (in pages) if successful, or -1 if the heap could not be grown. + pub fn mem_grow(&mut self, span: SourceSpan) { + let _num_pages = self.stack.pop().expect("operand stack is empty"); + self.emit(Op::Exec("intrinsics::mem::memory_grow".parse().unwrap()), span); self.stack.push(Type::I32); } - /// TODO(pauls): For now, we simply return u32::MAX as if the heap is already fully grown - pub fn mem_size(&mut self) { - const MAX_HEAP_PAGES: u32 = u32::MAX / PAGE_SIZE; - self.emit(Op::PushU32(MAX_HEAP_PAGES)); + /// Returns the size (in pages) of the heap (from the perspective of Wasm programs) + pub fn mem_size(&mut self, span: SourceSpan) { + self.emit(Op::Exec("intrinsics::mem::memory_size".parse().unwrap()), span); self.stack.push(Type::U32); } } @@ -45,11 +59,11 @@ impl<'a> OpEmitter<'a> { /// /// Internally, this pushes the address of the local on the stack, then delegates to /// [OpEmitter::load] - pub fn load_local(&mut self, local: hir::LocalId) { + pub fn load_local(&mut self, local: hir::LocalId, span: SourceSpan) { let ty = self.function.local(local).ty.clone(); - self.emit(Op::LocAddr(local)); + self.emit(Op::LocAddr(local), span); self.stack.push(Type::Ptr(Box::new(ty.clone()))); - self.load(ty) + self.load(ty, span) } /// Load a value corresponding to the pointee type of a pointer operand on the stack. @@ -57,20 +71,20 @@ impl<'a> OpEmitter<'a> { /// The type of the pointer determines what address space the pointer value represents; /// either the Miden-native address space (word-addressable), or the IR's byte-addressable /// address space. - pub fn load(&mut self, ty: Type) { + pub fn load(&mut self, ty: Type, span: SourceSpan) { let ptr = self.stack.pop().expect("operand stack is empty"); match ptr.ty() { Type::Ptr(_) => { // Convert the pointer to a native pointer representation - self.emit_native_ptr(); + self.emit_native_ptr(span); match &ty { - Type::I128 => self.load_quad_word(None), - Type::I64 | Type::U64 => self.load_double_word(None), - Type::Felt => self.load_felt(None), - Type::I32 | Type::U32 => self.load_word(None), + Type::I128 => self.load_quad_word(None, span), + Type::I64 | Type::U64 => self.load_double_word(None, span), + Type::Felt => self.load_felt(None, span), + Type::I32 | Type::U32 => self.load_word(None, span), ty @ (Type::I16 | Type::U16 | Type::U8 | Type::I8 | Type::I1) => { - self.load_word(None); - self.trunc_int32(ty.size_in_bits() as u32); + self.load_word(None, span); + self.trunc_int32(ty.size_in_bits() as u32, span); } ty => todo!("support for loading {ty} is not yet implemented"), } @@ -86,16 +100,16 @@ impl<'a> OpEmitter<'a> { /// Load a value of type `ty` from `addr`. /// /// NOTE: The address represented by `addr` is in the IR's byte-addressable address space. - pub fn load_imm(&mut self, addr: u32, ty: Type) { + pub fn load_imm(&mut self, addr: u32, ty: Type, span: SourceSpan) { let ptr = NativePtr::from_ptr(addr); match &ty { - Type::I128 => self.load_quad_word(Some(ptr)), - Type::I64 | Type::U64 => self.load_double_word(Some(ptr)), - Type::Felt => self.load_felt(Some(ptr)), - Type::I32 | Type::U32 => self.load_word(Some(ptr)), + Type::I128 => self.load_quad_word(Some(ptr), span), + Type::I64 | Type::U64 => self.load_double_word(Some(ptr), span), + Type::Felt => self.load_felt(Some(ptr), span), + Type::I32 | Type::U32 => self.load_word(Some(ptr), span), Type::I16 | Type::U16 | Type::U8 | Type::I8 | Type::I1 => { - self.load_word(Some(ptr)); - self.trunc_int32(ty.size_in_bits() as u32); + self.load_word(Some(ptr), span); + self.trunc_int32(ty.size_in_bits() as u32, span); } ty => todo!("support for loading {ty} is not yet implemented"), } @@ -109,81 +123,87 @@ impl<'a> OpEmitter<'a> { /// Instructions which must act on a pointer will expect the stack to have /// these values in that order so that they can perform any necessary /// re-alignment. - fn emit_native_ptr(&mut self) { - self.emit_all(&[ - // Copy the address - // - // [addr, addr] - Op::Dup(0), - // Obtain the absolute offset - // - // [abs_offset, addr] - Op::U32ModImm(16), - // Obtain the byte offset - // - // [abs_offset, abs_offset, addr] - Op::Dup(0), - // [offset, abs_offset, addr] - Op::U32ModImm(4), - // Obtain the element index - // - // [abs_offset, offset, addr] - Op::Swap(1), - // [index, byte_offset, addr] - Op::U32DivImm(4), - // Translate the address to Miden's address space - // - // [addr, index, offset] - Op::Movup(2), - // [waddr, index, offset] - Op::U32DivImm(16), - ]); + fn emit_native_ptr(&mut self, span: SourceSpan) { + self.emit_all( + &[ + // Copy the address + // + // [addr, addr] + Op::Dup(0), + // Obtain the absolute offset + // + // [abs_offset, addr] + Op::U32ModImm(16), + // Obtain the byte offset + // + // [abs_offset, abs_offset, addr] + Op::Dup(0), + // [offset, abs_offset, addr] + Op::U32ModImm(4), + // Obtain the element index + // + // [abs_offset, offset, addr] + Op::Swap(1), + // [index, byte_offset, addr] + Op::U32DivImm(4), + // Translate the address to Miden's address space + // + // [addr, index, offset] + Op::Movup(2), + // [waddr, index, offset] + Op::U32DivImm(16), + ], + span, + ); } /// Load a field element from a naturally aligned address, either immediate or dynamic /// /// A native pointer triplet is expected on the stack if an immediate is not given. - fn load_felt(&mut self, ptr: Option) { + fn load_felt(&mut self, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.load_felt_imm(imm); + return self.load_felt_imm(imm, span); } - self.emit(Op::Exec("intrinsics::mem::load_felt".parse().unwrap())); + self.emit(Op::Exec("intrinsics::mem::load_felt".parse().unwrap()), span); } - fn load_felt_imm(&mut self, ptr: NativePtr) { + fn load_felt_imm(&mut self, ptr: NativePtr, span: SourceSpan) { assert!(ptr.is_element_aligned(), "felt values must be naturally aligned"); match ptr.index { - 0 => self.emit(Op::MemLoadImm(ptr.waddr)), + 0 => self.emit(Op::MemLoadImm(ptr.waddr), span), 1 => { - self.emit_all(&[ - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - Op::Movup(4), - Op::Movup(4), - Op::Drop, - Op::Drop, - Op::Drop, - ]); + self.emit_all( + &[ + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + Op::Movup(4), + Op::Movup(4), + Op::Drop, + Op::Drop, + Op::Drop, + ], + span, + ); } 2 => { - self.emit_all(&[ - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - Op::Drop, - Op::Drop, - Op::Swap(1), - Op::Drop, - ]); + self.emit_all( + &[ + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + Op::Drop, + Op::Drop, + Op::Swap(1), + Op::Drop, + ], + span, + ); } 3 => { - self.emit_all(&[ - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - Op::Drop, - Op::Drop, - Op::Drop, - ]); + self.emit_all( + &[Op::Padw, Op::MemLoadwImm(ptr.waddr), Op::Drop, Op::Drop, Op::Drop], + span, + ); } _ => unreachable!(), } @@ -193,404 +213,470 @@ impl<'a> OpEmitter<'a> { /// word /// /// Expects a native pointer triplet on the stack if an immediate address is not given. - fn load_word(&mut self, ptr: Option) { + fn load_word(&mut self, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.load_word_imm(imm); + return self.load_word_imm(imm, span); } - self.emit(Op::Exec("intrinsics::mem::load_sw".parse().unwrap())); + self.emit(Op::Exec("intrinsics::mem::load_sw".parse().unwrap()), span); } /// Loads a single 32-bit machine word from the given immediate address. - fn load_word_imm(&mut self, ptr: NativePtr) { + fn load_word_imm(&mut self, ptr: NativePtr, span: SourceSpan) { let is_aligned = ptr.is_element_aligned(); let rshift = 32 - ptr.offset as u32; match ptr.index { - 0 if is_aligned => self.emit(Op::MemLoadImm(ptr.waddr)), + 0 if is_aligned => self.emit(Op::MemLoadImm(ptr.waddr), span), 0 => { - self.emit_all(&[ - // Load a quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Move the two elements across which the desired machine word spans - // to the bottom of the stack temporarily - Op::Movdn(4), - Op::Movdn(4), - // Drop the unused elements - Op::Drop, - Op::Drop, - // Shift the high bits left by the offset - Op::U32ShlImm(ptr.offset as u32), - // Move the low bits to the top and shift them right - Op::Swap(1), - Op::U32ShrImm(rshift), - // OR the high and low bits together - Op::U32Or, - ]); + self.emit_all( + &[ + // Load a quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Move the two elements across which the desired machine word spans + // to the bottom of the stack temporarily + Op::Movdn(4), + Op::Movdn(4), + // Drop the unused elements + Op::Drop, + Op::Drop, + // Shift the high bits left by the offset + Op::U32ShlImm(ptr.offset as u32), + // Move the low bits to the top and shift them right + Op::Swap(1), + Op::U32ShrImm(rshift), + // OR the high and low bits together + Op::U32Or, + ], + span, + ); } - 1 if is_aligned => self.emit_all(&[ - // Load a quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop the first unused element - Op::Drop, - // Move the desired element past the last two unused - Op::Movdn(3), - // Drop the remaining unused elements - Op::Drop, - Op::Drop, - ]), - 1 => { - self.emit_all(&[ + 1 if is_aligned => self.emit_all( + &[ // Load a quad-word Op::Padw, Op::MemLoadwImm(ptr.waddr), // Drop the first unused element Op::Drop, - // Move the two elements across which the desired machine word spans - // to the bottom of the stack temporarily - Op::Movdn(3), + // Move the desired element past the last two unused Op::Movdn(3), - // Drop the remaining unused element + // Drop the remaining unused elements Op::Drop, - // Shift the high bits left by the offset - Op::U32ShlImm(ptr.offset as u32), - // Move the low bits to the top and shift them right - Op::Swap(1), - Op::U32ShrImm(rshift), - // OR the high and low bits together - Op::U32Or, - ]); + Op::Drop, + ], + span, + ), + 1 => { + self.emit_all( + &[ + // Load a quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop the first unused element + Op::Drop, + // Move the two elements across which the desired machine word spans + // to the bottom of the stack temporarily + Op::Movdn(3), + Op::Movdn(3), + // Drop the remaining unused element + Op::Drop, + // Shift the high bits left by the offset + Op::U32ShlImm(ptr.offset as u32), + // Move the low bits to the top and shift them right + Op::Swap(1), + Op::U32ShrImm(rshift), + // OR the high and low bits together + Op::U32Or, + ], + span, + ); } - 2 if is_aligned => self.emit_all(&[ - // Load a quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop the first two unused elements - Op::Drop, - Op::Drop, - // Swap the last remaining unused element to the top and drop it - Op::Swap(1), - Op::Drop, - ]), - 2 => { - self.emit_all(&[ + 2 if is_aligned => self.emit_all( + &[ // Load a quad-word Op::Padw, Op::MemLoadwImm(ptr.waddr), // Drop the first two unused elements Op::Drop, Op::Drop, - // Shift the high bits left by the offset - Op::U32ShlImm(ptr.offset as u32), - // Move the low bits to the top and shift them right + // Swap the last remaining unused element to the top and drop it Op::Swap(1), - Op::U32ShrImm(rshift), - // OR the high and low bits together - Op::U32Or, - ]); - } - 3 if is_aligned => self.emit_all(&[ - // Load a quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop the three unused elements - Op::Drop, - Op::Drop, - Op::Drop, - ]), - 3 => { - self.emit_all(&[ - // Load the quad-word containing the low bits - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - // Move the element we need to the bottom temporarily - Op::Movdn(4), - // Drop the unused elements - Op::Drop, - Op::Drop, Op::Drop, - // Shift the low bits right by the offset - Op::U32ShrImm(rshift), - // Load the quad-word containing the high bits + ], + span, + ), + 2 => { + self.emit_all( + &[ + // Load a quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop the first two unused elements + Op::Drop, + Op::Drop, + // Shift the high bits left by the offset + Op::U32ShlImm(ptr.offset as u32), + // Move the low bits to the top and shift them right + Op::Swap(1), + Op::U32ShrImm(rshift), + // OR the high and low bits together + Op::U32Or, + ], + span, + ); + } + 3 if is_aligned => self.emit_all( + &[ + // Load a quad-word Op::Padw, Op::MemLoadwImm(ptr.waddr), - // Drop the unused elements + // Drop the three unused elements Op::Drop, Op::Drop, Op::Drop, - // Shift the high bits left by the offset - Op::U32ShlImm(ptr.offset as u32), - // OR the high and low bits together - Op::U32Or, - ]); + ], + span, + ), + 3 => { + self.emit_all( + &[ + // Load the quad-word containing the low bits + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + // Move the element we need to the bottom temporarily + Op::Movdn(4), + // Drop the unused elements + Op::Drop, + Op::Drop, + Op::Drop, + // Shift the low bits right by the offset + Op::U32ShrImm(rshift), + // Load the quad-word containing the high bits + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop the unused elements + Op::Drop, + Op::Drop, + Op::Drop, + // Shift the high bits left by the offset + Op::U32ShlImm(ptr.offset as u32), + // OR the high and low bits together + Op::U32Or, + ], + span, + ); } _ => unreachable!(), } } /// Load a pair of machine words (32-bit elements) to the operand stack - fn load_double_word(&mut self, ptr: Option) { + fn load_double_word(&mut self, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.load_double_word_imm(imm); + return self.load_double_word_imm(imm, span); } - self.emit(Op::Exec("intrinsics::mem::load_dw".parse().unwrap())); + self.emit(Op::Exec("intrinsics::mem::load_dw".parse().unwrap()), span); } - fn load_double_word_imm(&mut self, ptr: NativePtr) { + fn load_double_word_imm(&mut self, ptr: NativePtr, span: SourceSpan) { let aligned = ptr.is_element_aligned(); match ptr.index { 0 if aligned => { - self.emit_all(&[ - // Load quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Move the two elements we need to the bottom temporarily - Op::Movdn(4), - Op::Movdn(4), - // Drop the unused elements - Op::Drop, - Op::Drop, - ]); + self.emit_all( + &[ + // Load quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Move the two elements we need to the bottom temporarily + Op::Movdn(4), + Op::Movdn(4), + // Drop the unused elements + Op::Drop, + Op::Drop, + ], + span, + ); } 0 => { // An unaligned double-word load spans three elements - self.emit_all(&[ - // Load quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Move the unused element to the top and drop it - Op::Movup(4), - Op::Drop, - ]); - self.realign_double_word(ptr); + self.emit_all( + &[ + // Load quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Move the unused element to the top and drop it + Op::Movup(4), + Op::Drop, + ], + span, + ); + self.realign_double_word(ptr, span); } 1 if aligned => { - self.emit_all(&[ - // Load quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop the first word, its unused - Op::Drop, - // Move the last word up and drop it, also unused - Op::Movup(3), - Op::Drop, - ]); + self.emit_all( + &[ + // Load quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop the first word, its unused + Op::Drop, + // Move the last word up and drop it, also unused + Op::Movup(3), + Op::Drop, + ], + span, + ); } 1 => { // An unaligned double-word load spans three elements - self.emit_all(&[ - // Load a quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop the unused element - Op::Drop, - ]); - self.realign_double_word(ptr); + self.emit_all( + &[ + // Load a quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop the unused element + Op::Drop, + ], + span, + ); + self.realign_double_word(ptr, span); } 2 if aligned => { - self.emit_all(&[ - // Load quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop unused words - Op::Drop, - Op::Drop, - ]); + self.emit_all( + &[ + // Load quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop unused words + Op::Drop, + Op::Drop, + ], + span, + ); } 2 => { // An unaligned double-word load spans three elements, // and in this case, two quad-words, because the last // element is across a quad-word boundary - self.emit_all(&[ - // Load the second quad-word first - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - // Move the element we need to the bottom temporarily - Op::Movdn(4), - // Drop the three unused elements of this word - Op::Drop, - Op::Drop, - Op::Drop, - // Load the first quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop the two unused elements - Op::Drop, - Op::Drop, - ]); - self.realign_double_word(ptr); + self.emit_all( + &[ + // Load the second quad-word first + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + // Move the element we need to the bottom temporarily + Op::Movdn(4), + // Drop the three unused elements of this word + Op::Drop, + Op::Drop, + Op::Drop, + // Load the first quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop the two unused elements + Op::Drop, + Op::Drop, + ], + span, + ); + self.realign_double_word(ptr, span); } 3 if aligned => { - self.emit_all(&[ - // Load second word, drop unused elements - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - Op::Movup(4), - Op::Drop, - Op::Movup(3), - Op::Drop, - // Load first word, drop unused elements - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - Op::Drop, - Op::Drop, - Op::Drop, - ]); + self.emit_all( + &[ + // Load second word, drop unused elements + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + Op::Movup(4), + Op::Drop, + Op::Movup(3), + Op::Drop, + // Load first word, drop unused elements + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + Op::Drop, + Op::Drop, + Op::Drop, + ], + span, + ); } 3 => { - self.emit_all(&[ - // Load second word, drop unused element - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - Op::Movup(4), - Op::Drop, - // Load first word, drop unused elements - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - Op::Drop, - Op::Drop, - Op::Drop, - ]); - self.realign_double_word(ptr); + self.emit_all( + &[ + // Load second word, drop unused element + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + Op::Movup(4), + Op::Drop, + // Load first word, drop unused elements + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + Op::Drop, + Op::Drop, + Op::Drop, + ], + span, + ); + self.realign_double_word(ptr, span); } _ => unimplemented!("unaligned loads are not yet implemented: {ptr:#?}"), } } /// Load a quartet of machine words (32-bit elements) to the operand stack - fn load_quad_word(&mut self, ptr: Option) { + fn load_quad_word(&mut self, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.load_quad_word_imm(imm); + return self.load_quad_word_imm(imm, span); } - self.emit(Op::Exec("intrinsics::mem::load_qw".parse().unwrap())); + self.emit(Op::Exec("intrinsics::mem::load_qw".parse().unwrap()), span); } - fn load_quad_word_imm(&mut self, ptr: NativePtr) { + fn load_quad_word_imm(&mut self, ptr: NativePtr, span: SourceSpan) { // For all other cases, more complicated loads are required let aligned = ptr.is_element_aligned(); match ptr.index { // Naturally-aligned - 0 if aligned => self.emit_all(&[Op::Padw, Op::MemLoadwImm(ptr.waddr)]), + 0 if aligned => self.emit_all(&[Op::Padw, Op::MemLoadwImm(ptr.waddr)], span), 0 => { // An unaligned quad-word load spans five elements - self.emit_all(&[ - // Load second quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - // Drop all but the first element - Op::Movdn(4), - Op::Drop, - Op::Drop, - Op::Drop, - // Load first quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - ]); - self.realign_quad_word(ptr); + self.emit_all( + &[ + // Load second quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + // Drop all but the first element + Op::Movdn(4), + Op::Drop, + Op::Drop, + Op::Drop, + // Load first quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + ], + span, + ); + self.realign_quad_word(ptr, span); } 1 if aligned => { - self.emit_all(&[ - // Load second quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - // Drop last element - Op::Movup(4), - Op::Drop, - // Load first quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop first element - Op::Drop, - ]); + self.emit_all( + &[ + // Load second quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + // Drop last element + Op::Movup(4), + Op::Drop, + // Load first quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop first element + Op::Drop, + ], + span, + ); } 1 => { // An unaligned double-word load spans five elements - self.emit_all(&[ - // Load second quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - // Drop all but the first two elements - Op::Movdn(4), - Op::Movdn(4), - Op::Drop, - Op::Drop, - // Load first quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop the first word - Op::Drop, - ]); - self.realign_quad_word(ptr); + self.emit_all( + &[ + // Load second quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + // Drop all but the first two elements + Op::Movdn(4), + Op::Movdn(4), + Op::Drop, + Op::Drop, + // Load first quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop the first word + Op::Drop, + ], + span, + ); + self.realign_quad_word(ptr, span); } 2 if aligned => { - self.emit_all(&[ - // Load second quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop last two elements - Op::Movup(4), - Op::Movup(4), - Op::Drop, - Op::Drop, - // Load first quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop first two elements - Op::Drop, - Op::Drop, - ]); + self.emit_all( + &[ + // Load second quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop last two elements + Op::Movup(4), + Op::Movup(4), + Op::Drop, + Op::Drop, + // Load first quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop first two elements + Op::Drop, + Op::Drop, + ], + span, + ); } 2 => { // An unaligned double-word load spans five elements - self.emit_all(&[ - // Load the second quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - // Drop the last element - Op::Movup(4), - Op::Drop, - // Load the first quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop the two unused elements - Op::Drop, - Op::Drop, - ]); - self.realign_quad_word(ptr); + self.emit_all( + &[ + // Load the second quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + // Drop the last element + Op::Movup(4), + Op::Drop, + // Load the first quad-word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop the two unused elements + Op::Drop, + Op::Drop, + ], + span, + ); + self.realign_quad_word(ptr, span); } 3 if aligned => { - self.emit_all(&[ - // Load second word, drop last element - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - Op::Movup(4), - Op::Drop, - // Load first word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop first three elements - Op::Drop, - Op::Drop, - Op::Drop, - ]); + self.emit_all( + &[ + // Load second word, drop last element + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + Op::Movup(4), + Op::Drop, + // Load first word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop first three elements + Op::Drop, + Op::Drop, + Op::Drop, + ], + span, + ); } 3 => { // An unaligned quad-word load spans five elements, - self.emit_all(&[ - // Load second word - Op::Padw, - Op::MemLoadwImm(ptr.waddr + 1), - // Load first word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Drop unused elements - Op::Drop, - Op::Drop, - Op::Drop, - ]); - self.realign_quad_word(ptr); + self.emit_all( + &[ + // Load second word + Op::Padw, + Op::MemLoadwImm(ptr.waddr + 1), + // Load first word + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Drop unused elements + Op::Drop, + Op::Drop, + Op::Drop, + ], + span, + ); + self.realign_quad_word(ptr, span); } _ => unimplemented!("unaligned loads are not yet implemented: {ptr:#?}"), } @@ -635,69 +721,72 @@ impl<'a> OpEmitter<'a> { /// have to perform a sequence of shifts and masks to get the bits where they belong. This /// function performs those steps, with the assumption that the caller has three values on /// the operand stack representing any unaligned double-word value - fn realign_double_word(&mut self, ptr: NativePtr) { + fn realign_double_word(&mut self, ptr: NativePtr, span: SourceSpan) { // The stack starts as: [chunk_hi, chunk_mid, chunk_lo] // // We will refer to the parts of our desired double-word value // as two parts, `x_hi` and `x_lo`. - self.emit_all(&[ - // Re-align the high bits by shifting out the offset - // - // This gives us the first half of the first word. - // - // [x_hi_hi, chunk_mid, chunk__lo] - Op::U32ShlImm(ptr.offset as u32), - // Move the value below the other chunks temporarily - // - // [chunk_mid, chunk_lo, x_hi_hi] - Op::Movdn(3), - // We must split the middle chunk into two parts, - // one containing the bits to be combined with the - // first machine word; the other to be combined with - // the second machine word. - // - // First, we duplicate the chunk, since we need two - // copies of it: - // - // [chunk_mid, chunk_mid, chunk_lo, x_hi_hi] - Op::Dup(0), - // Then, we shift the chunk right by 32 - offset bits, - // re-aligning the low bits of the first word, and - // isolating them. - // - // [x_hi_lo, chunk_mid, chunk_lo, x_hi_hi] - Op::U32ShrImm(32 - ptr.offset as u32), - // Move the high bits back to the top - // - // [x_hi_hi, x_hi_lo, chunk_mid, chunk_lo] - Op::Movup(3), - // OR the two parts of the `x_hi` chunk together - // - // [x_hi, chunk_mid, chunk_lo] - Op::U32Or, - // Move `x_hi` to the bottom for later - Op::Movdn(2), - // Now, we need to re-align the high bits of the second word - // by shifting the remaining copy of the middle chunk, similar - // to what we did at the very beginning. - // - // This gives us the first half of the second word. - // - // [x_lo_hi, chunk_lo, x_hi] - Op::U32ShlImm(ptr.offset as u32), - // Next, swap the low bit chunk to the top temporarily - Op::Swap(1), - // Shift the value right, as done previously for the middle chunk - Op::U32ShrImm(32 - ptr.offset as u32), - // OR the two halves together, giving us our second word, `x_lo` - // - // [x_lo, x_hi] - Op::U32Or, - // Swap the words so they are in the correct order - // - // [x_hi, x_lo] - Op::Swap(1), - ]); + self.emit_all( + &[ + // Re-align the high bits by shifting out the offset + // + // This gives us the first half of the first word. + // + // [x_hi_hi, chunk_mid, chunk__lo] + Op::U32ShlImm(ptr.offset as u32), + // Move the value below the other chunks temporarily + // + // [chunk_mid, chunk_lo, x_hi_hi] + Op::Movdn(3), + // We must split the middle chunk into two parts, + // one containing the bits to be combined with the + // first machine word; the other to be combined with + // the second machine word. + // + // First, we duplicate the chunk, since we need two + // copies of it: + // + // [chunk_mid, chunk_mid, chunk_lo, x_hi_hi] + Op::Dup(0), + // Then, we shift the chunk right by 32 - offset bits, + // re-aligning the low bits of the first word, and + // isolating them. + // + // [x_hi_lo, chunk_mid, chunk_lo, x_hi_hi] + Op::U32ShrImm(32 - ptr.offset as u32), + // Move the high bits back to the top + // + // [x_hi_hi, x_hi_lo, chunk_mid, chunk_lo] + Op::Movup(3), + // OR the two parts of the `x_hi` chunk together + // + // [x_hi, chunk_mid, chunk_lo] + Op::U32Or, + // Move `x_hi` to the bottom for later + Op::Movdn(2), + // Now, we need to re-align the high bits of the second word + // by shifting the remaining copy of the middle chunk, similar + // to what we did at the very beginning. + // + // This gives us the first half of the second word. + // + // [x_lo_hi, chunk_lo, x_hi] + Op::U32ShlImm(ptr.offset as u32), + // Next, swap the low bit chunk to the top temporarily + Op::Swap(1), + // Shift the value right, as done previously for the middle chunk + Op::U32ShrImm(32 - ptr.offset as u32), + // OR the two halves together, giving us our second word, `x_lo` + // + // [x_lo, x_hi] + Op::U32Or, + // Swap the words so they are in the correct order + // + // [x_hi, x_lo] + Op::Swap(1), + ], + span, + ); } /// This handles emitting code that handles aligning an unaligned quad machine-word value @@ -714,131 +803,134 @@ impl<'a> OpEmitter<'a> { /// /// See the example in [OpEmitter::realign_quad_word] for more details on how bits are /// laid out in each word, and what is required to realign unaligned words. - fn realign_quad_word(&mut self, ptr: NativePtr) { + fn realign_quad_word(&mut self, ptr: NativePtr, span: SourceSpan) { // The stack starts as: [chunk_hi, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo] // // We will refer to the parts of our desired quad-word value // as four parts, `x_hi2`, `x_hi1`, `x_lo2`, and `x_lo1`, where // the integer suffix should appear in decreasing order on the // stack when we're done. - self.emit_all(&[ - // Re-align the high bits by shifting out the offset - // - // This gives us the first half of `x_hi2`. - // - // [x_hi2_hi, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk__lo] - Op::U32ShlImm(ptr.offset as u32), - // Move the value below the other chunks temporarily - // - // [chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk__lo, x_hi2_hi] - Op::Movdn(5), - // We must split the `chunk_mid_hi` chunk into two parts, - // one containing the bits to be combined with `x_hi2_hi`; - // the other to be combined with `x_hi1_hi`. - // - // First, we duplicate the chunk, since we need two - // copies of it: - // - // [chunk_mid_hi, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2_hi] - Op::Dup(0), - // Then, we shift the chunk right by 32 - offset bits, - // re-aligning the low bits of `x_hi2`, and isolating them. - // - // [x_hi2_lo, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2_hi] - Op::U32ShrImm(32 - ptr.offset as u32), - // Move the high bits of `x_hi2` back to the top - // - // [x_hi2_hi, x_hi2_lo, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo] - Op::Movup(3), - // OR the two parts of the `x_hi2` chunk together - // - // [x_hi2, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo] - Op::U32Or, - // Move `x_hi2` to the bottom for later - // - // [chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2] - Op::Movdn(5), - // Now, we need to re-align the high bits of `x_hi1` by shifting - // the remaining copy of `chunk_mid_hi`, similar to what we did for `x_hi2` - // - // This gives us the first half of `x_hi1` - // - // [x_hi1_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2] - Op::U32ShlImm(ptr.offset as u32), - // Next, move the chunk containing the low bits of `x_hi1` to the top temporarily - // - // [chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2, x_hi1_hi] - Op::Movdn(5), - // Duplicate it, as we need two copies - // - // [chunk_mid_mid, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2, x_hi1_hi] - Op::Dup(0), - // Shift the value right, as done previously for the low bits of `x_hi2` - // - // [x_hi1_lo, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2, x_hi1_hi] - Op::U32ShrImm(32 - ptr.offset as u32), - // Move the high bits of `x_hi1` to the top - Op::Movup(5), - // OR the two halves together, giving us our second word, `x_hi1` - // - // [x_hi1, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2] - Op::U32Or, - // Move the word to the bottom of the stack - // - // [chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2, x_hi1] - Op::Movdn(5), - // Now, we need to re-align the high bits of `x_lo2` by shifting - // the remaining copy of `chunk_mid_mid`, as done previously. - // - // [x_lo2_hi, chunk_mid_lo, chunk_lo, x_hi2, x_hi1] - Op::U32ShlImm(ptr.offset as u32), - // Next, move the chunk containing the low bits of `x_lo2` to the top temporarily - // - // [chunk_mid_lo, chunk_lo, x_hi2, x_hi1, x_lo2_hi] - Op::Movdn(5), - // Duplicate it, as done previously - // - // [chunk_mid_lo, chunk_mid_lo, chunk_lo, x_hi2, x_hi1, x_lo2_hi] - Op::Dup(0), - // Shift the value right to get the low bits of `x_lo2` - // - // [x_lo2_lo, chunk_mid_lo, chunk_lo, x_hi2, x_hi1, x_lo2_hi] - Op::U32ShrImm(32 - ptr.offset as u32), - // Move the high bits of `x_lo2` to the top - // - // [x_lo2_hi, x_lo2_lo, chunk_mid_lo, chunk_lo, x_hi2, x_hi1] - Op::Movup(6), - // OR the two halves together, giving us our third word, `x_lo2` - // - // [x_lo2, chunk_mid_lo, chunk_lo, x_hi2, x_hi1] - Op::U32Or, - // Move to the bottom of the stack - // - // [chunk_mid_lo, chunk_lo, x_hi2, x_hi1, x_lo2] - Op::Movdn(5), - // Re-align the high bits of `x_lo1` - // - // [x_lo1_hi, chunk_lo, x_hi2, x_hi1, x_lo2] - Op::U32ShlImm(ptr.offset as u32), - // Move the chunk containing the low bits to the top - // - // [chunk_lo, x_hi2, x_hi1, x_lo2, x_lo1_hi] - Op::Movdn(5), - // Shift the value right to get the low bits of `x_lo1` - Op::U32ShrImm(32 - ptr.offset as u32), - // Move the high bits of `x_lo1` to the top - // - // [x_lo1_hi, x_lo1_lo, x_hi2, x_hi1, x_lo2] - Op::Movup(5), - // OR the two halves together, giving us our fourth word, `x_lo1` - // - // [x_lo1, x_hi2, x_hi1, x_lo2] - Op::U32Or, - // Move to the bottom - // - // [x_hi2, x_hi1, x_lo2, x_lo1] - Op::Movdn(5), - ]); + self.emit_all( + &[ + // Re-align the high bits by shifting out the offset + // + // This gives us the first half of `x_hi2`. + // + // [x_hi2_hi, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk__lo] + Op::U32ShlImm(ptr.offset as u32), + // Move the value below the other chunks temporarily + // + // [chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk__lo, x_hi2_hi] + Op::Movdn(5), + // We must split the `chunk_mid_hi` chunk into two parts, + // one containing the bits to be combined with `x_hi2_hi`; + // the other to be combined with `x_hi1_hi`. + // + // First, we duplicate the chunk, since we need two + // copies of it: + // + // [chunk_mid_hi, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2_hi] + Op::Dup(0), + // Then, we shift the chunk right by 32 - offset bits, + // re-aligning the low bits of `x_hi2`, and isolating them. + // + // [x_hi2_lo, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2_hi] + Op::U32ShrImm(32 - ptr.offset as u32), + // Move the high bits of `x_hi2` back to the top + // + // [x_hi2_hi, x_hi2_lo, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo] + Op::Movup(3), + // OR the two parts of the `x_hi2` chunk together + // + // [x_hi2, chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo] + Op::U32Or, + // Move `x_hi2` to the bottom for later + // + // [chunk_mid_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2] + Op::Movdn(5), + // Now, we need to re-align the high bits of `x_hi1` by shifting + // the remaining copy of `chunk_mid_hi`, similar to what we did for `x_hi2` + // + // This gives us the first half of `x_hi1` + // + // [x_hi1_hi, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2] + Op::U32ShlImm(ptr.offset as u32), + // Next, move the chunk containing the low bits of `x_hi1` to the top temporarily + // + // [chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2, x_hi1_hi] + Op::Movdn(5), + // Duplicate it, as we need two copies + // + // [chunk_mid_mid, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2, x_hi1_hi] + Op::Dup(0), + // Shift the value right, as done previously for the low bits of `x_hi2` + // + // [x_hi1_lo, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2, x_hi1_hi] + Op::U32ShrImm(32 - ptr.offset as u32), + // Move the high bits of `x_hi1` to the top + Op::Movup(5), + // OR the two halves together, giving us our second word, `x_hi1` + // + // [x_hi1, chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2] + Op::U32Or, + // Move the word to the bottom of the stack + // + // [chunk_mid_mid, chunk_mid_lo, chunk_lo, x_hi2, x_hi1] + Op::Movdn(5), + // Now, we need to re-align the high bits of `x_lo2` by shifting + // the remaining copy of `chunk_mid_mid`, as done previously. + // + // [x_lo2_hi, chunk_mid_lo, chunk_lo, x_hi2, x_hi1] + Op::U32ShlImm(ptr.offset as u32), + // Next, move the chunk containing the low bits of `x_lo2` to the top temporarily + // + // [chunk_mid_lo, chunk_lo, x_hi2, x_hi1, x_lo2_hi] + Op::Movdn(5), + // Duplicate it, as done previously + // + // [chunk_mid_lo, chunk_mid_lo, chunk_lo, x_hi2, x_hi1, x_lo2_hi] + Op::Dup(0), + // Shift the value right to get the low bits of `x_lo2` + // + // [x_lo2_lo, chunk_mid_lo, chunk_lo, x_hi2, x_hi1, x_lo2_hi] + Op::U32ShrImm(32 - ptr.offset as u32), + // Move the high bits of `x_lo2` to the top + // + // [x_lo2_hi, x_lo2_lo, chunk_mid_lo, chunk_lo, x_hi2, x_hi1] + Op::Movup(6), + // OR the two halves together, giving us our third word, `x_lo2` + // + // [x_lo2, chunk_mid_lo, chunk_lo, x_hi2, x_hi1] + Op::U32Or, + // Move to the bottom of the stack + // + // [chunk_mid_lo, chunk_lo, x_hi2, x_hi1, x_lo2] + Op::Movdn(5), + // Re-align the high bits of `x_lo1` + // + // [x_lo1_hi, chunk_lo, x_hi2, x_hi1, x_lo2] + Op::U32ShlImm(ptr.offset as u32), + // Move the chunk containing the low bits to the top + // + // [chunk_lo, x_hi2, x_hi1, x_lo2, x_lo1_hi] + Op::Movdn(5), + // Shift the value right to get the low bits of `x_lo1` + Op::U32ShrImm(32 - ptr.offset as u32), + // Move the high bits of `x_lo1` to the top + // + // [x_lo1_hi, x_lo1_lo, x_hi2, x_hi1, x_lo2] + Op::Movup(5), + // OR the two halves together, giving us our fourth word, `x_lo1` + // + // [x_lo1, x_hi2, x_hi1, x_lo2] + Op::U32Or, + // Move to the bottom + // + // [x_hi2, x_hi1, x_lo2, x_lo1] + Op::Movdn(5), + ], + span, + ); } } @@ -849,11 +941,11 @@ impl<'a> OpEmitter<'a> { /// /// Internally, this pushes the address of the given local on the stack, and delegates to /// [OpEmitter::store] to perform the actual store. - pub fn store_local(&mut self, local: hir::LocalId) { + pub fn store_local(&mut self, local: hir::LocalId, span: SourceSpan) { let ty = self.function.local(local).ty.clone(); - self.emit(Op::LocAddr(local)); + self.emit(Op::LocAddr(local), span); self.stack.push(Type::Ptr(Box::new(ty))); - self.store() + self.store(span) } /// Store a value of type `value` to the address in the Miden address space @@ -861,7 +953,7 @@ impl<'a> OpEmitter<'a> { /// /// The type of the pointer is given as `ptr`, and can be used for both validation and /// determining alignment. - pub fn store(&mut self) { + pub fn store(&mut self, span: SourceSpan) { let ptr = self.stack.pop().expect("operand stack is empty"); let value = self.stack.pop().expect("operand stack is empty"); let ptr_ty = ptr.ty(); @@ -871,15 +963,15 @@ impl<'a> OpEmitter<'a> { match ptr_ty { Type::Ptr(_) => { // Convert the pointer to a native pointer representation - self.emit_native_ptr(); + self.emit_native_ptr(span); match value_ty { - Type::I128 => self.store_quad_word(None), - Type::I64 | Type::U64 => self.store_double_word(None), - Type::Felt => self.store_felt(None), - Type::I32 | Type::U32 => self.store_word(None), - ref ty if ty.size_in_bytes() <= 4 => self.store_small(ty, None), - Type::Array(ref elem_ty, _) => self.store_array(elem_ty, None), - Type::Struct(ref struct_ty) => self.store_struct(struct_ty, None), + Type::I128 => self.store_quad_word(None, span), + Type::I64 | Type::U64 => self.store_double_word(None, span), + Type::Felt => self.store_felt(None, span), + Type::I32 | Type::U32 => self.store_word(None, span), + ref ty if ty.size_in_bytes() <= 4 => self.store_small(ty, None, span), + Type::Array(ref elem_ty, _) => self.store_array(elem_ty, None, span), + Type::Struct(ref struct_ty) => self.store_struct(struct_ty, None, span), ty => unimplemented!( "invalid store: support for storing {ty} has not been implemented" ), @@ -895,26 +987,26 @@ impl<'a> OpEmitter<'a> { /// Store a value of type `ty` to `addr`. /// /// NOTE: The address represented by `addr` is in the IR's byte-addressable address space. - pub fn store_imm(&mut self, addr: u32) { + pub fn store_imm(&mut self, addr: u32, span: SourceSpan) { let value = self.stack.pop().expect("operand stack is empty"); let value_ty = value.ty(); assert!(!value_ty.is_zst(), "cannot store a zero-sized type in memory"); let ptr = NativePtr::from_ptr(addr); match value_ty { - Type::I128 => self.store_quad_word(Some(ptr)), - Type::I64 | Type::U64 => self.store_double_word(Some(ptr)), - Type::Felt => self.store_felt(Some(ptr)), - Type::I32 | Type::U32 => self.store_word(Some(ptr)), - ref ty if ty.size_in_bytes() <= 4 => self.store_small(ty, Some(ptr)), - Type::Array(ref elem_ty, _) => self.store_array(elem_ty, Some(ptr)), - Type::Struct(ref struct_ty) => self.store_struct(struct_ty, Some(ptr)), + Type::I128 => self.store_quad_word(Some(ptr), span), + Type::I64 | Type::U64 => self.store_double_word(Some(ptr), span), + Type::Felt => self.store_felt(Some(ptr), span), + Type::I32 | Type::U32 => self.store_word(Some(ptr), span), + ref ty if ty.size_in_bytes() <= 4 => self.store_small(ty, Some(ptr), span), + Type::Array(ref elem_ty, _) => self.store_array(elem_ty, Some(ptr), span), + Type::Struct(ref struct_ty) => self.store_struct(struct_ty, Some(ptr), span), ty => { unimplemented!("invalid store: support for storing {ty} has not been implemented") } } } - pub fn memset(&mut self) { + pub fn memset(&mut self, span: SourceSpan) { let dst = self.stack.pop().expect("operand stack is empty"); let count = self.stack.pop().expect("operand stack is empty"); let value = self.stack.pop().expect("operand stack is empty"); @@ -926,28 +1018,34 @@ impl<'a> OpEmitter<'a> { // Prepare to loop until `count` iterations have been performed let current_block = self.current_block; let body = self.function.create_block(); - self.emit_all(&[ - // [dst, count, value..] - Op::PushU32(0), // [i, dst, count, value..] - Op::Dup(2), // [count, i, dst, count, value..] - Op::GteImm(Felt::ZERO), // [count > 0, i, dst, count, value..] - Op::While(body), - ]); + self.emit_all( + &[ + // [dst, count, value..] + Op::PushU32(0), // [i, dst, count, value..] + Op::Dup(2), // [count, i, dst, count, value..] + Op::GteImm(Felt::ZERO), // [count > 0, i, dst, count, value..] + Op::While(body), + ], + span, + ); // Loop body - compute address for next value to be written let value_size = value.ty().size_in_bytes(); self.switch_to_block(body); - self.emit_all(&[ - // [i, dst, count, value..] - // Offset the pointer by the current iteration count * aligned size of value, and trap - // if it overflows - Op::Dup(1), // [dst, i, dst, count, value] - Op::Dup(1), // [i, dst, i, dst, count, value] - Op::PushU32(value_size.try_into().expect("invalid value size")), /* [value_size, i, - * dst, ..] */ - Op::U32OverflowingMadd, // [value_size * i + dst, i, dst, count, value] - Op::Assertz, // [aligned_dst, i, dst, count, value..] - ]); + self.emit_all( + &[ + // [i, dst, count, value..] + // Offset the pointer by the current iteration count * aligned size of value, and + // trap if it overflows + Op::Dup(1), // [dst, i, dst, count, value] + Op::Dup(1), // [i, dst, i, dst, count, value] + Op::PushU32(value_size.try_into().expect("invalid value size")), /* [value_size, i, + * dst, ..] */ + Op::U32OverflowingMadd, // [value_size * i + dst, i, dst, count, value] + Op::Assertz, // [aligned_dst, i, dst, count, value..] + ], + span, + ); // Loop body - move value to top of stack, swap with pointer self.stack.push(value); @@ -955,23 +1053,26 @@ impl<'a> OpEmitter<'a> { self.stack.push(dst.clone()); self.stack.push(dst.ty()); self.stack.push(dst.ty()); - self.dup(4); // [value, aligned_dst, i, dst, count, value] - self.swap(1); // [aligned_dst, value, i, dst, count, value] + self.dup(4, span); // [value, aligned_dst, i, dst, count, value] + self.swap(1, span); // [aligned_dst, value, i, dst, count, value] // Loop body - write value to destination - self.store(); // [i, dst, count, value] + self.store(span); // [i, dst, count, value] // Loop body - increment iteration count, determine whether to continue loop - self.emit_all(&[ - Op::U32WrappingAddImm(1), - Op::Dup(0), // [i++, i++, dst, count, value] - Op::Dup(3), // [count, i++, i++, dst, count, value] - Op::U32Gte, // [i++ >= count, i++, dst, count, value] - ]); + self.emit_all( + &[ + Op::U32WrappingAddImm(1), + Op::Dup(0), // [i++, i++, dst, count, value] + Op::Dup(3), // [count, i++, i++, dst, count, value] + Op::U32Gte, // [i++ >= count, i++, dst, count, value] + ], + span, + ); // Cleanup - at end of 'while' loop, drop the 4 operands remaining on the stack self.switch_to_block(current_block); - self.dropn(4); + self.dropn(4, span); } /// Copy `count * sizeof(*ty)` from a source address to a destination address. @@ -985,7 +1086,7 @@ impl<'a> OpEmitter<'a> { /// The semantics of this instruction are as follows: /// /// * The `` - pub fn memcpy(&mut self) { + pub fn memcpy(&mut self, span: SourceSpan) { let src = self.stack.pop().expect("operand stack is empty"); let dst = self.stack.pop().expect("operand stack is empty"); let count = self.stack.pop().expect("operand stack is empty"); @@ -1000,11 +1101,14 @@ impl<'a> OpEmitter<'a> { match value_size { // Word-sized values have an optimized intrinsic we can lean on 16 => { - self.emit_all(&[ - // [src, dst, count] - Op::Movup(2), // [count, src, dst] - Op::Exec("std::mem::memcopy".parse().unwrap()), - ]); + self.emit_all( + &[ + // [src, dst, count] + Op::Movup(2), // [count, src, dst] + Op::Exec("std::mem::memcopy".parse().unwrap()), + ], + span, + ); return; } // Values which can be broken up into word-sized chunks can piggy-back on the @@ -1012,13 +1116,16 @@ impl<'a> OpEmitter<'a> { // multiplying `count` by the number of words in each value size if size % 16 == 0 => { let factor = size / 16; - self.emit_all(&[ - // [src, dst, count] - Op::Movup(2), // [count, src, dst] - Op::U32OverflowingMulImm(factor), - Op::Assertz, // [count * (size / 16), src, dst] - Op::Exec("std::mem::memcopy".parse().unwrap()), - ]); + self.emit_all( + &[ + // [src, dst, count] + Op::Movup(2), // [count, src, dst] + Op::U32OverflowingMulImm(factor), + Op::Assertz, // [count * (size / 16), src, dst] + Op::Exec("std::mem::memcopy".parse().unwrap()), + ], + span, + ); return; } // For now, all other values fallback to the default implementation @@ -1028,31 +1135,37 @@ impl<'a> OpEmitter<'a> { // Prepare to loop until `count` iterations have been performed let current_block = self.current_block; let body = self.function.create_block(); - self.emit_all(&[ - // [src, dst, count] - Op::PushU32(0), // [i, src, dst, count] - Op::Dup(3), // [count, i, src, dst, count] - Op::GteImm(Felt::ZERO), // [count > 0, i, src, dst, count] - Op::While(body), - ]); + self.emit_all( + &[ + // [src, dst, count] + Op::PushU32(0), // [i, src, dst, count] + Op::Dup(3), // [count, i, src, dst, count] + Op::GteImm(Felt::ZERO), // [count > 0, i, src, dst, count] + Op::While(body), + ], + span, + ); // Loop body - compute address for next value to be written self.switch_to_block(body); // Compute the source and destination addresses - self.emit_all(&[ - // [i, src, dst, count] - Op::Dup(2), // [dst, i, src, dst, count] - Op::Dup(1), // [i, dst, i, src, dst, count] - Op::PushU32(value_size), // [offset, i, dst, i, src, dst, count] - Op::U32OverflowingMadd, - Op::Assertz, // [new_dst := i * offset + dst, i, src, dst, count] - Op::Dup(2), // [src, new_dst, i, src, dst, count] - Op::Dup(2), // [i, src, new_dst, i, src, dst, count] - Op::PushU32(value_size), // [offset, i, src, new_dst, i, src, dst, count] - Op::U32OverflowingMadd, - Op::Assertz, // [new_src := i * offset + src, new_dst, i, src, dst, count] - ]); + self.emit_all( + &[ + // [i, src, dst, count] + Op::Dup(2), // [dst, i, src, dst, count] + Op::Dup(1), // [i, dst, i, src, dst, count] + Op::PushU32(value_size), // [offset, i, dst, i, src, dst, count] + Op::U32OverflowingMadd, + Op::Assertz, // [new_dst := i * offset + dst, i, src, dst, count] + Op::Dup(2), // [src, new_dst, i, src, dst, count] + Op::Dup(2), // [i, src, new_dst, i, src, dst, count] + Op::PushU32(value_size), // [offset, i, src, new_dst, i, src, dst, count] + Op::U32OverflowingMadd, + Op::Assertz, // [new_src := i * offset + src, new_dst, i, src, dst, count] + ], + span, + ); // Load the source value self.stack.push(count.clone()); @@ -1061,39 +1174,42 @@ impl<'a> OpEmitter<'a> { self.stack.push(Type::U32); self.stack.push(dst.clone()); self.stack.push(src.clone()); - self.load(value_ty.clone()); // [value, new_dst, i, src, dst, count] + self.load(value_ty.clone(), span); // [value, new_dst, i, src, dst, count] // Write to the destination - self.swap(1); // [new_dst, value, i, src, dst, count] - self.store(); // [i, src, dst, count] + self.swap(1, span); // [new_dst, value, i, src, dst, count] + self.store(span); // [i, src, dst, count] // Increment iteration count, determine whether to continue loop - self.emit_all(&[ - Op::U32WrappingAddImm(1), - Op::Dup(0), // [i++, i++, src, dst, count] - Op::Dup(4), // [count, i++, i++, src, dst, count] - Op::U32Gte, // [i++ >= count, i++, src, dst, count] - ]); + self.emit_all( + &[ + Op::U32WrappingAddImm(1), + Op::Dup(0), // [i++, i++, src, dst, count] + Op::Dup(4), // [count, i++, i++, src, dst, count] + Op::U32Gte, // [i++ >= count, i++, src, dst, count] + ], + span, + ); // Cleanup - at end of 'while' loop, drop the 4 operands remaining on the stack self.switch_to_block(current_block); - self.dropn(4); + self.dropn(4, span); } /// Store a quartet of machine words (32-bit elements) to the operand stack - fn store_quad_word(&mut self, ptr: Option) { + fn store_quad_word(&mut self, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.store_quad_word_imm(imm); + return self.store_quad_word_imm(imm, span); } - self.emit(Op::Exec("intrinsics::mem::store_qw".parse().unwrap())); + self.emit(Op::Exec("intrinsics::mem::store_qw".parse().unwrap()), span); } - fn store_quad_word_imm(&mut self, ptr: NativePtr) { + fn store_quad_word_imm(&mut self, ptr: NativePtr, span: SourceSpan) { // For all other cases, more complicated loads are required let aligned = ptr.is_element_aligned(); match ptr.index { // Naturally-aligned - 0 if aligned => self.emit_all(&[Op::Padw, Op::MemLoadwImm(ptr.waddr)]), + 0 if aligned => self.emit_all(&[Op::Padw, Op::MemLoadwImm(ptr.waddr)], span), _ => { todo!() } @@ -1101,20 +1217,20 @@ impl<'a> OpEmitter<'a> { } /// Store a pair of machine words (32-bit elements) to the operand stack - fn store_double_word(&mut self, ptr: Option) { + fn store_double_word(&mut self, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.store_double_word_imm(imm); + return self.store_double_word_imm(imm, span); } - self.emit(Op::Exec("intrinsics::mem::store_dw".parse().unwrap())); + self.emit(Op::Exec("intrinsics::mem::store_dw".parse().unwrap()), span); } - fn store_double_word_imm(&mut self, ptr: NativePtr) { + fn store_double_word_imm(&mut self, ptr: NativePtr, span: SourceSpan) { // For all other cases, more complicated stores are required let aligned = ptr.is_element_aligned(); match ptr.index { // Naturally-aligned - 0 if aligned => self.emit_all(&[Op::Padw, Op::MemLoadwImm(ptr.waddr)]), + 0 if aligned => self.emit_all(&[Op::Padw, Op::MemLoadwImm(ptr.waddr)], span), _ => { todo!() } @@ -1125,180 +1241,198 @@ impl<'a> OpEmitter<'a> { /// word /// /// Expects a native pointer triplet on the stack if an immediate address is not given. - fn store_word(&mut self, ptr: Option) { + fn store_word(&mut self, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.store_word_imm(imm); + return self.store_word_imm(imm, span); } - self.emit(Op::Exec("intrinsics::mem::store_sw".parse().unwrap())); + self.emit(Op::Exec("intrinsics::mem::store_sw".parse().unwrap()), span); } /// Stores a single 32-bit machine word to the given immediate address. - fn store_word_imm(&mut self, ptr: NativePtr) { + fn store_word_imm(&mut self, ptr: NativePtr, span: SourceSpan) { let is_aligned = ptr.is_element_aligned(); let rshift = 32 - ptr.offset as u32; match ptr.index { - 0 if is_aligned => self.emit(Op::MemStoreImm(ptr.waddr)), + 0 if is_aligned => self.emit(Op::MemStoreImm(ptr.waddr), span), 0 => { let mask_hi = u32::MAX << rshift; let mask_lo = u32::MAX >> (ptr.offset as u32); - self.emit_all(&[ - // Load the full quad-word on to the operand stack + self.emit_all( + &[ + // Load the full quad-word on to the operand stack + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Manipulate the bits of the first two elements, such that the 32-bit + // word we're storing is placed at the correct offset from the start + // of the memory cell when viewing the cell as a set of 4 32-bit chunks + // + // First, mask out the bits we plan to overwrite with the store op from the + // first two elements + Op::Swap(1), + Op::PushU32(mask_lo), + Op::U32And, + Op::Swap(1), + Op::PushU32(mask_hi), + Op::U32And, + // Now, we need to shift/mask/split the 32-bit value into two elements, + // then combine them with the preserved bits of the + // original contents of the cell + // + // We start with the bits belonging to the first element in the cell + Op::Dup(4), + Op::U32ShrImm(ptr.offset as u32), + Op::U32Or, + // Then the bits belonging to the second element in the cell + Op::Movup(4), + Op::U32ShlImm(rshift), + Op::Movup(2), + Op::U32Or, + // Make sure the elements of the cell are in order + Op::Swap(1), + // Write the word back to the cell + Op::MemStorewImm(ptr.waddr), + // Clean up the operand stack + Op::Dropw, + ], + span, + ); + } + 1 if is_aligned => self.emit_all( + &[ + // Load a quad-word Op::Padw, Op::MemLoadwImm(ptr.waddr), - // Manipulate the bits of the first two elements, such that the 32-bit - // word we're storing is placed at the correct offset from the start - // of the memory cell when viewing the cell as a set of 4 32-bit chunks - // - // First, mask out the bits we plan to overwrite with the store op from the - // first two elements - Op::Swap(1), - Op::PushU32(mask_lo), - Op::U32And, - Op::Swap(1), - Op::PushU32(mask_hi), - Op::U32And, - // Now, we need to shift/mask/split the 32-bit value into two elements, then - // combine them with the preserved bits of the original - // contents of the cell - // - // We start with the bits belonging to the first element in the cell - Op::Dup(4), - Op::U32ShrImm(ptr.offset as u32), - Op::U32Or, - // Then the bits belonging to the second element in the cell + // Replace the stored element Op::Movup(4), - Op::U32ShlImm(rshift), - Op::Movup(2), - Op::U32Or, - // Make sure the elements of the cell are in order - Op::Swap(1), + Op::Swap(2), + Op::Drop, // Write the word back to the cell Op::MemStorewImm(ptr.waddr), // Clean up the operand stack Op::Dropw, - ]); - } - 1 if is_aligned => self.emit_all(&[ - // Load a quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Replace the stored element - Op::Movup(4), - Op::Swap(2), - Op::Drop, - // Write the word back to the cell - Op::MemStorewImm(ptr.waddr), - // Clean up the operand stack - Op::Dropw, - ]), + ], + span, + ), 1 => { let mask_hi = u32::MAX << rshift; let mask_lo = u32::MAX >> (ptr.offset as u32); - self.emit_all(&[ - // Load the full quad-word on to the operand stack + self.emit_all( + &[ + // Load the full quad-word on to the operand stack + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Manipulate the bits of the middle two elements, such that the 32-bit + // word we're storing is placed at the correct offset from the start + // of the memory cell when viewing the cell as a set of 4 32-bit chunks + // + // First, mask out the bits we plan to overwrite with the store op from the + // first two elements + Op::Swap(2), // [elem3, elem2, elem1, elem4, value] + Op::PushU32(mask_lo), + Op::U32And, + Op::Swap(1), // [elem2, elem3, elem1, elem4, value] + Op::PushU32(mask_hi), + Op::U32And, + // Now, we need to shift/mask/split the 32-bit value into two elements, + // then combine them with the preserved bits of the + // original contents of the cell + // + // We start with the bits belonging to the second element in the cell + Op::Dup(4), // [value, elem2, elem3, elem1, elem4, value] + Op::U32ShrImm(ptr.offset as u32), + Op::U32Or, + // Then the bits belonging to the third element in the cell + Op::Movup(4), + Op::U32ShlImm(rshift), + Op::Movup(2), + Op::U32Or, // [elem3, elem2, elem1, elem4] + // Make sure the elements of the cell are in order + Op::Swap(1), + Op::Movup(2), // [elem1, elem2, elem3, elem4] + // Write the word back to the cell + Op::MemStorewImm(ptr.waddr), + // Clean up the operand stack + Op::Dropw, + ], + span, + ); + } + 2 if is_aligned => self.emit_all( + &[ + // Load a quad-word Op::Padw, Op::MemLoadwImm(ptr.waddr), - // Manipulate the bits of the middle two elements, such that the 32-bit - // word we're storing is placed at the correct offset from the start - // of the memory cell when viewing the cell as a set of 4 32-bit chunks - // - // First, mask out the bits we plan to overwrite with the store op from the - // first two elements - Op::Swap(2), // [elem3, elem2, elem1, elem4, value] - Op::PushU32(mask_lo), - Op::U32And, - Op::Swap(1), // [elem2, elem3, elem1, elem4, value] - Op::PushU32(mask_hi), - Op::U32And, - // Now, we need to shift/mask/split the 32-bit value into two elements, then - // combine them with the preserved bits of the original - // contents of the cell - // - // We start with the bits belonging to the second element in the cell - Op::Dup(4), // [value, elem2, elem3, elem1, elem4, value] - Op::U32ShrImm(ptr.offset as u32), - Op::U32Or, - // Then the bits belonging to the third element in the cell - Op::Movup(4), - Op::U32ShlImm(rshift), - Op::Movup(2), - Op::U32Or, // [elem3, elem2, elem1, elem4] - // Make sure the elements of the cell are in order - Op::Swap(1), - Op::Movup(2), // [elem1, elem2, elem3, elem4] + // Replace the stored element + Op::Movup(5), + Op::Swap(3), + Op::Drop, // Write the word back to the cell Op::MemStorewImm(ptr.waddr), // Clean up the operand stack Op::Dropw, - ]); - } - 2 if is_aligned => self.emit_all(&[ - // Load a quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Replace the stored element - Op::Movup(5), - Op::Swap(3), - Op::Drop, - // Write the word back to the cell - Op::MemStorewImm(ptr.waddr), - // Clean up the operand stack - Op::Dropw, - ]), + ], + span, + ), 2 => { let mask_hi = u32::MAX << rshift; let mask_lo = u32::MAX >> (ptr.offset as u32); - self.emit_all(&[ - // Load the full quad-word on to the operand stack + self.emit_all( + &[ + // Load the full quad-word on to the operand stack + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Manipulate the bits of the last two elements, such that the 32-bit + // word we're storing is placed at the correct offset from the start + // of the memory cell when viewing the cell as a set of 4 32-bit chunks + // + // First, mask out the bits we plan to overwrite with the store op from the + // first two elements + Op::Swap(3), // [elem4, elem2, elem3, elem1, value] + Op::PushU32(mask_lo), + Op::U32And, + Op::Movup(2), // [elem3, elem4, elem2, elem1, value] + Op::PushU32(mask_hi), + Op::U32And, + // Now, we need to shift/mask/split the 32-bit value into two elements, + // then combine them with the preserved bits of the + // original contents of the cell + // + // We start with the bits belonging to the third element in the cell + Op::Dup(4), // [value, elem3, elem4, elem2, elem1, value] + Op::U32ShrImm(ptr.offset as u32), + Op::U32Or, + // Then the bits belonging to the fourth element in the cell + Op::Movup(4), + Op::U32ShlImm(rshift), + Op::Movup(2), + Op::U32Or, // [elem4, elem3, elem2, elem1] + // Make sure the elements of the cell are in order + Op::Swap(2), // [elem2, elem3, elem4, elem1] + Op::Movup(3), // [elem1, elem2, elem3, elem4] + // Write the word back to the cell + Op::MemStorewImm(ptr.waddr), + // Clean up the operand stack + Op::Dropw, + ], + span, + ); + } + 3 if is_aligned => self.emit_all( + &[ + // Load a quad-word Op::Padw, Op::MemLoadwImm(ptr.waddr), - // Manipulate the bits of the last two elements, such that the 32-bit - // word we're storing is placed at the correct offset from the start - // of the memory cell when viewing the cell as a set of 4 32-bit chunks - // - // First, mask out the bits we plan to overwrite with the store op from the - // first two elements - Op::Swap(3), // [elem4, elem2, elem3, elem1, value] - Op::PushU32(mask_lo), - Op::U32And, - Op::Movup(2), // [elem3, elem4, elem2, elem1, value] - Op::PushU32(mask_hi), - Op::U32And, - // Now, we need to shift/mask/split the 32-bit value into two elements, then - // combine them with the preserved bits of the original - // contents of the cell - // - // We start with the bits belonging to the third element in the cell - Op::Dup(4), // [value, elem3, elem4, elem2, elem1, value] - Op::U32ShrImm(ptr.offset as u32), - Op::U32Or, - // Then the bits belonging to the fourth element in the cell + // Replace the stored element Op::Movup(4), - Op::U32ShlImm(rshift), - Op::Movup(2), - Op::U32Or, // [elem4, elem3, elem2, elem1] - // Make sure the elements of the cell are in order - Op::Swap(2), // [elem2, elem3, elem4, elem1] - Op::Movup(3), // [elem1, elem2, elem3, elem4] + Op::Drop, // Write the word back to the cell Op::MemStorewImm(ptr.waddr), // Clean up the operand stack Op::Dropw, - ]); - } - 3 if is_aligned => self.emit_all(&[ - // Load a quad-word - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Replace the stored element - Op::Movup(4), - Op::Drop, - // Write the word back to the cell - Op::MemStorewImm(ptr.waddr), - // Clean up the operand stack - Op::Dropw, - ]), + ], + span, + ), 3 => { // This is a rather annoying edge case, as it requires us to store bits // across two different words. We start with the "hi" bits that go at @@ -1306,41 +1440,44 @@ impl<'a> OpEmitter<'a> { // fashion let mask_hi = u32::MAX << rshift; let mask_lo = u32::MAX >> (ptr.offset as u32); - self.emit_all(&[ - // Load the full quad-word on to the operand stack - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - // Manipulate the bits of the last element, such that the "high" bits - // of the 32-bit word we're storing is placed at the correct offset from the - // start of the memory cell when viewing the cell as a set - // of 4 32-bit chunks - // - // First, mask out the bits we plan to overwrite with the store op from the - // last element - Op::Swap(3), // [elem4, elem2, elem3, elem1, value] - Op::PushU32(mask_lo), - Op::U32And, - // Now, we need to shift/mask/split the 32-bit value into the bits that will be - // merged with this word - Op::Dup(4), // [value, elem4, elem2, elem3, elem1, value] - Op::U32ShrImm(ptr.offset as u32), - Op::U32Or, - // Move the fourth element back into place - Op::Swap(3), // [elem1, elem2, elem3, elem4, value] - // Write the first word and clear the operand stack - Op::MemStorewImm(ptr.waddr), - Op::Dropw, - // Compute the bits of the value that we'll merge into the second word - Op::U32ShlImm(rshift), - // Load the first element of the second word - Op::MemLoadImm(ptr.waddr + 1), - // Mask out the bits we plan to overwrite - Op::PushU32(mask_hi), - Op::U32And, - // Merge the bits and write back the second word - Op::U32Or, - Op::MemStoreImm(ptr.waddr + 1), - ]); + self.emit_all( + &[ + // Load the full quad-word on to the operand stack + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + // Manipulate the bits of the last element, such that the "high" bits + // of the 32-bit word we're storing is placed at the correct offset from + // the start of the memory cell when viewing the + // cell as a set of 4 32-bit chunks + // + // First, mask out the bits we plan to overwrite with the store op from the + // last element + Op::Swap(3), // [elem4, elem2, elem3, elem1, value] + Op::PushU32(mask_lo), + Op::U32And, + // Now, we need to shift/mask/split the 32-bit value into the bits that + // will be merged with this word + Op::Dup(4), // [value, elem4, elem2, elem3, elem1, value] + Op::U32ShrImm(ptr.offset as u32), + Op::U32Or, + // Move the fourth element back into place + Op::Swap(3), // [elem1, elem2, elem3, elem4, value] + // Write the first word and clear the operand stack + Op::MemStorewImm(ptr.waddr), + Op::Dropw, + // Compute the bits of the value that we'll merge into the second word + Op::U32ShlImm(rshift), + // Load the first element of the second word + Op::MemLoadImm(ptr.waddr + 1), + // Mask out the bits we plan to overwrite + Op::PushU32(mask_hi), + Op::U32And, + // Merge the bits and write back the second word + Op::U32Or, + Op::MemStoreImm(ptr.waddr + 1), + ], + span, + ); } _ => unreachable!(), } @@ -1349,113 +1486,122 @@ impl<'a> OpEmitter<'a> { /// Store a field element to a naturally aligned address, either immediate or dynamic /// /// A native pointer triplet is expected on the stack if an immediate is not given. - fn store_felt(&mut self, ptr: Option) { + fn store_felt(&mut self, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.store_felt_imm(imm); + return self.store_felt_imm(imm, span); } - self.emit(Op::Exec("intrinsics::mem::store_felt".parse().unwrap())); + self.emit(Op::Exec("intrinsics::mem::store_felt".parse().unwrap()), span); } - fn store_felt_imm(&mut self, ptr: NativePtr) { + fn store_felt_imm(&mut self, ptr: NativePtr, span: SourceSpan) { assert!(ptr.is_element_aligned(), "felt values must be naturally aligned"); match ptr.index { - 0 => self.emit(Op::MemStoreImm(ptr.waddr)), + 0 => self.emit(Op::MemStoreImm(ptr.waddr), span), 1 => { - self.emit_all(&[ - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - Op::Movup(4), - Op::Swap(2), - Op::Drop, - Op::MemStorewImm(ptr.waddr), - Op::Dropw, - ]); + self.emit_all( + &[ + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + Op::Movup(4), + Op::Swap(2), + Op::Drop, + Op::MemStorewImm(ptr.waddr), + Op::Dropw, + ], + span, + ); } 2 => { - self.emit_all(&[ - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - Op::Movup(4), - Op::Swap(3), - Op::Drop, - Op::MemStorewImm(ptr.waddr), - Op::Dropw, - ]); + self.emit_all( + &[ + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + Op::Movup(4), + Op::Swap(3), + Op::Drop, + Op::MemStorewImm(ptr.waddr), + Op::Dropw, + ], + span, + ); } 3 => { - self.emit_all(&[ - Op::Padw, - Op::MemLoadwImm(ptr.waddr), - Op::Movup(3), - Op::Drop, - Op::MemStorewImm(ptr.waddr), - Op::Dropw, - ]); + self.emit_all( + &[ + Op::Padw, + Op::MemLoadwImm(ptr.waddr), + Op::Movup(3), + Op::Drop, + Op::MemStorewImm(ptr.waddr), + Op::Dropw, + ], + span, + ); } _ => unreachable!(), } } - fn store_small(&mut self, ty: &Type, ptr: Option) { + fn store_small(&mut self, ty: &Type, ptr: Option, span: SourceSpan) { if let Some(imm) = ptr { - return self.store_small_imm(ty, imm); + return self.store_small_imm(ty, imm, span); } let type_size = ty.size_in_bits(); if type_size == 32 { - self.store_word(ptr); + self.store_word(ptr, span); return; } // Duplicate the address - self.emit_all(&[Op::Dup(2), Op::Dup(2), Op::Dup(2)]); + self.emit_all(&[Op::Dup(2), Op::Dup(2), Op::Dup(2)], span); // Load the current 32-bit value at `ptr` - self.load_word(ptr); + self.load_word(ptr, span); // Mask out the bits we're going to be writing from the loaded value let mask = u32::MAX << type_size; - self.const_mask_u32(mask); + self.const_mask_u32(mask, span); // Mix in the bits we want to write: [masked, addr1, addr2, addr3, value] - self.emit(Op::Movup(5)); - self.bor_u32(); + self.emit(Op::Movup(5), span); + self.bor_u32(span); // Store the combined bits: [value, addr1, addr2, addr3] - self.emit(Op::Movdn(4)); - self.store_word(ptr); + self.emit(Op::Movdn(4), span); + self.store_word(ptr, span); } - fn store_small_imm(&mut self, ty: &Type, ptr: NativePtr) { + fn store_small_imm(&mut self, ty: &Type, ptr: NativePtr, span: SourceSpan) { assert!(ptr.alignment() as usize >= ty.min_alignment()); let type_size = ty.size_in_bits(); if type_size == 32 { - self.store_word_imm(ptr); + self.store_word_imm(ptr, span); return; } // Load the current 32-bit value at `ptr` - self.load_word_imm(ptr); + self.load_word_imm(ptr, span); // Mask out the bits we're going to be writing from the loaded value let mask = u32::MAX << type_size; - self.const_mask_u32(mask); + self.const_mask_u32(mask, span); // Mix in the bits we want to write - self.emit(Op::Movup(4)); - self.bor_u32(); + self.emit(Op::Movup(4), span); + self.bor_u32(span); // Store the combined bits - self.store_word_imm(ptr); + self.store_word_imm(ptr, span); } - fn store_array(&mut self, _element_ty: &Type, _ptr: Option) { + fn store_array(&mut self, _element_ty: &Type, _ptr: Option, _span: SourceSpan) { todo!() } - fn store_struct(&mut self, _ty: &StructType, _ptr: Option) { + fn store_struct(&mut self, _ty: &StructType, _ptr: Option, _span: SourceSpan) { todo!() } } diff --git a/codegen/masm/src/codegen/emit/mod.rs b/codegen/masm/src/codegen/emit/mod.rs index 2c5d8c86..8d932786 100644 --- a/codegen/masm/src/codegen/emit/mod.rs +++ b/codegen/masm/src/codegen/emit/mod.rs @@ -1,3 +1,5 @@ +use midenc_hir::diagnostics::Span; + /// The field modulus for Miden's prime field pub const P: u64 = (2u128.pow(64) - 2u128.pow(32) + 1) as u64; @@ -88,7 +90,7 @@ pub mod unary; use core::ops::{Deref, DerefMut}; use miden_assembly::ast::InvokeKind; -use midenc_hir::{self as hir, Immediate, Type}; +use midenc_hir::{self as hir, diagnostics::SourceSpan, Immediate, Type}; use super::{Operand, OperandStack}; use crate::masm::{self as masm, Op}; @@ -118,14 +120,14 @@ impl<'a> InstOpEmitter<'a> { } } - pub fn exec(&mut self, callee: hir::FunctionIdent) { + pub fn exec(&mut self, callee: hir::FunctionIdent, span: SourceSpan) { let import = self.dfg.get_import(&callee).unwrap(); - self.emitter.exec(import); + self.emitter.exec(import, span); } - pub fn syscall(&mut self, callee: hir::FunctionIdent) { + pub fn syscall(&mut self, callee: hir::FunctionIdent, span: SourceSpan) { let import = self.dfg.get_import(&callee).unwrap(); - self.emitter.syscall(import); + self.emitter.syscall(import, span); } #[inline(always)] @@ -218,30 +220,30 @@ impl<'a> OpEmitter<'a> { /// Emit `op` to the current block #[inline(always)] - pub fn emit(&mut self, op: masm::Op) { + pub fn emit(&mut self, op: masm::Op, span: SourceSpan) { self.maybe_register_invoke(&op); - self.current_block().push(op) + self.current_block().push(op, span) } /// Emit `n` copies of `op` to the current block #[inline(always)] - pub fn emit_n(&mut self, count: usize, op: masm::Op) { + pub fn emit_n(&mut self, count: usize, op: masm::Op, span: SourceSpan) { self.maybe_register_invoke(&op); - self.current_block().push_n(count, op); + self.current_block().push_n(count, op, span); } /// Emit `ops` to the current block #[inline(always)] - pub fn emit_all(&mut self, ops: &[masm::Op]) { + pub fn emit_all(&mut self, ops: &[masm::Op], span: SourceSpan) { for op in ops { self.maybe_register_invoke(op); } - self.current_block().extend_from_slice(ops); + self.current_block().extend(ops.iter().copied().map(|op| Span::new(span, op))); } /// Emit `n` copies of the sequence `ops` to the current block #[inline(always)] - pub fn emit_repeat(&mut self, count: usize, ops: &[masm::Op]) { + pub fn emit_repeat(&mut self, count: usize, ops: &[Span]) { for op in ops { self.maybe_register_invoke(op); } @@ -252,7 +254,7 @@ impl<'a> OpEmitter<'a> { #[inline] pub fn emit_template(&mut self, count: usize, template: F) where - F: Fn(usize) -> [Op; N], + F: Fn(usize) -> [Span; N], { for op in template(0) { self.maybe_register_invoke(&op); @@ -269,28 +271,28 @@ impl<'a> OpEmitter<'a> { /// /// This has no effect on the state of the emulated operand stack #[inline] - pub fn push_immediate(&mut self, imm: Immediate) { + pub fn push_immediate(&mut self, imm: Immediate, span: SourceSpan) { match imm { - Immediate::I1(i) => self.emit(Op::PushU8(i as u8)), - Immediate::I8(i) => self.emit(Op::PushU8(i as u8)), - Immediate::U8(i) => self.emit(Op::PushU8(i)), - Immediate::U16(i) => self.emit(Op::PushU32(i as u32)), - Immediate::I16(i) => self.emit(Op::PushU32(i as u16 as u32)), - Immediate::U32(i) => self.emit(Op::PushU32(i)), - Immediate::I32(i) => self.emit(Op::PushU32(i as u32)), - Immediate::U64(i) => self.push_u64(i), - Immediate::I64(i) => self.push_i64(i), - Immediate::U128(i) => self.push_u128(i), - Immediate::I128(i) => self.push_i128(i), - Immediate::Felt(i) => self.emit(Op::Push(i)), + Immediate::I1(i) => self.emit(Op::PushU8(i as u8), span), + Immediate::I8(i) => self.emit(Op::PushU8(i as u8), span), + Immediate::U8(i) => self.emit(Op::PushU8(i), span), + Immediate::U16(i) => self.emit(Op::PushU32(i as u32), span), + Immediate::I16(i) => self.emit(Op::PushU32(i as u16 as u32), span), + Immediate::U32(i) => self.emit(Op::PushU32(i), span), + Immediate::I32(i) => self.emit(Op::PushU32(i as u32), span), + Immediate::U64(i) => self.push_u64(i, span), + Immediate::I64(i) => self.push_i64(i, span), + Immediate::U128(i) => self.push_u128(i, span), + Immediate::I128(i) => self.push_i128(i, span), + Immediate::Felt(i) => self.emit(Op::Push(i), span), Immediate::F64(_) => unimplemented!("floating-point immediates are not supported"), } } /// Push a literal on the operand stack, and update the emulated stack accordingly - pub fn literal>(&mut self, imm: I) { + pub fn literal>(&mut self, imm: I, span: SourceSpan) { let imm = imm.into(); - self.push_immediate(imm); + self.push_immediate(imm, span); self.stack.push(imm); } @@ -308,7 +310,7 @@ impl<'a> OpEmitter<'a> { /// Duplicate an item on the stack to the top #[inline] #[track_caller] - pub fn dup(&mut self, i: u8) { + pub fn dup(&mut self, i: u8, span: SourceSpan) { assert_valid_stack_index!(i); let index = i as usize; let i = self.stack.effective_index(index) as u8; @@ -318,14 +320,14 @@ impl<'a> OpEmitter<'a> { let n = last.size(); let offset = (n - 1) as u8; for _ in 0..n { - self.emit(Op::Dup(i + offset)); + self.emit(Op::Dup(i + offset), span); } } /// Move an item on the stack to the top #[inline] #[track_caller] - pub fn movup(&mut self, i: u8) { + pub fn movup(&mut self, i: u8, span: SourceSpan) { assert_valid_stack_index!(i); let index = i as usize; let i = self.stack.effective_index(index) as u8; @@ -335,14 +337,14 @@ impl<'a> OpEmitter<'a> { let n = moved.size(); let offset = (n - 1) as u8; for _ in 0..n { - self.emit(Op::Movup(i + offset)); + self.emit(Op::Movup(i + offset), span); } } /// Move an item from the top of the stack to the `n`th position #[inline] #[track_caller] - pub fn movdn(&mut self, i: u8) { + pub fn movdn(&mut self, i: u8, span: SourceSpan) { assert_valid_stack_index!(i); let index = i as usize; let i = self.stack.effective_index_inclusive(index) as u8; @@ -351,14 +353,14 @@ impl<'a> OpEmitter<'a> { self.stack.movdn(index); // Emit low-level instructions corresponding to the operand we moved for _ in 0..top_size { - self.emit(Op::Movdn(i)); + self.emit(Op::Movdn(i), span); } } /// Swap an item with the top of the stack #[inline] #[track_caller] - pub fn swap(&mut self, i: u8) { + pub fn swap(&mut self, i: u8, span: SourceSpan) { assert!(i > 0, "swap requires a non-zero index"); assert_valid_stack_index!(i); let index = i as usize; @@ -368,37 +370,37 @@ impl<'a> OpEmitter<'a> { self.stack.swap(index); match (src, dst) { (1, 1) => { - self.emit(Op::Swap(i)); + self.emit(Op::Swap(i), span); } (1, n) if i == 1 => { // We can simply move the top element below the `dst` operand - self.emit(Op::Movdn(i + (n - 1))); + self.emit(Op::Movdn(i + (n - 1)), span); } (n, 1) if i == n => { // We can simply move the `dst` element to the top - self.emit(Op::Movup(i)); + self.emit(Op::Movup(i), span); } (n, m) if i == n => { // We can simply move `dst` down for _ in 0..n { - self.emit(Op::Movdn(i + (m - 1))); + self.emit(Op::Movdn(i + (m - 1)), span); } } (n, m) => { assert!(i >= n); let offset = m - 1; for _ in 0..n { - self.emit(Op::Movdn(i + offset)); + self.emit(Op::Movdn(i + offset), span); } let i = (i as i8 + (m as i8 - n as i8)) as u8; match i - 1 { 1 => { assert_eq!(m, 1); - self.emit(Op::Swap(1)); + self.emit(Op::Swap(1), span); } i => { for _ in 0..m { - self.emit(Op::Movup(i)); + self.emit(Op::Movup(i), span); } } } @@ -409,18 +411,18 @@ impl<'a> OpEmitter<'a> { /// Drop the top operand on the stack #[inline] #[track_caller] - pub fn drop(&mut self) { + pub fn drop(&mut self, span: SourceSpan) { let elem = self.stack.pop().expect("operand stack is empty"); match elem.size() { 1 => { - self.emit(Op::Drop); + self.emit(Op::Drop, span); } 4 => { - self.emit(Op::Dropw); + self.emit(Op::Dropw, span); } n => { for _ in 0..n { - self.emit(Op::Drop); + self.emit(Op::Drop, span); } } } @@ -429,27 +431,27 @@ impl<'a> OpEmitter<'a> { /// Drop the top `n` operands on the stack #[inline] #[track_caller] - pub fn dropn(&mut self, n: usize) { + pub fn dropn(&mut self, n: usize, span: SourceSpan) { assert!(self.stack.len() >= n); assert_ne!(n, 0); let raw_len: usize = self.stack.iter().rev().take(n).map(|o| o.size()).sum(); self.stack.dropn(n); match raw_len { 1 => { - self.emit(Op::Drop); + self.emit(Op::Drop, span); } 4 => { - self.emit(Op::Dropw); + self.emit(Op::Dropw, span); } n => { - self.emit_n(n / 4, Op::Dropw); - self.emit_n(n % 4, Op::Drop); + self.emit_n(n / 4, Op::Dropw, span); + self.emit_n(n % 4, Op::Drop, span); } } } /// Remove all but the top `n` values on the operand stack - pub fn truncate_stack(&mut self, n: usize) { + pub fn truncate_stack(&mut self, n: usize, span: SourceSpan) { let stack_size = self.stack.len(); let num_to_drop = stack_size - n; @@ -460,8 +462,8 @@ impl<'a> OpEmitter<'a> { if stack_size == num_to_drop { let raw_size = self.stack.raw_len(); self.stack.dropn(num_to_drop); - self.emit_n(raw_size / 4, Op::Dropw); - self.emit_n(raw_size % 4, Op::Dropw); + self.emit_n(raw_size / 4, Op::Dropw, span); + self.emit_n(raw_size % 4, Op::Dropw, span); return; } @@ -471,12 +473,12 @@ impl<'a> OpEmitter<'a> { if n == 1 { match stack_size { 2 => { - self.swap(1); - self.drop(); + self.swap(1, span); + self.drop(span); } n => { - self.movdn(n as u8 - 1); - self.dropn(n - 1); + self.movdn(n as u8 - 1, span); + self.dropn(n - 1, span); } } return; @@ -487,23 +489,23 @@ impl<'a> OpEmitter<'a> { // come up with a smarter/more efficient method for offset in 0..num_to_drop { let index = stack_size - 1 - offset; - self.drop_operand_at_position(index); + self.drop_operand_at_position(index, span); } } /// Remove the `n`th value from the top of the operand stack - pub fn drop_operand_at_position(&mut self, n: usize) { + pub fn drop_operand_at_position(&mut self, n: usize, span: SourceSpan) { match n { 0 => { - self.drop(); + self.drop(span); } 1 => { - self.swap(1); - self.drop(); + self.swap(1, span); + self.drop(span); } n => { - self.movup(n as u8); - self.drop(); + self.movup(n as u8, span); + self.drop(span); } } } @@ -520,28 +522,29 @@ impl<'a> OpEmitter<'a> { n: usize, m: usize, is_commutative_binary_operand: bool, + span: SourceSpan, ) { match (n, m) { (0, 0) => { - self.dup(0); + self.dup(0, span); } (actual, 0) => { - self.dup(actual as u8); + self.dup(actual as u8, span); } (actual, 1) => { // If the dependent is binary+commutative, we can // leave operands in either the 0th or 1st position, // as long as both operands are on top of the stack if !is_commutative_binary_operand { - self.dup(actual as u8); - self.swap(1); + self.dup(actual as u8, span); + self.swap(1, span); } else { - self.dup(actual as u8); + self.dup(actual as u8, span); } } (actual, expected) => { - self.dup(actual as u8); - self.movdn(expected as u8); + self.dup(actual as u8, span); + self.movdn(expected as u8, span); } } } @@ -558,6 +561,7 @@ impl<'a> OpEmitter<'a> { n: usize, m: usize, is_commutative_binary_operand: bool, + span: SourceSpan, ) { match (n, m) { (n, m) if n == m => (), @@ -566,19 +570,19 @@ impl<'a> OpEmitter<'a> { // leave operands in either the 0th or 1st position, // as long as both operands are on top of the stack if !is_commutative_binary_operand { - self.swap(1); + self.swap(1, span); } } (actual, 0) => { - self.movup(actual as u8); + self.movup(actual as u8, span); } (actual, 1) => { - self.movup(actual as u8); - self.swap(1); + self.movup(actual as u8, span); + self.swap(1, span); } (actual, expected) => { - self.movup(actual as u8); - self.movdn(expected as u8); + self.movup(actual as u8, span); + self.movdn(expected as u8, span); } } } @@ -624,21 +628,21 @@ mod tests { let four = Immediate::U64(2u64.pow(32)); let five = Immediate::U64(2u64.pow(32) | 2u64.pow(33) | u32::MAX as u64); - emitter.literal(one); - emitter.literal(two); - emitter.literal(three); - emitter.literal(four); - emitter.literal(five); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); + emitter.literal(three, SourceSpan::default()); + emitter.literal(four, SourceSpan::default()); + emitter.literal(five, SourceSpan::default()); { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 5); - assert_eq!(ops[0], Op::PushU32(1)); - assert_eq!(ops[1], Op::PushU32(2)); - assert_eq!(ops[2], Op::PushU8(3)); - assert_eq!(ops[3], Op::Push2([Felt::new(1), Felt::ZERO])); - assert_eq!(ops[4], Op::Push2([Felt::new(3), Felt::new(u32::MAX as u64)])); + assert_eq!(ops[0].into_inner(), Op::PushU32(1)); + assert_eq!(ops[1].into_inner(), Op::PushU32(2)); + assert_eq!(ops[2].into_inner(), Op::PushU8(3)); + assert_eq!(ops[3].into_inner(), Op::Push2([Felt::new(1), Felt::ZERO])); + assert_eq!(ops[4].into_inner(), Op::Push2([Felt::new(3), Felt::new(u32::MAX as u64)])); } assert_eq!(emitter.stack()[0], five); @@ -647,7 +651,7 @@ mod tests { assert_eq!(emitter.stack()[3], two); assert_eq!(emitter.stack()[4], one); - emitter.dup(0); + emitter.dup(0, SourceSpan::default()); assert_eq!(emitter.stack()[0], five); assert_eq!(emitter.stack()[1], five); assert_eq!(emitter.stack()[2], four); @@ -658,12 +662,12 @@ mod tests { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 7); - assert_eq!(ops[5], Op::Dup(1)); - assert_eq!(ops[6], Op::Dup(1)); + assert_eq!(ops[5].into_inner(), Op::Dup(1)); + assert_eq!(ops[6].into_inner(), Op::Dup(1)); } assert_eq!(emitter.stack().effective_index(3), 6); - emitter.dup(3); + emitter.dup(3, SourceSpan::default()); assert_eq!(emitter.stack()[0], three); assert_eq!(emitter.stack()[1], five); assert_eq!(emitter.stack()[2], five); @@ -675,12 +679,12 @@ mod tests { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 8); - assert_eq!(ops[6], Op::Dup(1)); - assert_eq!(ops[7], Op::Dup(6)); + assert_eq!(ops[6].into_inner(), Op::Dup(1)); + assert_eq!(ops[7].into_inner(), Op::Dup(6)); } assert_eq!(emitter.stack().effective_index(1), 1); - emitter.swap(1); + emitter.swap(1, SourceSpan::default()); assert_eq!(emitter.stack().effective_index(1), 2); assert_eq!(emitter.stack()[0], five); assert_eq!(emitter.stack()[1], three); @@ -693,12 +697,12 @@ mod tests { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 9); - assert_eq!(ops[7], Op::Dup(6)); - assert_eq!(ops[8], Op::Movdn(2)); + assert_eq!(ops[7].into_inner(), Op::Dup(6)); + assert_eq!(ops[8].into_inner(), Op::Movdn(2)); } assert_eq!(emitter.stack().effective_index(3), 5); - emitter.swap(3); + emitter.swap(3, SourceSpan::default()); assert_eq!(emitter.stack()[0], four); assert_eq!(emitter.stack()[1], three); assert_eq!(emitter.stack()[2], five); @@ -710,15 +714,17 @@ mod tests { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 13); - assert_eq!(ops[8], Op::Movdn(2)); // [five_a, five_b, three, five_c, five_d, four_a, four_b] - assert_eq!(ops[9], Op::Movdn(6)); // [five_b, three, five_c, five_d, four_a, four_b, five_a] - assert_eq!(ops[10], Op::Movdn(6)); // [three, five_c, five_d, four_a, four_b, five_a, five_b] - assert_eq!(ops[11], Op::Movup(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] - assert_eq!(ops[12], Op::Movup(4)); // [four_a, four_b, three, five_c, five_d, five_a, - // five_b] + assert_eq!(ops[8].into_inner(), Op::Movdn(2)); // [five_a, five_b, three, five_c, five_d, four_a, four_b] + assert_eq!(ops[9].into_inner(), Op::Movdn(6)); // [five_b, three, five_c, five_d, four_a, four_b, five_a] + assert_eq!(ops[10].into_inner(), Op::Movdn(6)); // [three, five_c, five_d, four_a, four_b, five_a, five_b] + assert_eq!(ops[11].into_inner(), Op::Movup(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] + assert_eq!(ops[12].into_inner(), Op::Movup(4)); // [four_a, four_b, three, five_c, + // five_d, + // five_a, + // five_b] } - emitter.movdn(2); + emitter.movdn(2, SourceSpan::default()); assert_eq!(emitter.stack()[0], three); assert_eq!(emitter.stack()[1], five); assert_eq!(emitter.stack()[2], four); @@ -730,16 +736,18 @@ mod tests { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 15); - assert_eq!(ops[9], Op::Movdn(6)); // [five_b, three, five_c, five_d, four_a, four_b, five_a] - assert_eq!(ops[10], Op::Movdn(6)); // [three, five_c, five_d, four_a, four_b, five_a, five_b] - assert_eq!(ops[11], Op::Movup(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] - assert_eq!(ops[12], Op::Movup(4)); // [four_a, four_b, three, five_c, five_d, five_a, five_b] - assert_eq!(ops[13], Op::Movdn(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] - assert_eq!(ops[14], Op::Movdn(4)); // [three, five_c, five_d, four_a, four_b, five_a, - // five_b] + assert_eq!(ops[9].into_inner(), Op::Movdn(6)); // [five_b, three, five_c, five_d, four_a, four_b, five_a] + assert_eq!(ops[10].into_inner(), Op::Movdn(6)); // [three, five_c, five_d, four_a, four_b, five_a, five_b] + assert_eq!(ops[11].into_inner(), Op::Movup(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] + assert_eq!(ops[12].into_inner(), Op::Movup(4)); // [four_a, four_b, three, five_c, five_d, five_a, five_b] + assert_eq!(ops[13].into_inner(), Op::Movdn(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] + assert_eq!(ops[14].into_inner(), Op::Movdn(4)); // [three, five_c, five_d, four_a, + // four_b, + // five_a, + // five_b] } - emitter.movup(2); + emitter.movup(2, SourceSpan::default()); assert_eq!(emitter.stack()[0], four); assert_eq!(emitter.stack()[1], three); assert_eq!(emitter.stack()[2], five); @@ -751,14 +759,16 @@ mod tests { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 17); - assert_eq!(ops[13], Op::Movdn(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] - assert_eq!(ops[14], Op::Movdn(4)); // [three, five_c, five_d, four_a, four_b, five_a, five_b] - assert_eq!(ops[15], Op::Movup(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] - assert_eq!(ops[16], Op::Movup(4)); // [four_a, four_b, three, five_c, five_d, five_a, - // five_b] + assert_eq!(ops[13].into_inner(), Op::Movdn(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] + assert_eq!(ops[14].into_inner(), Op::Movdn(4)); // [three, five_c, five_d, four_a, four_b, five_a, five_b] + assert_eq!(ops[15].into_inner(), Op::Movup(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] + assert_eq!(ops[16].into_inner(), Op::Movup(4)); // [four_a, four_b, three, five_c, + // five_d, + // five_a, + // five_b] } - emitter.drop(); + emitter.drop(SourceSpan::default()); assert_eq!(emitter.stack()[0], three); assert_eq!(emitter.stack()[1], five); assert_eq!(emitter.stack()[2], five); @@ -770,13 +780,13 @@ mod tests { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 19); - assert_eq!(ops[15], Op::Movup(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] - assert_eq!(ops[16], Op::Movup(4)); // [four_a, four_b, three, five_c, five_d, five_a, five_b] - assert_eq!(ops[17], Op::Drop); // [four_b, three, five_c, five_d, five_a, five_b] - assert_eq!(ops[18], Op::Drop); // [three, five_c, five_d, five_a, five_b] + assert_eq!(ops[15].into_inner(), Op::Movup(4)); // [four_b, three, five_c, five_d, four_a, five_a, five_b] + assert_eq!(ops[16].into_inner(), Op::Movup(4)); // [four_a, four_b, three, five_c, five_d, five_a, five_b] + assert_eq!(ops[17].into_inner(), Op::Drop); // [four_b, three, five_c, five_d, five_a, five_b] + assert_eq!(ops[18].into_inner(), Op::Drop); // [three, five_c, five_d, five_a, five_b] } - emitter.copy_operand_to_position(5, 3, false); + emitter.copy_operand_to_position(5, 3, false, SourceSpan::default()); assert_eq!(emitter.stack()[0], three); assert_eq!(emitter.stack()[1], five); assert_eq!(emitter.stack()[2], five); @@ -784,14 +794,14 @@ mod tests { assert_eq!(emitter.stack()[4], three); assert_eq!(emitter.stack()[5], two); - emitter.drop_operand_at_position(4); + emitter.drop_operand_at_position(4, SourceSpan::default()); assert_eq!(emitter.stack()[0], three); assert_eq!(emitter.stack()[1], five); assert_eq!(emitter.stack()[2], five); assert_eq!(emitter.stack()[3], one); assert_eq!(emitter.stack()[4], two); - emitter.move_operand_to_position(4, 2, false); + emitter.move_operand_to_position(4, 2, false, SourceSpan::default()); assert_eq!(emitter.stack()[0], three); assert_eq!(emitter.stack()[1], five); assert_eq!(emitter.stack()[2], two); @@ -847,7 +857,7 @@ mod tests { assert_eq!(emitter.stack()[4], v10); assert_eq!(emitter.stack()[2], v15); - emitter.copy_operand_to_position(4, 2, false); + emitter.copy_operand_to_position(4, 2, false, SourceSpan::default()); assert_eq!(emitter.stack()[5], v10); assert_eq!(emitter.stack()[2], v10); @@ -855,8 +865,8 @@ mod tests { let block = emitter.current_block(); let ops = block.ops.as_slice(); assert_eq!(ops.len(), 2); - assert_eq!(ops[0], Op::Dup(4)); - assert_eq!(ops[1], Op::Movdn(2)); + assert_eq!(ops[0].into_inner(), Op::Dup(4)); + assert_eq!(ops[1].into_inner(), Op::Movdn(2)); } } @@ -870,26 +880,26 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.add_imm(one, Overflow::Checked); + emitter.add_imm(one, Overflow::Checked, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.add(Overflow::Checked); + emitter.add(Overflow::Checked, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); - emitter.add_imm(one, Overflow::Overflowing); + emitter.add_imm(one, Overflow::Overflowing, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], Type::U32); - emitter.drop(); - emitter.dup(0); - emitter.add(Overflow::Overflowing); + emitter.drop(SourceSpan::default()); + emitter.dup(0, SourceSpan::default()); + emitter.add(Overflow::Overflowing, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], Type::U32); @@ -905,26 +915,26 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.sub_imm(one, Overflow::Checked); + emitter.sub_imm(one, Overflow::Checked, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.sub(Overflow::Checked); + emitter.sub(Overflow::Checked, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); - emitter.sub_imm(one, Overflow::Overflowing); + emitter.sub_imm(one, Overflow::Overflowing, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], Type::U32); - emitter.drop(); - emitter.dup(0); - emitter.sub(Overflow::Overflowing); + emitter.drop(SourceSpan::default()); + emitter.dup(0, SourceSpan::default()); + emitter.sub(Overflow::Overflowing, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], Type::U32); @@ -940,26 +950,26 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.mul_imm(one, Overflow::Checked); + emitter.mul_imm(one, Overflow::Checked, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.mul(Overflow::Checked); + emitter.mul(Overflow::Checked, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); - emitter.mul_imm(one, Overflow::Overflowing); + emitter.mul_imm(one, Overflow::Overflowing, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], Type::U32); - emitter.drop(); - emitter.dup(0); - emitter.mul(Overflow::Overflowing); + emitter.drop(SourceSpan::default()); + emitter.dup(0, SourceSpan::default()); + emitter.mul(Overflow::Overflowing, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], Type::U32); @@ -975,20 +985,20 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.eq_imm(two); + emitter.eq_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], one); - emitter.assert(None); + emitter.assert(None, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], one); - emitter.dup(0); - emitter.eq(); + emitter.dup(0, SourceSpan::default()); + emitter.eq(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1003,20 +1013,20 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.neq_imm(two); + emitter.neq_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], one); - emitter.assertz(None); + emitter.assertz(None, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], one); - emitter.dup(0); - emitter.neq(); + emitter.dup(0, SourceSpan::default()); + emitter.neq(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1031,15 +1041,15 @@ mod tests { let t = Immediate::I1(true); let f = Immediate::I1(false); - emitter.literal(t); - emitter.literal(f); + emitter.literal(t, SourceSpan::default()); + emitter.literal(f, SourceSpan::default()); - emitter.and_imm(t); + emitter.and_imm(t, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], t); - emitter.and(); + emitter.and(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1054,15 +1064,15 @@ mod tests { let t = Immediate::I1(true); let f = Immediate::I1(false); - emitter.literal(t); - emitter.literal(f); + emitter.literal(t, SourceSpan::default()); + emitter.literal(f, SourceSpan::default()); - emitter.or_imm(t); + emitter.or_imm(t, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], t); - emitter.or(); + emitter.or(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1077,15 +1087,15 @@ mod tests { let t = Immediate::I1(true); let f = Immediate::I1(false); - emitter.literal(t); - emitter.literal(f); + emitter.literal(t, SourceSpan::default()); + emitter.literal(f, SourceSpan::default()); - emitter.xor_imm(t); + emitter.xor_imm(t, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], t); - emitter.xor(); + emitter.xor(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1099,9 +1109,9 @@ mod tests { let t = Immediate::I1(true); - emitter.literal(t); + emitter.literal(t, SourceSpan::default()); - emitter.not(); + emitter.not(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1116,17 +1126,17 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.gt_imm(two); + emitter.gt_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], one); - emitter.drop(); - emitter.dup(0); - emitter.gt(); + emitter.drop(SourceSpan::default()); + emitter.dup(0, SourceSpan::default()); + emitter.gt(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1141,17 +1151,17 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.gte_imm(two); + emitter.gte_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], one); - emitter.drop(); - emitter.dup(0); - emitter.gte(); + emitter.drop(SourceSpan::default()); + emitter.dup(0, SourceSpan::default()); + emitter.gte(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1166,17 +1176,17 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.lt_imm(two); + emitter.lt_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], one); - emitter.drop(); - emitter.dup(0); - emitter.lt(); + emitter.drop(SourceSpan::default()); + emitter.dup(0, SourceSpan::default()); + emitter.lt(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1191,17 +1201,17 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.lte_imm(two); + emitter.lte_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I1); assert_eq!(emitter.stack()[1], one); - emitter.drop(); - emitter.dup(0); - emitter.lte(); + emitter.drop(SourceSpan::default()); + emitter.dup(0, SourceSpan::default()); + emitter.lte(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1216,15 +1226,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.checked_div_imm(two); + emitter.checked_div_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.checked_div(); + emitter.checked_div(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1239,15 +1249,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.unchecked_div_imm(two); + emitter.unchecked_div_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.unchecked_div(); + emitter.unchecked_div(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1262,15 +1272,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.checked_mod_imm(two); + emitter.checked_mod_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.checked_mod(); + emitter.checked_mod(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1285,15 +1295,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.unchecked_mod_imm(two); + emitter.unchecked_mod_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.unchecked_mod(); + emitter.unchecked_mod(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1308,16 +1318,16 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.checked_divmod_imm(two); + emitter.checked_divmod_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 3); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], Type::U32); assert_eq!(emitter.stack()[2], one); - emitter.checked_divmod(); + emitter.checked_divmod(SourceSpan::default()); assert_eq!(emitter.stack_len(), 3); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], Type::U32); @@ -1334,16 +1344,16 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.unchecked_divmod_imm(two); + emitter.unchecked_divmod_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 3); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], Type::U32); assert_eq!(emitter.stack()[2], one); - emitter.unchecked_divmod(); + emitter.unchecked_divmod(SourceSpan::default()); assert_eq!(emitter.stack_len(), 3); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], Type::U32); @@ -1360,15 +1370,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.exp_imm(two); + emitter.exp_imm(two, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.exp(); + emitter.exp(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1383,15 +1393,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.band_imm(one); + emitter.band_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.band(); + emitter.band(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1406,15 +1416,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.bor_imm(one); + emitter.bor_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.bor(); + emitter.bor(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1429,15 +1439,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.bxor_imm(one); + emitter.bxor_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.bxor(); + emitter.bxor(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1452,15 +1462,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.shl_imm(one); + emitter.shl_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.shl(); + emitter.shl(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1475,15 +1485,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.shr_imm(one); + emitter.shr_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.shr(); + emitter.shr(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1498,15 +1508,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.rotl_imm(one); + emitter.rotl_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.rotl(); + emitter.rotl(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1521,15 +1531,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.rotr_imm(one); + emitter.rotr_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.rotr(); + emitter.rotr(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1544,15 +1554,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.min_imm(one); + emitter.min_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.min(); + emitter.min(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1567,15 +1577,15 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); - emitter.max_imm(one); + emitter.max_imm(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::U32); assert_eq!(emitter.stack()[1], one); - emitter.max(); + emitter.max(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1589,9 +1599,9 @@ mod tests { let max = Immediate::U32(u32::MAX); - emitter.literal(max); + emitter.literal(max, SourceSpan::default()); - emitter.trunc(&Type::U16); + emitter.trunc(&Type::U16, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U16); } @@ -1605,9 +1615,9 @@ mod tests { let one = Immediate::U16(1); - emitter.literal(one); + emitter.literal(one, SourceSpan::default()); - emitter.zext(&Type::U32); + emitter.zext(&Type::U32, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1621,9 +1631,9 @@ mod tests { let num = Immediate::I16(-128); - emitter.literal(num); + emitter.literal(num, SourceSpan::default()); - emitter.sext(&Type::I32); + emitter.sext(&Type::I32, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I32); } @@ -1637,9 +1647,9 @@ mod tests { let num = Immediate::U32(128); - emitter.literal(num); + emitter.literal(num, SourceSpan::default()); - emitter.cast(&Type::I32); + emitter.cast(&Type::I32, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I32); } @@ -1654,9 +1664,9 @@ mod tests { let addr = Immediate::U32(128); let ptr = Type::Ptr(Box::new(Type::Array(Box::new(Type::U64), 8))); - emitter.literal(addr); + emitter.literal(addr, SourceSpan::default()); - emitter.inttoptr(&ptr); + emitter.inttoptr(&ptr, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], ptr); } @@ -1670,9 +1680,9 @@ mod tests { let num = Immediate::U32(128); - emitter.literal(num); + emitter.literal(num, SourceSpan::default()); - emitter.is_odd(); + emitter.is_odd(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::I1); } @@ -1686,9 +1696,9 @@ mod tests { let num = Immediate::U32(128); - emitter.literal(num); + emitter.literal(num, SourceSpan::default()); - emitter.popcnt(); + emitter.popcnt(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1702,9 +1712,9 @@ mod tests { let num = Immediate::U32(128); - emitter.literal(num); + emitter.literal(num, SourceSpan::default()); - emitter.bnot(); + emitter.bnot(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1718,9 +1728,9 @@ mod tests { let ten = Immediate::U32(10); - emitter.literal(ten); + emitter.literal(ten, SourceSpan::default()); - emitter.pow2(); + emitter.pow2(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1734,9 +1744,9 @@ mod tests { let ten = Immediate::U32(10); - emitter.literal(ten); + emitter.literal(ten, SourceSpan::default()); - emitter.incr(); + emitter.incr(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1750,9 +1760,9 @@ mod tests { let ten = Immediate::Felt(Felt::new(10)); - emitter.literal(ten); + emitter.literal(ten, SourceSpan::default()); - emitter.inv(); + emitter.inv(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::Felt); } @@ -1766,9 +1776,9 @@ mod tests { let ten = Immediate::Felt(Felt::new(10)); - emitter.literal(ten); + emitter.literal(ten, SourceSpan::default()); - emitter.neg(); + emitter.neg(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::Felt); } @@ -1782,10 +1792,10 @@ mod tests { let ten = Immediate::U32(10); - emitter.literal(ten); + emitter.literal(ten, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); - emitter.assert(None); + emitter.assert(None, SourceSpan::default()); assert_eq!(emitter.stack_len(), 0); } @@ -1798,10 +1808,10 @@ mod tests { let ten = Immediate::U32(10); - emitter.literal(ten); + emitter.literal(ten, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); - emitter.assertz(None); + emitter.assertz(None, SourceSpan::default()); assert_eq!(emitter.stack_len(), 0); } @@ -1814,15 +1824,15 @@ mod tests { let ten = Immediate::U32(10); - emitter.literal(ten); - emitter.literal(ten); - emitter.literal(ten); + emitter.literal(ten, SourceSpan::default()); + emitter.literal(ten, SourceSpan::default()); + emitter.literal(ten, SourceSpan::default()); assert_eq!(emitter.stack_len(), 3); - emitter.assert_eq_imm(ten); + emitter.assert_eq_imm(ten, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); - emitter.assert_eq(); + emitter.assert_eq(SourceSpan::default()); assert_eq!(emitter.stack_len(), 0); } @@ -1837,12 +1847,12 @@ mod tests { let one = Immediate::U32(1); let two = Immediate::U32(2); - emitter.literal(one); - emitter.literal(two); - emitter.literal(t); + emitter.literal(one, SourceSpan::default()); + emitter.literal(two, SourceSpan::default()); + emitter.literal(t, SourceSpan::default()); assert_eq!(emitter.stack_len(), 3); - emitter.select(); + emitter.select(SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); } @@ -1868,11 +1878,11 @@ mod tests { let t = Immediate::I1(true); let one = Immediate::U32(1); - emitter.literal(t); - emitter.literal(one); + emitter.literal(t, SourceSpan::default()); + emitter.literal(one, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); - emitter.exec(&callee); + emitter.exec(&callee, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], return_ty); } @@ -1889,11 +1899,11 @@ mod tests { emitter.push(addr); assert_eq!(emitter.stack_len(), 1); - emitter.load(Type::U32); + emitter.load(Type::U32, SourceSpan::default()); assert_eq!(emitter.stack_len(), 1); assert_eq!(emitter.stack()[0], Type::U32); - emitter.load_imm(128, Type::I32); + emitter.load_imm(128, Type::I32, SourceSpan::default()); assert_eq!(emitter.stack_len(), 2); assert_eq!(emitter.stack()[0], Type::I32); assert_eq!(emitter.stack()[1], Type::U32); diff --git a/codegen/masm/src/codegen/emit/primop.rs b/codegen/masm/src/codegen/emit/primop.rs index 73d5eb1b..8012c6f0 100644 --- a/codegen/masm/src/codegen/emit/primop.rs +++ b/codegen/masm/src/codegen/emit/primop.rs @@ -1,5 +1,6 @@ use midenc_hir::{ - self as hir, ArgumentExtension, ArgumentPurpose, Felt, FieldElement, Immediate, Type, + self as hir, diagnostics::SourceSpan, ArgumentExtension, ArgumentPurpose, Felt, FieldElement, + Immediate, Type, }; use super::{int64, OpEmitter}; @@ -9,7 +10,7 @@ impl<'a> OpEmitter<'a> { /// Assert that an integer value on the stack has the value 1 /// /// This operation consumes the input value. - pub fn assert(&mut self, code: Option) { + pub fn assert(&mut self, code: Option, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let code = code.unwrap_or_default(); match arg.ty() { @@ -21,16 +22,19 @@ impl<'a> OpEmitter<'a> { | Type::U8 | Type::I8 | Type::I1 => { - self.emit(Op::AssertWithError(code)); + self.emit(Op::AssertWithError(code), span); } Type::I128 | Type::U128 => { - self.emit_all(&[ - Op::Pushw([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::ONE]), - Op::AssertEqwWithError(code), - ]); + self.emit_all( + &[ + Op::Pushw([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::ONE]), + Op::AssertEqwWithError(code), + ], + span, + ); } Type::U64 | Type::I64 => { - self.emit_all(&[Op::AssertzWithError(code), Op::AssertWithError(code)]); + self.emit_all(&[Op::AssertzWithError(code), Op::AssertWithError(code)], span); } ty if !ty.is_integer() => { panic!("invalid argument to assert: expected integer, got {ty}") @@ -42,7 +46,7 @@ impl<'a> OpEmitter<'a> { /// Assert that an integer value on the stack has the value 0 /// /// This operation consumes the input value. - pub fn assertz(&mut self, code: Option) { + pub fn assertz(&mut self, code: Option, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let code = code.unwrap_or_default(); match arg.ty() { @@ -54,13 +58,13 @@ impl<'a> OpEmitter<'a> { | Type::U8 | Type::I8 | Type::I1 => { - self.emit(Op::AssertzWithError(code)); + self.emit(Op::AssertzWithError(code), span); } Type::U64 | Type::I64 => { - self.emit_all(&[Op::AssertzWithError(code), Op::AssertzWithError(code)]); + self.emit_all(&[Op::AssertzWithError(code), Op::AssertzWithError(code)], span); } Type::U128 | Type::I128 => { - self.emit_all(&[Op::Pushw([Felt::ZERO; 4]), Op::AssertEqwWithError(code)]); + self.emit_all(&[Op::Pushw([Felt::ZERO; 4]), Op::AssertEqwWithError(code)], span); } ty if !ty.is_integer() => { panic!("invalid argument to assertz: expected integer, got {ty}") @@ -72,7 +76,7 @@ impl<'a> OpEmitter<'a> { /// Assert that the top two integer values on the stack have the same value /// /// This operation consumes the input values. - pub fn assert_eq(&mut self) { + pub fn assert_eq(&mut self, span: SourceSpan) { let rhs = self.pop().expect("operand stack is empty"); let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); @@ -86,17 +90,20 @@ impl<'a> OpEmitter<'a> { | Type::U8 | Type::I8 | Type::I1 => { - self.emit(Op::AssertEq); + self.emit(Op::AssertEq, span); } - Type::U128 | Type::I128 => self.emit(Op::AssertEqw), + Type::U128 | Type::I128 => self.emit(Op::AssertEqw, span), Type::U64 | Type::I64 => { - self.emit_all(&[ - // compare the hi bits - Op::Movup(2), - Op::AssertEq, - // compare the low bits - Op::AssertEq, - ]); + self.emit_all( + &[ + // compare the hi bits + Op::Movup(2), + Op::AssertEq, + // compare the low bits + Op::AssertEq, + ], + span, + ); } ty if !ty.is_integer() => { panic!("invalid argument to assert_eq: expected integer, got {ty}") @@ -109,7 +116,7 @@ impl<'a> OpEmitter<'a> { /// as the provided immediate. /// /// This operation consumes the input value. - pub fn assert_eq_imm(&mut self, imm: Immediate) { + pub fn assert_eq_imm(&mut self, imm: Immediate, span: SourceSpan) { let lhs = self.pop().expect("operand stack is empty"); let ty = lhs.ty(); assert_eq!(ty, imm.ty(), "expected assert_eq_imm operands to have the same type"); @@ -122,11 +129,11 @@ impl<'a> OpEmitter<'a> { | Type::U8 | Type::I8 | Type::I1 => { - self.emit_all(&[Op::EqImm(imm.as_felt().unwrap()), Op::Assert]); + self.emit_all(&[Op::EqImm(imm.as_felt().unwrap()), Op::Assert], span); } Type::I128 | Type::U128 => { - self.push_immediate(imm); - self.emit(Op::AssertEqw) + self.push_immediate(imm, span); + self.emit(Op::AssertEqw, span) } Type::I64 | Type::U64 => { let imm = match imm { @@ -135,12 +142,15 @@ impl<'a> OpEmitter<'a> { _ => unreachable!(), }; let (hi, lo) = int64::to_raw_parts(imm); - self.emit_all(&[ - Op::EqImm(Felt::new(hi as u64)), - Op::Assert, - Op::EqImm(Felt::new(lo as u64)), - Op::Assert, - ]) + self.emit_all( + &[ + Op::EqImm(Felt::new(hi as u64)), + Op::Assert, + Op::EqImm(Felt::new(lo as u64)), + Op::Assert, + ], + span, + ) } ty if !ty.is_integer() => { panic!("invalid argument to assert_eq: expected integer, got {ty}") @@ -160,7 +170,7 @@ impl<'a> OpEmitter<'a> { /// * Pop `b` and `a` from the stack, and push back `b` if `c` is true, or `a` if `c` is false. /// /// This operation will assert that the selected value is a valid value for the given type. - pub fn select(&mut self) { + pub fn select(&mut self, span: SourceSpan) { let c = self.stack.pop().expect("operand stack is empty"); let b = self.stack.pop().expect("operand stack is empty"); let a = self.stack.pop().expect("operand stack is empty"); @@ -175,23 +185,26 @@ impl<'a> OpEmitter<'a> { | Type::I16 | Type::U8 | Type::I8 - | Type::I1 => self.emit(Op::Cdrop), - Type::I128 | Type::U128 => self.emit(Op::Cdropw), + | Type::I1 => self.emit(Op::Cdrop, span), + Type::I128 | Type::U128 => self.emit(Op::Cdropw, span), Type::I64 | Type::U64 => { // Perform two conditional drops, one for each 32-bit limb // corresponding to the value which is being selected - self.emit_all(&[ - // stack starts as [c, b_hi, b_lo, a_hi, a_lo] - Op::Dup(0), // [c, c, b_hi, b_lo, a_hi, a_lo] - Op::Movdn(6), // [c, b_hi, b_lo, a_hi, a_lo, c] - Op::Movup(3), // [a_hi, c, b_hi, b_lo, a_lo, c] - Op::Movup(2), // [b_hi, a_hi, c, b_lo, a_lo, c] - Op::Movup(6), // [c, b_hi, a_hi, c, b_lo, a_lo] - Op::Cdrop, // [d_hi, c, b_lo, a_lo] - Op::Movdn(4), // [c, b_lo, a_lo, d_hi] - Op::Cdrop, // [d_lo, d_hi] - Op::Swap(1), // [d_hi, d_lo] - ]); + self.emit_all( + &[ + // stack starts as [c, b_hi, b_lo, a_hi, a_lo] + Op::Dup(0), // [c, c, b_hi, b_lo, a_hi, a_lo] + Op::Movdn(6), // [c, b_hi, b_lo, a_hi, a_lo, c] + Op::Movup(3), // [a_hi, c, b_hi, b_lo, a_lo, c] + Op::Movup(2), // [b_hi, a_hi, c, b_lo, a_lo, c] + Op::Movup(6), // [c, b_hi, a_hi, c, b_lo, a_lo] + Op::Cdrop, // [d_hi, c, b_lo, a_lo] + Op::Movdn(4), // [c, b_lo, a_lo, d_hi] + Op::Cdrop, // [d_lo, d_hi] + Op::Swap(1), // [d_hi, d_lo] + ], + span, + ); } ty if !ty.is_integer() => { panic!("invalid argument to assert_eq: expected integer, got {ty}") @@ -204,7 +217,7 @@ impl<'a> OpEmitter<'a> { /// Execute the given procedure. /// /// A function called using this operation is invoked in the same memory context as the caller. - pub fn exec(&mut self, callee: &hir::ExternalFunction) { + pub fn exec(&mut self, callee: &hir::ExternalFunction, span: SourceSpan) { let import = callee; let callee = import.id; let signature = &import.signature; @@ -270,7 +283,7 @@ impl<'a> OpEmitter<'a> { ); // Zero-extend this argument self.stack.push(arg); - self.zext(¶m.ty); + self.zext(¶m.ty, span); self.stack.drop(); } // Caller can provide a smaller type which will be sign-extended to the expected @@ -307,7 +320,7 @@ impl<'a> OpEmitter<'a> { } // Push the operand back on the stack for `sext` self.stack.push(arg); - self.sext(¶m.ty); + self.sext(¶m.ty, span); self.stack.drop(); } ArgumentExtension::Zext | ArgumentExtension::Sext => (), @@ -318,13 +331,13 @@ impl<'a> OpEmitter<'a> { self.stack.push(result.ty.clone()); } - self.emit(Op::Exec(callee)); + self.emit(Op::Exec(callee), span); } /// Execute the given procedure as a syscall. /// /// A function called using this operation is invoked in the same memory context as the caller. - pub fn syscall(&mut self, _callee: &hir::ExternalFunction) { + pub fn syscall(&mut self, _callee: &hir::ExternalFunction, _span: SourceSpan) { todo!() } } diff --git a/codegen/masm/src/codegen/emit/smallint.rs b/codegen/masm/src/codegen/emit/smallint.rs index 3b776b67..b45b4163 100644 --- a/codegen/masm/src/codegen/emit/smallint.rs +++ b/codegen/masm/src/codegen/emit/smallint.rs @@ -8,7 +8,7 @@ //! For signed smallint operations, we implement them in terms of a two's complement representation, //! using a set of common primitives. The only thing that changes are which bits are considered by //! those primitives. -use midenc_hir::Overflow; +use midenc_hir::{diagnostics::SourceSpan, Overflow}; use super::OpEmitter; use crate::masm::Op; @@ -17,50 +17,50 @@ use crate::masm::Op; impl<'a> OpEmitter<'a> { /// Check that a u32 value on the stack can fit in the unsigned N-bit integer range #[inline(always)] - pub fn is_valid_uint(&mut self, n: u32) { + pub fn is_valid_uint(&mut self, n: u32, span: SourceSpan) { // Use fallible conversion from u32 - self.try_int32_to_uint(n); + self.try_int32_to_uint(n, span); } /// Check that the 32-bit value on the stack can fit in the signed N-bit integer range #[inline(always)] - pub fn is_valid_int(&mut self, n: u32) { - self.try_int32_to_int(n); + pub fn is_valid_int(&mut self, n: u32, span: SourceSpan) { + self.try_int32_to_int(n, span); } /// Check if the sign bit of an N-bit integer on the stack, is set. #[inline] - pub fn is_signed_smallint(&mut self, n: u32) { + pub fn is_signed_smallint(&mut self, n: u32, span: SourceSpan) { assert_valid_integer_size!(n, 1, 32); match n { // i1 is never signed - 1 => self.emit(Op::PushU32(0)), - n => self.is_const_flag_set_u32(1 << (n - 1)), + 1 => self.emit(Op::PushU32(0), span), + n => self.is_const_flag_set_u32(1 << (n - 1), span), } } /// Asserts the N-bit integer on the stack does not have its sign bit set. #[inline] - pub fn assert_unsigned_smallint(&mut self, n: u32) { + pub fn assert_unsigned_smallint(&mut self, n: u32, span: SourceSpan) { match n { // i1 is always unsigned 1 => (), n => { - self.is_signed_smallint(n); - self.emit(Op::Assert); + self.is_signed_smallint(n, span); + self.emit(Op::Assert, span); } } } /// Convert a signed N-bit integer to a field element #[inline(always)] - pub fn int_to_felt(&mut self, n: u32) { - self.assert_unsigned_smallint(n); + pub fn int_to_felt(&mut self, n: u32, span: SourceSpan) { + self.assert_unsigned_smallint(n, span); } /// Convert an unsigned N-bit integer to a field element #[inline(always)] - pub fn uint_to_felt(&mut self, n: u32) { + pub fn uint_to_felt(&mut self, n: u32, _span: SourceSpan) { // Conversion to felt is a no-op assert_valid_integer_size!(n, 1, 32); } @@ -69,35 +69,35 @@ impl<'a> OpEmitter<'a> { /// /// This operation will trap if the value has the sign bit set. #[inline] - pub fn int_to_u64(&mut self, n: u32) { - self.assert_unsigned_smallint(n); - self.emit(Op::PushU32(0)); + pub fn int_to_u64(&mut self, n: u32, span: SourceSpan) { + self.assert_unsigned_smallint(n, span); + self.emit(Op::PushU32(0), span); } /// Convert an unsigned N-bit integer to u64 #[inline(always)] - pub fn uint_to_u64(&mut self, _: u32) { - self.emit(Op::PushU32(0)); + pub fn uint_to_u64(&mut self, _: u32, span: SourceSpan) { + self.emit(Op::PushU32(0), span); } /// Convert a signed N-bit integer to i128 #[inline] - pub fn int_to_i128(&mut self, n: u32) { - self.sext_smallint(n, 128); + pub fn int_to_i128(&mut self, n: u32, span: SourceSpan) { + self.sext_smallint(n, 128, span); } /// Convert an unsigned N-bit integer to i128 #[inline(always)] - pub fn uint_to_i128(&mut self, _n: u32) { + pub fn uint_to_i128(&mut self, _n: u32, span: SourceSpan) { // zero-extend to i128 - self.emit_n(3, Op::PushU32(0)); + self.emit_n(3, Op::PushU32(0), span); } /// Sign-extend the N-bit value on the stack to M-bits, where M is >= N and <= 256. /// /// This assumes the value on the stack is a valid N-bit integer in two's complement /// representation, i.e. the most significant bit is the sign bit. - pub fn sext_smallint(&mut self, n: u32, m: u32) { + pub fn sext_smallint(&mut self, n: u32, m: u32, span: SourceSpan) { assert_valid_integer_size!(n, n, 256); // No-op if n == m { @@ -112,27 +112,30 @@ impl<'a> OpEmitter<'a> { // We optimize larger extensions by re-using the is_signed flag let is_large = m > 32; // Get the value of the sign bit - self.is_signed_smallint(n); + self.is_signed_smallint(n, span); if is_large { // Make a copy for selecting padding later - self.emit(Op::Dup(0)); - self.select_int32(sign_bits, 0); - self.emit_all(&[ - // Move the input value to the top of the stack - Op::Movup(2), - // Sign-extend to i32 - Op::U32Or, - // Move the is_signed flag back to the top - Op::Swap(1), - ]); + self.emit(Op::Dup(0), span); + self.select_int32(sign_bits, 0, span); + self.emit_all( + &[ + // Move the input value to the top of the stack + Op::Movup(2), + // Sign-extend to i32 + Op::U32Or, + // Move the is_signed flag back to the top + Op::Swap(1), + ], + span, + ); // Select the padding element value - self.select_int32(u32::MAX, 0); + self.select_int32(u32::MAX, 0, span); // Pad out to M bits - self.pad_int32(m); + self.pad_int32(m, span); } else { - self.select_int32(sign_bits, 0); + self.select_int32(sign_bits, 0, span); // Sign-extend to i32 - self.emit(Op::U32Or); + self.emit(Op::U32Or, span); } } @@ -140,31 +143,31 @@ impl<'a> OpEmitter<'a> { /// /// This assumes the value on the stack is a valid N-bit integer. #[inline] - pub fn zext_smallint(&mut self, n: u32, m: u32) { + pub fn zext_smallint(&mut self, n: u32, m: u32, span: SourceSpan) { assert_valid_integer_size!(n, n, 256); // No-op if n == m { return; } - self.zext_int32(m); + self.zext_int32(m, span); } - pub fn add_uint(&mut self, n: u32, overflow: Overflow) { + pub fn add_uint(&mut self, n: u32, overflow: Overflow, span: SourceSpan) { match overflow { - Overflow::Unchecked => self.add_u32(Overflow::Unchecked), + Overflow::Unchecked => self.add_u32(Overflow::Unchecked, span), overflow => { - self.add_u32(Overflow::Checked); - self.handle_uint_overflow(n, overflow) + self.add_u32(Overflow::Checked, span); + self.handle_uint_overflow(n, overflow, span) } } } - pub fn add_imm_uint(&mut self, imm: u32, n: u32, overflow: Overflow) { + pub fn add_imm_uint(&mut self, imm: u32, n: u32, overflow: Overflow, span: SourceSpan) { match overflow { - Overflow::Unchecked => self.add_imm_u32(imm, Overflow::Unchecked), + Overflow::Unchecked => self.add_imm_u32(imm, Overflow::Unchecked, span), overflow => { - self.add_imm_u32(imm, Overflow::Checked); - self.handle_uint_overflow(n, overflow) + self.add_imm_u32(imm, Overflow::Checked, span); + self.handle_uint_overflow(n, overflow, span) } } } @@ -172,12 +175,12 @@ impl<'a> OpEmitter<'a> { /// Pops two u32 values off the stack, `b` and `a`, and performs `a - b`. /// /// See the [Overflow] type for how overflow semantics can change the operation. - pub fn sub_uint(&mut self, n: u32, overflow: Overflow) { + pub fn sub_uint(&mut self, n: u32, overflow: Overflow, span: SourceSpan) { match overflow { - Overflow::Unchecked => self.sub_u32(overflow), + Overflow::Unchecked => self.sub_u32(overflow, span), overflow => { - self.sub_u32(overflow); - self.handle_uint_overflow(n, overflow); + self.sub_u32(overflow, span); + self.handle_uint_overflow(n, overflow, span); } } } @@ -188,67 +191,67 @@ impl<'a> OpEmitter<'a> { /// /// Subtracting zero is a no-op. #[inline] - pub fn sub_imm_uint(&mut self, imm: u32, n: u32, overflow: Overflow) { + pub fn sub_imm_uint(&mut self, imm: u32, n: u32, overflow: Overflow, span: SourceSpan) { if imm == 0 { return; } match overflow { - Overflow::Unchecked => self.sub_imm_u32(imm, overflow), + Overflow::Unchecked => self.sub_imm_u32(imm, overflow, span), overflow => { - self.sub_imm_u32(imm, overflow); - self.handle_uint_overflow(n, overflow); + self.sub_imm_u32(imm, overflow, span); + self.handle_uint_overflow(n, overflow, span); } } } - pub fn mul_uint(&mut self, n: u32, overflow: Overflow) { + pub fn mul_uint(&mut self, n: u32, overflow: Overflow, span: SourceSpan) { match overflow { - Overflow::Unchecked => self.mul_u32(Overflow::Unchecked), + Overflow::Unchecked => self.mul_u32(Overflow::Unchecked, span), overflow => { - self.mul_u32(Overflow::Checked); - self.handle_uint_overflow(n, overflow) + self.mul_u32(Overflow::Checked, span); + self.handle_uint_overflow(n, overflow, span) } } } - pub fn mul_imm_uint(&mut self, imm: u32, n: u32, overflow: Overflow) { + pub fn mul_imm_uint(&mut self, imm: u32, n: u32, overflow: Overflow, span: SourceSpan) { match overflow { - Overflow::Unchecked => self.mul_imm_u32(imm, Overflow::Unchecked), + Overflow::Unchecked => self.mul_imm_u32(imm, Overflow::Unchecked, span), overflow => { - self.mul_imm_u32(imm, Overflow::Checked); - self.handle_uint_overflow(n, overflow) + self.mul_imm_u32(imm, Overflow::Checked, span); + self.handle_uint_overflow(n, overflow, span) } } } #[inline] - pub fn checked_div_uint(&mut self, n: u32) { - self.checked_div_u32(); - self.int32_to_uint(n); + pub fn checked_div_uint(&mut self, n: u32, span: SourceSpan) { + self.checked_div_u32(span); + self.int32_to_uint(n, span); } #[inline] - pub fn checked_div_imm_uint(&mut self, imm: u32, n: u32) { - self.checked_div_imm_u32(imm); - self.int32_to_uint(n); + pub fn checked_div_imm_uint(&mut self, imm: u32, n: u32, span: SourceSpan) { + self.checked_div_imm_u32(imm, span); + self.int32_to_uint(n, span); } #[inline(always)] - pub fn unchecked_div_uint(&mut self, _n: u32) { - self.unchecked_div_u32(); + pub fn unchecked_div_uint(&mut self, _n: u32, span: SourceSpan) { + self.unchecked_div_u32(span); } #[inline(always)] - pub fn unchecked_div_imm_uint(&mut self, imm: u32, _n: u32) { - self.unchecked_div_imm_u32(imm); + pub fn unchecked_div_imm_uint(&mut self, imm: u32, _n: u32, span: SourceSpan) { + self.unchecked_div_imm_u32(imm, span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a % b`. /// /// This operation is checked, so if the operands or result are not valid u32, execution traps. #[inline(always)] - pub fn checked_mod_uint(&mut self, _n: u32) { - self.checked_mod_u32(); + pub fn checked_mod_uint(&mut self, _n: u32, span: SourceSpan) { + self.checked_mod_u32(span); } /// Pops a u32 value off the stack, `a`, and performs `a % `. @@ -257,24 +260,24 @@ impl<'a> OpEmitter<'a> { /// /// This operation is checked, so if the operand or result are not valid u32, execution traps. #[inline(always)] - pub fn checked_mod_imm_uint(&mut self, imm: u32, _n: u32) { - self.checked_mod_imm_u32(imm); + pub fn checked_mod_imm_uint(&mut self, imm: u32, _n: u32, span: SourceSpan) { + self.checked_mod_imm_u32(imm, span); } /// Pops two u32 values off the stack, `b` and `a`, and performs `a % b`. /// /// This operation is unchecked, so the result is not guaranteed to be a valid u32 #[inline(always)] - pub fn unchecked_mod_uint(&mut self, _n: u32) { - self.unchecked_mod_u32(); + pub fn unchecked_mod_uint(&mut self, _n: u32, span: SourceSpan) { + self.unchecked_mod_u32(span); } /// Pops a u32 value off the stack, `a`, and performs `a % `. /// /// This function will panic if the divisor is zero. #[inline(always)] - pub fn unchecked_mod_imm_uint(&mut self, imm: u32, _n: u32) { - self.unchecked_mod_imm_u32(imm); + pub fn unchecked_mod_imm_uint(&mut self, imm: u32, _n: u32, span: SourceSpan) { + self.unchecked_mod_imm_u32(imm, span); } /// Pops two u32 values off the stack, `b` and `a`, and pushes `a / b`, then `a % b` on the @@ -282,16 +285,16 @@ impl<'a> OpEmitter<'a> { /// /// This operation is checked, so if the operands or result are not valid u32, execution traps. #[inline(always)] - pub fn checked_divmod_uint(&mut self, _n: u32) { - self.checked_divmod_u32(); + pub fn checked_divmod_uint(&mut self, _n: u32, span: SourceSpan) { + self.checked_divmod_u32(span); } /// Pops a u32 value off the stack, `a`, and pushes `a / `, then `a % ` on the stack. /// /// This operation is checked, so if the operands or result are not valid u32, execution traps. #[inline(always)] - pub fn checked_divmod_imm_uint(&mut self, imm: u32, _n: u32) { - self.checked_divmod_imm_u32(imm); + pub fn checked_divmod_imm_uint(&mut self, imm: u32, _n: u32, span: SourceSpan) { + self.checked_divmod_imm_u32(imm, span); } /// Pops two u32 values off the stack, `b` and `a`, and pushes `a / b`, then `a % b` on the @@ -299,33 +302,36 @@ impl<'a> OpEmitter<'a> { /// /// This operation is unchecked, so the result is not guaranteed to be a valid u32 #[inline(always)] - pub fn unchecked_divmod_uint(&mut self, _n: u32) { - self.unchecked_divmod_u32(); + pub fn unchecked_divmod_uint(&mut self, _n: u32, span: SourceSpan) { + self.unchecked_divmod_u32(span); } /// Pops a u32 value off the stack, `a`, and pushes `a / `, then `a % ` on the stack. /// /// This operation is unchecked, so the result is not guaranteed to be a valid u32 #[inline(always)] - pub fn unchecked_divmod_imm_uint(&mut self, imm: u32, _n: u32) { - self.unchecked_divmod_imm_u32(imm) + pub fn unchecked_divmod_imm_uint(&mut self, imm: u32, _n: u32, span: SourceSpan) { + self.unchecked_divmod_imm_u32(imm, span) } - pub fn handle_uint_overflow(&mut self, n: u32, overflow: Overflow) { + pub fn handle_uint_overflow(&mut self, n: u32, overflow: Overflow, span: SourceSpan) { match overflow { Overflow::Unchecked => (), - Overflow::Checked => self.int32_to_uint(n), - Overflow::Wrapping => self.emit(Op::U32ModImm(2u32.pow(n))), + Overflow::Checked => self.int32_to_uint(n, span), + Overflow::Wrapping => self.emit(Op::U32ModImm(2u32.pow(n)), span), Overflow::Overflowing => { - self.try_int32_to_uint(n); - self.emit_all(&[ - // move result to top, and wrap it at 2^n - Op::Swap(1), - Op::U32ModImm(2u32.pow(n)), - // move is_valid flag to top, and invert it - Op::Swap(1), - Op::Not, - ]); + self.try_int32_to_uint(n, span); + self.emit_all( + &[ + // move result to top, and wrap it at 2^n + Op::Swap(1), + Op::U32ModImm(2u32.pow(n)), + // move is_valid flag to top, and invert it + Op::Swap(1), + Op::Not, + ], + span, + ); } } } diff --git a/codegen/masm/src/codegen/emit/unary.rs b/codegen/masm/src/codegen/emit/unary.rs index d7dfe3c2..737c158b 100644 --- a/codegen/masm/src/codegen/emit/unary.rs +++ b/codegen/masm/src/codegen/emit/unary.rs @@ -24,7 +24,7 @@ impl<'a> OpEmitter<'a> { /// This function assumes that an integer value of type `src` is on top of the operand stack, /// and will ensure a value of type `dst` is on the operand stack after truncation, or that /// execution traps. - pub fn trunc(&mut self, dst: &Type) { + pub fn trunc(&mut self, dst: &Type, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let src = arg.ty(); assert!( @@ -35,33 +35,33 @@ impl<'a> OpEmitter<'a> { match (&src, dst) { // If the types are equivalent, it's a no-op (src, dst) if src == dst => (), - (Type::Felt, _) if n <= 32 => self.trunc_felt(n), + (Type::Felt, _) if n <= 32 => self.trunc_felt(n, span), // Truncating i128 to u128, and vice versa is a bitcast (Type::I128 | Type::U128, Type::U128 | Type::I128) => (), // Truncating to felt - (Type::U128 | Type::I128, Type::Felt) => self.trunc_i128_to_felt(), + (Type::U128 | Type::I128, Type::Felt) => self.trunc_i128_to_felt(span), // Truncating a 128-bit integer to 64 bits or smaller - (Type::U128 | Type::I128, _) if n <= 64 => self.trunc_i128(n), + (Type::U128 | Type::I128, _) if n <= 64 => self.trunc_i128(n, span), // Truncating i64/u64 to felt - (Type::I64 | Type::U64, Type::Felt) => self.trunc_int64_to_felt(), + (Type::I64 | Type::U64, Type::Felt) => self.trunc_int64_to_felt(span), // Truncating i64 to u64, and vice versa is a bitcast (Type::I64 | Type::U64, Type::U64 | Type::I64) => (), // Truncating a u64/i64 to 32 bits or smaller - (Type::I64 | Type::U64, _) if n <= 32 => self.trunc_int64(n), + (Type::I64 | Type::U64, _) if n <= 32 => self.trunc_int64(n, span), // Truncating a felt to 32 bits or smaller - (Type::Felt, _) if n <= 32 => self.trunc_felt(n), + (Type::Felt, _) if n <= 32 => self.trunc_felt(n, span), // Truncating i32 to u32, and vice versa is a bitcast (Type::I32 | Type::U32, Type::U32 | Type::I32) => (), // Truncating an i32/u32 to smaller than 32 bits - (Type::I32 | Type::U32, _) if n <= 32 => self.trunc_int32(n), + (Type::I32 | Type::U32, _) if n <= 32 => self.trunc_int32(n, span), // Truncating i16 to u16, and vice versa is a bitcast (Type::I16 | Type::U16, Type::U16 | Type::I16) => (), // Truncating an i16/u16 to smaller than 16 bits - (Type::I16 | Type::U16, _) if n <= 16 => self.trunc_int32(n), + (Type::I16 | Type::U16, _) if n <= 16 => self.trunc_int32(n, span), // Truncating i8 to u8, and vice versa is a bitcast (Type::I8 | Type::U8, Type::U8 | Type::I8) => (), // Truncating an i8/u8 to smaller than 8 bits - (Type::I8 | Type::U8, _) if n <= 8 => self.trunc_int32(n), + (Type::I8 | Type::U8, _) if n <= 8 => self.trunc_int32(n, span), (src, dst) => unimplemented!("unsupported truncation of {src} to {dst}"), } self.stack.push(dst.clone()); @@ -93,7 +93,7 @@ impl<'a> OpEmitter<'a> { /// This function assumes that an integer value of type `src` is on top of the operand stack, /// and will ensure a value of type `dst` is on the operand stack after truncation, or that /// execution traps. - pub fn zext(&mut self, dst: &Type) { + pub fn zext(&mut self, dst: &Type, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let src = arg.ty(); let src_bits = src.size_in_bits() as u32; @@ -106,13 +106,13 @@ impl<'a> OpEmitter<'a> { // If the types are equivalent, it's a no-op, but only if they are integers (src, dst) if src == dst => (), // Zero-extending a u64 to i128 simply requires pushing a 0u64 on the stack - (Type::U64, Type::U128 | Type::I128) => self.push_u64(0), - (Type::Felt, Type::U64 | Type::U128 | Type::I128) => self.zext_felt(dst_bits), + (Type::U64, Type::U128 | Type::I128) => self.push_u64(0, span), + (Type::Felt, Type::U64 | Type::U128 | Type::I128) => self.zext_felt(dst_bits, span), (Type::U32, Type::U64 | Type::I64 | Type::U128 | Type::I128) => { - self.zext_int32(dst_bits) + self.zext_int32(dst_bits, span) } (Type::I1 | Type::U8 | Type::U16, Type::U64 | Type::I64 | Type::U128 | Type::I128) => { - self.zext_smallint(src_bits, dst_bits) + self.zext_smallint(src_bits, dst_bits, span) } // Zero-extending to u32/i32 from smaller integers is a no-op (Type::I1 | Type::U8 | Type::U16, Type::U32 | Type::I32) => (), @@ -153,7 +153,7 @@ impl<'a> OpEmitter<'a> { /// This function assumes that an integer value of type `src` is on top of the operand stack, /// and will ensure a value of type `dst` is on the operand stack after truncation, or that /// execution traps. - pub fn sext(&mut self, dst: &Type) { + pub fn sext(&mut self, dst: &Type, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let src = arg.ty(); assert!( @@ -170,19 +170,19 @@ impl<'a> OpEmitter<'a> { match (&src, dst) { // If the types are equivalent, it's a no-op (src, dst) if src == dst => (), - (Type::U64 | Type::I64, Type::I128) => self.sext_int64(128), - (Type::Felt, Type::I64 | Type::I128) => self.sext_felt(dst_bits), - (Type::I32 | Type::U32, Type::I64 | Type::I128) => self.sext_int32(dst_bits), + (Type::U64 | Type::I64, Type::I128) => self.sext_int64(128, span), + (Type::Felt, Type::I64 | Type::I128) => self.sext_felt(dst_bits, span), + (Type::I32 | Type::U32, Type::I64 | Type::I128) => self.sext_int32(dst_bits, span), ( Type::I1 | Type::I8 | Type::U8 | Type::I16 | Type::U16, Type::I32 | Type::I64 | Type::I128, - ) => self.sext_smallint(src_bits, dst_bits), + ) => self.sext_smallint(src_bits, dst_bits, span), (src, dst) => panic!("unsupported sign-extension from {src} to {dst}"), } self.stack.push(dst.clone()); } - pub fn bitcast(&mut self, dst: &Type) { + pub fn bitcast(&mut self, dst: &Type, _span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let src = arg.ty(); assert!( @@ -216,7 +216,7 @@ impl<'a> OpEmitter<'a> { /// This function assumes that an integer value of type `src` is on top of the operand stack, /// and will ensure a value of type `dst` is on the operand stack after truncation, or that /// execution traps. - pub fn cast(&mut self, dst: &Type) { + pub fn cast(&mut self, dst: &Type, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let src = arg.ty(); assert!( @@ -228,118 +228,121 @@ impl<'a> OpEmitter<'a> { let dst_bits = dst.size_in_bits() as u32; match (&src, dst) { // u128 - (Type::U128, Type::I128) => self.assert_unsigned_int128(), - (Type::U128, Type::I64) => self.u128_to_i64(), - (Type::U128 | Type::I128, Type::U64) => self.int128_to_u64(), - (Type::U128 | Type::I128, Type::Felt) => self.int128_to_felt(), - (Type::U128 | Type::I128, Type::U32) => self.int128_to_u32(), + (Type::U128, Type::I128) => self.assert_unsigned_int128(span), + (Type::U128, Type::I64) => self.u128_to_i64(span), + (Type::U128 | Type::I128, Type::U64) => self.int128_to_u64(span), + (Type::U128 | Type::I128, Type::Felt) => self.int128_to_felt(span), + (Type::U128 | Type::I128, Type::U32) => self.int128_to_u32(span), (Type::U128 | Type::I128, Type::U16 | Type::U8 | Type::I1) => { - self.int128_to_u32(); - self.int32_to_uint(dst_bits); + self.int128_to_u32(span); + self.int32_to_uint(dst_bits, span); } (Type::U128, Type::I32) => { - self.int128_to_u32(); - self.assert_unsigned_int32(); + self.int128_to_u32(span); + self.assert_unsigned_int32(span); } (Type::U128, Type::I16 | Type::I8) => { - self.int128_to_u32(); - self.int32_to_int(dst_bits); + self.int128_to_u32(span); + self.int32_to_int(dst_bits, span); } // i128 - (Type::I128, Type::I64) => self.i128_to_i64(), + (Type::I128, Type::I64) => self.i128_to_i64(span), (Type::I128, Type::I32 | Type::I16 | Type::I8) => { - self.i128_to_i64(); - self.i64_to_int(dst_bits); + self.i128_to_i64(span); + self.i64_to_int(dst_bits, span); } // i64 - (Type::I64, Type::I128) => self.sext_int64(128), - (Type::I64, Type::U128) => self.zext_int64(128), - (Type::I64, Type::U64) => self.assert_unsigned_int64(), - (Type::I64, Type::Felt) => self.i64_to_felt(), + (Type::I64, Type::I128) => self.sext_int64(128, span), + (Type::I64, Type::U128) => self.zext_int64(128, span), + (Type::I64, Type::U64) => self.assert_unsigned_int64(span), + (Type::I64, Type::Felt) => self.i64_to_felt(span), (Type::I64, Type::U32 | Type::U16 | Type::U8 | Type::I1) => { - self.assert_unsigned_int64(); - self.u64_to_uint(dst_bits); + self.assert_unsigned_int64(span); + self.u64_to_uint(dst_bits, span); } (Type::I64, Type::I32 | Type::I16 | Type::I8) => { - self.i64_to_int(dst_bits); + self.i64_to_int(dst_bits, span); } // u64 - (Type::U64, Type::I128 | Type::U128) => self.zext_int64(128), - (Type::U64, Type::I64) => self.assert_i64(), - (Type::U64, Type::Felt) => self.u64_to_felt(), + (Type::U64, Type::I128 | Type::U128) => self.zext_int64(128, span), + (Type::U64, Type::I64) => self.assert_i64(span), + (Type::U64, Type::Felt) => self.u64_to_felt(span), (Type::U64, Type::U32 | Type::U16 | Type::U8 | Type::I1) => { - self.u64_to_uint(dst_bits); + self.u64_to_uint(dst_bits, span); } (Type::U64, Type::I32 | Type::I16 | Type::I8) => { // Convert to N bits as unsigned - self.u64_to_uint(dst_bits); + self.u64_to_uint(dst_bits, span); // Verify that the input value is still unsigned - self.assert_unsigned_smallint(dst_bits); + self.assert_unsigned_smallint(dst_bits, span); } // felt - (Type::Felt, Type::I64 | Type::I128) => self.sext_felt(dst_bits), - (Type::Felt, Type::U128) => self.zext_felt(dst_bits), - (Type::Felt, Type::U64) => self.felt_to_u64(), + (Type::Felt, Type::I64 | Type::I128) => self.sext_felt(dst_bits, span), + (Type::Felt, Type::U128) => self.zext_felt(dst_bits, span), + (Type::Felt, Type::U64) => self.felt_to_u64(span), (Type::Felt, Type::U32 | Type::U16 | Type::U8 | Type::I1) => { - self.felt_to_uint(dst_bits); + self.felt_to_uint(dst_bits, span); } (Type::Felt, Type::I32 | Type::I16 | Type::I8) => { - self.felt_to_int(dst_bits); + self.felt_to_int(dst_bits, span); } // u32 - (Type::U32, Type::I64 | Type::U64 | Type::I128) => self.zext_int32(dst_bits), - (Type::U32, Type::I32) => self.assert_i32(), + (Type::U32, Type::I64 | Type::U64 | Type::I128) => self.zext_int32(dst_bits, span), + (Type::U32, Type::I32) => self.assert_i32(span), (Type::U32, Type::U16 | Type::U8 | Type::I1) => { - self.int32_to_uint(dst_bits); + self.int32_to_uint(dst_bits, span); } - (Type::U32, Type::I16 | Type::I8) => self.int32_to_int(dst_bits), + (Type::U32, Type::I16 | Type::I8) => self.int32_to_int(dst_bits, span), // i32 - (Type::I32, Type::I64 | Type::I128) => self.sext_int32(dst_bits), + (Type::I32, Type::I64 | Type::I128) => self.sext_int32(dst_bits, span), (Type::I32, Type::U64) => { - self.assert_i32(); - self.emit(Op::PushU32(0)); + self.assert_i32(span); + self.emit(Op::PushU32(0), span); } (Type::I32, Type::U32) => { - self.assert_i32(); + self.assert_i32(span); } (Type::I32, Type::U16 | Type::U8 | Type::I1) => { - self.int32_to_uint(dst_bits); + self.int32_to_uint(dst_bits, span); } - (Type::I32, Type::I16 | Type::I8) => self.int32_to_int(dst_bits), + (Type::I32, Type::I16 | Type::I8) => self.int32_to_int(dst_bits, span), // i8/i16 (Type::I8 | Type::I16, Type::I32 | Type::I64 | Type::I128) => { - self.sext_smallint(src_bits, dst_bits); + self.sext_smallint(src_bits, dst_bits, span); } (Type::I8 | Type::I16, Type::U32 | Type::U64) => { - self.assert_unsigned_smallint(src_bits); - self.zext_smallint(src_bits, dst_bits); + self.assert_unsigned_smallint(src_bits, span); + self.zext_smallint(src_bits, dst_bits, span); } (Type::I16, Type::U16) | (Type::I8, Type::U8) => { - self.assert_unsigned_smallint(src_bits); + self.assert_unsigned_smallint(src_bits, span); } - (Type::I16, Type::U8 | Type::I1) => self.int32_to_int(dst_bits), - (Type::I16, Type::I8) => self.int32_to_int(dst_bits), + (Type::I16, Type::U8 | Type::I1) => self.int32_to_int(dst_bits, span), + (Type::I16, Type::I8) => self.int32_to_int(dst_bits, span), (Type::I8, Type::I1) => { - self.emit_all(&[ - // Assert that input is either 0 or 1 - // - // NOTE: The comparison here is unsigned, so the sign - // bit being set will make the i8 larger than 0 or 1 - Op::Dup(0), - Op::PushU32(2), - Op::Lt, - Op::Assert, - ]); + self.emit_all( + &[ + // Assert that input is either 0 or 1 + // + // NOTE: The comparison here is unsigned, so the sign + // bit being set will make the i8 larger than 0 or 1 + Op::Dup(0), + Op::PushU32(2), + Op::Lt, + Op::Assert, + ], + span, + ); } // i1 - (Type::I1, _) => self.zext_smallint(src_bits, dst_bits), + (Type::I1, _) => self.zext_smallint(src_bits, dst_bits, span), (src, dst) => unimplemented!("unsupported cast from {src} to {dst}"), } self.stack.push(dst.clone()); } /// Cast `arg` to a pointer value - pub fn inttoptr(&mut self, ty: &Type) { + pub fn inttoptr(&mut self, ty: &Type, span: SourceSpan) { assert!(ty.is_pointer(), "exected pointer typed argument"); // For now, we're strict about the types of values we'll allow casting from let arg = self.stack.pop().expect("operand stack is empty"); @@ -349,7 +352,7 @@ impl<'a> OpEmitter<'a> { self.stack.push(ty.clone()); } Type::Felt => { - self.emit(Op::U32Assert); + self.emit(Op::U32Assert, span); self.stack.push(ty.clone()); } int => panic!("invalid inttoptr cast: cannot cast value of type {int} to {ty}"), @@ -361,7 +364,7 @@ impl<'a> OpEmitter<'a> { /// The result is placed on the stack as a boolean value. /// /// This operation consumes the input operand. - pub fn is_odd(&mut self) { + pub fn is_odd(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); match arg.ty() { // For both signed and unsigned types, @@ -377,17 +380,17 @@ impl<'a> OpEmitter<'a> { | Type::U32 | Type::I32 | Type::Felt => { - self.emit(Op::IsOdd); + self.emit(Op::IsOdd, span); } // For i64/u64, we use the native instruction // on the lower limb to check for odd/even Type::I64 | Type::U64 => { - self.emit_all(&[Op::Drop, Op::IsOdd]); + self.emit_all(&[Op::Drop, Op::IsOdd], span); } // For i128, same as above, but more elements are dropped Type::I128 | Type::U128 => { - self.emit_n(3, Op::Drop); - self.emit(Op::IsOdd); + self.emit_n(3, Op::Drop, span); + self.emit(Op::IsOdd, span); } Type::F64 => { unimplemented!("is_odd support for floating-point values is not yet implemented") @@ -401,43 +404,49 @@ impl<'a> OpEmitter<'a> { /// place the result back on the operand stack as a u32 value. /// /// This operation consumes the input operand. - pub fn ilog2(&mut self) { + pub fn ilog2(&mut self, span: SourceSpan) { let ty = self.stack.peek().expect("operand stack is empty").ty(); match &ty { - Type::Felt => self.emit(Op::Ilog2), + Type::Felt => self.emit(Op::Ilog2, span), Type::I128 | Type::U128 | Type::I64 | Type::U64 => { // Compute the number of leading zeros // // NOTE: This function handles popping the input and pushing // a u32 result on the stack for us, so we can omit any stack // manipulation here. - self.clz(); + self.clz(span); let bits = ty.size_in_bits(); // ilog2 is bits - clz - 1 - self.emit_all(&[ - Op::PushU8(bits as u8), - Op::Swap(1), - Op::Sub, - Op::U32OverflowingSubImm(1), - Op::Assertz, - ]); + self.emit_all( + &[ + Op::PushU8(bits as u8), + Op::Swap(1), + Op::Sub, + Op::U32OverflowingSubImm(1), + Op::Assertz, + ], + span, + ); } Type::I32 | Type::U32 | Type::I16 | Type::U16 | Type::I8 | Type::U8 => { let _ = self.stack.pop(); - self.emit_all(&[ - // Compute ilog2 on the advice stack - Op::Ilog2, - // Drop the operand - Op::Drop, - // Move the result to the operand stack - Op::AdvPush(1), - ]); + self.emit_all( + &[ + // Compute ilog2 on the advice stack + Op::Ilog2, + // Drop the operand + Op::Drop, + // Move the result to the operand stack + Op::AdvPush(1), + ], + span, + ); self.stack.push(Type::U32); } Type::I1 => { // 2^0 == 1 let _ = self.stack.pop(); - self.emit_all(&[Op::Drop, Op::PushU8(0)]); + self.emit_all(&[Op::Drop, Op::PushU8(0)], span); self.stack.push(Type::U32); } ty if !ty.is_integer() => { @@ -451,46 +460,52 @@ impl<'a> OpEmitter<'a> { /// and place the count back on the stack as a u32 value. /// /// This operation consumes the input operand. - pub fn popcnt(&mut self) { + pub fn popcnt(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); match arg.ty() { Type::I128 | Type::U128 => { - self.emit_all(&[ - // [x3, x2, x1, x0] - Op::U32Popcnt, - // [popcnt3, x2, x1, x0] - Op::Swap(1), - // [x2, popcnt3, x1, x0] - Op::U32Popcnt, - // [popcnt2, popcnt3, x1, x0] - Op::Add, - // [popcnt_hi, x1, x0] - Op::Movdn(2), - // [x1, x0, popcnt] - Op::U32Popcnt, - // [popcnt1, x0, popcnt] - Op::Swap(1), - // [x0, popcnt1, popcnt] - Op::U32Popcnt, - // [popcnt0, popcnt1, popcnt] - // - // This last instruction adds all three values together mod 2^32 - Op::U32WrappingAdd3, - ]); + self.emit_all( + &[ + // [x3, x2, x1, x0] + Op::U32Popcnt, + // [popcnt3, x2, x1, x0] + Op::Swap(1), + // [x2, popcnt3, x1, x0] + Op::U32Popcnt, + // [popcnt2, popcnt3, x1, x0] + Op::Add, + // [popcnt_hi, x1, x0] + Op::Movdn(2), + // [x1, x0, popcnt] + Op::U32Popcnt, + // [popcnt1, x0, popcnt] + Op::Swap(1), + // [x0, popcnt1, popcnt] + Op::U32Popcnt, + // [popcnt0, popcnt1, popcnt] + // + // This last instruction adds all three values together mod 2^32 + Op::U32WrappingAdd3, + ], + span, + ); } Type::I64 | Type::U64 => { - self.emit_all(&[ - // Get popcnt of high bits - Op::U32Popcnt, - // Swap to low bits and repeat - Op::Swap(1), - Op::U32Popcnt, - // Add both counts to get the total count - Op::Add, - ]); + self.emit_all( + &[ + // Get popcnt of high bits + Op::U32Popcnt, + // Swap to low bits and repeat + Op::Swap(1), + Op::U32Popcnt, + // Add both counts to get the total count + Op::Add, + ], + span, + ); } Type::I32 | Type::U32 | Type::I16 | Type::U16 | Type::I8 | Type::U8 | Type::I1 => { - self.emit(Op::U32Popcnt); + self.emit(Op::U32Popcnt, span); } ty if !ty.is_integer() => { panic!("invalid popcnt on {ty}: only integral types are supported") @@ -504,7 +519,7 @@ impl<'a> OpEmitter<'a> { /// and place the count back on the stack as a u32 value. /// /// This operation is implemented so that it consumes the input operand. - pub fn clz(&mut self) { + pub fn clz(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); match arg.ty() { Type::I128 | Type::U128 => { @@ -513,51 +528,61 @@ impl<'a> OpEmitter<'a> { // library intrinsics to get the count for those limbs. We then add the count // for the low bits to that of the high bits, if the high bits are all zero, // otherwise we take just the high bit count. - self.emit_all(&[ - // Count leading zeros in the high bits - Op::Exec(u64_clz), // [hi_clz, lo_hi, lo_lo] - // Count leading zeros in the low bits - Op::Movup(2), // [lo_lo, hi_clz, lo_hi] - Op::Movup(2), // [lo_hi, lo_lo, hi_clz] - Op::Exec(u64_clz), // [lo_clz, hi_clz] - // Add the low bit leading zeros to those of the high bits, if the high bits - // are all zeros; otherwise return only the high bit count - Op::PushU32(0), // [0, lo_clz, hi_clz] - Op::Dup(2), // [hi_clz, 0, lo_clz, hi_clz] - Op::LtImm(Felt::new(32)), // [hi_clz < 32, 0, lo_clz, hi_clz] - Op::Cdrop, // [hi_clz < 32 ? 0 : lo_clz, hi_clz] - Op::Add, - ]); + self.emit_all( + &[ + // Count leading zeros in the high bits + Op::Exec(u64_clz), // [hi_clz, lo_hi, lo_lo] + // Count leading zeros in the low bits + Op::Movup(2), // [lo_lo, hi_clz, lo_hi] + Op::Movup(2), // [lo_hi, lo_lo, hi_clz] + Op::Exec(u64_clz), // [lo_clz, hi_clz] + // Add the low bit leading zeros to those of the high bits, if the high + // bits are all zeros; otherwise return only the + // high bit count + Op::PushU32(0), // [0, lo_clz, hi_clz] + Op::Dup(2), // [hi_clz, 0, lo_clz, hi_clz] + Op::LtImm(Felt::new(32)), // [hi_clz < 32, 0, lo_clz, hi_clz] + Op::Cdrop, // [hi_clz < 32 ? 0 : lo_clz, hi_clz] + Op::Add, + ], + span, + ); } Type::I64 | Type::U64 => { - self.emit(Op::Exec("std::math::u64::clz".parse().unwrap())); + self.emit(Op::Exec("std::math::u64::clz".parse().unwrap()), span); } Type::I32 | Type::U32 => { - self.emit(Op::U32Clz); + self.emit(Op::U32Clz, span); } Type::I16 | Type::U16 => { // There are always 16 leading zeroes from the perspective of the // MASM u32clz instruction for values of (i|u)16 type, so subtract // that from the count - self.emit_all(&[ - Op::U32Clz, - // Subtract the excess bits from the count - Op::U32WrappingSubImm(16), - ]); + self.emit_all( + &[ + Op::U32Clz, + // Subtract the excess bits from the count + Op::U32WrappingSubImm(16), + ], + span, + ); } Type::I8 | Type::U8 => { // There are always 24 leading zeroes from the perspective of the // MASM u32clz instruction for values of (i|u)8 type, so subtract // that from the count - self.emit_all(&[ - Op::U32Clz, - // Subtract the excess bits from the count - Op::U32WrappingSubImm(24), - ]); + self.emit_all( + &[ + Op::U32Clz, + // Subtract the excess bits from the count + Op::U32WrappingSubImm(24), + ], + span, + ); } Type::I1 => { // There is exactly one leading zero if false, or zero if true - self.emit(Op::EqImm(Felt::ZERO)); + self.emit(Op::EqImm(Felt::ZERO), span); } ty if !ty.is_integer() => { panic!("invalid clz on {ty}: only integral types are supported") @@ -571,7 +596,7 @@ impl<'a> OpEmitter<'a> { /// and place the count back on the stack as a u32 value. /// /// This operation is implemented so that it consumes the input operand. - pub fn clo(&mut self) { + pub fn clo(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); match arg.ty() { // The implementation here is effectively the same as `clz`, just with minor adjustments @@ -581,59 +606,70 @@ impl<'a> OpEmitter<'a> { // library intrinsics to get the count for those limbs. We then add the count // for the low bits to that of the high bits, if the high bits are all one, // otherwise we take just the high bit count. - self.emit_all(&[ - // Count leading ones in the high bits - Op::Exec(u64_clo), // [hi_clo, lo_hi, lo_lo] - // Count leading ones in the low bits - Op::Movup(2), // [lo_lo, hi_clo, lo_hi] - Op::Movup(2), // [lo_hi, lo_lo, hi_clo] - Op::Exec(u64_clo), // [lo_clo, hi_clo] - // Add the low bit leading ones to those of the high bits, if the high bits - // are all one; otherwise return only the high bit count - Op::PushU32(0), // [0, lo_clo, hi_clo] - Op::Dup(2), // [hi_clo, 0, lo_clo, hi_clo] - Op::LtImm(Felt::new(32)), // [hi_clo < 32, 0, lo_clo, hi_clo] - Op::Cdrop, // [hi_clo < 32 ? 0 : lo_clo, hi_clo] - Op::Add, - ]); - } - Type::I64 | Type::U64 => self.emit(Op::Exec("std::math::u64::clo".parse().unwrap())), + self.emit_all( + &[ + // Count leading ones in the high bits + Op::Exec(u64_clo), // [hi_clo, lo_hi, lo_lo] + // Count leading ones in the low bits + Op::Movup(2), // [lo_lo, hi_clo, lo_hi] + Op::Movup(2), // [lo_hi, lo_lo, hi_clo] + Op::Exec(u64_clo), // [lo_clo, hi_clo] + // Add the low bit leading ones to those of the high bits, if the high bits + // are all one; otherwise return only the high bit count + Op::PushU32(0), // [0, lo_clo, hi_clo] + Op::Dup(2), // [hi_clo, 0, lo_clo, hi_clo] + Op::LtImm(Felt::new(32)), // [hi_clo < 32, 0, lo_clo, hi_clo] + Op::Cdrop, // [hi_clo < 32 ? 0 : lo_clo, hi_clo] + Op::Add, + ], + span, + ); + } + Type::I64 | Type::U64 => { + self.emit(Op::Exec("std::math::u64::clo".parse().unwrap()), span) + } Type::I32 | Type::U32 => { - self.emit(Op::U32Clo); + self.emit(Op::U32Clo, span); } Type::I16 | Type::U16 => { // There are always 16 leading zeroes from the perspective of the // MASM u32clo instruction for values of (i|u)16 type, so to get // the correct count, we need to bitwise-OR in a 16 bits of leading // ones, then subtract that from the final count. - self.emit_all(&[ - // OR in the leading 16 ones - Op::PushU32(u32::MAX << 16), - Op::U32Or, - // Obtain the count - Op::U32Clo, - // Subtract the leading bits we added from the count - Op::U32WrappingSubImm(16), - ]); + self.emit_all( + &[ + // OR in the leading 16 ones + Op::PushU32(u32::MAX << 16), + Op::U32Or, + // Obtain the count + Op::U32Clo, + // Subtract the leading bits we added from the count + Op::U32WrappingSubImm(16), + ], + span, + ); } Type::I8 | Type::U8 => { // There are always 24 leading zeroes from the perspective of the // MASM u32clo instruction for values of (i|u)8 type, so as with the // 16-bit values, we need to bitwise-OR in 24 bits of leading ones, // then subtract them from the final count. - self.emit_all(&[ - // OR in the leading 24 ones - Op::PushU32(u32::MAX << 8), - Op::U32Or, - // Obtain the count - Op::U32Clo, - // Subtract the excess bits from the count - Op::U32WrappingSubImm(24), - ]); + self.emit_all( + &[ + // OR in the leading 24 ones + Op::PushU32(u32::MAX << 8), + Op::U32Or, + // Obtain the count + Op::U32Clo, + // Subtract the excess bits from the count + Op::U32WrappingSubImm(24), + ], + span, + ); } Type::I1 => { // There is exactly one leading one if true, or zero if false - self.emit(Op::EqImm(Felt::ONE)); + self.emit(Op::EqImm(Felt::ONE), span); } ty if !ty.is_integer() => { panic!("invalid clo on {ty}: only integral types are supported") @@ -647,7 +683,7 @@ impl<'a> OpEmitter<'a> { /// and place the count back on the stack as a u32 value. /// /// This operation is implemented so that it consumes the input operand. - pub fn ctz(&mut self) { + pub fn ctz(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); match arg.ty() { Type::I128 | Type::U128 => { @@ -656,60 +692,72 @@ impl<'a> OpEmitter<'a> { // library intrinsics to get the count for those limbs. We then add the count // for the low bits to that of the high bits, if the high bits are all one, // otherwise we take just the high bit count. - self.emit_all(&[ - // Count trailing zeros in the high bits - Op::Exec(u64_ctz), // [hi_ctz, lo_hi, lo_lo] - // Count trailing zeros in the low bits - Op::Movup(2), // [lo_lo, hi_ctz, lo_hi] - Op::Movup(2), // [lo_hi, lo_lo, hi_ctz] - Op::Exec(u64_ctz), // [lo_ctz, hi_ctz] - // Add the high bit trailing zeros to those of the low bits, if the low bits - // are all zero; otherwise return only the low bit count - Op::Swap(1), - Op::PushU32(0), // [0, hi_ctz, lo_ctz] - Op::Dup(2), // [lo_ctz, 0, hi_ctz, lo_ctz] - Op::LtImm(Felt::new(32)), // [lo_ctz < 32, 0, hi_ctz, lo_ctz] - Op::Cdrop, // [lo_ctz < 32 ? 0 : hi_ctz, lo_ctz] - Op::Add, - ]); - } - Type::I64 | Type::U64 => self.emit(Op::Exec("std::math::u64::ctz".parse().unwrap())), - Type::I32 | Type::U32 => self.emit(Op::U32Ctz), + self.emit_all( + &[ + // Count trailing zeros in the high bits + Op::Exec(u64_ctz), // [hi_ctz, lo_hi, lo_lo] + // Count trailing zeros in the low bits + Op::Movup(2), // [lo_lo, hi_ctz, lo_hi] + Op::Movup(2), // [lo_hi, lo_lo, hi_ctz] + Op::Exec(u64_ctz), // [lo_ctz, hi_ctz] + // Add the high bit trailing zeros to those of the low bits, if the low + // bits are all zero; otherwise return only the low + // bit count + Op::Swap(1), + Op::PushU32(0), // [0, hi_ctz, lo_ctz] + Op::Dup(2), // [lo_ctz, 0, hi_ctz, lo_ctz] + Op::LtImm(Felt::new(32)), // [lo_ctz < 32, 0, hi_ctz, lo_ctz] + Op::Cdrop, // [lo_ctz < 32 ? 0 : hi_ctz, lo_ctz] + Op::Add, + ], + span, + ); + } + Type::I64 | Type::U64 => { + self.emit(Op::Exec("std::math::u64::ctz".parse().unwrap()), span) + } + Type::I32 | Type::U32 => self.emit(Op::U32Ctz, span), Type::I16 | Type::U16 => { // Clamp the total number of trailing zeros to 16 - self.emit_all(&[ - // Obtain the count - Op::U32Ctz, - // Clamp to 16 - // operand_stack: [16, ctz] - Op::PushU8(16), - // operand_stack: [ctz, 16, ctz] - Op::Dup(1), - // operand_stack: [ctz >= 16, 16, ctz] - Op::GteImm(Felt::new(16)), - // operand_stack: [actual_ctz] - Op::Cdrop, - ]); + self.emit_all( + &[ + // Obtain the count + Op::U32Ctz, + // Clamp to 16 + // operand_stack: [16, ctz] + Op::PushU8(16), + // operand_stack: [ctz, 16, ctz] + Op::Dup(1), + // operand_stack: [ctz >= 16, 16, ctz] + Op::GteImm(Felt::new(16)), + // operand_stack: [actual_ctz] + Op::Cdrop, + ], + span, + ); } Type::I8 | Type::U8 => { // Clamp the total number of trailing zeros to 8 - self.emit_all(&[ - // Obtain the count - Op::U32Ctz, - // Clamp to 8 - // operand_stack: [8, ctz] - Op::PushU8(8), - // operand_stack: [ctz, 8, ctz] - Op::Dup(1), - // operand_stack: [ctz >= 8, 8, ctz] - Op::GteImm(Felt::new(8)), - // operand_stack: [actual_ctz] - Op::Cdrop, - ]); + self.emit_all( + &[ + // Obtain the count + Op::U32Ctz, + // Clamp to 8 + // operand_stack: [8, ctz] + Op::PushU8(8), + // operand_stack: [ctz, 8, ctz] + Op::Dup(1), + // operand_stack: [ctz >= 8, 8, ctz] + Op::GteImm(Felt::new(8)), + // operand_stack: [actual_ctz] + Op::Cdrop, + ], + span, + ); } Type::I1 => { // There is exactly one trailing zero if false, or zero if true - self.emit(Op::EqImm(Felt::ZERO)); + self.emit(Op::EqImm(Felt::ZERO), span); } ty if !ty.is_integer() => { panic!("invalid ctz on {ty}: only integral types are supported") @@ -723,7 +771,7 @@ impl<'a> OpEmitter<'a> { /// and place the count back on the stack as a u32 value. /// /// This operation is implemented so that it consumes the input operand. - pub fn cto(&mut self) { + pub fn cto(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); match arg.ty() { Type::I128 | Type::U128 => { @@ -732,32 +780,37 @@ impl<'a> OpEmitter<'a> { // library intrinsics to get the count for those limbs. We then add the count // for the low bits to that of the high bits, if the high bits are all one, // otherwise we take just the high bit count. - self.emit_all(&[ - // Count trailing ones in the high bits - Op::Exec(u64_cto), // [hi_cto, lo_hi, lo_lo] - // Count trailing ones in the low bits - Op::Movup(2), // [lo_lo, hi_cto, lo_hi] - Op::Movup(2), // [lo_hi, lo_lo, hi_cto] - Op::Exec(u64_cto), // [lo_cto, hi_cto] - // Add the high bit trailing ones to those of the low bits, if the low bits - // are all one; otherwise return only the low bit count - Op::Swap(1), - Op::PushU32(0), // [0, hi_cto, lo_cto] - Op::Dup(2), // [lo_cto, 0, hi_cto, lo_cto] - Op::LtImm(Felt::new(32)), // [lo_cto < 32, 0, hi_cto, lo_cto] - Op::Cdrop, // [lo_cto < 32 ? 0 : hi_cto, lo_cto] - Op::Add, - ]); - } - Type::I64 | Type::U64 => self.emit(Op::Exec("std::math::u64::cto".parse().unwrap())), + self.emit_all( + &[ + // Count trailing ones in the high bits + Op::Exec(u64_cto), // [hi_cto, lo_hi, lo_lo] + // Count trailing ones in the low bits + Op::Movup(2), // [lo_lo, hi_cto, lo_hi] + Op::Movup(2), // [lo_hi, lo_lo, hi_cto] + Op::Exec(u64_cto), // [lo_cto, hi_cto] + // Add the high bit trailing ones to those of the low bits, if the low bits + // are all one; otherwise return only the low bit count + Op::Swap(1), + Op::PushU32(0), // [0, hi_cto, lo_cto] + Op::Dup(2), // [lo_cto, 0, hi_cto, lo_cto] + Op::LtImm(Felt::new(32)), // [lo_cto < 32, 0, hi_cto, lo_cto] + Op::Cdrop, // [lo_cto < 32 ? 0 : hi_cto, lo_cto] + Op::Add, + ], + span, + ); + } + Type::I64 | Type::U64 => { + self.emit(Op::Exec("std::math::u64::cto".parse().unwrap()), span) + } Type::I32 | Type::U32 | Type::I16 | Type::U16 | Type::I8 | Type::U8 => { // The number of trailing ones is de-facto clamped by the bitwidth of // the value, since all of the padding bits are leading zeros. - self.emit(Op::U32Cto) + self.emit(Op::U32Cto, span) } Type::I1 => { // There is exactly one trailing one if true, or zero if false - self.emit(Op::EqImm(Felt::ONE)); + self.emit(Op::EqImm(Felt::ONE), span); } ty if !ty.is_integer() => { panic!("invalid cto on {ty}: only integral types are supported") @@ -772,11 +825,11 @@ impl<'a> OpEmitter<'a> { /// This has the effect of changing all 1 bits to 0s, and all 0 bits to 1s. /// /// This operation consumes the input operand. - pub fn bnot(&mut self) { + pub fn bnot(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let ty = arg.ty(); match &ty { - Type::I1 => self.emit(Op::Not), + Type::I1 => self.emit(Op::Not, span), Type::I8 | Type::U8 | Type::I16 @@ -790,13 +843,18 @@ impl<'a> OpEmitter<'a> { let num_elements = ty.size_in_bits() / 32; match num_elements { 0 | 1 => { - self.emit(Op::U32Not); + self.emit(Op::U32Not, span); } 2 => { - self.emit_repeat(2, &[Op::Swap(1), Op::U32Not]); + self.emit_repeat( + 2, + &[Span::new(span, Op::Swap(1)), Span::new(span, Op::U32Not)], + ); } n => { - self.emit_template(n, |n| [Op::Movup(n as u8), Op::U32Not]); + self.emit_template(n, |n| { + [Span::new(span, Op::Movup(n as u8)), Span::new(span, Op::U32Not)] + }); } } } @@ -811,10 +869,10 @@ impl<'a> OpEmitter<'a> { /// Invert the boolean value on top of the operand stack. /// /// This operation consumes the input operand. - pub fn not(&mut self) { + pub fn not(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); assert_eq!(arg.ty(), Type::I1, "logical NOT requires a boolean value"); - self.emit(Op::Not); + self.emit(Op::Not, span); self.stack.push(Type::I1); } @@ -824,36 +882,39 @@ impl<'a> OpEmitter<'a> { /// The input value must be < 64, or execution will trap. /// /// This operation consumes the input operand. - pub fn pow2(&mut self) { + pub fn pow2(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let ty = arg.ty(); match &ty { Type::U64 => { - self.emit_all(&[ - // Assert that the high bits are zero - Op::Assertz, - // This asserts if value > 63, thus result is guaranteed to fit in u64 - Op::Pow2, - // Obtain the u64 representation by splitting the felt result - Op::U32Split, - ]); + self.emit_all( + &[ + // Assert that the high bits are zero + Op::Assertz, + // This asserts if value > 63, thus result is guaranteed to fit in u64 + Op::Pow2, + // Obtain the u64 representation by splitting the felt result + Op::U32Split, + ], + span, + ); } Type::I64 => { - self.emit(Op::Exec("intrinsics::i64::pow2".parse().unwrap())); + self.emit(Op::Exec("intrinsics::i64::pow2".parse().unwrap()), span); } Type::Felt => { - self.emit(Op::Pow2); + self.emit(Op::Pow2, span); } Type::U32 => { - self.emit_all(&[Op::Pow2, Op::U32Assert]); + self.emit_all(&[Op::Pow2, Op::U32Assert], span); } Type::I32 => { - self.emit(Op::Exec("intrinsics::i32::pow2".parse().unwrap())); + self.emit(Op::Exec("intrinsics::i32::pow2".parse().unwrap()), span); } Type::U8 | Type::U16 => { - self.emit_all(&[Op::Pow2, Op::U32Assert]); + self.emit_all(&[Op::Pow2, Op::U32Assert], span); // Cast u32 to u8/u16 - self.int32_to_uint(ty.size_in_bits() as u32); + self.int32_to_uint(ty.size_in_bits() as u32, span); } ty if !ty.is_unsigned_integer() => { panic!( @@ -870,27 +931,27 @@ impl<'a> OpEmitter<'a> { /// The input value must be an integer, and overflow has wrapping semantics. /// /// This operation consumes the input operand. - pub fn incr(&mut self) { + pub fn incr(&mut self, span: SourceSpan) { let arg = self.stack.pop().expect("operand stack is empty"); let ty = arg.ty(); match &ty { // For this specific case, wrapping u64 arithmetic works for both i64/u64 Type::I64 | Type::U64 => { - self.push_u64(1); - self.add_u64(Overflow::Wrapping); + self.push_u64(1, span); + self.add_u64(Overflow::Wrapping, span); } Type::Felt => { - self.emit(Op::Incr); + self.emit(Op::Incr, span); } // For this specific case, wrapping u32 arithmetic works for both i32/u32 Type::I32 | Type::U32 => { - self.add_imm_u32(1, Overflow::Wrapping); + self.add_imm_u32(1, Overflow::Wrapping, span); } // We need to wrap the result for smallint types Type::I8 | Type::U8 | Type::I16 | Type::U16 => { let bits = ty.size_in_bits() as u32; - self.add_imm_u32(1, Overflow::Wrapping); - self.unchecked_mod_imm_u32(2u32.pow(bits)); + self.add_imm_u32(1, Overflow::Wrapping, span); + self.unchecked_mod_imm_u32(2u32.pow(bits), span); } ty if !ty.is_integer() => { panic!("invalid unary operand: incr requires an integer operand, got {ty}") @@ -904,12 +965,12 @@ impl<'a> OpEmitter<'a> { /// `n^-1 mod P`. /// /// This operation consumes the input operand. - pub fn inv(&mut self) { + pub fn inv(&mut self, span: SourceSpan) { let arg = self.pop().expect("operand stack is empty"); let ty = arg.ty(); match &ty { Type::Felt => { - self.emit(Op::Inv); + self.emit(Op::Inv, span); } ty if !ty.is_integer() => { panic!("invalid unary operand: inv requires an integer, got {ty}") @@ -922,12 +983,12 @@ impl<'a> OpEmitter<'a> { /// Compute the modular negation of the operand on top of the stack, `n`, i.e. `-n mod P`. /// /// This operation consumes the input operand. - pub fn neg(&mut self) { + pub fn neg(&mut self, span: SourceSpan) { let arg = self.pop().expect("operand stack is empty"); let ty = arg.ty(); match &ty { Type::Felt => { - self.emit(Op::Neg); + self.emit(Op::Neg, span); } ty if !ty.is_integer() => { panic!("invalid unary operand: neg requires an integer, got {ty}") diff --git a/codegen/masm/src/codegen/emitter.rs b/codegen/masm/src/codegen/emitter.rs index a12f7932..e8181530 100644 --- a/codegen/masm/src/codegen/emitter.rs +++ b/codegen/masm/src/codegen/emitter.rs @@ -1,8 +1,13 @@ use std::{collections::BTreeMap, rc::Rc}; use cranelift_entity::SecondaryMap; -use hir::Type; -use midenc_hir::{self as hir, adt::SparseMap, assert_matches}; +use midenc_hir::{ + self as hir, + adt::SparseMap, + assert_matches, + diagnostics::{SourceSpan, Span}, + Type, +}; use midenc_hir_analysis::{ DominatorTree, GlobalVariableLayout, LivenessAnalysis, Loop, LoopAnalysis, }; @@ -188,7 +193,6 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { // Continue normally, by emitting the contents of the block based on the given schedule for op in block_schedule.iter() { match op { - ScheduleOp::Init(_) | ScheduleOp::Enter(_) | ScheduleOp::Exit => continue, ScheduleOp::Inst(inst_info) => self.emit_inst(inst_info, tasks), ScheduleOp::Drop(value) => { let mut emitter = self.emitter(); @@ -196,7 +200,7 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { .stack() .find(value) .expect("could not find value on the operand stack"); - emitter.drop_operand_at_position(pos); + emitter.drop_operand_at_position(pos, SourceSpan::default()); } } } @@ -210,17 +214,19 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { // NOTE: This does not include block arguments for control flow instructions, those are // handled separately within the specific handlers for those instructions let args = self.function.f.dfg.inst_args(inst_info.inst); - self.schedule_operands(args, inst_info.plain_arguments()).unwrap_or_else(|err| { - panic!( - "failed to schedule operands: {:?} \n for inst: {} {:?}\n with error: {err:?}\n \ - constraints: {:?}\n stack: {:?}", - args, - inst_info.inst, - self.function.f.dfg.inst(inst_info.inst), - inst_info.plain_arguments(), - self.stack, - ) - }); + let span = self.function.f.dfg.inst_span(inst_info.inst); + self.schedule_operands(args, inst_info.plain_arguments(), span) + .unwrap_or_else(|err| { + panic!( + "failed to schedule operands: {:?} \n for inst: {} {:?}\n with error: \ + {err:?}\n constraints: {:?}\n stack: {:?}", + args, + inst_info.inst, + self.function.f.dfg.inst(inst_info.inst), + inst_info.plain_arguments(), + self.stack, + ) + }); match self.function.f.dfg.inst(inst_info.inst) { ix @ (Instruction::RetImm(_) | Instruction::Ret(_)) => self.emit_ret(inst_info, ix), @@ -241,16 +247,17 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { panic!("expected switch instructions to have been rewritten before stackification") } Instruction::LocalVar(ref op) => { + let span = self.function.f.dfg.inst_span(inst_info.inst); let local = self.function.locals[&op.local]; let args = op.args.as_slice(&self.function.f.dfg.value_lists); let mut emitter = self.inst_emitter(inst_info.inst); match op.op { hir::Opcode::Store => { assert_eq!(args.len(), 1); - emitter.store_local(local); + emitter.store_local(local, span); } hir::Opcode::Load => { - emitter.load_local(local); + emitter.load_local(local, span); } opcode => unimplemented!("unrecognized local variable op '{opcode}'"), } @@ -266,22 +273,23 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { self.function.f.dfg.inst_block(inst_info.inst).unwrap(), ); + let span = self.function.f.dfg.inst_span(inst_info.inst); let num_args = self.function.f.dfg.inst_args(inst_info.inst).len(); let level = self.controlling_loop_level().unwrap_or(0); let mut emitter = self.emitter(); // Upon return, the operand stack should only contain the function result(s), // so empty the stack before proceeding. - emitter.truncate_stack(num_args); + emitter.truncate_stack(num_args, span); // If this instruction is the immediate variant, we need to push the return // value on the stack at this point. if let Instruction::RetImm(hir::RetImm { arg, .. }) = ix { - emitter.literal(*arg); + emitter.literal(*arg, span); } // If we're in a loop, push N zeroes on the stack, where N is the current loop depth for _ in 0..level { - emitter.literal(false); + emitter.literal(false, span); } } @@ -300,14 +308,15 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { /// current block, up to the terminator, and then emit instructions to either continue the /// loop, or exit the current loop to the target loop. fn emit_br(&mut self, inst_info: &InstInfo, op: &hir::Br, tasks: &mut Tasks) { - let destination = op.destination; + let destination = op.successor.destination; let is_first_visit = !self.visited; let in_loop_header = self.block_info.is_loop_header(); // Move block arguments into position - let args = op.args.as_slice(&self.function.f.dfg.value_lists); - self.schedule_operands(args, inst_info.block_arguments(destination)) + let span = self.function.f.dfg.inst_span(inst_info.inst); + let args = op.successor.args.as_slice(&self.function.f.dfg.value_lists); + self.schedule_operands(args, inst_info.block_arguments(destination), span) .unwrap_or_else(|err| { panic!("failed to schedule operands for {}: {err:?}", inst_info.inst) }); @@ -322,7 +331,7 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { if in_loop_header { // We're in a loop header, emit the target block inside a while loop let body_blk = self.masm_block_id(destination); - self.emit_ops([Op::PushU8(1), Op::While(body_blk)]); + self.emit_ops([Op::PushU8(1), Op::While(body_blk)], span); tasks.push(Task::Block { block: destination, controlling_loop, @@ -348,17 +357,17 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { }); let target_level = self.loop_level(self.block_info.source); let mut emitter = self.emitter(); - emitter.literal(true); + emitter.literal(true, span); for _ in 0..(current_level - target_level) { - emitter.literal(false); + emitter.literal(false, span); } } } fn emit_cond_br(&mut self, inst_info: &InstInfo, op: &hir::CondBr, tasks: &mut Tasks) { let cond = op.cond; - let then_dest = op.then_dest.0; - let else_dest = op.else_dest.0; + let then_dest = op.then_dest.destination; + let else_dest = op.else_dest.destination; // Ensure `cond` is on top of the stack, and remove it at the same time assert_eq!( @@ -368,6 +377,7 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { cond ); + let span = self.function.f.dfg.inst_span(inst_info.inst); if !self.visited { let then_blk = self.masm_block_id(then_dest); let else_blk = self.masm_block_id(else_dest); @@ -377,14 +387,16 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { if self.block_info.is_loop_header() { let body_blk = self.function.f_prime.create_block(); // We always unconditionally enter the loop the first time - self.emit_ops([Op::PushU8(1), Op::While(body_blk)]); - self.emit_op_to(body_blk, Op::If(then_blk, else_blk)); + self.emit_ops([Op::PushU8(1), Op::While(body_blk)], span); + self.emit_op_to(body_blk, Op::If(then_blk, else_blk), span); } else { - self.emit_op(Op::If(then_blk, else_blk)); + self.emit_op(Op::If(then_blk, else_blk), span); } - let successors = - [(then_dest, then_blk, op.then_dest.1), (else_dest, else_blk, op.else_dest.1)]; + let successors = [ + (then_dest, then_blk, op.then_dest.args), + (else_dest, else_blk, op.else_dest.args), + ]; for (block, masm_block, args) in successors.into_iter() { // Make a copy of the operand stack in the current block // to be used as the state of the operand stack in the @@ -400,6 +412,7 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { inst_info.block_arguments(block), masm_block, &mut stack, + span, ) .unwrap_or_else(|err| { panic!( @@ -440,9 +453,9 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { // prior to this push.1 instruction holds the actual conditional, which // will be evaluated by the `if.true` nested inside the target `while.true` let mut emitter = self.emitter(); - emitter.literal(true); + emitter.literal(true, span); for _ in 0..(current_level - target_level) { - emitter.literal(false); + emitter.literal(false, span); } } } @@ -460,15 +473,16 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { self.function.f.id, op.global ) }); + let span = self.function.f.dfg.inst_span(inst_info.inst); match self.function.f.dfg.global_value(op.global) { hir::GlobalValueData::Load { ref ty, .. } => { let mut emitter = self.inst_emitter(inst_info.inst); - emitter.load_imm(addr, ty.clone()); + emitter.load_imm(addr, ty.clone(), span); } hir::GlobalValueData::IAddImm { .. } | hir::GlobalValueData::Symbol { .. } => { let mut emitter = self.inst_emitter(inst_info.inst); emitter.stack_mut().push(addr); - emitter.inttoptr(&Type::Ptr(Type::U8.into())); + emitter.inttoptr(&Type::Ptr(Type::U8.into()), span); } } } @@ -476,51 +490,52 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { fn emit_unary_imm_op(&mut self, inst_info: &InstInfo, op: &hir::UnaryOpImm) { use midenc_hir::Immediate; + let span = self.function.f.dfg.inst_span(inst_info.inst); let mut emitter = self.inst_emitter(inst_info.inst); match op.op { hir::Opcode::ImmI1 => { assert_matches!(op.imm, Immediate::I1(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmI8 => { assert_matches!(op.imm, Immediate::I8(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmU8 => { assert_matches!(op.imm, Immediate::U8(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmI16 => { assert_matches!(op.imm, Immediate::I16(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmU16 => { assert_matches!(op.imm, Immediate::U16(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmI32 => { assert_matches!(op.imm, Immediate::I32(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmU32 => { assert_matches!(op.imm, Immediate::U32(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmI64 => { assert_matches!(op.imm, Immediate::I64(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmU64 => { assert_matches!(op.imm, Immediate::U64(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmFelt => { assert_matches!(op.imm, Immediate::Felt(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } hir::Opcode::ImmF64 => { assert_matches!(op.imm, Immediate::F64(_)); - emitter.literal(op.imm); + emitter.literal(op.imm, span); } opcode => unimplemented!("unrecognized unary with immediate opcode: '{opcode}'"), } @@ -529,20 +544,21 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { fn emit_unary_op(&mut self, inst_info: &InstInfo, op: &hir::UnaryOp) { let inst = inst_info.inst; let result = self.function.f.dfg.first_result(inst); + let span = self.function.f.dfg.inst_span(inst_info.inst); let mut emitter = self.inst_emitter(inst); match op.op { - hir::Opcode::Neg => emitter.neg(), - hir::Opcode::Inv => emitter.inv(), - hir::Opcode::Incr => emitter.incr(), - hir::Opcode::Ilog2 => emitter.ilog2(), - hir::Opcode::Pow2 => emitter.pow2(), - hir::Opcode::Not => emitter.not(), - hir::Opcode::Bnot => emitter.bnot(), - hir::Opcode::Popcnt => emitter.popcnt(), - hir::Opcode::Clz => emitter.clz(), - hir::Opcode::Ctz => emitter.ctz(), - hir::Opcode::Clo => emitter.clo(), - hir::Opcode::Cto => emitter.cto(), + hir::Opcode::Neg => emitter.neg(span), + hir::Opcode::Inv => emitter.inv(span), + hir::Opcode::Incr => emitter.incr(span), + hir::Opcode::Ilog2 => emitter.ilog2(span), + hir::Opcode::Pow2 => emitter.pow2(span), + hir::Opcode::Not => emitter.not(span), + hir::Opcode::Bnot => emitter.bnot(span), + hir::Opcode::Popcnt => emitter.popcnt(span), + hir::Opcode::Clz => emitter.clz(span), + hir::Opcode::Ctz => emitter.ctz(span), + hir::Opcode::Clo => emitter.clo(span), + hir::Opcode::Cto => emitter.cto(span), // This opcode is a no-op hir::Opcode::PtrToInt => { let result_ty = emitter.value_type(result).clone(); @@ -553,32 +569,32 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { // We lower this cast to an assertion, to ensure the value is a valid pointer hir::Opcode::IntToPtr => { let ptr_ty = emitter.value_type(result).clone(); - emitter.inttoptr(&ptr_ty); + emitter.inttoptr(&ptr_ty, span); } // The semantics of cast for now are basically your standard integer coercion rules // // We may eliminate this in favor of more specific casts in the future hir::Opcode::Cast => { let dst_ty = emitter.value_type(result).clone(); - emitter.cast(&dst_ty); + emitter.cast(&dst_ty, span); } hir::Opcode::Bitcast => { let dst_ty = emitter.value_type(result).clone(); - emitter.bitcast(&dst_ty); + emitter.bitcast(&dst_ty, span); } hir::Opcode::Trunc => { let dst_ty = emitter.value_type(result).clone(); - emitter.trunc(&dst_ty); + emitter.trunc(&dst_ty, span); } hir::Opcode::Zext => { let dst_ty = emitter.value_type(result).clone(); - emitter.zext(&dst_ty); + emitter.zext(&dst_ty, span); } hir::Opcode::Sext => { let dst_ty = emitter.value_type(result).clone(); - emitter.sext(&dst_ty); + emitter.sext(&dst_ty, span); } - hir::Opcode::IsOdd => emitter.is_odd(), + hir::Opcode::IsOdd => emitter.is_odd(span), opcode => unimplemented!("unrecognized unary opcode: '{opcode}'"), } } @@ -586,37 +602,40 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { fn emit_binary_imm_op(&mut self, inst_info: &InstInfo, op: &hir::BinaryOpImm) { use midenc_hir::Overflow; + let span = self.function.f.dfg.inst_span(inst_info.inst); let mut emitter = self.inst_emitter(inst_info.inst); let overflow = op.overflow.unwrap_or(Overflow::Checked); match op.op { - hir::Opcode::Eq => emitter.eq_imm(op.imm), - hir::Opcode::Neq => emitter.neq_imm(op.imm), - hir::Opcode::Gt => emitter.gt_imm(op.imm), - hir::Opcode::Gte => emitter.gte_imm(op.imm), - hir::Opcode::Lt => emitter.lt_imm(op.imm), - hir::Opcode::Lte => emitter.lte_imm(op.imm), - hir::Opcode::Add => emitter.add_imm(op.imm, overflow), - hir::Opcode::Sub => emitter.sub_imm(op.imm, overflow), - hir::Opcode::Mul => emitter.mul_imm(op.imm, overflow), - hir::Opcode::Div if overflow.is_checked() => emitter.checked_div_imm(op.imm), - hir::Opcode::Div => emitter.unchecked_div_imm(op.imm), - hir::Opcode::Min => emitter.min_imm(op.imm), - hir::Opcode::Max => emitter.max_imm(op.imm), - hir::Opcode::Mod if overflow.is_checked() => emitter.checked_mod_imm(op.imm), - hir::Opcode::Mod => emitter.unchecked_mod_imm(op.imm), - hir::Opcode::DivMod if overflow.is_checked() => emitter.checked_divmod_imm(op.imm), - hir::Opcode::DivMod => emitter.unchecked_divmod_imm(op.imm), - hir::Opcode::Exp => emitter.exp_imm(op.imm), - hir::Opcode::And => emitter.and_imm(op.imm), - hir::Opcode::Band => emitter.band_imm(op.imm), - hir::Opcode::Or => emitter.or_imm(op.imm), - hir::Opcode::Bor => emitter.bor_imm(op.imm), - hir::Opcode::Xor => emitter.xor_imm(op.imm), - hir::Opcode::Bxor => emitter.bxor_imm(op.imm), - hir::Opcode::Shl => emitter.shl_imm(op.imm), - hir::Opcode::Shr => emitter.shr_imm(op.imm), - hir::Opcode::Rotl => emitter.rotl_imm(op.imm), - hir::Opcode::Rotr => emitter.rotr_imm(op.imm), + hir::Opcode::Eq => emitter.eq_imm(op.imm, span), + hir::Opcode::Neq => emitter.neq_imm(op.imm, span), + hir::Opcode::Gt => emitter.gt_imm(op.imm, span), + hir::Opcode::Gte => emitter.gte_imm(op.imm, span), + hir::Opcode::Lt => emitter.lt_imm(op.imm, span), + hir::Opcode::Lte => emitter.lte_imm(op.imm, span), + hir::Opcode::Add => emitter.add_imm(op.imm, overflow, span), + hir::Opcode::Sub => emitter.sub_imm(op.imm, overflow, span), + hir::Opcode::Mul => emitter.mul_imm(op.imm, overflow, span), + hir::Opcode::Div if overflow.is_checked() => emitter.checked_div_imm(op.imm, span), + hir::Opcode::Div => emitter.unchecked_div_imm(op.imm, span), + hir::Opcode::Min => emitter.min_imm(op.imm, span), + hir::Opcode::Max => emitter.max_imm(op.imm, span), + hir::Opcode::Mod if overflow.is_checked() => emitter.checked_mod_imm(op.imm, span), + hir::Opcode::Mod => emitter.unchecked_mod_imm(op.imm, span), + hir::Opcode::DivMod if overflow.is_checked() => { + emitter.checked_divmod_imm(op.imm, span) + } + hir::Opcode::DivMod => emitter.unchecked_divmod_imm(op.imm, span), + hir::Opcode::Exp => emitter.exp_imm(op.imm, span), + hir::Opcode::And => emitter.and_imm(op.imm, span), + hir::Opcode::Band => emitter.band_imm(op.imm, span), + hir::Opcode::Or => emitter.or_imm(op.imm, span), + hir::Opcode::Bor => emitter.bor_imm(op.imm, span), + hir::Opcode::Xor => emitter.xor_imm(op.imm, span), + hir::Opcode::Bxor => emitter.bxor_imm(op.imm, span), + hir::Opcode::Shl => emitter.shl_imm(op.imm, span), + hir::Opcode::Shr => emitter.shr_imm(op.imm, span), + hir::Opcode::Rotl => emitter.rotl_imm(op.imm, span), + hir::Opcode::Rotr => emitter.rotr_imm(op.imm, span), opcode => unimplemented!("unrecognized binary with immediate opcode: '{opcode}'"), } } @@ -624,37 +643,38 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { fn emit_binary_op(&mut self, inst_info: &InstInfo, op: &hir::BinaryOp) { use midenc_hir::Overflow; + let span = self.function.f.dfg.inst_span(inst_info.inst); let mut emitter = self.inst_emitter(inst_info.inst); let overflow = op.overflow.unwrap_or(Overflow::Checked); match op.op { - hir::Opcode::Eq => emitter.eq(), - hir::Opcode::Neq => emitter.neq(), - hir::Opcode::Gt => emitter.gt(), - hir::Opcode::Gte => emitter.gte(), - hir::Opcode::Lt => emitter.lt(), - hir::Opcode::Lte => emitter.lte(), - hir::Opcode::Add => emitter.add(overflow), - hir::Opcode::Sub => emitter.sub(overflow), - hir::Opcode::Mul => emitter.mul(overflow), - hir::Opcode::Div if overflow.is_checked() => emitter.checked_div(), - hir::Opcode::Div => emitter.unchecked_div(), - hir::Opcode::Min => emitter.min(), - hir::Opcode::Max => emitter.max(), - hir::Opcode::Mod if overflow.is_checked() => emitter.checked_mod(), - hir::Opcode::Mod => emitter.unchecked_mod(), - hir::Opcode::DivMod if overflow.is_checked() => emitter.checked_divmod(), - hir::Opcode::DivMod => emitter.unchecked_divmod(), - hir::Opcode::Exp => emitter.exp(), - hir::Opcode::And => emitter.and(), - hir::Opcode::Band => emitter.band(), - hir::Opcode::Or => emitter.or(), - hir::Opcode::Bor => emitter.bor(), - hir::Opcode::Xor => emitter.xor(), - hir::Opcode::Bxor => emitter.bxor(), - hir::Opcode::Shl => emitter.shl(), - hir::Opcode::Shr => emitter.shr(), - hir::Opcode::Rotl => emitter.rotl(), - hir::Opcode::Rotr => emitter.rotr(), + hir::Opcode::Eq => emitter.eq(span), + hir::Opcode::Neq => emitter.neq(span), + hir::Opcode::Gt => emitter.gt(span), + hir::Opcode::Gte => emitter.gte(span), + hir::Opcode::Lt => emitter.lt(span), + hir::Opcode::Lte => emitter.lte(span), + hir::Opcode::Add => emitter.add(overflow, span), + hir::Opcode::Sub => emitter.sub(overflow, span), + hir::Opcode::Mul => emitter.mul(overflow, span), + hir::Opcode::Div if overflow.is_checked() => emitter.checked_div(span), + hir::Opcode::Div => emitter.unchecked_div(span), + hir::Opcode::Min => emitter.min(span), + hir::Opcode::Max => emitter.max(span), + hir::Opcode::Mod if overflow.is_checked() => emitter.checked_mod(span), + hir::Opcode::Mod => emitter.unchecked_mod(span), + hir::Opcode::DivMod if overflow.is_checked() => emitter.checked_divmod(span), + hir::Opcode::DivMod => emitter.unchecked_divmod(span), + hir::Opcode::Exp => emitter.exp(span), + hir::Opcode::And => emitter.and(span), + hir::Opcode::Band => emitter.band(span), + hir::Opcode::Or => emitter.or(span), + hir::Opcode::Bor => emitter.bor(span), + hir::Opcode::Xor => emitter.xor(span), + hir::Opcode::Bxor => emitter.bxor(span), + hir::Opcode::Shl => emitter.shl(span), + hir::Opcode::Shr => emitter.shr(span), + hir::Opcode::Rotl => emitter.rotl(span), + hir::Opcode::Rotr => emitter.rotr(span), opcode => unimplemented!("unrecognized binary opcode: '{opcode}'"), } } @@ -664,32 +684,39 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { } fn emit_load_op(&mut self, inst_info: &InstInfo, op: &hir::LoadOp) { + let span = self.function.f.dfg.inst_span(inst_info.inst); let mut emitter = self.inst_emitter(inst_info.inst); - emitter.load(op.ty.clone()); + emitter.load(op.ty.clone(), span); } fn emit_primop_imm(&mut self, inst_info: &InstInfo, op: &hir::PrimOpImm) { let args = op.args.as_slice(&self.function.f.dfg.value_lists); + let span = self.function.f.dfg.inst_span(inst_info.inst); let mut emitter = self.inst_emitter(inst_info.inst); match op.op { hir::Opcode::Assert => { assert_eq!(args.len(), 1); - emitter - .assert(Some(op.imm.as_u32().expect("invalid assertion error code immediate"))); + emitter.assert( + Some(op.imm.as_u32().expect("invalid assertion error code immediate")), + span, + ); } hir::Opcode::Assertz => { assert_eq!(args.len(), 1); - emitter.assertz(Some( - op.imm.as_u32().expect("invalid assertion error code immediate"), - )); + emitter.assertz( + Some(op.imm.as_u32().expect("invalid assertion error code immediate")), + span, + ); } hir::Opcode::AssertEq => { - emitter.assert_eq_imm(op.imm); + emitter.assert_eq_imm(op.imm, span); } // Store a value at a constant address hir::Opcode::Store => { - emitter - .store_imm(op.imm.as_u32().expect("invalid address immediate: out of range")); + emitter.store_imm( + op.imm.as_u32().expect("invalid address immediate: out of range"), + span, + ); } opcode => unimplemented!("unrecognized primop with immediate opcode: '{opcode}'"), } @@ -697,65 +724,66 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { fn emit_primop(&mut self, inst_info: &InstInfo, op: &hir::PrimOp) { let args = op.args.as_slice(&self.function.f.dfg.value_lists); + let span = self.function.f.dfg.inst_span(inst_info.inst); let mut emitter = self.inst_emitter(inst_info.inst); match op.op { // Pop a value of the given type off the stack and assert it's value is one hir::Opcode::Assert => { assert_eq!(args.len(), 1); - emitter.assert(None); + emitter.assert(None, span); } // Pop a value of the given type off the stack and assert it's value is zero hir::Opcode::Assertz => { assert_eq!(args.len(), 1); - emitter.assertz(None); + emitter.assertz(None, span); } // Pop two values of the given type off the stack and assert equality hir::Opcode::AssertEq => { assert_eq!(args.len(), 2); - emitter.assert_eq(); + emitter.assert_eq(span); } // Allocate a local and push its address on the operand stack hir::Opcode::Alloca => { assert!(args.is_empty()); let result = emitter.dfg().first_result(inst_info.inst); let ty = emitter.value_type(result).clone(); - emitter.alloca(&ty); + emitter.alloca(&ty, span); } // Store a value at a given pointer hir::Opcode::Store => { assert_eq!(args.len(), 2); - emitter.store(); + emitter.store(span); } // Grow the heap by `num_pages` pages hir::Opcode::MemGrow => { assert_eq!(args.len(), 1); - emitter.mem_grow(); + emitter.mem_grow(span); } // Return the size of the heap in pages hir::Opcode::MemSize => { assert_eq!(args.len(), 0); - emitter.mem_size(); + emitter.mem_size(span); } // Write `count` copies of `value` starting at the destination address hir::Opcode::MemSet => { assert_eq!(args.len(), 3); - emitter.memset(); + emitter.memset(span); } // Copy `count * sizeof(ctrl_ty)` bytes from source to destination address hir::Opcode::MemCpy => { assert_eq!(args.len(), 3); - emitter.memcpy(); + emitter.memcpy(span); } // Conditionally select between two values hir::Opcode::Select => { assert_eq!(args.len(), 3); - emitter.select(); + emitter.select(span); } // This instruction should not be reachable at runtime, so we emit an assertion // that will always fail if for some reason it is reached hir::Opcode::Unreachable => { // assert(false) - emitter.emit_all(&[Op::PushU32(0), Op::Assert]); + emitter.emit_all(&[Op::PushU32(0), Op::Assert], span); } opcode => unimplemented!("unrecognized primop with immediate opcode: '{opcode}'"), } @@ -764,10 +792,11 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { fn emit_call_op(&mut self, inst_info: &InstInfo, op: &hir::Call) { assert_ne!(op.callee, self.function.f.id, "unexpected recursive call"); + let span = self.function.f.dfg.inst_span(inst_info.inst); let mut emitter = self.inst_emitter(inst_info.inst); match op.op { - hir::Opcode::Syscall => emitter.syscall(op.callee), - hir::Opcode::Call => emitter.exec(op.callee), + hir::Opcode::Syscall => emitter.syscall(op.callee, span), + hir::Opcode::Call => emitter.exec(op.callee, span), opcode => unimplemented!("unrecognized procedure call opcode: '{opcode}'"), } } @@ -811,7 +840,8 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { ) { while let Some((prev, new)) = rewrites.pop() { for mut op in asm.blocks[prev].ops.iter().cloned() { - match op { + let span = op.span(); + match &mut *op { Op::If(ref mut then_blk, ref mut else_blk) => { let prev_then_blk = *then_blk; let prev_else_blk = *else_blk; @@ -828,19 +858,19 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { Op::Exec(id) => { self.function.f_prime.register_absolute_invocation_target( miden_assembly::ast::InvokeKind::Exec, - id, + *id, ); } Op::Call(id) => { self.function.f_prime.register_absolute_invocation_target( miden_assembly::ast::InvokeKind::Call, - id, + *id, ); } Op::Syscall(id) => { self.function.f_prime.register_absolute_invocation_target( miden_assembly::ast::InvokeKind::SysCall, - id, + *id, ); } Op::LocAddr(_) @@ -854,7 +884,7 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { } _ => (), } - self.function.f_prime.body.block_mut(new).push(op); + self.function.f_prime.body.block_mut(new).push(op.into_inner(), span); } } } @@ -874,9 +904,10 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { let value = operand.as_value().expect("unexpected non-ssa value on stack"); // If the given value is not live on entry to this block, it should be dropped if !self.function.liveness.is_live_at(&value, pp) { - println!( + log::trace!( "should drop {value} at {} (visited={})", - self.block_info.source, self.visited + self.block_info.source, + self.visited ); unused.push(value); constraints.push(Constraint::Move); @@ -940,7 +971,7 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { // we've found so far, and then reset our cursor to the top if unused_batch { let mut emitter = self.emitter(); - emitter.dropn(batch_size); + emitter.dropn(batch_size, SourceSpan::default()); batch_size = 0; current_index = 0; continue; @@ -971,33 +1002,34 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { .count(); let mut emitter = self.emitter(); if unused_chunk_size > 1 { - emitter.movdn(unused_chunk_size as u8); - emitter.dropn(unused_chunk_size); + emitter.movdn(unused_chunk_size as u8, SourceSpan::default()); + emitter.dropn(unused_chunk_size, SourceSpan::default()); } else { - emitter.swap(1); - emitter.drop(); + emitter.swap(1, SourceSpan::default()); + emitter.drop(SourceSpan::default()); } } // We've got multiple unused values together, so choose instead // to move the unused value to the top and drop it _ => { let mut emitter = self.emitter(); - emitter.movup(current_index as u8); - emitter.drop(); + emitter.movup(current_index as u8, SourceSpan::default()); + emitter.drop(SourceSpan::default()); } } batch_size = 0; current_index = 0; } } else { - self.schedule_operands(&unused, &constraints).unwrap_or_else(|err| { - panic!( - "failed to schedule unused operands for {}: {err:?}", - self.block_info.source - ) - }); + self.schedule_operands(&unused, &constraints, SourceSpan::default()) + .unwrap_or_else(|err| { + panic!( + "failed to schedule unused operands for {}: {err:?}", + self.block_info.source + ) + }); let mut emitter = self.emitter(); - emitter.dropn(unused.len()); + emitter.dropn(unused.len(), SourceSpan::default()); } } } @@ -1006,11 +1038,12 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { &mut self, expected: &[hir::Value], constraints: &[Constraint], + span: SourceSpan, ) -> Result<(), SolverError> { match OperandMovementConstraintSolver::new(expected, constraints, &self.stack) { Ok(solver) => { let mut emitter = self.emitter(); - solver.solve_and_apply(&mut emitter) + solver.solve_and_apply(&mut emitter, span) } Err(SolverError::AlreadySolved) => Ok(()), Err(err) => { @@ -1025,11 +1058,12 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { constraints: &[Constraint], block: masm::BlockId, stack: &mut OperandStack, + span: SourceSpan, ) -> Result<(), SolverError> { match OperandMovementConstraintSolver::new(expected, constraints, stack) { Ok(solver) => { let mut emitter = OpEmitter::new(self.function.f_prime, block, stack); - solver.solve_and_apply(&mut emitter) + solver.solve_and_apply(&mut emitter, span) } Err(SolverError::AlreadySolved) => Ok(()), Err(err) => { @@ -1064,8 +1098,26 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { } // Entering a top-level loop, set the controlling loop (None, controlling_loop @ Some(_)) => { + for l in self.function.loops.loops() { + log::debug!( + "l {:?} is loop header {:?}", + l, + self.function.loops.loop_header(l) + ); + log::debug!( + "l in loop with current_block {:?}", + self.function.loops.is_in_loop(current_block, l) + ); + log::debug!( + "l in loop with target_block {:?}", + self.function.loops.is_in_loop(target_block, l) + ); + } assert!(is_first_visit); - assert_eq!(self.controlling_loop, None); + assert_eq!( + self.controlling_loop, None, + "expected no controlling loop entering {target_block} from {current_block}" + ); controlling_loop } // Escaping a loop @@ -1139,18 +1191,18 @@ impl<'b, 'f: 'b> BlockEmitter<'b, 'f> { } #[inline] - fn emit_op(&mut self, op: Op) { - self.current_block().push(op); + fn emit_op(&mut self, op: Op, span: SourceSpan) { + self.current_block().push(op, span); } #[inline] - fn emit_op_to(&mut self, block: masm::BlockId, op: Op) { - self.block(block).push(op); + fn emit_op_to(&mut self, block: masm::BlockId, op: Op, span: SourceSpan) { + self.block(block).push(op, span); } #[inline] - fn emit_ops(&mut self, ops: impl IntoIterator) { - self.current_block().extend(ops); + fn emit_ops(&mut self, ops: impl IntoIterator, span: SourceSpan) { + self.current_block().extend(ops.into_iter().map(|op| Span::new(span, op))); } fn controlling_loop_level(&self) -> Option { diff --git a/codegen/masm/src/codegen/mod.rs b/codegen/masm/src/codegen/mod.rs index 2f025858..117623f1 100644 --- a/codegen/masm/src/codegen/mod.rs +++ b/codegen/masm/src/codegen/mod.rs @@ -4,6 +4,7 @@ mod opt; mod scheduler; mod stack; +pub(crate) use self::emit::mem::PAGE_SIZE; pub use self::{ emitter::FunctionEmitter, scheduler::Scheduler, diff --git a/codegen/masm/src/codegen/opt/operands/solver.rs b/codegen/masm/src/codegen/opt/operands/solver.rs index 0304a8a7..9677b5c8 100644 --- a/codegen/masm/src/codegen/opt/operands/solver.rs +++ b/codegen/masm/src/codegen/opt/operands/solver.rs @@ -1,4 +1,4 @@ -use midenc_hir as hir; +use midenc_hir::{self as hir, SourceSpan}; use smallvec::SmallVec; use super::{tactics::Tactic, *}; @@ -232,6 +232,7 @@ impl OperandMovementConstraintSolver { pub fn solve_and_apply( self, emitter: &mut crate::codegen::emit::OpEmitter<'_>, + span: SourceSpan, ) -> Result<(), SolverError> { match self.context.arity() { // No arguments, nothing to solve @@ -241,7 +242,7 @@ impl OperandMovementConstraintSolver { let expected = self.context.expected()[0]; if let Some(current_position) = self.context.stack().position(&expected.value) { if current_position > 0 { - emitter.move_operand_to_position(current_position, 0, false); + emitter.move_operand_to_position(current_position, 0, false, span); } } else { assert!( @@ -258,7 +259,7 @@ impl OperandMovementConstraintSolver { ) }, ); - emitter.copy_operand_to_position(current_position, 0, false); + emitter.copy_operand_to_position(current_position, 0, false, span); } Ok(()) @@ -269,16 +270,16 @@ impl OperandMovementConstraintSolver { for action in actions.into_iter() { match action { Action::Copy(index) => { - emitter.copy_operand_to_position(index as usize, 0, false); + emitter.copy_operand_to_position(index as usize, 0, false, span); } Action::Swap(index) => { - emitter.swap(index); + emitter.swap(index, span); } Action::MoveUp(index) => { - emitter.movup(index); + emitter.movup(index, span); } Action::MoveDown(index) => { - emitter.movdn(index); + emitter.movdn(index, span); } } } diff --git a/codegen/masm/src/codegen/scheduler.rs b/codegen/masm/src/codegen/scheduler.rs index 73f37478..02f0b4a1 100644 --- a/codegen/masm/src/codegen/scheduler.rs +++ b/codegen/masm/src/codegen/scheduler.rs @@ -146,12 +146,6 @@ pub struct BlockInfo { pub source: hir::Block, /// The target MASM block which will be emitted from this info pub target: masm::BlockId, - /// The id of the last instruction in the source HIR block, - /// this is commonly used to check for liveness after the end - /// of a block - pub last_inst: hir::Inst, - /// The innermost loop to which this block belongs - pub innermost_loop: Option, /// If set, indicates that this block is the loop header /// for the specified loop. pub loop_header: Option, @@ -212,12 +206,6 @@ impl Schedule { /// optimizer would. #[derive(Debug, Clone)] pub enum ScheduleOp { - /// Always the first instruction in a schedule, represents entry into a function - Init(hir::Block), - /// Push the current block context on the context stack, and switch to the given block context - Enter(hir::Block), - /// Pop the most recent block context from the context stack and switch to it - Exit, /// Emit the given instruction, using the provided analysis Inst(Rc), /// Drop the first occurrence of the given value on the operand stack @@ -233,7 +221,7 @@ pub enum Plan { /// This represents entering a block, so all further instructions /// are scheduled in the context of the given block until an ExitBlock /// meta-instruction is encountered. - Start(hir::Block), + Start, /// Schedule execution of an instruction's pre-requisites PreInst(Rc), /// Schedule execution of the given instruction @@ -280,24 +268,16 @@ impl<'a> Scheduler<'a> { pub fn build(mut self) -> Schedule { self.precompute_block_infos(); - let entry_block_id = self.f.dfg.entry_block(); let mut blockq = SmallVec::<[hir::Block; 8]>::from_slice(self.domtree.cfg_postorder()); while let Some(block_id) = blockq.pop() { - let is_entry_block = block_id == entry_block_id; let schedule = &mut self.schedule.block_schedules[block_id]; - if is_entry_block { - schedule.push(ScheduleOp::Init(block_id)); - } else { - schedule.push(ScheduleOp::Enter(block_id)); - } - let block_info = self.schedule.block_infos.get(block_id).cloned().unwrap(); let block_scheduler = BlockScheduler { f: self.f, liveness: self.liveness, block_info, inst_infos: Default::default(), - worklist: SmallVec::from_iter([Plan::Start(block_id)]), + worklist: SmallVec::from_iter([Plan::Start]), }; block_scheduler.schedule(schedule); } @@ -318,8 +298,6 @@ impl<'a> Scheduler<'a> { // Set the controlling loop let loop_header = self.loops.is_loop_header(block_id); - let last_inst = self.f.dfg.last_inst(block_id).unwrap(); - let innermost_loop = self.loops.innermost_loop(block_id); let depgraph = build_dependency_graph(block_id, self.f, self.liveness); let treegraph = OrderedTreeGraph::new(&depgraph) .expect("unable to topologically sort treegraph for block"); @@ -327,8 +305,6 @@ impl<'a> Scheduler<'a> { let info = Rc::new(BlockInfo { source: block_id, target: masm_block_id, - last_inst, - innermost_loop, loop_header, depgraph, treegraph, @@ -353,10 +329,8 @@ impl<'a> BlockScheduler<'a> { // here, we will emit scheduling operations in "normal" order. while let Some(plan) = self.worklist.pop() { match plan { - Plan::Start(_) => self.visit_block(), - Plan::Finish => { - scheduled_ops.push(ScheduleOp::Exit); - } + Plan::Start => self.visit_block(), + Plan::Finish => continue, // We're emitting code required to execute an instruction, such as materialization // of data dependencies used as direct arguments. This is only // emitted when an instruction has arguments which are derived from @@ -692,7 +666,10 @@ impl<'a> BlockScheduler<'a> { }); match self.f.dfg.analyze_branch(inst) { - BranchInfo::SingleDest(block, block_args) => { + BranchInfo::SingleDest(hir::SuccessorInfo { + destination: block, + args: block_args, + }) => { inst_info.successors.push(Successor { block, arg_count: block_args.len() as u16, @@ -728,7 +705,7 @@ impl<'a> BlockScheduler<'a> { index as usize, "successor ordering constraint violation: {arg:?}" ); - let jt = hir::JumpTable { + let succ = hir::SuccessorInfo { destination: block, args: block_args, }; @@ -736,7 +713,7 @@ impl<'a> BlockScheduler<'a> { block_args[index as usize], arg_id, arg_source_id, - Some(&[jt]), + Some(&[succ]), )); } Node::Argument(arg) => { @@ -746,11 +723,11 @@ impl<'a> BlockScheduler<'a> { } } } - BranchInfo::MultiDest(ref jts) => { - for jt in jts.iter() { + BranchInfo::MultiDest(ref succs) => { + for succ in succs.iter() { inst_info.successors.push(Successor { - block: jt.destination, - arg_count: jt.args.len() as u16, + block: succ.destination, + arg_count: succ.args.len() as u16, }); } for (succ_idx, arg) in self @@ -775,7 +752,7 @@ impl<'a> BlockScheduler<'a> { inst_args[index as usize], arg_id, arg_source_id, - Some(jts), + Some(succs), )); } Node::Argument(ArgumentNode::Indirect { @@ -784,9 +761,9 @@ impl<'a> BlockScheduler<'a> { debug_assert_eq!( succ_idx - inst_args.len() - - jts[..(successor as usize)] + - succs[..(successor as usize)] .iter() - .map(|jt| jt.args.len()) + .map(|succ| succ.args.len()) .sum::(), index as usize, "successor ordering constraint violation: {arg:?}" @@ -794,12 +771,12 @@ impl<'a> BlockScheduler<'a> { if !arg_source_id.is_stack() { inst_info.pre.insert(arg_source_id); } - let block_arg = jts[successor as usize].args[index as usize]; + let block_arg = succs[successor as usize].args[index as usize]; inst_info.args.push(self.constraint( block_arg, arg_id, arg_source_id, - Some(jts), + Some(succs), )); } Node::Argument(ArgumentNode::Conditional { @@ -808,9 +785,9 @@ impl<'a> BlockScheduler<'a> { debug_assert_eq!( succ_idx - inst_args.len() - - jts[..(successor as usize)] + - succs[..(successor as usize)] .iter() - .map(|jt| jt.args.len()) + .map(|succ| succ.args.len()) .sum::(), index as usize, "successor ordering constraint violation: {arg:?}" @@ -823,12 +800,12 @@ impl<'a> BlockScheduler<'a> { //inst_info.post.insert(arg_source_id); inst_info.pre.insert(arg_source_id); } - let block_arg = jts[successor as usize].args[index as usize]; + let block_arg = succs[successor as usize].args[index as usize]; inst_info.args.push(self.constraint( block_arg, arg_id, arg_source_id, - Some(jts), + Some(succs), )); } _ => unreachable!(), @@ -961,7 +938,7 @@ impl<'a> BlockScheduler<'a> { arg: hir::Value, arg_node: NodeId, arg_sourced_from: NodeId, - successors: Option<&[hir::JumpTable<'_>]>, + successors: Option<&[hir::SuccessorInfo<'_>]>, ) -> Constraint { if cfg!(debug_assertions) { assert_matches!( @@ -1069,9 +1046,9 @@ fn build_dependency_graph( } match function.dfg.analyze_branch(inst) { - BranchInfo::SingleDest(_, args) => { + BranchInfo::SingleDest(succ) => { // Add edges representing these data dependencies in later blocks - for (arg_idx, arg) in args.iter().copied().enumerate() { + for (arg_idx, arg) in succ.args.iter().copied().enumerate() { let arg_node = ArgumentNode::Indirect { inst, index: arg_idx.try_into().expect("too many successor arguments"), @@ -1080,15 +1057,15 @@ fn build_dependency_graph( graph.add_data_dependency(node_id, arg_node, arg, pp, function); } } - BranchInfo::MultiDest(ref jts) => { + BranchInfo::MultiDest(ref succs) => { // Preprocess the arguments which are used so we can determine materialization // requirements - for jt in jts.iter() { - for arg in jt.args.iter().copied() { + for succ in succs.iter() { + for arg in succ.args.iter().copied() { block_arg_uses .entry(arg) .or_insert_with(Default::default) - .insert(jt.destination); + .insert(succ.destination); } } // For each successor, check if we should implicitly require an argument along that @@ -1096,11 +1073,11 @@ fn build_dependency_graph( // somewhere downstream. We only consider block arguments passed to // at least one other successor, and which are not already explicitly // provided to this successor. - let materialization_threshold = jts.len(); + let materialization_threshold = succs.len(); // Finally, add edges to the dependency graph representing the nature of each // argument - for (succ_idx, jt) in jts.iter().enumerate() { - for (arg_idx, arg) in jt.args.iter().copied().enumerate() { + for (succ_idx, succ) in succs.iter().enumerate() { + for (arg_idx, arg) in succ.args.iter().copied().enumerate() { let is_conditionally_materialized = block_arg_uses[&arg].len() < materialization_threshold; let must_materialize = @@ -1372,11 +1349,11 @@ fn dce( let successor = successor as usize; let index = index as usize; let value = match &branch_info { - BranchInfo::SingleDest(_, args) => { + BranchInfo::SingleDest(succ) => { assert_eq!(successor, 0); - args[index] + succ.args[index] } - BranchInfo::MultiDest(ref jts) => jts[successor].args[index], + BranchInfo::MultiDest(ref succs) => succs[successor].args[index], BranchInfo::NotABranch => unreachable!( "indirect/conditional arguments are only valid as successors of a \ branch instruction" diff --git a/codegen/masm/src/compiler/masm.rs b/codegen/masm/src/compiler/masm.rs new file mode 100644 index 00000000..034aec93 --- /dev/null +++ b/codegen/masm/src/compiler/masm.rs @@ -0,0 +1,75 @@ +use miden_assembly::Library as CompiledLibrary; +use midenc_hir::Symbol; +use midenc_session::{diagnostics::Report, Emit, OutputMode, OutputType, Session}; + +use crate::{Library, MastArtifact, Module, Program}; + +/// The artifact produced by lowering an [hir::Program] to Miden Assembly +/// +/// This type is used in compilation pipelines to abstract over the type of output requested. +pub enum MasmArtifact { + /// An executable program, with a defined entrypoint + Executable(Box), + /// A library, linkable into a program as needed + Library(Box), +} + +impl MasmArtifact { + pub fn assemble(&self, session: &Session) -> Result { + match self { + Self::Executable(program) => program.assemble(session).map(MastArtifact::Executable), + Self::Library(library) => library.assemble(session).map(MastArtifact::Library), + } + } + + /// Get an iterator over the modules in this library + pub fn modules(&self) -> impl Iterator + '_ { + match self { + Self::Executable(ref program) => program.library().modules(), + Self::Library(ref lib) => lib.modules(), + } + } + + pub fn insert(&mut self, module: Box) { + match self { + Self::Executable(ref mut program) => program.insert(module), + Self::Library(ref mut lib) => lib.insert(module), + } + } + + pub fn link_library(&mut self, lib: CompiledLibrary) { + match self { + Self::Executable(ref mut program) => program.link_library(lib), + Self::Library(ref mut library) => library.link_library(lib), + } + } + + pub fn unwrap_executable(self) -> Box { + match self { + Self::Executable(program) => program, + Self::Library(_) => panic!("tried to unwrap a mast library as an executable"), + } + } +} + +impl Emit for MasmArtifact { + fn name(&self) -> Option { + None + } + + fn output_type(&self, _mode: OutputMode) -> OutputType { + OutputType::Masm + } + + fn write_to( + &self, + writer: W, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()> { + match self { + Self::Executable(ref prog) => prog.write_to(writer, mode, session), + Self::Library(ref lib) => lib.write_to(writer, mode, session), + } + } +} diff --git a/codegen/masm/src/compiler/mast.rs b/codegen/masm/src/compiler/mast.rs new file mode 100644 index 00000000..ca99d724 --- /dev/null +++ b/codegen/masm/src/compiler/mast.rs @@ -0,0 +1,56 @@ +use std::sync::Arc; + +use miden_assembly::Library as CompiledLibrary; +use midenc_hir::Symbol; +use midenc_session::{Emit, OutputMode, OutputType, Session}; + +/// The artifact produced by lowering a [Program] to a Merkelized Abstract Syntax Tree +/// +/// This type is used in compilation pipelines to abstract over the type of output requested. +pub enum MastArtifact { + /// A MAST artifact which can be executed by the VM directly + Executable(Arc), + /// A MAST artifact which can be used as a dependency by a [miden_core::Program] + Library(Arc), +} + +impl MastArtifact { + pub fn unwrap_program(self) -> Arc { + match self { + Self::Executable(prog) => prog, + Self::Library(_) => panic!("attempted to unwrap 'mast' library as program"), + } + } +} + +impl Emit for MastArtifact { + fn name(&self) -> Option { + None + } + + fn output_type(&self, mode: OutputMode) -> OutputType { + match mode { + OutputMode::Text => OutputType::Mast, + OutputMode::Binary => OutputType::Masl, + } + } + + fn write_to( + &self, + writer: W, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()> { + match self { + Self::Executable(ref prog) => { + if matches!(mode, OutputMode::Binary) { + log::warn!( + "unable to write 'masl' output type for miden_core::Program: skipping.." + ); + } + prog.write_to(writer, mode, session) + } + Self::Library(ref lib) => lib.write_to(writer, mode, session), + } + } +} diff --git a/codegen/masm/src/compiler/mod.rs b/codegen/masm/src/compiler/mod.rs new file mode 100644 index 00000000..e895a6bf --- /dev/null +++ b/codegen/masm/src/compiler/mod.rs @@ -0,0 +1,154 @@ +mod masm; +mod mast; + +use midenc_hir::{ + self as hir, + pass::{RewritePass, RewriteSet}, +}; +use midenc_session::{diagnostics::Report, Session}; + +pub use self::{masm::MasmArtifact, mast::MastArtifact}; +use crate::{intrinsics, ConvertHirToMasm, Program}; + +pub type CompilerResult = Result; + +/// [MasmCompiler] is a compiler from Miden IR to MASM IR, an intermediate representation +/// of Miden Assembly which is used within the Miden compiler framework for various purposes, +/// and can be emitted directly to textual Miden Assembly. +/// +/// The [MasmCompiler] is designed to compile a [midenc_hir::Program] +/// +/// can be used to take a linked [midenc_hir::Program] and +/// compile it to MASM IR, an intermediate representation of Miden Assembly +/// used within the compiler. +pub struct MasmCompiler<'a> { + session: &'a Session, + analyses: hir::pass::AnalysisManager, +} +impl<'a> MasmCompiler<'a> { + pub fn new(session: &'a Session) -> Self { + Self { + session, + analyses: hir::pass::AnalysisManager::new(), + } + } + + /// Compile an [hir::Program] that has been linked and is ready to be compiled. + pub fn compile(&mut self, mut input: Box) -> CompilerResult { + use midenc_hir::pass::ConversionPass; + + let mut rewrites = default_rewrites([], self.session); + + let modules = input.modules_mut().take(); + for mut module in modules.into_iter() { + rewrites.apply(&mut module, &mut self.analyses, self.session)?; + input.modules_mut().insert(module); + } + + let mut convert_to_masm = ConvertHirToMasm::::default(); + let mut artifact = convert_to_masm.convert(input, &mut self.analyses, self.session)?; + + // Ensure intrinsics modules are linked + artifact.insert(Box::new( + intrinsics::load("intrinsics::mem", &self.session.source_manager) + .expect("undefined intrinsics module"), + )); + artifact.insert(Box::new( + intrinsics::load("intrinsics::i32", &self.session.source_manager) + .expect("undefined intrinsics module"), + )); + artifact.insert(Box::new( + intrinsics::load("intrinsics::i64", &self.session.source_manager) + .expect("undefined intrinsics module"), + )); + + Ok(artifact) + } + + /// Compile a single [hir::Module] as a program. + /// + /// It is assumed that the given module has been validated, and that all necessary + /// rewrites have been applied. If one of these invariants is not upheld, compilation + /// may fail. + pub fn compile_module(&mut self, input: Box) -> CompilerResult> { + assert!(input.entrypoint().is_some(), "cannot compile a program without an entrypoint"); + + let program = + hir::ProgramBuilder::new(&self.session.diagnostics).with_module(input)?.link()?; + + match self.compile(program)? { + MasmArtifact::Executable(program) => Ok(program), + _ => unreachable!("expected compiler to produce an executable, got a library"), + } + } + + /// Compile a set of [hir::Module] as a program. + /// + /// It is assumed that the given modules have been validated, and that all necessary + /// rewrites have been applied. If one of these invariants is not upheld, compilation + /// may fail. + pub fn compile_modules>>( + &mut self, + input: I, + ) -> CompilerResult> { + let mut builder = hir::ProgramBuilder::new(&self.session.diagnostics); + for module in input.into_iter() { + builder.add_module(module)?; + } + + let program = builder.link()?; + + assert!(program.has_entrypoint(), "cannot compile a program without an entrypoint"); + + match self.compile(program)? { + MasmArtifact::Executable(program) => Ok(program), + _ => unreachable!("expected compiler to produce an executable, got a library"), + } + } +} + +pub fn default_rewrites

(registered: P, session: &Session) -> RewriteSet +where + P: IntoIterator>>, +

::IntoIter: ExactSizeIterator, +{ + use midenc_hir::pass::ModuleRewritePassAdapter; + + let registered = registered.into_iter(); + + // If no rewrites were explicitly enabled, and conversion to Miden Assembly is, + // then we must ensure that the basic transformation passes are applied. + // + // Otherwise, assume that the intent was to skip those rewrites and do not add them + let mut rewrites = RewriteSet::default(); + if registered.len() == 0 { + if session.should_codegen() { + let fn_rewrites = default_function_rewrites(session); + for rewrite in fn_rewrites { + rewrites.push(ModuleRewritePassAdapter::new(rewrite)); + } + } + } else { + rewrites.extend(registered); + } + + rewrites +} + +pub fn default_function_rewrites(session: &Session) -> RewriteSet { + use midenc_hir_transform as transforms; + + // If no rewrites were explicitly enabled, and conversion to Miden Assembly is, + // then we must ensure that the basic transformation passes are applied. + // + // Otherwise, assume that the intent was to skip those rewrites and do not add them + let mut rewrites = RewriteSet::default(); + if session.should_codegen() { + rewrites.push(transforms::SplitCriticalEdges); + rewrites.push(transforms::Treeify); + rewrites.push(transforms::InlineBlocks); + rewrites.push(transforms::ApplySpills); + } + + rewrites +} diff --git a/codegen/masm/src/convert.rs b/codegen/masm/src/convert.rs index 9ae861d5..affcbac0 100644 --- a/codegen/masm/src/convert.rs +++ b/codegen/masm/src/convert.rs @@ -9,7 +9,7 @@ use midenc_session::Session; use crate::{ codegen::{FunctionEmitter, OperandStack, Scheduler, TypedValue}, - masm, + masm, MasmArtifact, }; type ProgramGlobalVariableAnalysis = analysis::GlobalVariableAnalysis; @@ -48,7 +48,7 @@ impl PassInfo for ConvertHirToMasm { impl ConversionPass for ConvertHirToMasm { type From = Box; - type To = Box; + type To = MasmArtifact; fn convert( &mut self, @@ -56,42 +56,37 @@ impl ConversionPass for ConvertHirToMasm { analyses: &mut AnalysisManager, session: &Session, ) -> ConversionResult { - let mut masm_program = Box::new(masm::Program::from_hir(&program)); + // Ensure global variable analysis is computed + let globals = + analyses.get_or_compute::(&program, session)?; + + let mut artifact = if program.has_entrypoint() { + masm::Program::from_hir(&program, &globals) + .map(Box::new) + .map(MasmArtifact::Executable)? + } else { + MasmArtifact::Library(Box::new(masm::Library::from_hir(&program, &globals))) + }; + + // Move link libraries to artifact + let libraries = core::mem::take(program.libraries_mut()); + for lib in libraries.into_values() { + artifact.link_library(lib); + } // Remove the set of modules to compile from the program let modules = program.modules_mut().take(); - // Ensure global variable analysis is computed - analyses.get_or_compute::(&program, session)?; - for module in modules.into_iter() { // Convert the module let mut convert_to_masm = ConvertHirToMasm::::default(); let masm_module = convert_to_masm.convert(module, analyses, session)?; - // If this module makes use of any intrinsics modules, and those modules are not - // already present, add them to the program. - for import in masm_module - .imports - .iter() - .filter(|import| import.name.as_str().starts_with("intrinsics::")) - { - if masm_program.contains(import.name) { - continue; - } - match masm::intrinsics::load(import.name.as_str(), &session.codemap) { - Some(loaded) => { - masm_program.insert(Box::new(loaded)); - } - None => unimplemented!("unrecognized intrinsic module: '{}'", &import.name), - } - } - // Add to the final Miden Assembly program - masm_program.insert(masm_module); + artifact.insert(masm_module); } - Ok(masm_program) + Ok(artifact) } } diff --git a/codegen/masm/src/emulator/functions.rs b/codegen/masm/src/emulator/functions.rs index 9f4d4bec..45c6165c 100644 --- a/codegen/masm/src/emulator/functions.rs +++ b/codegen/masm/src/emulator/functions.rs @@ -341,7 +341,7 @@ impl Instruction { #[inline(always)] pub fn op(&self, function: &Function) -> Option { - function.body.get(self.ip) + function.body.get(self.ip).map(|op| op.into_inner()) } } @@ -484,7 +484,7 @@ impl Activation { #[cfg(test)] mod tests { - use midenc_hir::{assert_matches, Signature}; + use midenc_hir::{assert_matches, Signature, SourceSpan}; use super::*; @@ -736,6 +736,7 @@ mod tests { } fn test_function() -> Arc { + let span = SourceSpan::default(); let mut function = Function::new("test::main".parse().unwrap(), Signature::new(vec![], vec![])); let then_blk = function.create_block(); @@ -743,29 +744,29 @@ mod tests { let while_blk = function.create_block(); { let body = function.block_mut(function.body.id()); - body.push(Op::PushU8(2)); - body.push(Op::PushU8(1)); - body.push(Op::Dup(1)); - body.push(Op::Dup(1)); - body.push(Op::U32Lt); - body.push(Op::If(then_blk, else_blk)); - body.push(Op::Exec("test::foo".parse().unwrap())); + body.push(Op::PushU8(2), span); + body.push(Op::PushU8(1), span); + body.push(Op::Dup(1), span); + body.push(Op::Dup(1), span); + body.push(Op::U32Lt, span); + body.push(Op::If(then_blk, else_blk), span); + body.push(Op::Exec("test::foo".parse().unwrap()), span); } { let then_body = function.block_mut(then_blk); - then_body.push(Op::PushU8(1)); - then_body.push(Op::While(while_blk)); + then_body.push(Op::PushU8(1), span); + then_body.push(Op::While(while_blk), span); } { let else_body = function.block_mut(else_blk); - else_body.push(Op::U32Max); + else_body.push(Op::U32Max, span); } { let while_body = function.block_mut(while_blk); - while_body.push(Op::Dup(1)); - while_body.push(Op::Dup(1)); - while_body.push(Op::Incr); - while_body.push(Op::U32Lt); + while_body.push(Op::Dup(1), span); + while_body.push(Op::Dup(1), span); + while_body.push(Op::Incr, span); + while_body.push(Op::U32Lt, span); } Arc::new(function) diff --git a/codegen/masm/src/emulator/mod.rs b/codegen/masm/src/emulator/mod.rs index c3c80e6d..9a85a809 100644 --- a/codegen/masm/src/emulator/mod.rs +++ b/codegen/masm/src/emulator/mod.rs @@ -300,7 +300,7 @@ impl Emulator { self.load_module(module)?; cursor.move_next(); } - self.entrypoint = program.entrypoint; + self.entrypoint = Some(program.entrypoint()); // TODO: Load data segments diff --git a/codegen/masm/src/lib.rs b/codegen/masm/src/lib.rs index 66ef3e0d..a4d938de 100644 --- a/codegen/masm/src/lib.rs +++ b/codegen/masm/src/lib.rs @@ -1,20 +1,20 @@ #![feature(array_windows)] +#![feature(iter_array_chunks)] #![feature(is_sorted)] mod codegen; +mod compiler; mod convert; mod emulator; mod masm; #[cfg(test)] mod tests; -use midenc_hir::{ - self as hir, - pass::{RewritePass, RewriteSet}, -}; -use midenc_session::Session; - pub use self::{ + compiler::{ + default_function_rewrites, default_rewrites, CompilerResult, MasmArtifact, MasmCompiler, + MastArtifact, + }, convert::ConvertHirToMasm, emulator::{ Breakpoint, BreakpointEvent, CallFrame, DebugInfo, DebugInfoWithStack, EmulationError, @@ -22,161 +22,3 @@ pub use self::{ }, masm::*, }; - -/// This error type represents all of the errors produced by [MasmCompiler] -#[derive(Debug, thiserror::Error)] -pub enum CompilerError { - /// Two or more modules conflict with each other - #[error(transparent)] - ModuleConflict(#[from] hir::ModuleConflictError), - /// An error occurred at link-time - #[error(transparent)] - Linker(#[from] hir::LinkerError), - /// An error occurred during analysis - #[error(transparent)] - Analysis(#[from] hir::pass::AnalysisError), - /// An error occurred during application of a rewrite - #[error(transparent)] - Rewrite(#[from] hir::pass::RewriteError), - /// An error occurred during application of a conversion - #[error(transparent)] - Conversion(#[from] hir::pass::ConversionError), -} - -pub type CompilerResult = Result; - -/// [MasmCompiler] is a compiler from Miden IR to MASM IR, an intermediate representation -/// of Miden Assembly which is used within the Miden compiler framework for various purposes, -/// and can be emitted directly to textual Miden Assembly. -/// -/// The [MasmCompiler] is designed to compile a [midenc_hir::Program] -/// -/// can be used to take a linked [midenc_hir::Program] and -/// compile it to MASM IR, an intermediate representation of Miden Assembly -/// used within the compiler. -pub struct MasmCompiler<'a> { - session: &'a Session, - analyses: hir::pass::AnalysisManager, -} -impl<'a> MasmCompiler<'a> { - pub fn new(session: &'a Session) -> Self { - Self { - session, - analyses: hir::pass::AnalysisManager::new(), - } - } - - /// Compile an [hir::Program] that has been linked and is ready to be compiled. - pub fn compile(&mut self, mut input: Box) -> CompilerResult> { - use midenc_hir::pass::ConversionPass; - - let mut rewrites = default_rewrites([], self.session); - - let modules = input.modules_mut().take(); - for mut module in modules.into_iter() { - rewrites.apply(&mut module, &mut self.analyses, self.session)?; - input.modules_mut().insert(module); - } - - let mut convert_to_masm = ConvertHirToMasm::::default(); - let mut program = convert_to_masm.convert(input, &mut self.analyses, self.session)?; - - // Ensure standard library is linked - for module in intrinsics::load_stdlib(&self.session.codemap) { - program.insert(Box::new(module.clone())); - } - - // Ensure intrinsics modules are linked - program.insert(Box::new( - intrinsics::load("intrinsics::mem", &self.session.codemap) - .expect("undefined intrinsics module"), - )); - program.insert(Box::new( - intrinsics::load("intrinsics::i32", &self.session.codemap) - .expect("undefined intrinsics module"), - )); - program.insert(Box::new( - intrinsics::load("intrinsics::i64", &self.session.codemap) - .expect("undefined intrinsics module"), - )); - - Ok(program) - } - - /// Compile a single [hir::Module] as a program. - /// - /// It is assumed that the given module has been validated, and that all necessary - /// rewrites have been applied. If one of these invariants is not upheld, compilation - /// may fail. - pub fn compile_module(&mut self, input: Box) -> CompilerResult> { - let program = - hir::ProgramBuilder::new(&self.session.diagnostics).with_module(input)?.link()?; - - self.compile(program) - } - - /// Compile a set of [hir::Module] as a program. - /// - /// It is assumed that the given modules have been validated, and that all necessary - /// rewrites have been applied. If one of these invariants is not upheld, compilation - /// may fail. - pub fn compile_modules>>( - &mut self, - input: I, - ) -> CompilerResult> { - let mut builder = hir::ProgramBuilder::new(&self.session.diagnostics); - for module in input.into_iter() { - builder.add_module(module)?; - } - - let program = builder.link()?; - - self.compile(program) - } -} - -pub fn default_rewrites

(registered: P, session: &Session) -> RewriteSet -where - P: IntoIterator>>, -

::IntoIter: ExactSizeIterator, -{ - use midenc_hir::pass::ModuleRewritePassAdapter; - - let registered = registered.into_iter(); - - // If no rewrites were explicitly enabled, and conversion to Miden Assembly is, - // then we must ensure that the basic transformation passes are applied. - // - // Otherwise, assume that the intent was to skip those rewrites and do not add them - let mut rewrites = RewriteSet::default(); - if registered.len() == 0 { - if session.should_codegen() { - let fn_rewrites = default_function_rewrites(session); - for rewrite in fn_rewrites { - rewrites.push(ModuleRewritePassAdapter::new(rewrite)); - } - } - } else { - rewrites.extend(registered); - } - - rewrites -} - -pub fn default_function_rewrites(session: &Session) -> RewriteSet { - use midenc_hir_transform as transforms; - - // If no rewrites were explicitly enabled, and conversion to Miden Assembly is, - // then we must ensure that the basic transformation passes are applied. - // - // Otherwise, assume that the intent was to skip those rewrites and do not add them - let mut rewrites = RewriteSet::default(); - if session.should_codegen() { - rewrites.push(transforms::SplitCriticalEdges); - rewrites.push(transforms::Treeify); - rewrites.push(transforms::InlineBlocks); - rewrites.push(transforms::ApplySpills); - } - - rewrites -} diff --git a/codegen/masm/src/masm/function.rs b/codegen/masm/src/masm/function.rs index 652f954b..74e15d29 100644 --- a/codegen/masm/src/masm/function.rs +++ b/codegen/masm/src/masm/function.rs @@ -6,8 +6,11 @@ use miden_assembly::{ ast::{self, ProcedureName}, LibraryNamespace, LibraryPath, }; -use miden_diagnostics::{SourceSpan, Spanned}; -use midenc_hir::{formatter::PrettyPrint, AttributeSet, FunctionIdent, Ident, Signature, Type}; +use midenc_hir::{ + diagnostics::{SourceSpan, Span, Spanned}, + formatter::PrettyPrint, + AttributeSet, FunctionIdent, Ident, Signature, Type, +}; use smallvec::SmallVec; use super::*; @@ -158,17 +161,13 @@ impl Function { kind: ast::InvokeKind, target: FunctionIdent, ) { - let module_name_span = miden_assembly::SourceSpan::new( - target.module.span.start_index().0..target.module.span.end_index().0, - ); - let module_id = ast::Ident::new_unchecked(miden_assembly::Span::new( + let module_name_span = target.module.span; + let module_id = ast::Ident::new_unchecked(Span::new( module_name_span, Arc::from(target.module.as_str().to_string().into_boxed_str()), )); - let name_span = miden_assembly::SourceSpan::new( - target.function.span.start_index().0..target.function.span.end_index().0, - ); - let id = ast::Ident::new_unchecked(miden_assembly::Span::new( + let name_span = target.function.span; + let id = ast::Ident::new_unchecked(Span::new( name_span, Arc::from(target.function.as_str().to_string().into_boxed_str()), )); @@ -190,9 +189,11 @@ impl Function { pub fn from_ast(module: Ident, proc: &ast::Procedure) -> Box { use midenc_hir::{Linkage, Symbol}; + let proc_span = proc.name().span(); + let proc_name = Symbol::intern(AsRef::::as_ref(proc.name())); let id = FunctionIdent { module, - function: Ident::with_empty_span(Symbol::intern(AsRef::::as_ref(proc.name()))), + function: Ident::new(proc_name, proc_span), }; let mut signature = Signature::new(vec![], vec![]); @@ -218,9 +219,9 @@ impl Function { pub fn to_ast( &self, - codemap: &miden_diagnostics::CodeMap, imports: &midenc_hir::ModuleImportInfo, locals: &BTreeSet, + tracing_enabled: bool, ) -> ast::Procedure { let visibility = if self.signature.is_kernel() { ast::Visibility::Syscall @@ -229,36 +230,60 @@ impl Function { } else { ast::Visibility::Private }; - let source_id = self.span.source_id(); - let span = - miden_assembly::SourceSpan::new(self.span.start_index().0..self.span.end_index().0); - let source_file = codemap.get(source_id).ok().map(|sf| { - let nf = miden_assembly::diagnostics::SourceFile::new( - sf.name().as_str().unwrap(), - sf.source().to_string(), - ); - Arc::new(nf) - }); - let name_span = miden_assembly::SourceSpan::new( - self.name.function.span.start_index().0..self.name.function.span.end_index().0, - ); - let id = ast::Ident::new_unchecked(miden_assembly::Span::new( - name_span, + let id = ast::Ident::new_unchecked(Span::new( + self.name.function.span, Arc::from(self.name.function.as_str().to_string().into_boxed_str()), )); let name = ast::ProcedureName::new_unchecked(id); - let body = self.body.to_block(codemap, imports, locals); + let mut body = self.body.to_block(imports, locals); + + // Emit trace events on entry/exit from the procedure body, if not already present + if tracing_enabled { + emit_trace_frame_events(self.span, &mut body); + } let num_locals = u16::try_from(self.locals.len()).expect("too many locals"); - let mut proc = ast::Procedure::new(span, visibility, name, num_locals, body) - .with_source_file(source_file); + let mut proc = ast::Procedure::new(self.span, visibility, name, num_locals, body); proc.extend_invoked(self.invoked().cloned()); proc } } +fn emit_trace_frame_events(span: SourceSpan, body: &mut ast::Block) { + use midenc_hir::{TRACE_FRAME_END, TRACE_FRAME_START}; + + let ops = body.iter().as_slice(); + let has_frame_start = match ops.get(1) { + Some(ast::Op::Inst(inst)) => match inst.inner() { + ast::Instruction::Trace(imm) => { + matches!(imm, ast::Immediate::Value(val) if val.into_inner() == TRACE_FRAME_START) + } + _ => false, + }, + _ => false, + }; + + // If we have the frame start event, we do not need to emit any further events + if has_frame_start { + return; + } + + // Because [ast::Block] does not have a mutator that lets us insert an op at the start, we need + // to push the events at the end, then use access to the mutable slice via `iter_mut` to move + // elements around. + body.push(ast::Op::Inst(Span::new(span, ast::Instruction::Nop))); + body.push(ast::Op::Inst(Span::new(span, ast::Instruction::Trace(TRACE_FRAME_END.into())))); + body.push(ast::Op::Inst(Span::new(span, ast::Instruction::Nop))); + body.push(ast::Op::Inst(Span::new( + span, + ast::Instruction::Trace(TRACE_FRAME_START.into()), + ))); + let ops = body.iter_mut().into_slice(); + ops.rotate_right(2); +} + impl fmt::Debug for Function { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Function") diff --git a/codegen/masm/src/masm/import.rs b/codegen/masm/src/masm/import.rs deleted file mode 100644 index 96c44f64..00000000 --- a/codegen/masm/src/masm/import.rs +++ /dev/null @@ -1,129 +0,0 @@ -use core::{ - hash::{Hash, Hasher}, - str::FromStr, -}; - -use anyhow::bail; -use miden_diagnostics::{SourceSpan, Spanned}; -use midenc_hir::Symbol; - -/// This represents an import statement in Miden Assembly -#[derive(Debug, Copy, Clone, Spanned)] -pub struct Import { - /// The source span corresponding to this import statement, if applicable - #[span] - pub span: SourceSpan, - /// The fully-qualified name of the imported module, e.g. `std::math::u64` - pub name: Symbol, - /// The name to which the imported module is aliased locally, e.g. `u64` - /// is the alias for `use std::math::u64`, which is the default behavior. - /// - /// However, custom aliases are permitted, and we may use this to disambiguate - /// imported modules, e.g. `use std::math::u64->my_u64` will result in the - /// alias for this import being `my_u64`. - pub alias: Symbol, -} -impl Import { - /// Returns true if this import has a custom alias, or if it uses the - /// default aliasing behavior for imports - pub fn is_aliased(&self) -> bool { - !self.name.as_str().ends_with(self.alias.as_str()) - } - - /// Returns true if this import conflicts with `other` - /// - /// A conflict arises when the same name is used to reference two different - /// imports locally within a module, i.e. the aliases conflict - pub fn conflicts_with(&self, other: &Self) -> bool { - self.alias == other.alias && self.name != other.name - } -} -impl Eq for Import {} -impl PartialEq for Import { - fn eq(&self, other: &Self) -> bool { - // If the names are different, the imports can't be equivalent - if self.name != other.name { - return false; - } - // Otherwise, equivalence depends on the aliasing of the import - match (self.is_aliased(), other.is_aliased()) { - (true, true) => { - // Two imports that are custom aliased are equivalent only if - // both the fully-qualified name and the alias are identical - self.alias == other.alias - } - (true, false) | (false, true) => { - // If one import is aliased and the other is not, the imports - // are never equivalent, because they can't possibly refer to - // the same module by the same name - false - } - (false, false) => { - // Two unaliased imports are the same if their names are the same - true - } - } - } -} -impl PartialOrd for Import { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} -impl Ord for Import { - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.name - .cmp(&other.name) - .then_with(|| self.alias.cmp(&other.alias)) - } -} -impl Hash for Import { - fn hash(&self, state: &mut H) { - self.name.hash(state); - self.alias.hash(state); - } -} -impl FromStr for Import { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let s = s.trim(); - let s = s.strip_prefix("use ").unwrap_or(s); - if s.contains(char::is_whitespace) { - bail!( - "invalid import '{}': unexpected whitespace in identifier", - s - ); - } - let (name, alias) = match s.rsplit_once("->") { - None => match s.rsplit_once("::") { - None => { - let name = Symbol::intern(s); - (name, name) - } - Some((_, alias)) if alias.is_empty() => { - bail!("invalid import '{}': trailing '::' is not allowed", s) - } - Some((_, alias)) => { - let name = Symbol::intern(s); - let alias = Symbol::intern(alias); - (name, alias) - } - }, - Some((_, alias)) if alias.is_empty() => { - bail!("invalid import '{}': alias cannot be empty", s) - } - Some((fqn, alias)) => { - let name = Symbol::intern(fqn); - let alias = Symbol::intern(alias); - (name, alias) - } - }; - - Ok(Self { - span: SourceSpan::UNKNOWN, - name, - alias, - }) - } -} diff --git a/codegen/masm/src/masm/intrinsics.rs b/codegen/masm/src/masm/intrinsics.rs index c214a223..a72400b8 100644 --- a/codegen/masm/src/masm/intrinsics.rs +++ b/codegen/masm/src/masm/intrinsics.rs @@ -1,5 +1,5 @@ use miden_assembly::{ast::ModuleKind, LibraryPath}; -use miden_diagnostics::{CodeMap, FileName}; +use midenc_hir::diagnostics::{PrintDiagnostic, SourceManager}; use super::Module; @@ -12,54 +12,36 @@ const MEM_INTRINSICS: &str = /// This is a mapping of intrinsics module name to the raw MASM source for that module const INTRINSICS: [(&str, &str, &str); 3] = [ - ("intrinsics::i32", I32_INTRINSICS, "i32.masm"), - ("intrinsics::i64", I64_INTRINSICS, "i64.masm"), - ("intrinsics::mem", MEM_INTRINSICS, "mem.masm"), + ( + "intrinsics::i32", + I32_INTRINSICS, + concat!(env!("CARGO_MANIFEST_DIR"), "/intrinsics/i32.masm"), + ), + ( + "intrinsics::i64", + I64_INTRINSICS, + concat!(env!("CARGO_MANIFEST_DIR"), "/intrinsics/i64.masm"), + ), + ( + "intrinsics::mem", + MEM_INTRINSICS, + concat!(env!("CARGO_MANIFEST_DIR"), "/intrinsics/mem.masm"), + ), ]; /// This helper loads the named module from the set of intrinsics modules defined in this crate. /// /// Expects the fully-qualified name to be given, e.g. `intrinsics::mem` -pub fn load>(name: N, codemap: &CodeMap) -> Option { +pub fn load>(name: N, source_manager: &dyn SourceManager) -> Option { let name = name.as_ref(); let (name, source, filename) = INTRINSICS.iter().copied().find(|(n, ..)| *n == name)?; - let id = codemap.add(FileName::Virtual(filename.into()), source.to_string()); - let source_file = codemap.get(id).unwrap(); + let source_file = source_manager.load(filename, source.to_string()); let path = LibraryPath::new(name).expect("invalid module name"); - match Module::parse_source_file(path, ModuleKind::Library, source_file, codemap) { + match Module::parse(ModuleKind::Library, path, source_file.clone()) { Ok(module) => Some(module), - Err(err) => match err { - crate::LoadModuleError::Report(report) => { - let report = miden_assembly::diagnostics::reporting::PrintDiagnostic::new( - report.into_report(), - ); - panic!("failed to parse intrinsic module: {report}"); - } - other => panic!("unexpected syntax error in intrinsic module: {other}"), - }, + Err(err) => { + let err = PrintDiagnostic::new(err); + panic!("failed to parse intrinsic module: {err}"); + } } } - -/// This helper loads the Miden Standard Library modules from the current miden-stdlib crate -pub fn load_stdlib(codemap: &CodeMap) -> &'static [Module] { - use std::sync::OnceLock; - - use miden_assembly::Library; - use miden_diagnostics::SourceSpan; - use miden_stdlib::StdLibrary; - - static LOADED: OnceLock> = OnceLock::new(); - - LOADED - .get_or_init(|| { - let library = StdLibrary::default(); - - let mut loaded = Vec::with_capacity(library.modules().len()); - for module in library.modules() { - let ir_module = Module::from_ast(module, SourceSpan::UNKNOWN, codemap); - loaded.push(ir_module); - } - loaded - }) - .as_slice() -} diff --git a/codegen/masm/src/masm/mod.rs b/codegen/masm/src/masm/mod.rs index 2f7e7e07..7ddcbb3c 100644 --- a/codegen/masm/src/masm/mod.rs +++ b/codegen/masm/src/masm/mod.rs @@ -11,8 +11,8 @@ pub use midenc_hir::{ pub use self::{ function::{FrozenFunctionList, Function, FunctionList}, - module::{FrozenModuleTree, LoadModuleError, Module, ModuleTree}, - program::Program, + module::{FrozenModuleTree, Module, ModuleTree}, + program::{Library, Program}, region::Region, }; @@ -42,6 +42,15 @@ pub struct NativePtr { pub addrspace: midenc_hir::AddressSpace, } impl NativePtr { + pub fn new(waddr: u32, index: u8, offset: u8) -> Self { + Self { + waddr, + index, + offset, + addrspace: Default::default(), + } + } + /// Translates a raw pointer (assumed to be in a byte-addressable address space) to /// a native pointer value, in the default [hir::AddressSpace]. pub fn from_ptr(addr: u32) -> Self { diff --git a/codegen/masm/src/masm/module.rs b/codegen/masm/src/masm/module.rs index 8a7249e1..417bcffb 100644 --- a/codegen/masm/src/masm/module.rs +++ b/codegen/masm/src/masm/module.rs @@ -1,42 +1,18 @@ -use std::{ - collections::BTreeSet, - fmt, - path::{Path, PathBuf}, - sync::Arc, -}; +use std::{collections::BTreeSet, fmt, path::Path, sync::Arc}; use intrusive_collections::{intrusive_adapter, RBTree, RBTreeAtomicLink}; use miden_assembly::{ ast::{self, ModuleKind}, - diagnostics::{RelatedError, Report, SourceFile as MasmSourceFile}, - LibraryNamespace, LibraryPath, + LibraryPath, +}; +use midenc_hir::{ + diagnostics::{Report, SourceFile, SourceSpan, Span, Spanned}, + formatter::PrettyPrint, + FunctionIdent, Ident, Symbol, }; -use miden_diagnostics::{CodeMap, SourceFile, SourceIndex, SourceSpan}; -use midenc_hir::{formatter::PrettyPrint, FunctionIdent, Ident, Symbol}; use super::{function::Functions, FrozenFunctionList, Function, ModuleImportInfo}; -#[derive(Debug, thiserror::Error)] -pub enum LoadModuleError { - #[error("failed to load module from disk: {0}")] - Io(#[from] std::io::Error), - #[error("invalid path to module: '{}' is not a file", .0.display())] - InvalidPath(PathBuf), - #[error(transparent)] - InvalidIdent(#[from] miden_assembly::ast::IdentError), - #[error(transparent)] - InvalidModulePath(#[from] miden_assembly::PathError), - #[error(transparent)] - InvalidNamespace(#[from] miden_assembly::library::LibraryNamespaceError), - #[error(transparent)] - Report(#[from] RelatedError), -} -impl From for LoadModuleError { - fn from(report: Report) -> Self { - Self::Report(RelatedError::new(report)) - } -} - /// This represents a single compiled Miden Assembly module in a form that is /// designed to integrate well with the rest of our IR. You can think of this /// as an intermediate representation corresponding to the Miden Assembly AST, @@ -81,6 +57,18 @@ impl Module { } } + /// Parse a [Module] from `source` using the given [ModuleKind] and [LibraryPath] + pub fn parse( + kind: ModuleKind, + path: LibraryPath, + source: Arc, + ) -> Result { + let span = source.source_span(); + let mut parser = ast::Module::parser(kind); + let ast = parser.parse(path, source)?; + Ok(Self::from_ast(&ast, span)) + } + /// Returns true if this module is a kernel module pub fn is_kernel(&self) -> bool { self.kind.is_kernel() @@ -112,49 +100,7 @@ impl Module { self.functions.iter().any(|f| f.name.function == name) } - /// Parse a [Module] from the given string - pub fn parse_source_file( - name: LibraryPath, - kind: ModuleKind, - source_file: Arc, - codemap: &CodeMap, - ) -> Result { - let filename = source_file.name().as_str().expect("invalid source file name"); - let module = ast::Module::parse( - name, - kind, - Arc::new(MasmSourceFile::new(filename, source_file.source().to_string())), - )?; - let span = source_file.source_span(); - Ok(Self::from_ast(&module, span, codemap)) - } - - /// Parse a [Module] from the given file path - pub fn parse_file>( - ns: Option, - kind: ModuleKind, - path: P, - codemap: &CodeMap, - ) -> Result { - let path = path.as_ref(); - let id = codemap.add_file(path)?; - let source_file = codemap.get(id).unwrap(); - let fallback_ns = match path.parent().and_then(|p| p.to_str()) { - None => LibraryNamespace::Anon, - Some(parent_dirname) => parent_dirname.parse::()?, - }; - let ns = ns.unwrap_or(fallback_ns); - let name = ast::Ident::new(path.file_stem().unwrap().to_str().unwrap())?; - let module_path = LibraryPath::new_from_components(ns, [name]); - let module = ast::Module::parse_file(module_path, kind, path)?; - let span = source_file.source_span(); - Ok(Self::from_ast(&module, span, codemap)) - } - - pub fn from_ast(ast: &ast::Module, span: SourceSpan, _codemap: &CodeMap) -> Self { - use miden_assembly::Spanned as MasmSpanned; - - let source_id = span.source_id(); + pub fn from_ast(ast: &ast::Module, span: SourceSpan) -> Self { let mut module = Self::new(ast.path().clone(), ast.kind()); module.span = span; module.docs = ast.docs().map(|s| s.to_string()); @@ -162,9 +108,6 @@ impl Module { let mut imports = ModuleImportInfo::default(); for import in ast.imports() { let span = import.name.span(); - let start = SourceIndex::new(source_id, (span.start() as u32).into()); - let end = SourceIndex::new(source_id, (span.end() as u32).into()); - let span = SourceSpan::new(start, end); let alias = Symbol::intern(import.name.as_str()); let name = if import.is_aliased() { Symbol::intern(import.path.last()) @@ -216,29 +159,13 @@ impl Module { } /// Convert this module into its [miden_assembly::ast::Module] representation. - pub fn to_ast(&self, codemap: &miden_diagnostics::CodeMap) -> Result { - let source_id = self.span.source_id(); - let source_file = if let Ok(source_file) = codemap.get(source_id) { - let file = miden_assembly::diagnostics::SourceFile::new( - source_file.name().as_str().unwrap(), - source_file.source().to_string(), - ); - Some(Arc::new(file)) - } else { - None - }; - let span = - miden_assembly::SourceSpan::new(self.span.start_index().0..self.span.end_index().0); - let mut ast = ast::Module::new(self.kind, self.name.clone()) - .with_source_file(source_file) - .with_span(span); - ast.set_docs(self.docs.clone().map(miden_assembly::Span::unknown)); + pub fn to_ast(&self, tracing_enabled: bool) -> Result { + let mut ast = ast::Module::new(self.kind, self.name.clone()).with_span(self.span); + ast.set_docs(self.docs.clone().map(Span::unknown)); // Create module import table for ir_import in self.imports.iter() { - let ir_span = ir_import.span; - let span = - miden_assembly::SourceSpan::new(ir_span.start_index().0..ir_span.end_index().0); + let span = ir_import.span; let name = ast::Ident::new_with_span(span, ir_import.alias.as_str()).map_err(Report::msg)?; let path = LibraryPath::new(ir_import.name.as_str()).expect("invalid import path"); @@ -260,9 +187,9 @@ impl Module { for function in self.functions.iter() { ast.define_procedure(ast::Export::Procedure(function.to_ast( - codemap, &self.imports, &locals, + tracing_enabled, )))?; } @@ -276,10 +203,10 @@ impl Module { /// `

/std/math/u64.masm` pub fn write_to_directory>( &self, - codemap: &miden_diagnostics::CodeMap, dir: P, + session: &midenc_session::Session, ) -> std::io::Result<()> { - use std::fs::File; + use midenc_session::{Emit, OutputMode}; let mut path = dir.as_ref().to_path_buf(); assert!(path.is_dir()); @@ -288,18 +215,8 @@ impl Module { } assert!(path.set_extension("masm")); - let mut out = File::create(&path)?; - self.emit(codemap, &mut out) - } - - /// Write this module as Miden Assembly text to `out` - pub fn emit( - &self, - codemap: &miden_diagnostics::CodeMap, - out: &mut dyn std::io::Write, - ) -> std::io::Result<()> { - let ast = self.to_ast(codemap).map_err(std::io::Error::other)?; - out.write_fmt(format_args!("{}", &ast)) + let ast = self.to_ast(false).map_err(std::io::Error::other)?; + ast.write_to_file(&path, OutputMode::Text, session) } } impl midenc_hir::formatter::PrettyPrint for Module { @@ -370,12 +287,18 @@ impl midenc_session::Emit for Module { Some(self.id.as_symbol()) } - fn output_type(&self) -> midenc_session::OutputType { + fn output_type(&self, _mode: midenc_session::OutputMode) -> midenc_session::OutputType { midenc_session::OutputType::Masm } - fn write_to(&self, mut writer: W) -> std::io::Result<()> { - writer.write_fmt(format_args!("{}", self)) + fn write_to( + &self, + writer: W, + mode: midenc_session::OutputMode, + session: &midenc_session::Session, + ) -> std::io::Result<()> { + let ast = self.to_ast(false).map_err(std::io::Error::other)?; + ast.write_to(writer, mode, session) } } @@ -414,7 +337,23 @@ impl Default for Modules { Self::Open(Default::default()) } } +impl Clone for Modules { + fn clone(&self) -> Self { + let mut out = ModuleTree::default(); + for module in self.iter() { + out.insert(Box::new(module.clone())); + } + Self::Open(out) + } +} impl Modules { + pub fn len(&self) -> usize { + match self { + Self::Open(ref tree) => tree.iter().count(), + Self::Frozen(ref tree) => tree.iter().count(), + } + } + pub fn iter(&self) -> impl Iterator + '_ { match self { Self::Open(ref tree) => ModulesIter::Open(tree.iter()), diff --git a/codegen/masm/src/masm/program.rs b/codegen/masm/src/masm/program.rs index aaf08211..9c1b6635 100644 --- a/codegen/masm/src/masm/program.rs +++ b/codegen/masm/src/masm/program.rs @@ -3,32 +3,61 @@ use std::{fmt, path::Path, sync::Arc}; use hir::{Signature, Symbol}; use miden_assembly::{ ast::{ModuleKind, ProcedureName}, - LibraryNamespace, + KernelLibrary, Library as CompiledLibrary, LibraryNamespace, }; -use midenc_hir::{self as hir, DataSegmentTable, FunctionIdent, Ident}; +use miden_core::crypto::hash::Rpo256; +use midenc_hir::{ + self as hir, diagnostics::Report, DataSegmentTable, Felt, FieldElement, FunctionIdent, Ident, + SourceSpan, +}; +use midenc_hir_analysis::GlobalVariableAnalysis; +use midenc_session::{Emit, Session}; use super::{module::Modules, *}; -/// A [Program] represents a complete set of modules which are intended to -/// be shipped together as an artifact, either as an executable, or as a library -/// to be integrated into a larger executable. -/// -/// Modules are stored in a [Program] in a b-tree map, keyed by the module name. -/// This is done to make accessing modules by name efficient, and to ensure a -/// stable ordering for compiled programs when emitted as text. -#[derive(Default)] +inventory::submit! { + midenc_session::CompileFlag::new("test_harness") + .long("test-harness") + .action(midenc_session::FlagAction::SetTrue) + .help("If present, causes the code generator to emit extra code for the VM test harness") + .help_heading("Testing") +} + +/// A [Program] represents a complete set of modules which are intended to be shipped and executed +/// together. +#[derive(Clone)] pub struct Program { - /// The set of modules which belong to this program - modules: Modules, - /// The data segment table for this program - pub segments: DataSegmentTable, + /// The code for this program + library: Library, /// The function identifier for the program entrypoint, if applicable - pub entrypoint: Option, + entrypoint: FunctionIdent, + /// The base address of the dynamic heap, as computed by the codegen backend + /// + /// Defaults to an offset which is two 64k pages from the start of linear memory + heap_base: u32, } impl Program { - /// Create a new, empty [Program] - pub fn empty() -> Self { - Self::default() + /// Create a new [Program] initialized from a [DataSegmentTable], a set of [Module]s, and an + /// optional entrypoint function. + /// + /// A `main.masm` module will be generated which invokes the given entrypoint on startup, after + /// initializing the global heap of the root context, based on the provided data segment table. + /// + /// You should generally prefer to use [Program::from_hir], but this constructor allows you to + /// manually produce a MASM program from its constituent parts. + pub fn new(entrypoint: FunctionIdent, segments: DataSegmentTable, modules: M) -> Self + where + M: IntoIterator>, + { + use crate::codegen::PAGE_SIZE; + + let library = Library::new(segments, modules); + Self { + library, + entrypoint, + // By default, we assume the first two pages are reserved for shadow stack and globals + heap_base: 2 * PAGE_SIZE, + } } /// Create a new [Program] initialized from an [hir::Program]. @@ -41,57 +70,456 @@ impl Program { /// invokes the entrypoint /// /// None of the HIR modules will have been added yet - pub fn from_hir(program: &hir::Program) -> Self { - let mut modules = Modules::default(); - - // Create executable module if we have an entrypoint - let entrypoint = program.entrypoint(); - if let Some(entry) = entrypoint { - let mut exe = - Box::new(Module::new(LibraryNamespace::Exec.into(), ModuleKind::Executable)); - exe.imports.add(entry); - let entry_module = exe - .imports - .alias(&entry.module) - .expect("something went wrong when adding entrypoint import"); - let start_id = FunctionIdent { - module: Ident::with_empty_span(Symbol::intern(LibraryNamespace::EXEC_PATH)), - function: Ident::with_empty_span(Symbol::intern(ProcedureName::MAIN_PROC_NAME)), - }; - let start_sig = Signature::new([], []); - let mut start = Box::new(Function::new(start_id, start_sig)); - { - let body = start.body_mut(); - body.push(Op::Exec(FunctionIdent { - module: entry_module, - function: entry.function, - })); + pub fn from_hir( + program: &hir::Program, + globals: &GlobalVariableAnalysis, + ) -> Result { + use crate::codegen::PAGE_SIZE; + + let Some(entrypoint) = program.entrypoint() else { + return Err(Report::msg("invalid program: no entrypoint")); + }; + let library = Library::from_hir(program, globals); + + // Compute the first page boundary after the end of the globals table to use as the start + // of the dynamic heap when the program is executed + let heap_base = + u32::try_from(program.globals().size_in_bytes().next_multiple_of(PAGE_SIZE as usize)) + .expect("unable to allocate dynamic heap: global table too large"); + Ok(Self { + library, + entrypoint, + heap_base, + }) + } + + /// Link this [Program] against the given kernel during assembly + pub fn link_kernel(&mut self, kernel: KernelLibrary) { + self.library.link_kernel(kernel); + } + + /// Link this [Program] against the given library during assembly + pub fn link_library(&mut self, library: CompiledLibrary) { + self.library.link_library(library); + } + + /// Get the set of [CompiledLibrary] this program links against + pub fn link_libraries(&self) -> &[CompiledLibrary] { + self.library.link_libraries() + } + + /// Generate an executable module which when run expects the raw data segment data to be + /// provided on the advice stack in the same order as initialization, and the operands of + /// the entrypoint function on the operand stack. + fn generate_main(&self, entrypoint: FunctionIdent, emit_test_harness: bool) -> Box { + let mut exe = Box::new(Module::new(LibraryNamespace::Exec.into(), ModuleKind::Executable)); + let start_id = FunctionIdent { + module: Ident::with_empty_span(Symbol::intern(LibraryNamespace::EXEC_PATH)), + function: Ident::with_empty_span(Symbol::intern(ProcedureName::MAIN_PROC_NAME)), + }; + let start_sig = Signature::new([], []); + let mut start = Box::new(Function::new(start_id, start_sig)); + { + let body = start.body_mut(); + // Initialize dynamic heap + body.push(Op::PushU32(self.heap_base), SourceSpan::default()); + body.push( + Op::Exec("intrinsics::mem::heap_init".parse().unwrap()), + SourceSpan::default(), + ); + // Initialize data segments from advice stack + self.emit_data_segment_initialization(body); + // Possibly initialize test harness + if emit_test_harness { + self.emit_test_harness(body); + } + // Invoke the program entrypoint + body.push(Op::Exec(entrypoint), SourceSpan::default()); + } + exe.push_back(start); + exe + } + + fn emit_test_harness(&self, block: &mut Block) { + let span = SourceSpan::default(); + + // Advice Stack: [dest_ptr, num_words, ...] + block.push(Op::AdvPush(2), span); // => [num_words, dest_ptr] on operand stack + block.push(Op::Exec("std::mem::pipe_words_to_memory".parse().unwrap()), span); + // Drop the commitment + block.push(Op::Drop, span); + // If we know the stack pointer address, update it to the value of `'write_ptr`, but cast + // into the Rust address space (multiplying it by 16). So a word address of 1, is equal to + // a byte address of 16, because each field element holds 4 bytes, and there are 4 elements + // in a word. + // + // If we don't know the stack pointer, just drop the `'write_ptr` value + if let Some(sp) = self.stack_pointer() { + block.push(Op::U32OverflowingMulImm(16), span); + block.push(Op::Assertz, span); + // Align the stack pointer to a word boundary + let elem_addr = (sp / 4) + (sp % 4 > 0) as u32; + let word_addr = (elem_addr / 4) + (elem_addr % 4 > 0) as u32; + block.push(Op::MemStoreImm(word_addr), span); + } else { + block.push(Op::Drop, span); + } + } + + /// Emit the sequence of instructions necessary to consume rodata from the advice stack and + /// populate the global heap with the data segments of this program, verifying that the + /// commitments match. + fn emit_data_segment_initialization(&self, block: &mut Block) { + // Emit data segment initialization code + // + // NOTE: This depends on the program being executed with the data for all data + // segments having been pushed on the advice stack in the same order as visited + // here, with the same encoding. The program will fail to execute if it is not + // set up correctly. + // + // TODO(pauls): To facilitate automation of this, we should emit a file to disk + // that includes the raw encoding of the data we expect to be placed on the advice + // stack, in a manner which allows us to simply read that file as an array of felt + // and use that directly via `AdviceInputs` + let pipe_preimage_to_memory = "std::mem::pipe_preimage_to_memory".parse().unwrap(); + for segment in self.library.segments.iter() { + // Don't bother emitting anything for zeroed segments + if segment.is_zeroed() { + continue; + } + let size = segment.size(); + let offset = segment.offset(); + let base = NativePtr::from_ptr(offset); + let segment_data = segment.init(); + + // TODO(pauls): Do we ever have a need for data segments which are not aligned + // to an word boundary? If so, we need to implement that + // support when emitting the entry for a program + assert_eq!( + base.offset, + 0, + "unsupported data segment alignment {}: must be aligned to a 32 byte boundary", + base.alignment() + ); + assert_eq!( + base.index, + 0, + "unsupported data segment alignment {}: must be aligned to a 32 byte boundary", + base.alignment() + ); + + // Compute the commitment for the data + let num_elements = size.next_multiple_of(4) / 4; + let num_words = num_elements.next_multiple_of(4) / 4; + let mut elements = Vec::with_capacity(num_elements as usize); + // TODO(pauls): If the word containing the first element overlaps with the + // previous segment, then ensure the overlapping elements + // are mixed together, so that the data is preserved, and + // the commitment is correct + let mut iter = segment_data.as_slice().iter().copied().array_chunks::<4>(); + elements.extend(iter.by_ref().map(|bytes| Felt::new(u32::from_be_bytes(bytes) as u64))); + if let Some(remainder) = iter.into_remainder() { + let mut chunk = [0u8; 4]; + for (i, byte) in remainder.into_iter().enumerate() { + chunk[i] = byte; + } + elements.push(Felt::new(u32::from_be_bytes(chunk) as u64)); + } + elements.resize(num_elements as usize, Felt::ZERO); + let digest = Rpo256::hash_elements(&elements); + let span = SourceSpan::default(); + + // COM + block.push(Op::Pushw(digest.into()), span); + // write_ptr + block.push(Op::PushU32(base.waddr), span); + // num_words + block.push(Op::PushU32(num_words), span); + // [num_words, write_ptr, COM, ..] -> [write_ptr'] + block.push(Op::Exec(pipe_preimage_to_memory), span); + // drop write_ptr' + block.push(Op::Drop, span); + } + } + + /// Get the expected [miden_processor::AdviceInputs] needed to execute this program. + pub fn advice_inputs(&self) -> miden_processor::AdviceInputs { + use miden_processor::AdviceInputs; + + let mut stack = Vec::with_capacity( + self.library + .segments + .iter() + .map(|segment| segment.size() as usize) + .sum::() + / 4, + ); + + let mut current_size = 0usize; + for segment in self.library.segments.iter() { + if segment.is_zeroed() { + continue; + } + let size = segment.size() as usize; + let num_elements = size.next_multiple_of(4) / 4; + let num_words = num_elements.next_multiple_of(4) / 4; + let mut iter = segment.init().as_slice().iter().copied().array_chunks::<4>(); + stack.extend(iter.by_ref().map(|bytes| Felt::new(u32::from_be_bytes(bytes) as u64))); + if let Some(remainder) = iter.into_remainder() { + let mut chunk = [0u8; 4]; + for (i, byte) in remainder.into_iter().enumerate() { + chunk[i] = byte; + } + stack.push(Felt::new(u32::from_be_bytes(chunk) as u64)); } - exe.push_back(start); - modules.insert(exe); + let num_elements_with_padding = num_words * 4; + stack.resize(current_size + num_elements_with_padding, Felt::ZERO); + current_size += num_elements_with_padding; + } + + AdviceInputs::default().with_stack(stack) + } + + #[inline(always)] + pub fn entrypoint(&self) -> FunctionIdent { + self.entrypoint + } + + #[inline(always)] + pub fn stack_pointer(&self) -> Option { + self.library.stack_pointer + } + + /// Freezes this program, preventing further modifications + pub fn freeze(mut self: Box) -> Arc { + self.library.modules.freeze(); + Arc::from(self) + } + + /// Get an iterator over the modules in this program + pub fn modules(&self) -> impl Iterator + '_ { + self.library.modules.iter() + } + + /// Access the frozen module tree of this program, and panic if not frozen + pub fn unwrap_frozen_modules(&self) -> &FrozenModuleTree { + self.library.unwrap_frozen_modules() + } + + /// Insert a module into this program. + /// + /// The insertion order is not preserved - modules are ordered by name. + /// + /// NOTE: This function will panic if the program has been frozen + pub fn insert(&mut self, module: Box) { + self.library.insert(module) + } + + /// Get a reference to a module in this program by name + pub fn get(&self, name: &Q) -> Option<&Module> + where + Q: ?Sized + Ord, + Ident: core::borrow::Borrow, + { + self.library.get(name) + } + + /// Returns true if this program contains a [Module] named `name` + pub fn contains(&self, name: N) -> bool + where + Ident: PartialEq, + { + self.library.contains(name) + } + + /// Write this [Program] to the given output directory. + pub fn write_to_directory>( + &self, + path: P, + session: &Session, + ) -> std::io::Result<()> { + let path = path.as_ref(); + assert!(path.is_dir()); + + self.library.write_to_directory(path, session)?; + + let main = self.generate_main(self.entrypoint, /* test_harness= */ false); + main.write_to_directory(path, session)?; + + Ok(()) + } + + // Assemble this program to MAST + pub fn assemble(&self, session: &Session) -> Result, Report> { + use miden_assembly::{Assembler, CompileOptions}; + + let debug_mode = session.options.emit_debug_decorators(); + + let mut assembler = + Assembler::new(session.source_manager.clone()).with_debug_mode(debug_mode); + + // Link extra libraries + for library in self.library.libraries.iter() { + assembler.add_library(library)?; } - let segments = program.segments().clone(); + // Assemble library + for module in self.library.modules.iter() { + let kind = module.kind; + let module = module.to_ast(debug_mode).map(Box::new)?; + assembler.add_module_with_options( + module, + CompileOptions { + kind, + warnings_as_errors: false, + path: None, + }, + )?; + } + + let emit_test_harness = session.get_flag("test_harness"); + let main = self.generate_main(self.entrypoint, emit_test_harness); + let main = main.to_ast(debug_mode).map(Box::new)?; + assembler.assemble_program(main).map(Arc::new) + } + + pub(crate) fn library(&self) -> &Library { + &self.library + } +} +impl fmt::Display for Program { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.library, f) + } +} + +impl Emit for Program { + fn name(&self) -> Option { + None + } + + fn output_type(&self, _mode: midenc_session::OutputMode) -> midenc_session::OutputType { + midenc_session::OutputType::Masm + } + + fn write_to( + &self, + mut writer: W, + mode: midenc_session::OutputMode, + _session: &Session, + ) -> std::io::Result<()> { + assert_eq!( + mode, + midenc_session::OutputMode::Text, + "binary mode is not supported for masm ir programs" + ); + writer.write_fmt(format_args!("{}\n", self)) + } +} + +/// A [Library] represents a set of modules and its dependencies, which are compiled/assembled +/// together into a single artifact, and then linked into a [Program] for execution at a later +/// time. +/// +/// Modules are stored in a [Library] in a B-tree map, keyed by the module name. This is done to +/// make accessing modules by name efficient, and to ensure a stable ordering for compiled programs +/// when emitted as text. +#[derive(Default, Clone)] +pub struct Library { + /// The set of modules which belong to this program + modules: Modules, + /// The set of libraries to link this program against + libraries: Vec, + /// The kernel library to link against + kernel: Option, + /// The data segment table for this program + pub segments: DataSegmentTable, + /// The address of the `__stack_pointer` global, if such a global has been defined + stack_pointer: Option, +} +impl Library { + /// Create a new, empty [Library] + pub fn empty() -> Self { + Self::default() + } + + /// Create a new [Library] initialized from a [DataSegmentTable] and a set of [Module]s. + /// + /// You should generally prefer to use [Library::from_hir], but this constructor allows you to + /// manually produce a MASM program from its constituent parts. + pub fn new(segments: DataSegmentTable, modules: M) -> Self + where + M: IntoIterator>, + { + let mut module_tree = ModuleTree::default(); + for module in modules { + module_tree.insert(module); + } + let modules = Modules::Open(module_tree); Self { modules, + libraries: vec![], + kernel: None, segments, - entrypoint, + stack_pointer: None, } } - /// Freezes this program, preventing further modifications - pub fn freeze(mut self: Box) -> Arc { + /// Create a new [Library] initialized from an [hir::Program]. + /// + /// The resulting [Library] will have the following: + /// + /// * Data segments described by the original [hir::Program] + /// + /// None of the HIR modules will have been added yet + pub fn from_hir( + program: &hir::Program, + globals: &GlobalVariableAnalysis, + ) -> Self { + let stack_pointer = program.globals().find("__stack_pointer".parse().unwrap()); + let stack_pointer = if let Some(stack_pointer) = stack_pointer { + let global_table_offset = globals.layout().global_table_offset(); + Some(global_table_offset + unsafe { program.globals().offset_of(stack_pointer) }) + } else { + None + }; + Self { + modules: Modules::default(), + libraries: vec![], + kernel: None, + segments: program.segments().clone(), + stack_pointer, + } + } + + /// Link this [Library] against the given kernel during assembly + pub fn link_kernel(&mut self, kernel: KernelLibrary) { + self.kernel = Some(kernel); + } + + /// Link this [Library] against the given library during assembly + pub fn link_library(&mut self, library: CompiledLibrary) { + self.libraries.push(library); + } + + /// Get the set of [CompiledLibrary] this library links against + pub fn link_libraries(&self) -> &[CompiledLibrary] { + self.libraries.as_slice() + } + + /// Freezes this library, preventing further modifications + pub fn freeze(mut self: Box) -> Arc { self.modules.freeze(); Arc::from(self) } - /// Get an iterator over the modules in this program + /// Get an iterator over the modules in this library pub fn modules(&self) -> impl Iterator + '_ { self.modules.iter() } - /// Access the frozen module tree of this program, and panic if not frozen + /// Access the frozen module tree of this library, and panic if not frozen pub fn unwrap_frozen_modules(&self) -> &FrozenModuleTree { match self.modules { Modules::Frozen(ref modules) => modules, @@ -99,7 +527,7 @@ impl Program { } } - /// Insert a module into this program. + /// Insert a module into this library. /// /// The insertion order is not preserved - modules are ordered by name. /// @@ -108,15 +536,7 @@ impl Program { self.modules.insert(module); } - pub fn is_executable(&self) -> bool { - self.entrypoint.is_some() - } - - pub fn is_library(&self) -> bool { - self.entrypoint.is_none() - } - - /// Get a reference to a module in this program by name + /// Get a reference to a module in this library by name pub fn get(&self, name: &Q) -> Option<&Module> where Q: ?Sized + Ord, @@ -125,7 +545,7 @@ impl Program { self.modules.get(name) } - /// Returns true if this program contains a [Module] named `name` + /// Returns true if this library contains a [Module] named `name` pub fn contains(&self, name: N) -> bool where Ident: PartialEq, @@ -133,40 +553,88 @@ impl Program { self.modules.iter().any(|m| m.id == name) } - /// Write this [Program] to the given output directory. - /// - /// The provided [miden_diagnostics::CodeMap] is used for computing source locations. + /// Write this [Library] to the given output directory. pub fn write_to_directory>( &self, - codemap: &miden_diagnostics::CodeMap, path: P, + session: &Session, ) -> std::io::Result<()> { let path = path.as_ref(); assert!(path.is_dir()); for module in self.modules.iter() { - module.write_to_directory(codemap, path)?; + module.write_to_directory(path, session)?; } Ok(()) } + + // Assemble this library to MAST + pub fn assemble(&self, session: &Session) -> Result, Report> { + use miden_assembly::Assembler; + + let debug_mode = session.options.emit_debug_decorators(); + + let mut assembler = + Assembler::new(session.source_manager.clone()).with_debug_mode(debug_mode); + + // Link extra libraries + for library in self.libraries.iter() { + assembler.add_library(library)?; + } + + // Assemble library + let mut modules = Vec::with_capacity(self.modules.len()); + for module in self.modules.iter() { + let module = module.to_ast(debug_mode).map(Box::new)?; + modules.push(module); + } + assembler.assemble_library(modules).map(Arc::new) + } } -impl fmt::Display for Program { +impl fmt::Display for Library { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for module in self.modules.iter() { - if module.name.is_exec_path() { + // Don't print intrinsic modules + if module.id.as_str().starts_with("intrinsics::") { continue; } - writeln!(f, "mod {}\n", &module.name)?; - writeln!(f, "{}", module)?; + if ["intrinsics", "std"].contains(&module.name.namespace().as_str()) { + // Skip printing the standard library modules and intrinsics + // modules to focus on the user-defined modules and avoid the + // stack overflow error when printing large programs + // https://github.com/0xPolygonMiden/miden-formatting/issues/4 + continue; + } else { + writeln!(f, "# mod {}\n", &module.name)?; + writeln!(f, "{}", module)?; + } } + Ok(()) + } +} - if let Some(module) = self.modules.iter().find(|m| m.name.is_exec_path()) { - writeln!(f, "program\n")?; - writeln!(f, "{}", module)?; - } +impl Emit for Library { + fn name(&self) -> Option { + None + } - Ok(()) + fn output_type(&self, _mode: midenc_session::OutputMode) -> midenc_session::OutputType { + midenc_session::OutputType::Masm + } + + fn write_to( + &self, + mut writer: W, + mode: midenc_session::OutputMode, + _session: &Session, + ) -> std::io::Result<()> { + assert_eq!( + mode, + midenc_session::OutputMode::Text, + "binary mode is not supported for masm ir libraries" + ); + writer.write_fmt(format_args!("{}\n", self)) } } diff --git a/codegen/masm/src/masm/region.rs b/codegen/masm/src/masm/region.rs index 02ca85a2..c710469c 100644 --- a/codegen/masm/src/masm/region.rs +++ b/codegen/masm/src/masm/region.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeSet, fmt}; use cranelift_entity::PrimaryMap; use miden_assembly::ast; -use midenc_hir::{formatter::PrettyPrint, FunctionIdent, Ident}; +use midenc_hir::{diagnostics::Span, formatter::PrettyPrint, FunctionIdent, Ident}; use smallvec::smallvec; use super::*; @@ -53,7 +53,7 @@ impl Region { } /// Get the instruction under `ip`, if valid - pub fn get(&self, ip: InstructionPointer) -> Option { + pub fn get(&self, ip: InstructionPointer) -> Option> { self.blocks[ip.block].ops.get(ip.index).copied() } @@ -85,11 +85,10 @@ impl Region { /// local/external function maps to handle calls present in the body of the region. pub fn to_block( &self, - codemap: &miden_diagnostics::CodeMap, imports: &ModuleImportInfo, locals: &BTreeSet, ) -> ast::Block { - emit_block(self.body, &self.blocks, codemap, imports, locals) + emit_block(self.body, &self.blocks, imports, locals) } /// Create a [Region] from a [miden_assembly::ast::CodeBody] and the set of imports @@ -149,11 +148,13 @@ fn import_block( for op in block.iter() { match op { ast::Op::Inst(ix) => { + let span = ix.span(); let current_block = region.block_mut(current_block_id); - let mut ops = Op::from_masm(current_module, (**ix).clone()); - current_block.append(&mut ops); + let ops = Op::from_masm(current_module, (**ix).clone()); + current_block.extend(ops.into_iter().map(|op| Span::new(span, op))); } ast::Op::If { + span, ref then_blk, ref else_blk, .. @@ -162,22 +163,25 @@ fn import_block( let else_blk_id = region.create_block(); import_block(current_module, region, then_blk_id, then_blk); import_block(current_module, region, else_blk_id, else_blk); - region.block_mut(current_block_id).push(Op::If(then_blk_id, else_blk_id)); + region.block_mut(current_block_id).push(Op::If(then_blk_id, else_blk_id), *span); } ast::Op::Repeat { - count, ref body, .. + span, + count, + ref body, + .. } => { let body_blk = region.create_block(); import_block(current_module, region, body_blk, body); let count = u16::try_from(*count).unwrap_or_else(|_| { panic!("invalid repeat count: expected {count} to be less than 255") }); - region.block_mut(current_block_id).push(Op::Repeat(count, body_blk)); + region.block_mut(current_block_id).push(Op::Repeat(count, body_blk), *span); } - ast::Op::While { ref body, .. } => { + ast::Op::While { span, ref body, .. } => { let body_blk = region.create_block(); import_block(current_module, region, body_blk, body); - region.block_mut(current_block_id).push(Op::While(body_blk)); + region.block_mut(current_block_id).push(Op::While(body_blk), *span); } } } @@ -189,34 +193,31 @@ fn import_block( fn emit_block( block_id: BlockId, blocks: &PrimaryMap, - codemap: &miden_diagnostics::CodeMap, imports: &ModuleImportInfo, locals: &BTreeSet, ) -> ast::Block { let current_block = &blocks[block_id]; let mut ops = Vec::with_capacity(current_block.ops.len()); for op in current_block.ops.iter().copied() { - match op { + let span = op.span(); + match op.into_inner() { Op::If(then_blk, else_blk) => { - let then_blk = emit_block(then_blk, blocks, codemap, imports, locals); - let else_blk = emit_block(else_blk, blocks, codemap, imports, locals); + let then_blk = emit_block(then_blk, blocks, imports, locals); + let else_blk = emit_block(else_blk, blocks, imports, locals); ops.push(ast::Op::If { - span: Default::default(), + span, then_blk, else_blk, }); } Op::While(blk) => { - let body = emit_block(blk, blocks, codemap, imports, locals); - ops.push(ast::Op::While { - span: Default::default(), - body, - }); + let body = emit_block(blk, blocks, imports, locals); + ops.push(ast::Op::While { span, body }); } Op::Repeat(n, blk) => { - let body = emit_block(blk, blocks, codemap, imports, locals); + let body = emit_block(blk, blocks, imports, locals); ops.push(ast::Op::Repeat { - span: Default::default(), + span, count: n as u32, body, }); @@ -225,7 +226,7 @@ fn emit_block( ops.extend( op.into_masm(imports, locals) .into_iter() - .map(|inst| ast::Op::Inst(miden_assembly::Span::unknown(inst))), + .map(|inst| ast::Op::Inst(Span::new(span, inst))), ); } } diff --git a/codegen/masm/src/tests.rs b/codegen/masm/src/tests.rs index 9a0830d6..17f0b7b1 100644 --- a/codegen/masm/src/tests.rs +++ b/codegen/masm/src/tests.rs @@ -1,6 +1,8 @@ +#![allow(unused_imports)] use std::{cell::RefCell, sync::Arc}; use midenc_hir::{ + self as hir, pass::{AnalysisManager, ConversionPass}, testing::{self, TestContext}, AbiParam, CallConv, Felt, FieldElement, FunctionIdent, Immediate, InstBuilder, Linkage, @@ -127,7 +129,6 @@ impl TestByEmulationHarness { convert_to_masm .convert(function, &mut analyses, &self.context.session) .map(Box::new) - .map_err(CompilerError::Conversion) } pub fn set_cycle_budget(&mut self, budget: usize) { @@ -285,7 +286,7 @@ fn fib_emulator() { .expect("failed to link program"); let mut compiler = MasmCompiler::new(&harness.context.session); - let program = compiler.compile(program).expect("compilation failed"); + let program = compiler.compile(program).expect("compilation failed").unwrap_executable(); println!("{}", program.get("test").unwrap()); @@ -341,7 +342,7 @@ fn codegen_fundamental_if() { let program = builder.with_entrypoint(id).link().expect("failed to link program"); let mut compiler = MasmCompiler::new(&harness.context.session); - let program = compiler.compile(program).expect("compilation failed"); + let program = compiler.compile(program).expect("compilation failed").unwrap_executable(); let a = Felt::new(3); let b = Felt::new(4); @@ -407,7 +408,7 @@ fn codegen_fundamental_loops() { let program = builder.with_entrypoint(id).link().expect("failed to link program"); let mut compiler = MasmCompiler::new(&harness.context.session); - let program = compiler.compile(program).expect("compilation failed"); + let program = compiler.compile(program).expect("compilation failed").unwrap_executable(); let a = Felt::new(3); let n = Felt::new(4); @@ -438,7 +439,7 @@ fn codegen_sum_matrix() { // Compile let mut compiler = MasmCompiler::new(&harness.context.session); - let program = compiler.compile(program).expect("compilation failed"); + let program = compiler.compile(program).expect("compilation failed").unwrap_executable(); println!("{}", program.get("test").unwrap()); @@ -479,7 +480,7 @@ fn i32_checked_neg() { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -527,7 +528,11 @@ fn codegen_mem_store_sw_load_sw() { let program = builder.with_entrypoint(id).link().expect("failed to link program"); let mut compiler = MasmCompiler::new(&context.session); - let program = compiler.compile(program).expect("compilation failed").freeze(); + let program = compiler + .compile(program) + .expect("compilation failed") + .unwrap_executable() + .freeze(); // eprintln!("{}", program); @@ -556,6 +561,7 @@ fn codegen_mem_store_sw_load_sw() { .unwrap(); } +#[allow(unused)] macro_rules! proptest_unary_numeric_op { ($ty_name:ident :: $op:ident, $ty:ty => $ret:ty, $rust_op:ident) => { proptest_unary_numeric_op_impl!($ty_name :: $op, $ty => $ret, $rust_op, 0..$ty_name::MAX); @@ -566,6 +572,7 @@ macro_rules! proptest_unary_numeric_op { }; } +#[allow(unused)] macro_rules! proptest_unary_numeric_op_impl { ($ty_name:ident :: $op:ident, $ty:ty => $ret:ty, $rust_op:ident, $strategy:expr) => { paste::paste! { @@ -603,7 +610,7 @@ macro_rules! proptest_unary_numeric_op_impl { // Compile let mut compiler = MasmCompiler::new(&harness.context.session); - let program = compiler.compile(program).expect("compilation failed"); + let program = compiler.compile(program).expect("compilation failed").unwrap_executable(); harness .emulator @@ -634,17 +641,18 @@ macro_rules! proptest_unary_numeric_op_impl { }; } -proptest_unary_numeric_op!(u64::clz, u64 => u32, leading_zeros); -proptest_unary_numeric_op!(i128::clz, i128 => u32, leading_zeros); -proptest_unary_numeric_op!(u64::ctz, u64 => u32, trailing_zeros); -proptest_unary_numeric_op!(i128::ctz, i128 => u32, trailing_zeros); -proptest_unary_numeric_op!(u64::clo, u64 => u32, leading_ones); -proptest_unary_numeric_op!(i128::clo, i128 => u32, leading_ones); -proptest_unary_numeric_op!(u64::cto, u64 => u32, trailing_ones); -proptest_unary_numeric_op!(i128::cto, i128 => u32, trailing_ones); -proptest_unary_numeric_op!(u64::ilog2, u64 => u32, ilog2, 1..u64::MAX); -proptest_unary_numeric_op!(i128::ilog2, i128 => u32, ilog2, 1..i128::MAX); +//proptest_unary_numeric_op!(u64::clz, u64 => u32, leading_zeros); +//proptest_unary_numeric_op!(i128::clz, i128 => u32, leading_zeros); +//proptest_unary_numeric_op!(u64::ctz, u64 => u32, trailing_zeros); +//proptest_unary_numeric_op!(i128::ctz, i128 => u32, trailing_zeros); +//proptest_unary_numeric_op!(u64::clo, u64 => u32, leading_ones); +//proptest_unary_numeric_op!(i128::clo, i128 => u32, leading_ones); +//proptest_unary_numeric_op!(u64::cto, u64 => u32, trailing_ones); +//proptest_unary_numeric_op!(i128::cto, i128 => u32, trailing_ones); +//proptest_unary_numeric_op!(u64::ilog2, u64 => u32, ilog2, 1..u64::MAX); +//proptest_unary_numeric_op!(i128::ilog2, i128 => u32, ilog2, 1..i128::MAX); +#[allow(unused)] trait ToCanonicalRepr { fn ir_type() -> Type; fn canonicalize(self) -> SmallVec<[Felt; 4]>; @@ -811,7 +819,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsics module"), ) .freeze(), @@ -871,7 +879,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -895,7 +903,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -927,7 +935,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -959,7 +967,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -993,7 +1001,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -1018,7 +1026,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -1044,7 +1052,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -1069,7 +1077,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), @@ -1095,7 +1103,7 @@ proptest! { .emulator .load_module( Box::new( - intrinsics::load("intrinsics::i32", &harness.context.session.codemap) + intrinsics::load("intrinsics::i32", &harness.context.session.source_manager) .expect("undefined intrinsic module"), ) .freeze(), diff --git a/frontend-wasm/Cargo.toml b/frontend-wasm/Cargo.toml index 7ff73f37..4acd3ed9 100644 --- a/frontend-wasm/Cargo.toml +++ b/frontend-wasm/Cargo.toml @@ -12,24 +12,25 @@ readme.workspace = true edition.workspace = true [dependencies] -miden-core.workspace = true -midenc-hir.workspace = true -midenc-hir-type.workspace = true -miden-diagnostics.workspace = true -thiserror.workspace = true -smallvec.workspace = true -log.workspace = true anyhow.workspace = true -wasmparser = "0.118.1" +addr2line = "0.24" derive_more.workspace = true -indexmap.workspace = true -gimli = { version = "0.28.0", default-features = false, features = [ +gimli = { version = "0.31", default-features = false, features = [ 'read', 'std', ] } +indexmap.workspace = true +log.workspace = true +miden-core.workspace = true +midenc-hir.workspace = true +midenc-hir-type.workspace = true +midenc-session.workspace = true rustc-hash.workspace = true +smallvec.workspace = true +thiserror.workspace = true +wasmparser = "0.214" [dev-dependencies] wat.workspace = true -expect-test = "1.4.1" +expect-test.workspace = true miden-integration-tests.workspace = true diff --git a/frontend-wasm/src/code_translator/mod.rs b/frontend-wasm/src/code_translator/mod.rs index 5e55db02..f7203726 100644 --- a/frontend-wasm/src/code_translator/mod.rs +++ b/frontend-wasm/src/code_translator/mod.rs @@ -13,18 +13,17 @@ //! //! Based on Cranelift's Wasm -> CLIF translator v11.0.0 -use std::collections::hash_map; - -use miden_diagnostics::{DiagnosticsHandler, SourceSpan}; use midenc_hir::{ - cranelift_entity::packed_option::ReservedValue, Block, FieldElement, Immediate, Inst, - InstBuilder, Type, Type::*, Value, + cranelift_entity::packed_option::ReservedValue, + diagnostics::{DiagnosticsHandler, IntoDiagnostic, Report, Severity, SourceSpan}, + Block, FieldElement, Immediate, Inst, InstBuilder, Type, + Type::*, + Value, }; -use rustc_hash::FxHashMap; use wasmparser::{MemArg, Operator}; use crate::{ - error::{WasmError, WasmResult}, + error::WasmResult, intrinsics::{convert_intrinsics_call, is_miden_intrinsics_module}, miden_abi::{is_miden_abi_module, transform::transform_miden_abi_call}, module::{ @@ -57,7 +56,7 @@ pub fn translate_operator( span: SourceSpan, ) -> WasmResult<()> { if !state.reachable { - translate_unreachable_operator(op, builder, state, mod_types, span)?; + translate_unreachable_operator(op, builder, state, mod_types, diagnostics, span)?; return Ok(()); } @@ -85,13 +84,13 @@ pub fn translate_operator( Operator::GlobalGet { global_index } => { let global_index = GlobalIndex::from_u32(*global_index); let name = module.global_name(global_index); - let ty = ir_type(module.globals[global_index].ty)?; + let ty = ir_type(module.globals[global_index].ty, diagnostics)?; state.push1(builder.ins().load_symbol(name.as_str(), ty, span)); } Operator::GlobalSet { global_index } => { let global_index = GlobalIndex::from_u32(*global_index); let name = module.global_name(global_index); - let ty = ir_type(module.globals[global_index].ty)?; + let ty = ir_type(module.globals[global_index].ty, diagnostics)?; let ptr = builder .ins() .symbol_addr(name.as_str(), Ptr(ty.clone().into()), span); @@ -132,9 +131,9 @@ pub fn translate_operator( } Operator::Nop => {} /***************************** Control flow blocks *********************************/ - Operator::Block { blockty } => translate_block(blockty, builder, state, mod_types, span)?, - Operator::Loop { blockty } => translate_loop(blockty, builder, state, mod_types, span)?, - Operator::If { blockty } => translate_if(blockty, state, builder, mod_types, span)?, + Operator::Block { blockty } => translate_block(blockty, builder, state, mod_types, diagnostics, span)?, + Operator::Loop { blockty } => translate_loop(blockty, builder, state, mod_types, diagnostics, span)?, + Operator::If { blockty } => translate_if(blockty, state, builder, mod_types, diagnostics, span)?, Operator::Else => translate_else(state, builder, span)?, Operator::End => translate_end(state, builder, span), @@ -154,12 +153,12 @@ pub fn translate_operator( diagnostics, )?; } - Operator::CallIndirect { type_index: _, table_index: _, table_byte: _ } => { + Operator::CallIndirect { type_index: _, table_index: _ } => { // TODO: } /******************************* Memory management *********************************/ Operator::MemoryGrow { .. } => { - let arg = state.pop1_casted(U32, builder, span); + let arg = state.pop1_bitcasted(U32, builder, span); state.push1(builder.ins().mem_grow(arg, span)); } Operator::MemorySize { .. } => { @@ -510,100 +509,6 @@ pub fn translate_operator( Ok(()) } -fn translate_br_table( - targets: &wasmparser::BrTable<'_>, - state: &mut FuncTranslationState, - builder: &mut FunctionBuilderExt, - span: SourceSpan, -) -> Result<(), WasmError> { - let default = targets.default(); - let mut min_depth = default; - for depth in targets.targets() { - let depth = depth?; - if depth < min_depth { - min_depth = depth; - } - } - let jump_args_count = { - let i = state.control_stack.len() - 1 - (min_depth as usize); - let min_depth_frame = &state.control_stack[i]; - if min_depth_frame.is_loop() { - min_depth_frame.num_param_values() - } else { - min_depth_frame.num_return_values() - } - }; - let val = state.pop1(); - let val = if builder.data_flow_graph().value_type(val) != &U32 { - builder.ins().cast(val, U32, span) - } else { - val - }; - let mut data = Vec::with_capacity(targets.len() as usize); - if jump_args_count == 0 { - // No jump arguments - for depth in targets.targets() { - let depth = depth?; - let block = { - let i = state.control_stack.len() - 1 - (depth as usize); - let frame = &mut state.control_stack[i]; - frame.set_branched_to_exit(); - frame.br_destination() - }; - data.push((depth, block)); - } - let def_block = { - let i = state.control_stack.len() - 1 - (default as usize); - let frame = &mut state.control_stack[i]; - frame.set_branched_to_exit(); - frame.br_destination() - }; - builder.ins().switch(val, data, def_block, span); - } else { - // Here we have jump arguments, but Midens's switch op doesn't support them - // We then proceed to split the edges going out of the br_table - let return_count = jump_args_count; - let mut dest_block_sequence = vec![]; - let mut dest_block_map = FxHashMap::default(); - for depth in targets.targets() { - let depth = depth?; - let branch_block = match dest_block_map.entry(depth as usize) { - hash_map::Entry::Occupied(entry) => *entry.get(), - hash_map::Entry::Vacant(entry) => { - let block = builder.create_block(); - dest_block_sequence.push((depth as usize, block)); - *entry.insert(block) - } - }; - data.push((depth, branch_block)); - } - let default_branch_block = match dest_block_map.entry(default as usize) { - hash_map::Entry::Occupied(entry) => *entry.get(), - hash_map::Entry::Vacant(entry) => { - let block = builder.create_block(); - dest_block_sequence.push((default as usize, block)); - *entry.insert(block) - } - }; - builder.ins().switch(val, data, default_branch_block, span); - for (depth, dest_block) in dest_block_sequence { - builder.switch_to_block(dest_block); - builder.seal_block(dest_block); - let real_dest_block = { - let i = state.control_stack.len() - 1 - depth; - let frame = &mut state.control_stack[i]; - frame.set_branched_to_exit(); - frame.br_destination() - }; - let destination_args = state.peekn_mut(return_count); - builder.ins().br(real_dest_block, destination_args, span); - } - state.popn(return_count); - } - state.reachable = false; - Ok(()) -} - fn translate_load( ptr_ty: Type, memarg: &MemArg, @@ -656,8 +561,16 @@ fn translate_store( ) { let (addr_int, val) = state.pop2(); let val_ty = builder.data_flow_graph().value_type(val); - let arg = if ptr_ty != *val_ty { - builder.ins().trunc(val, ptr_ty.clone(), span) + let arg = if &ptr_ty != val_ty { + if ptr_ty.size_in_bits() == val_ty.size_in_bits() { + builder.ins().bitcast(val, ptr_ty.clone(), span) + } else if ptr_ty.is_unsigned_integer() && val_ty.is_signed_integer() { + let unsigned_val_ty = val_ty.as_unsigned(); + let uval = builder.ins().bitcast(val, unsigned_val_ty, span); + builder.ins().trunc(uval, ptr_ty.clone(), span) + } else { + builder.ins().trunc(val, ptr_ty.clone(), span) + } } else { val }; @@ -673,10 +586,14 @@ fn prepare_addr( span: SourceSpan, ) -> Value { let addr_int_ty = builder.data_flow_graph().value_type(addr_int); - let addr_u32 = if *addr_int_ty == U32 { + let addr_u32 = if addr_int_ty == &U32 { addr_int + } else if addr_int_ty == &I32 { + builder.ins().bitcast(addr_int, U32, span) + } else if matches!(addr_int_ty, Ptr(_)) { + builder.ins().ptrtoint(addr_int, U32, span) } else { - builder.ins().cast(addr_int, U32, span) + panic!("unexpected type used as pointer value: {addr_int_ty}"); }; let mut full_addr_int = addr_u32; if let Some(memarg) = memarg { @@ -688,14 +605,18 @@ fn prepare_addr( } // TODO(pauls): For now, asserting alignment helps us catch mistakes/bugs, but we should // probably make this something that can be disabled to avoid the overhead in release builds - if memarg.align > 1 { + if memarg.align > 0 { // Generate alignment assertion - aligned addresses should always produce 0 here let align_offset = builder.ins().mod_imm_unchecked( full_addr_int, - Immediate::U32(memarg.align as u32), + Immediate::U32(2u32.pow(memarg.align as u32)), + span, + ); + builder.ins().assertz_with_error( + align_offset, + midenc_hir::ASSERT_FAILED_ALIGNMENT, span, ); - builder.ins().assertz(align_offset, span); } }; builder.ins().inttoptr(full_addr_int, Type::Ptr(ptr_ty.clone().into()), span) @@ -842,14 +763,76 @@ fn translate_br_if_args( (br_destination, inputs) } +fn translate_br_table( + br_targets: &wasmparser::BrTable<'_>, + state: &mut FuncTranslationState, + builder: &mut FunctionBuilderExt, + span: SourceSpan, +) -> Result<(), Report> { + let mut targets = Vec::default(); + for depth in br_targets.targets() { + let depth = depth.into_diagnostic()?; + + targets.push(depth); + } + targets.sort(); + + let default_depth = br_targets.default(); + let min_depth = + core::cmp::min(targets.iter().copied().min().unwrap_or(default_depth), default_depth); + + let argc = { + let i = state.control_stack.len() - 1 - (min_depth as usize); + let min_depth_frame = &state.control_stack[i]; + if min_depth_frame.is_loop() { + min_depth_frame.num_param_values() + } else { + min_depth_frame.num_return_values() + } + }; + + let default_block = { + let i = state.control_stack.len() - 1 - (default_depth as usize); + let frame = &mut state.control_stack[i]; + frame.set_branched_to_exit(); + frame.br_destination() + }; + + let val = state.pop1(); + let val = if builder.data_flow_graph().value_type(val) != &U32 { + builder.ins().cast(val, U32, span) + } else { + val + }; + + let switch_builder = builder.ins().switch(val, span); + let switch_builder = + targets.into_iter().enumerate().fold(switch_builder, |acc, (label_idx, depth)| { + let block = { + let i = state.control_stack.len() - 1 - (depth as usize); + let frame = &mut state.control_stack[i]; + frame.set_branched_to_exit(); + frame.br_destination() + }; + let args = state.peekn_mut(argc); + acc.case(label_idx as u32, block, args) + }); + switch_builder.or_else(default_block, state.peekn_mut(argc)); + + state.popn(argc); + state.reachable = false; + Ok(()) +} + fn translate_block( blockty: &wasmparser::BlockType, builder: &mut FunctionBuilderExt, state: &mut FuncTranslationState, mod_types: &ModuleTypes, + diagnostics: &DiagnosticsHandler, span: SourceSpan, ) -> WasmResult<()> { - let blockty = BlockType::from_wasm(blockty, mod_types)?; + let blockty = BlockType::from_wasm(blockty, mod_types, diagnostics)?; let next = builder.create_block_with_params(blockty.results.clone(), span); state.push_block(next, blockty.params.len(), blockty.results.len()); Ok(()) @@ -966,9 +949,10 @@ fn translate_if( state: &mut FuncTranslationState, builder: &mut FunctionBuilderExt, mod_types: &ModuleTypes, + diagnostics: &DiagnosticsHandler, span: SourceSpan, ) -> WasmResult<()> { - let blockty = BlockType::from_wasm(blockty, mod_types)?; + let blockty = BlockType::from_wasm(blockty, mod_types, diagnostics)?; let cond = state.pop1(); // cond is expected to be a i32 value let cond_i1 = builder.ins().neq_imm(cond, Immediate::I32(0), span); @@ -1023,9 +1007,10 @@ fn translate_loop( builder: &mut FunctionBuilderExt, state: &mut FuncTranslationState, mod_types: &ModuleTypes, + diagnostics: &DiagnosticsHandler, span: SourceSpan, ) -> WasmResult<()> { - let blockty = BlockType::from_wasm(blockty, mod_types)?; + let blockty = BlockType::from_wasm(blockty, mod_types, diagnostics)?; let loop_body = builder.create_block_with_params(blockty.params.clone(), span); let next = builder.create_block_with_params(blockty.results.clone(), span); builder.ins().br(loop_body, state.peekn(blockty.params.len()), span); @@ -1044,6 +1029,7 @@ fn translate_unreachable_operator( builder: &mut FunctionBuilderExt, state: &mut FuncTranslationState, mod_types: &ModuleTypes, + diagnostics: &DiagnosticsHandler, span: SourceSpan, ) -> WasmResult<()> { debug_assert!(!state.reachable); @@ -1051,7 +1037,7 @@ fn translate_unreachable_operator( Operator::If { blockty } => { // Push a placeholder control stack entry. The if isn't reachable, // so we don't have any branches anywhere. - let blockty = BlockType::from_wasm(&blockty, mod_types)?; + let blockty = BlockType::from_wasm(&blockty, mod_types, diagnostics)?; state.push_if( Block::reserved_value(), ElseData::NoElse { diff --git a/frontend-wasm/src/code_translator/tests.rs b/frontend-wasm/src/code_translator/tests.rs index 16a04a02..1a982ca5 100644 --- a/frontend-wasm/src/code_translator/tests.rs +++ b/frontend-wasm/src/code_translator/tests.rs @@ -3,11 +3,13 @@ use core::fmt::Write; use expect_test::expect; use midenc_hir::Ident; -use crate::{test_utils::test_diagnostics, translate, WasmTranslationConfig}; +use crate::{test_utils::test_context, translate, WasmTranslationConfig}; /// Check IR generated for a Wasm op(s). /// Wrap Wasm ops in a function and check the IR generated for the entry block of that function. fn check_op(wat_op: &str, expected_ir: expect_test::Expect) { + let context = test_context(); + let wat = format!( r#" (module @@ -18,8 +20,7 @@ fn check_op(wat_op: &str, expected_ir: expect_test::Expect) { )"#, ); let wasm = wat::parse_str(wat).unwrap(); - let diagnostics = test_diagnostics(); - let module = translate(&wasm, &WasmTranslationConfig::default(), &diagnostics) + let module = translate(&wasm, &WasmTranslationConfig::default(), &context.session) .unwrap() .unwrap_one_module(); let func = module.function(Ident::from("test_wrapper")).unwrap(); @@ -54,7 +55,7 @@ fn memory_grow() { "#, expect![[r#" (let (v0 i32) (const.i32 1)) - (let (v1 u32) (cast v0)) + (let (v1 u32) (bitcast v0)) (let (v2 i32) (memory.grow v1)) "#]], ) @@ -86,9 +87,9 @@ fn memory_copy() { (let (v0 i32) (const.i32 20)) (let (v1 i32) (const.i32 10)) (let (v2 i32) (const.i32 1)) - (let (v3 u32) (cast v0)) + (let (v3 u32) (bitcast v0)) (let (v4 (ptr u8)) (inttoptr v3)) - (let (v5 u32) (cast v1)) + (let (v5 u32) (bitcast v1)) (let (v6 (ptr u8)) (inttoptr v5)) (memcpy v6 v4 v2) "#]], @@ -105,7 +106,7 @@ fn i32_load8_u() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) + (let (v1 u32) (bitcast v0)) (let (v2 (ptr u8)) (inttoptr v1)) (let (v3 u8) (load v2)) (let (v4 i32) (zext v3)) @@ -123,10 +124,12 @@ fn i32_load16_u() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) - (let (v2 (ptr u16)) (inttoptr v1)) - (let (v3 u16) (load v2)) - (let (v4 i32) (zext v3)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (mod.unchecked v1 2)) + (assertz 250 v2) + (let (v3 (ptr u16)) (inttoptr v1)) + (let (v4 u16) (load v3)) + (let (v5 i32) (zext v4)) "#]], ) } @@ -141,7 +144,7 @@ fn i32_load8_s() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) + (let (v1 u32) (bitcast v0)) (let (v2 (ptr i8)) (inttoptr v1)) (let (v3 i8) (load v2)) (let (v4 i32) (sext v3)) @@ -159,10 +162,12 @@ fn i32_load16_s() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) - (let (v2 (ptr i16)) (inttoptr v1)) - (let (v3 i16) (load v2)) - (let (v4 i32) (sext v3)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (mod.unchecked v1 2)) + (assertz 250 v2) + (let (v3 (ptr i16)) (inttoptr v1)) + (let (v4 i16) (load v3)) + (let (v5 i32) (sext v4)) "#]], ) } @@ -177,7 +182,7 @@ fn i64_load8_u() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) + (let (v1 u32) (bitcast v0)) (let (v2 (ptr u8)) (inttoptr v1)) (let (v3 u8) (load v2)) (let (v4 i64) (zext v3)) @@ -195,10 +200,12 @@ fn i64_load16_u() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) - (let (v2 (ptr u16)) (inttoptr v1)) - (let (v3 u16) (load v2)) - (let (v4 i64) (zext v3)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (mod.unchecked v1 2)) + (assertz 250 v2) + (let (v3 (ptr u16)) (inttoptr v1)) + (let (v4 u16) (load v3)) + (let (v5 i64) (zext v4)) "#]], ) } @@ -213,7 +220,7 @@ fn i64_load8_s() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) + (let (v1 u32) (bitcast v0)) (let (v2 (ptr i8)) (inttoptr v1)) (let (v3 i8) (load v2)) (let (v4 i64) (sext v3)) @@ -231,10 +238,12 @@ fn i64_load16_s() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) - (let (v2 (ptr i16)) (inttoptr v1)) - (let (v3 i16) (load v2)) - (let (v4 i64) (sext v3)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (mod.unchecked v1 2)) + (assertz 250 v2) + (let (v3 (ptr i16)) (inttoptr v1)) + (let (v4 i16) (load v3)) + (let (v5 i64) (sext v4)) "#]], ) } @@ -249,9 +258,9 @@ fn i64_load32_s() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) - (let (v2 u32) (mod.unchecked v1 2)) - (assertz v2) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (mod.unchecked v1 4)) + (assertz 250 v2) (let (v3 (ptr i32)) (inttoptr v1)) (let (v4 i32) (load v3)) (let (v5 i64) (sext v4)) @@ -269,9 +278,9 @@ fn i64_load32_u() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) - (let (v2 u32) (mod.unchecked v1 2)) - (assertz v2) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (mod.unchecked v1 4)) + (assertz 250 v2) (let (v3 (ptr u32)) (inttoptr v1)) (let (v4 u32) (load v3)) (let (v5 i64) (zext v4)) @@ -289,9 +298,9 @@ fn i32_load() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) - (let (v2 u32) (mod.unchecked v1 2)) - (assertz v2) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (mod.unchecked v1 4)) + (assertz 250 v2) (let (v3 (ptr i32)) (inttoptr v1)) (let (v4 i32) (load v3)) "#]], @@ -308,9 +317,9 @@ fn i64_load() { "#, expect![[r#" (let (v0 i32) (const.i32 1024)) - (let (v1 u32) (cast v0)) - (let (v2 u32) (mod.unchecked v1 3)) - (assertz v2) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (mod.unchecked v1 8)) + (assertz 250 v2) (let (v3 (ptr i64)) (inttoptr v1)) (let (v4 i64) (load v3)) "#]], @@ -328,9 +337,9 @@ fn i32_store() { expect![[r#" (let (v0 i32) (const.i32 1024)) (let (v1 i32) (const.i32 1)) - (let (v2 u32) (cast v0)) - (let (v3 u32) (mod.unchecked v2 2)) - (assertz v3) + (let (v2 u32) (bitcast v0)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) (let (v4 (ptr i32)) (inttoptr v2)) (store v4 v1) "#]], @@ -348,9 +357,9 @@ fn i64_store() { expect![[r#" (let (v0 i32) (const.i32 1024)) (let (v1 i64) (const.i64 1)) - (let (v2 u32) (cast v0)) - (let (v3 u32) (mod.unchecked v2 3)) - (assertz v3) + (let (v2 u32) (bitcast v0)) + (let (v3 u32) (mod.unchecked v2 8)) + (assertz 250 v3) (let (v4 (ptr i64)) (inttoptr v2)) (store v4 v1) "#]], @@ -368,10 +377,11 @@ fn i32_store8() { expect![[r#" (let (v0 i32) (const.i32 1024)) (let (v1 i32) (const.i32 1)) - (let (v2 u8) (trunc v1)) - (let (v3 u32) (cast v0)) - (let (v4 (ptr u8)) (inttoptr v3)) - (store v4 v2) + (let (v2 u32) (bitcast v1)) + (let (v3 u8) (trunc v2)) + (let (v4 u32) (bitcast v0)) + (let (v5 (ptr u8)) (inttoptr v4)) + (store v5 v3) "#]], ) } @@ -387,10 +397,13 @@ fn i32_store16() { expect![[r#" (let (v0 i32) (const.i32 1024)) (let (v1 i32) (const.i32 1)) - (let (v2 u16) (trunc v1)) - (let (v3 u32) (cast v0)) - (let (v4 (ptr u16)) (inttoptr v3)) - (store v4 v2) + (let (v2 u32) (bitcast v1)) + (let (v3 u16) (trunc v2)) + (let (v4 u32) (bitcast v0)) + (let (v5 u32) (mod.unchecked v4 2)) + (assertz 250 v5) + (let (v6 (ptr u16)) (inttoptr v4)) + (store v6 v3) "#]], ) } @@ -406,12 +419,13 @@ fn i64_store32() { expect![[r#" (let (v0 i32) (const.i32 1024)) (let (v1 i64) (const.i64 1)) - (let (v2 u32) (trunc v1)) - (let (v3 u32) (cast v0)) - (let (v4 u32) (mod.unchecked v3 2)) - (assertz v4) - (let (v5 (ptr u32)) (inttoptr v3)) - (store v5 v2) + (let (v2 u64) (bitcast v1)) + (let (v3 u32) (trunc v2)) + (let (v4 u32) (bitcast v0)) + (let (v5 u32) (mod.unchecked v4 4)) + (assertz 250 v5) + (let (v6 (ptr u32)) (inttoptr v4)) + (store v6 v3) "#]], ) } diff --git a/frontend-wasm/src/code_translator/tests_unsupported.rs b/frontend-wasm/src/code_translator/tests_unsupported.rs index 0b546aea..8e981fb8 100644 --- a/frontend-wasm/src/code_translator/tests_unsupported.rs +++ b/frontend-wasm/src/code_translator/tests_unsupported.rs @@ -1,5 +1,4 @@ -use miden_diagnostics::SourceSpan; -use midenc_hir::{CallConv, Linkage, ModuleBuilder, Signature}; +use midenc_hir::{CallConv, Linkage, ModuleBuilder, Signature, SourceSpan}; use wasmparser::{MemArg, Operator, Operator::*}; use super::translate_operator; @@ -10,13 +9,13 @@ use crate::{ module_translation_state::ModuleTranslationState, Module, }, - test_utils::test_diagnostics, + test_utils::test_context, }; fn check_unsupported(op: &Operator) { - let diagnostics = test_diagnostics(); + let context = test_context(); let mod_name = "noname"; - let module_info = Module::new(); + let module_info = Module::default(); let mut module_builder = ModuleBuilder::new(mod_name); let sig = Signature { params: vec![], @@ -29,7 +28,8 @@ fn check_unsupported(op: &Operator) { let mod_types = Default::default(); let mut state = FuncTranslationState::new(); let mut builder_ext = FunctionBuilderExt::new(&mut module_func_builder, &mut fb_ctx); - let mut module_state = ModuleTranslationState::new(&module_info, &mod_types, vec![]); + let mut module_state = + ModuleTranslationState::new(&module_info, &mod_types, vec![], &context.session.diagnostics); let result = translate_operator( op, &mut builder_ext, @@ -37,15 +37,11 @@ fn check_unsupported(op: &Operator) { &mut module_state, &module_info, &mod_types, - &diagnostics, + &context.session.diagnostics, SourceSpan::default(), ); assert!(result.is_err(), "Expected unsupported op error for {:?}", op); - assert_eq!( - result.unwrap_err().to_string(), - format!("Unsupported Wasm: Wasm op {:?} is not supported", op) - ); - assert!(diagnostics.has_errors(), "Expected diagnostics to have errors"); + assert_eq!(result.unwrap_err().to_string(), format!("Wasm op {:?} is not supported", op)); } // Wasm Spec v1.0 diff --git a/frontend-wasm/src/component/build_ir.rs b/frontend-wasm/src/component/build_ir.rs index d2274438..03f8dfbe 100644 --- a/frontend-wasm/src/component/build_ir.rs +++ b/frontend-wasm/src/component/build_ir.rs @@ -1,37 +1,40 @@ -use miden_diagnostics::DiagnosticsHandler; -use wasmparser::WasmFeatures; +use midenc_hir::diagnostics::Report; +use midenc_session::Session; use super::{ inline, translator::ComponentTranslator, ComponentTypesBuilder, LinearComponentTranslation, ParsedRootComponent, }; -use crate::{component::ComponentParser, error::WasmResult, WasmTranslationConfig}; +use crate::{ + component::ComponentParser, error::WasmResult, supported_component_model_features, + WasmTranslationConfig, +}; /// Translate a Wasm component binary into Miden IR component pub fn translate_component( wasm: &[u8], config: &WasmTranslationConfig, - diagnostics: &DiagnosticsHandler, + session: &Session, ) -> WasmResult { - let (mut component_types_builder, parsed_component) = parse(config, wasm, diagnostics)?; + let (mut component_types_builder, parsed_component) = parse(config, wasm, session)?; let linearized_component_translation = inline(&mut component_types_builder, &parsed_component)?; let component_types = component_types_builder.finish(); let parsed_modules = parsed_component.static_modules; - let translator = ComponentTranslator::new(component_types, parsed_modules, config, diagnostics); + let translator = ComponentTranslator::new(component_types, parsed_modules, config, session); translator.translate(linearized_component_translation) } fn parse<'data>( config: &WasmTranslationConfig, wasm: &'data [u8], - diagnostics: &DiagnosticsHandler, -) -> Result<(ComponentTypesBuilder, ParsedRootComponent<'data>), crate::WasmError> { - let wasm_features = WasmFeatures::all(); - let mut validator = wasmparser::Validator::new_with_features(wasm_features); + session: &Session, +) -> Result<(ComponentTypesBuilder, ParsedRootComponent<'data>), Report> { + let mut validator = + wasmparser::Validator::new_with_features(supported_component_model_features()); let mut component_types_builder = Default::default(); let component_parser = - ComponentParser::new(config, &mut validator, &mut component_types_builder); - let parsed_component = component_parser.parse(wasm, diagnostics)?; + ComponentParser::new(config, session, &mut validator, &mut component_types_builder); + let parsed_component = component_parser.parse(wasm)?; Ok((component_types_builder, parsed_component)) } @@ -55,7 +58,7 @@ fn inline( &parsed_component.static_modules, &parsed_component.static_components, ) - .map_err(|e| crate::WasmError::Unsupported(e.to_string()))?; + .map_err(Report::msg)?; Ok(component_dfg.finish()) } @@ -66,9 +69,7 @@ mod tests { use midenc_hir_type::Type; use super::*; - use crate::{ - component::StaticModuleIndex, config::ImportMetadata, test_utils::test_diagnostics, - }; + use crate::{component::StaticModuleIndex, config::ImportMetadata, test_utils::test_context}; #[test] fn translate_simple() { @@ -97,10 +98,10 @@ mod tests { "# .to_string(); let wasm = wat::parse_str(wat).unwrap(); - let diagnostics = test_diagnostics(); + let context = test_context(); let config = Default::default(); let (mut component_types_builder, parsed_component) = - parse(&config, &wasm, &diagnostics).unwrap(); + parse(&config, &wasm, &context.session).unwrap(); let component_translation = inline(&mut component_types_builder, &parsed_component).unwrap(); @@ -119,7 +120,7 @@ mod tests { component_types, parsed_component.static_modules, &config, - &diagnostics, + &context.session, ); let ir = translator.translate(component_translation).unwrap(); @@ -176,7 +177,7 @@ mod tests { ) "#.to_string(); let wasm = wat::parse_str(wat).unwrap(); - let diagnostics = test_diagnostics(); + let context = test_context(); let interface_function_ident = InterfaceFunctionIdent { interface: InterfaceIdent::from_full_ident("miden:add/add@1.0.0".to_string()), function: Symbol::intern("add"), @@ -195,7 +196,7 @@ mod tests { ..Default::default() }; let (mut component_types_builder, parsed_component) = - parse(&config, &wasm, &diagnostics).unwrap(); + parse(&config, &wasm, &context.session).unwrap(); let component_translation = inline(&mut component_types_builder, &parsed_component).unwrap(); assert_eq!(parsed_component.static_modules.len(), 1); @@ -224,7 +225,7 @@ mod tests { component_types, parsed_component.static_modules, &config, - &diagnostics, + &context.session, ); let ir = translator.translate(component_translation).unwrap(); diff --git a/frontend-wasm/src/component/info.rs b/frontend-wasm/src/component/info.rs index 3e4126c4..5cf0e4c5 100644 --- a/frontend-wasm/src/component/info.rs +++ b/frontend-wasm/src/component/info.rs @@ -61,6 +61,7 @@ pub struct LinearComponentTranslation { /// NB: Lots of the component model is not yet implemented in the runtime so /// this is going to undergo a lot of churn. #[derive(Default, Debug)] +#[allow(dead_code)] pub struct LinearComponent { /// A list of typed values that this component imports. /// @@ -213,6 +214,7 @@ pub enum GlobalInitializer { /// Declares a new defined resource within this component. /// /// Contains information about the destructor, for example. + #[allow(dead_code)] Resource(Resource), } @@ -223,6 +225,7 @@ pub struct ExtractMemory { /// The index of the memory being defined. pub index: RuntimeMemoryIndex, /// Where this memory is being extracted from. + #[allow(dead_code)] pub export: CoreExport, } @@ -260,6 +263,7 @@ pub enum InstantiateModule { /// This is similar to `Upvar` but notably the imports are provided as a /// two-level named map since import resolution order needs to happen at /// runtime. + #[allow(dead_code)] Import(RuntimeImportIndex, IndexMap>), } @@ -357,14 +361,17 @@ pub enum Export { options: CanonicalOptions, }, /// A module defined within this component is exported. + #[allow(dead_code)] ModuleStatic(StaticModuleIndex), /// A module imported into this component is exported. + #[allow(dead_code)] ModuleImport(RuntimeImportIndex), /// A nested instance is being exported which has recursively defined /// `Export` items. Instance(IndexMap), /// An exported type from a component or instance, currently only /// informational. + #[allow(dead_code)] Type(TypeDef), } @@ -372,12 +379,14 @@ pub enum Export { #[derive(Debug, Clone)] pub struct CanonicalOptions { /// The component instance that this bundle was associated with. + #[allow(dead_code)] pub instance: RuntimeComponentInstanceIndex, /// The encoding used for strings. pub string_encoding: StringEncoding, /// The memory used by these options, if specified. + #[allow(dead_code)] pub memory: Option, /// The realloc function used by these options, if specified. @@ -403,6 +412,7 @@ pub enum StringEncoding { /// This will have the effect of initializing runtime state for this resource, /// namely the destructor is fetched and stored. #[derive(Debug)] +#[allow(dead_code)] pub struct Resource { /// The local index of the resource being defined. pub index: DefinedResourceIndex, @@ -442,12 +452,15 @@ pub enum Trampoline { /// A `resource.new` intrinsic which will inject a new resource into the /// table specified. + #[allow(dead_code)] ResourceNew(TypeResourceTableIndex), /// Same as `ResourceNew`, but for the `resource.rep` intrinsic. + #[allow(dead_code)] ResourceRep(TypeResourceTableIndex), /// Same as `ResourceNew`, but for the `resource.drop` intrinsic. + #[allow(dead_code)] ResourceDrop(TypeResourceTableIndex), /// An intrinsic used by FACT-generated modules which will transfer an owned diff --git a/frontend-wasm/src/component/parser.rs b/frontend-wasm/src/component/parser.rs index 4590e750..a0600249 100644 --- a/frontend-wasm/src/component/parser.rs +++ b/frontend-wasm/src/component/parser.rs @@ -6,8 +6,11 @@ use std::{collections::HashMap, mem}; use indexmap::IndexMap; -use miden_diagnostics::DiagnosticsHandler; -use midenc_hir::cranelift_entity::PrimaryMap; +use midenc_hir::{ + cranelift_entity::PrimaryMap, + diagnostics::{IntoDiagnostic, Severity}, +}; +use midenc_session::Session; use rustc_hash::FxHashMap; use wasmparser::{ types::{ @@ -28,7 +31,7 @@ use crate::{ }, }, translation_utils::BuildFxHasher, - unsupported_diag, WasmError, WasmTranslationConfig, + unsupported_diag, WasmTranslationConfig, }; /// Structure used to parse a Wasm component @@ -36,6 +39,9 @@ pub struct ComponentParser<'a, 'data> { /// Configuration options for the translation. config: &'a WasmTranslationConfig, + /// The current compilation session + session: &'a Session, + /// The current component being parsed. /// /// This will get swapped out as parsing traverses the body of a @@ -285,11 +291,13 @@ impl<'a, 'data> ComponentParser<'a, 'data> { /// Creates a new parsing state ready to parse a component. pub fn new( config: &'a WasmTranslationConfig, + session: &'a Session, validator: &'a mut Validator, types: &'a mut ComponentTypesBuilder, ) -> Self { Self { config, + session, result: ParsedComponent::default(), validator, types, @@ -301,14 +309,10 @@ impl<'a, 'data> ComponentParser<'a, 'data> { } /// Parses the given the Wasm component - pub fn parse( - mut self, - component: &'data [u8], - diagnostics: &DiagnosticsHandler, - ) -> Result, crate::WasmError> { + pub fn parse(mut self, component: &'data [u8]) -> WasmResult> { let mut remaining = component; loop { - let payload = match self.parser.parse(remaining, true)? { + let payload = match self.parser.parse(remaining, true).into_diagnostic()? { Chunk::Parsed { payload, consumed } => { remaining = &remaining[consumed..]; payload @@ -316,7 +320,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> { Chunk::NeedMoreData(_) => unreachable!(), }; - match self.parse_payload(payload, component, diagnostics)? { + match self.parse_payload(payload, component)? { Action::KeepGoing => {} Action::Skip(n) => remaining = &remaining[n..], Action::Done => break, @@ -337,7 +341,6 @@ impl<'a, 'data> ComponentParser<'a, 'data> { &mut self, payload: Payload<'data>, component: &'data [u8], - diagnostics: &DiagnosticsHandler, ) -> WasmResult { match payload { Payload::Version { @@ -345,7 +348,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> { encoding, range, } => { - self.validator.version(num, encoding, &range)?; + self.validator.version(num, encoding, &range).into_diagnostic()?; match encoding { Encoding::Component => {} @@ -356,7 +359,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> { } Payload::End(offset) => { assert!(self.result.types.is_none()); - self.result.types = Some(self.validator.end(offset)?); + self.result.types = Some(self.validator.end(offset).into_diagnostic()?); // Exit the current lexical scope. If there is no parent (no // frame currently on the stack) then parsing is finished. // Otherwise that means that a nested component has been @@ -377,20 +380,31 @@ impl<'a, 'data> ComponentParser<'a, 'data> { .push(LocalInitializer::ComponentStatic(static_idx, closure_args)); } Payload::ComponentTypeSection(s) => self.component_type_section(s)?, - Payload::CoreTypeSection(s) => self.validator.core_type_section(&s)?, + Payload::CoreTypeSection(s) => { + self.validator.core_type_section(&s).into_diagnostic()? + } Payload::ComponentImportSection(s) => self.component_import_section(s)?, Payload::ComponentCanonicalSection(s) => self.component_canonical_section(s)?, - Payload::ModuleSection { parser, range } => { - self.module_section(range.clone(), parser, component, diagnostics)?; + Payload::ModuleSection { + parser, + unchecked_range: range, + } => { + self.module_section(range.clone(), parser, component)?; return Ok(Action::Skip(range.end - range.start)); } - Payload::ComponentSection { parser, range } => self.component_section(range, parser)?, + Payload::ComponentSection { + parser, + unchecked_range: range, + } => self.component_section(range, parser)?, Payload::InstanceSection(s) => self.core_instance_section(s)?, Payload::ComponentInstanceSection(s) => self.component_instance_section(s)?, Payload::ComponentExportSection(s) => self.component_export_section(s)?, Payload::ComponentStartSection { start, range } => { - self.validator.component_start_section(&start, &range)?; - unsupported_diag!(diagnostics, "component start section is not supported"); + self.validator.component_start_section(&start, &range).into_diagnostic()?; + unsupported_diag!( + &self.session.diagnostics, + "component start section is not supported" + ); } Payload::ComponentAliasSection(s) => self.component_alias_section(s)?, // All custom sections are ignored at this time. @@ -402,8 +416,8 @@ impl<'a, 'data> ComponentParser<'a, 'data> { // if it gets past validation provide a helpful error message to // debug. other => { - self.validator.payload(&other)?; - unsupported_diag!(diagnostics, "unsupported section {other:?}"); + self.validator.payload(&other).into_diagnostic()?; + unsupported_diag!(&self.session.diagnostics, "unsupported section {other:?}"); } } @@ -413,7 +427,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> { fn component_type_section( &mut self, s: wasmparser::ComponentTypeSectionReader<'data>, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { // When we see a type section the types are validated and then parsed. // Each active type definition is recorded in the // `ComponentTypesBuilder` tables, or this component's active scope. @@ -422,10 +436,10 @@ impl<'a, 'data> ComponentParser<'a, 'data> { // `Version` and `End` since multiple type sections can appear within a // component. let mut component_type_index = self.validator.types(0).unwrap().component_type_count(); - self.validator.component_type_section(&s)?; + self.validator.component_type_section(&s).into_diagnostic()?; let types = self.validator.types(0).unwrap(); for ty in s { - match ty? { + match ty.into_diagnostic()? { wasmparser::ComponentType::Resource { rep, dtor } => { let rep = convert_valtype(rep); let id = types.component_any_type_at(component_type_index).unwrap_resource(); @@ -448,13 +462,13 @@ impl<'a, 'data> ComponentParser<'a, 'data> { fn component_import_section( &mut self, s: wasmparser::ComponentImportSectionReader<'data>, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { // Processing the import section at this point is relatively simple // which is to simply record the name of the import and the type // information associated with it. - self.validator.component_import_section(&s)?; + self.validator.component_import_section(&s).into_diagnostic()?; for import in s { - let import = import?; + let import = import.into_diagnostic()?; let types = self.validator.types(0).unwrap(); let ty = types.component_entity_type_of_import(import.name.0).unwrap(); self.result.initializers.push(LocalInitializer::Import(import.name, ty)); @@ -465,14 +479,14 @@ impl<'a, 'data> ComponentParser<'a, 'data> { fn component_canonical_section( &mut self, s: wasmparser::ComponentCanonicalSectionReader<'data>, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { // Entries in the canonical section will get initializers recorded // with the listed options for lifting/lowering. let mut core_func_index = self.validator.types(0).unwrap().function_count(); - self.validator.component_canonical_section(&s)?; + self.validator.component_canonical_section(&s).into_diagnostic()?; for func in s { let types = self.validator.types(0).unwrap(); - let init = match func? { + let init = match func.into_diagnostic()? { wasmparser::CanonicalFunction::Lift { type_index, core_func_index, @@ -529,8 +543,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> { range: std::ops::Range, parser: Parser, component: &'data [u8], - diagnostics: &DiagnosticsHandler, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { // Core wasm modules are parsed inline directly here with the // `ModuleEnvironment` from core wasm compilation. This will return // to the caller the size of the module so it knows how many bytes @@ -539,13 +552,13 @@ impl<'a, 'data> ComponentParser<'a, 'data> { // Note that this is just initial type parsing of the core wasm // module and actual function translation is deferred until this // entire process has completed. - self.validator.module_section(&range)?; + self.validator.module_section(&range).into_diagnostic()?; let parsed_module = ModuleEnvironment::new( self.config, self.validator, self.types.module_types_builder_mut(), ) - .parse(parser, &component[range.start..range.end], diagnostics)?; + .parse(parser, &component[range.start..range.end], &self.session.diagnostics)?; let static_idx = self.static_modules.push(parsed_module); self.result.initializers.push(LocalInitializer::ModuleStatic(static_idx)); // Set a fallback name for the newly added parsed module to be used if @@ -562,7 +575,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> { &mut self, range: std::ops::Range, parser: Parser, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { // When a sub-component is found then the current parsing state // is pushed onto the `lexical_scopes` stack. This will subsequently // get popped as part of `Payload::End` processing above. @@ -571,7 +584,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> { // starts empty since it will only get populated if parsing of // the nested component ends up aliasing some outer module or // component. - self.validator.component_section(&range)?; + self.validator.component_section(&range).into_diagnostic()?; self.lexical_scopes.push(LexicalScope { parser: mem::replace(&mut self.parser, parser), parsed_component: mem::take(&mut self.result), @@ -583,14 +596,14 @@ impl<'a, 'data> ComponentParser<'a, 'data> { fn core_instance_section( &mut self, s: wasmparser::InstanceSectionReader<'data>, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { // Both core wasm instances and component instances record // initializers of what form of instantiation is performed which // largely just records the arguments given from wasmparser into a // `HashMap` for processing later during inlining. - self.validator.instance_section(&s)?; + self.validator.instance_section(&s).into_diagnostic()?; for instance in s { - let init = match instance? { + let init = match instance.into_diagnostic()? { wasmparser::Instance::Instantiate { module_index, args } => { let index = ModuleIndex::from_u32(module_index); instantiate_module(index, &args) @@ -607,11 +620,11 @@ impl<'a, 'data> ComponentParser<'a, 'data> { fn component_instance_section( &mut self, s: wasmparser::ComponentInstanceSectionReader<'data>, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { let mut index = self.validator.types(0).unwrap().component_instance_count(); - self.validator.component_instance_section(&s)?; + self.validator.component_instance_section(&s).into_diagnostic()?; for instance in s { - let init = match instance? { + let init = match instance.into_diagnostic()? { wasmparser::ComponentInstance::Instantiate { component_index, args, @@ -634,15 +647,15 @@ impl<'a, 'data> ComponentParser<'a, 'data> { fn component_export_section( &mut self, s: wasmparser::ComponentExportSectionReader<'data>, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { // Exports don't actually fill out the `initializers` array but // instead fill out the one other field in a `ParsedComponent`, the // `exports` field (as one might imagine). This for now simply // records the index of what's exported and that's tracked further // later during inlining. - self.validator.component_export_section(&s)?; + self.validator.component_export_section(&s).into_diagnostic()?; for export in s { - let export = export?; + let export = export.into_diagnostic()?; let item = self.kind_to_item(export.kind, export.index)?; let prev = self.result.exports.insert(export.name.0, item); assert!(prev.is_none()); @@ -654,13 +667,13 @@ impl<'a, 'data> ComponentParser<'a, 'data> { fn component_alias_section( &mut self, s: wasmparser::ComponentAliasSectionReader<'data>, - ) -> Result<(), crate::WasmError> { + ) -> WasmResult<()> { // Aliases of instance exports (either core or component) will be // recorded as an initializer of the appropriate type with outer // aliases handled specially via upvars and type processing. - self.validator.component_alias_section(&s)?; + self.validator.component_alias_section(&s).into_diagnostic()?; for alias in s { - let init = match alias? { + let init = match alias.into_diagnostic()? { wasmparser::ComponentAlias::InstanceExport { kind: _, instance_index, @@ -742,9 +755,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> { ComponentItem::Component(index) } wasmparser::ComponentExternalKind::Value => { - return Err(WasmError::Unsupported( - "component values are not supported".to_string(), - )); + unsupported_diag!(&self.session.diagnostics, "component values are not supported"); } wasmparser::ComponentExternalKind::Type => { let types = self.validator.types(0).unwrap(); diff --git a/frontend-wasm/src/component/translator.rs b/frontend-wasm/src/component/translator.rs index af62d16e..e28ad058 100644 --- a/frontend-wasm/src/component/translator.rs +++ b/frontend-wasm/src/component/translator.rs @@ -1,9 +1,10 @@ -use miden_diagnostics::DiagnosticsHandler; use midenc_hir::{ - cranelift_entity::PrimaryMap, CanonAbiImport, ComponentBuilder, ComponentExport, FunctionIdent, - FunctionType, Ident, InterfaceFunctionIdent, InterfaceIdent, Symbol, + cranelift_entity::PrimaryMap, diagnostics::Severity, CanonAbiImport, ComponentBuilder, + ComponentExport, FunctionIdent, FunctionType, Ident, InterfaceFunctionIdent, InterfaceIdent, + Symbol, }; use midenc_hir_type::Abi; +use midenc_session::Session; use rustc_hash::FxHashMap; use super::{ @@ -23,7 +24,7 @@ use crate::{ types::{EntityIndex, FuncIndex}, Module, ModuleImport, }, - WasmError, WasmTranslationConfig, + unsupported_diag, WasmTranslationConfig, }; /// A translator from the linearized Wasm component model to the Miden IR component @@ -42,7 +43,7 @@ pub struct ComponentTranslator<'a, 'data> { reallocs: FxHashMap, /// The post return functions used in CanonicalOptions in this component post_returns: FxHashMap, - diagnostics: &'a DiagnosticsHandler, + session: &'a Session, } impl<'a, 'data> ComponentTranslator<'a, 'data> { @@ -50,13 +51,13 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { component_types: ComponentTypes, parsed_modules: PrimaryMap>, config: &'a WasmTranslationConfig, - diagnostics: &'a DiagnosticsHandler, + session: &'a Session, ) -> Self { Self { component_types, parsed_modules, config, - diagnostics, + session, module_instances_source: PrimaryMap::new(), lower_imports: FxHashMap::default(), reallocs: FxHashMap::default(), @@ -70,7 +71,7 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { wasm_translation: LinearComponentTranslation, ) -> WasmResult { let mut component_builder: midenc_hir::ComponentBuilder<'a> = - midenc_hir::ComponentBuilder::new(self.diagnostics); + midenc_hir::ComponentBuilder::new(&self.session.diagnostics); dbg!(&wasm_translation.component.initializers); for initializer in &wasm_translation.component.initializers { match initializer { @@ -89,9 +90,10 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { } GlobalInitializer::ExtractMemory(mem) => { if mem.index.as_u32() > 0 { - return Err(WasmError::Unsupported( - "Only one memory is supported in the component".to_string(), - )); + unsupported_diag!( + &self.session.diagnostics, + "only one memory is supported in the component" + ); } } GlobalInitializer::ExtractRealloc(realloc) => { @@ -103,9 +105,10 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { self.post_returns.insert(post_return.index, func_id); } GlobalInitializer::Resource(_) => { - return Err(WasmError::Unsupported( - "Resource global initializers are not yet supported".to_string(), - )) + unsupported_diag!( + &self.session.diagnostics, + "resource global initializers are not yet supported" + ); } } } @@ -121,15 +124,16 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { instantiate_module: &InstantiateModule, component_builder: &mut ComponentBuilder<'_>, wasm_translation: &LinearComponentTranslation, - ) -> Result<(), WasmError> { + ) -> WasmResult<()> { match instantiate_module { InstantiateModule::Static(static_module_idx, args) => { if self.module_instances_source.values().any(|idx| *idx == *static_module_idx) { - return Err(WasmError::Unsupported(format!( + unsupported_diag!( + &self.session.diagnostics, "A module with a static index {} is already instantiated. We don't \ support multiple instantiations of the same module.", static_module_idx.as_u32() - ))); + ); } self.module_instances_source.push(*static_module_idx); // TODO: create and init module instance tables @@ -142,9 +146,10 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { module_args.push(self.module_arg_from_export(export)?); } CoreDef::InstanceFlags(_) => { - return Err(WasmError::Unsupported( - "Wasm component instance flags are not supported".to_string(), - )) + unsupported_diag!( + &self.session.diagnostics, + "Wasm component instance flags are not supported" + ); } CoreDef::Trampoline(trampoline_idx) => { let trampoline = &wasm_translation.trampolines[*trampoline_idx]; @@ -160,21 +165,26 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { } } let module_types = self.component_types.module_types(); - let mut module_state = - ModuleTranslationState::new(module, module_types, module_args); + let mut module_state = ModuleTranslationState::new( + module, + module_types, + module_args, + &self.session.diagnostics, + ); let ir_module = build_ir_module( self.parsed_modules.get_mut(*static_module_idx).unwrap(), module_types, &mut module_state, self.config, - self.diagnostics, + self.session, )?; component_builder.add_module(ir_module.into()).expect("module is already added"); } InstantiateModule::Import(..) => { - return Err(WasmError::Unsupported( - "Imported Wasm core module instantiation is not supported".to_string(), - )) + unsupported_diag!( + &self.session.diagnostics, + "Imported Wasm core module instantiation is not supported" + ); } }; Ok(()) @@ -188,7 +198,7 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { idx: usize, wasm_component: &LinearComponent, component_builder: &mut ComponentBuilder<'_>, - ) -> Result { + ) -> WasmResult { match trampoline { Trampoline::LowerImport { index, @@ -203,9 +213,11 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { component_builder.add_import(function_id, component_import.clone()); Ok(ModuleArgument::ComponentImport(component_import)) } - _ => Err(WasmError::Unsupported(format!( - "Not yet implemented trampoline type {trampoline:?}" - ))), + _ => unsupported_diag!( + &self.session.diagnostics, + "Not yet implemented trampoline type {:?}", + trampoline + ), } } @@ -232,13 +244,15 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { EntityIndex::Memory(_) => { unreachable!("Attempt to export memory from a module instance. ") } - EntityIndex::Global(_) => Err(WasmError::Unsupported( - "Exporting of core module globals are not yet supported".to_string(), - )), + EntityIndex::Global(_) => unsupported_diag!( + &self.session.diagnostics, + "Exporting of core module globals are not yet supported" + ), }, - ExportItem::Name(_) => Err(WasmError::Unsupported( - "Named core module exports are not yet supported".to_string(), - )), + ExportItem::Name(_) => unsupported_diag!( + &self.session.diagnostics, + "Named core module exports are not yet supported" + ), } } @@ -252,9 +266,7 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { ) -> WasmResult { let (import_idx, import_names) = &wasm_component.imports[runtime_import_index]; if import_names.len() != 1 { - return Err(crate::WasmError::Unsupported( - "multi-name imports not supported".to_string(), - )); + unsupported_diag!(&self.session.diagnostics, "multi-name imports not supported"); } let import_func_name = import_names.first().unwrap(); let (full_interface_name, _) = wasm_component.import_types[*import_idx].clone(); @@ -263,10 +275,15 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { function: Symbol::intern(import_func_name), }; let Some(import_metadata) = self.config.import_metadata.get(&interface_function) else { - return Err(crate::WasmError::MissingImportMetadata(format!( - "Import metadata for interface function {:?} not found", - &interface_function, - ))); + return Err(self + .session + .diagnostics + .diagnostic(Severity::Error) + .with_message(format!( + "wasm error: import metadata for interface function {interface_function:?} \ + not found" + )) + .into_report()); }; let lifted_func_ty = convert_lifted_func_ty(&signature, &self.component_types); @@ -301,11 +318,15 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { Ok(()) } Export::ModuleStatic(_) => { - Err(WasmError::Unsupported("Static module exports are not supported".to_string())) + unsupported_diag!( + &self.session.diagnostics, + "Static module exports are not supported" + ); } - Export::ModuleImport(_) => Err(WasmError::Unsupported( - "Exporting of an imported module is not supported".to_string(), - )), + Export::ModuleImport(_) => unsupported_diag!( + &self.session.diagnostics, + "Exporting of an imported module is not supported" + ), Export::Type(_) => { // Besides the function exports the individual type are also exported from the // component We can ignore them for now @@ -342,15 +363,18 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { ExportItem::Index(idx) => match idx { EntityIndex::Function(func_idx) => module.func_name(func_idx), EntityIndex::Table(_) | EntityIndex::Memory(_) | EntityIndex::Global(_) => { - return Err(WasmError::Unsupported(format!( - "Exporting of non-function entity {core_export:?} is not supported" - ))); + unsupported_diag!( + &self.session.diagnostics, + "Exporting of non-function entity {:?} is not supported", + core_export + ); } }, ExportItem::Name(_) => { - return Err(WasmError::Unsupported( - "Named exports are not yet supported".to_string(), - )) + unsupported_diag!( + &self.session.diagnostics, + "Named exports are not yet supported" + ); } }; @@ -360,14 +384,16 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { } } CoreDef::InstanceFlags(_) => { - return Err(WasmError::Unsupported( - "Component instance flags exports are not supported".to_string(), - )) + unsupported_diag!( + &self.session.diagnostics, + "Component instance flags exports are not supported" + ); } CoreDef::Trampoline(_) => { - return Err(WasmError::Unsupported( - "Trampoline core module exports are not supported".to_string(), - )) + unsupported_diag!( + &self.session.diagnostics, + "Trampoline core module exports are not supported" + ); } }) } @@ -377,10 +403,10 @@ impl<'a, 'data> ComponentTranslator<'a, 'data> { options: &CanonicalOptions, ) -> WasmResult { if options.string_encoding != StringEncoding::Utf8 { - return Err(WasmError::Unsupported( + unsupported_diag!( + &self.session.diagnostics, "UTF-8 is expected in CanonicalOptions, string transcoding is not yet supported" - .to_string(), - )); + ); } Ok(midenc_hir::CanonicalOptions { realloc: options.realloc.map(|idx| self.reallocs[&idx]), diff --git a/frontend-wasm/src/component/types/mod.rs b/frontend-wasm/src/component/types/mod.rs index 4531e92c..008608e5 100644 --- a/frontend-wasm/src/component/types/mod.rs +++ b/frontend-wasm/src/component/types/mod.rs @@ -9,10 +9,9 @@ pub mod resources; use core::{hash::Hash, ops::Index}; use anyhow::{bail, Result}; -use indexmap::IndexSet; use midenc_hir::cranelift_entity::{EntityRef, PrimaryMap}; use rustc_hash::FxHashMap; -use wasmparser::{names::KebabString, types}; +use wasmparser::{collections::IndexSet, names::KebabString, types}; use self::resources::ResourcesBuilder; use crate::{ @@ -1030,8 +1029,8 @@ impl From<&wasmparser::PrimitiveValType> for InterfaceType { wasmparser::PrimitiveValType::U32 => InterfaceType::U32, wasmparser::PrimitiveValType::S64 => InterfaceType::S64, wasmparser::PrimitiveValType::U64 => InterfaceType::U64, - wasmparser::PrimitiveValType::Float32 => InterfaceType::Float32, - wasmparser::PrimitiveValType::Float64 => InterfaceType::Float64, + wasmparser::PrimitiveValType::F32 => InterfaceType::Float32, + wasmparser::PrimitiveValType::F64 => InterfaceType::Float64, wasmparser::PrimitiveValType::Char => InterfaceType::Char, wasmparser::PrimitiveValType::String => InterfaceType::String, } diff --git a/frontend-wasm/src/config.rs b/frontend-wasm/src/config.rs index bb3927b7..62e6c171 100644 --- a/frontend-wasm/src/config.rs +++ b/frontend-wasm/src/config.rs @@ -1,4 +1,4 @@ -use alloc::{borrow::Cow, collections::BTreeMap}; +use alloc::{borrow::Cow, collections::BTreeMap, fmt}; use miden_core::crypto::hash::RpoDigest; use midenc_hir::InterfaceFunctionIdent; @@ -6,11 +6,16 @@ use midenc_hir::InterfaceFunctionIdent; /// Represents Miden VM codegen metadata for a function import. /// This struct will have more fields in the future e.g. where the function /// for this MAST hash is located (to be loaded by the VM) -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct ImportMetadata { /// The MAST root hash of the function to be used in codegen pub digest: RpoDigest, } +impl fmt::Debug for ImportMetadata { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_map().entry(&"digest", &self.digest.to_hex()).finish() + } +} /// Configuration for the WASM translation. #[derive(Debug)] @@ -41,7 +46,7 @@ impl Default for WasmTranslationConfig { source_name: Cow::Borrowed("noname"), override_name: None, generate_native_debuginfo: false, - parse_wasm_debuginfo: false, + parse_wasm_debuginfo: true, import_metadata: Default::default(), } } diff --git a/frontend-wasm/src/error.rs b/frontend-wasm/src/error.rs index fdefa99d..a42b399c 100644 --- a/frontend-wasm/src/error.rs +++ b/frontend-wasm/src/error.rs @@ -1,5 +1,7 @@ -use miden_diagnostics::{Diagnostic, ToDiagnostic}; -use midenc_hir::SymbolConflictError; +use midenc_hir::{ + diagnostics::{miette, Diagnostic, Report}, + SymbolConflictError, +}; use thiserror::Error; /// A WebAssembly translation error. @@ -7,13 +9,14 @@ use thiserror::Error; /// When a WebAssembly function can't be translated, one of these error codes will be returned /// to describe the failure. #[allow(missing_docs)] -#[derive(Error, Debug)] +#[derive(Error, Debug, Diagnostic)] pub enum WasmError { /// The input WebAssembly code is invalid. /// /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly /// code. This should never happen for validated WebAssembly code. - #[error("Invalid input WebAssembly code at offset {offset}: {message}")] + #[error("invalid input WebAssembly code at offset {offset}: {message}")] + #[diagnostic()] InvalidWebAssembly { /// A string describing the validation error. message: String, @@ -22,34 +25,33 @@ pub enum WasmError { }, /// A feature used by the WebAssembly code is not supported by the Miden IR. - #[error("Unsupported Wasm: {0}")] + #[error("unsupported WebAssembly code: {0}")] + #[diagnostic()] Unsupported(String), /// Too many functions were declared in a module #[error("Too many declared functions in the module")] + #[diagnostic()] FuncNumLimitExceeded, /// Duplicate symbol names were found in a module - #[error("{0}")] + #[error(transparent)] + #[diagnostic(transparent)] SymbolConflictError(#[from] SymbolConflictError), - /// Unable to translate function to HIR - #[error("Failed to build function. See diagnostics for details")] - InvalidFunctionError, - - /// An unknown error occurred - #[error("Unexpected: {0}")] - Unexpected(String), - - /// An error occurred during IR program linking - #[error("Failed to link module. See diagnostics for details")] - LinkerError(#[from] midenc_hir::LinkerError), - - #[error("Import metadata is missing: {0}")] + #[error("import metadata is missing: {0}")] + #[diagnostic()] MissingImportMetadata(String), - #[error("Export metadata is missing: {0}")] + #[error("export metadata is missing: {0}")] + #[diagnostic()] MissingExportMetadata(String), + + #[error(transparent)] + DwarfError(#[from] gimli::Error), + + #[error(transparent)] + Io(#[from] std::io::Error), } impl From for WasmError { @@ -61,25 +63,17 @@ impl From for WasmError { } } -impl ToDiagnostic for WasmError { - fn to_diagnostic(self) -> Diagnostic { - Diagnostic::error().with_message(self.to_string()) - } -} - /// A convenient alias for a `Result` that uses `WasmError` as the error type. -pub type WasmResult = Result; +pub type WasmResult = Result; /// Emit diagnostics and return an `Err(WasmError::Unsupported(msg))` where `msg` the string built /// by calling `format!` on the arguments to this macro. #[macro_export] macro_rules! unsupported_diag { - ($diagnostics:expr, $($arg:tt)*) => { - let message = format!($($arg)*); - $diagnostics - .diagnostic(miden_diagnostics::Severity::Error) - .with_message(message.clone()) - .emit(); - return Err($crate::error::WasmError::Unsupported(message)); - } + ($diagnostics:expr, $($arg:tt)*) => {{ + return Err($diagnostics + .diagnostic(Severity::Error) + .with_message(format!($($arg)*)) + .into_report()); + }} } diff --git a/frontend-wasm/src/lib.rs b/frontend-wasm/src/lib.rs index d0f87f1e..58c311f6 100644 --- a/frontend-wasm/src/lib.rs +++ b/frontend-wasm/src/lib.rs @@ -22,8 +22,9 @@ mod test_utils; use component::build_ir::translate_component; use error::WasmResult; -use miden_diagnostics::DiagnosticsHandler; +use midenc_session::Session; use module::build_ir::translate_module_as_component; +use wasmparser::WasmFeatures; pub use self::{config::*, error::WasmError}; @@ -32,13 +33,31 @@ pub use self::{config::*, error::WasmError}; pub fn translate( wasm: &[u8], config: &WasmTranslationConfig, - diagnostics: &DiagnosticsHandler, + session: &Session, ) -> WasmResult { if wasm[4..8] == [0x01, 0x00, 0x00, 0x00] { // Wasm core module // see https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md#component-definitions - translate_module_as_component(wasm, config, diagnostics) + translate_module_as_component(wasm, config, session) } else { - translate_component(wasm, config, diagnostics) + translate_component(wasm, config, session) } } + +/// The set of core WebAssembly features which we need to or wish to support +pub(crate) fn supported_features() -> WasmFeatures { + WasmFeatures::BULK_MEMORY + | WasmFeatures::FLOATS + | WasmFeatures::FUNCTION_REFERENCES + | WasmFeatures::MULTI_VALUE + | WasmFeatures::MUTABLE_GLOBAL + | WasmFeatures::SATURATING_FLOAT_TO_INT + | WasmFeatures::SIGN_EXTENSION + | WasmFeatures::TAIL_CALL +} + +/// The extended set of WebAssembly features which are enabled when working with the Wasm Component +/// Model +pub(crate) fn supported_component_model_features() -> WasmFeatures { + supported_features() | WasmFeatures::COMPONENT_MODEL +} diff --git a/frontend-wasm/src/miden_abi/stdlib/crypto/dsa.rs b/frontend-wasm/src/miden_abi/stdlib/crypto/dsa.rs index 2fee4dc5..d786cae2 100644 --- a/frontend-wasm/src/miden_abi/stdlib/crypto/dsa.rs +++ b/frontend-wasm/src/miden_abi/stdlib/crypto/dsa.rs @@ -12,6 +12,6 @@ pub(crate) fn signatures() -> ModuleFunctionTypeMap { RPO_FALCON512_VERIFY, FunctionType::new([Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt], []), ); - m.insert("miden:stdlib/std_crypto_dsa", funcs); + m.insert("std::crypto::dsa::rpo_falcon512", funcs); m } diff --git a/frontend-wasm/src/miden_abi/stdlib/crypto/hashes.rs b/frontend-wasm/src/miden_abi/stdlib/crypto/hashes.rs index 4a1d42fd..83b1dd78 100644 --- a/frontend-wasm/src/miden_abi/stdlib/crypto/hashes.rs +++ b/frontend-wasm/src/miden_abi/stdlib/crypto/hashes.rs @@ -3,31 +3,28 @@ use midenc_hir_type::Type::*; use crate::miden_abi::{FunctionTypeMap, ModuleFunctionTypeMap}; -pub(crate) const BLAKE3_HASH_1TO1: &str = "blake3_hash_1to1"; -pub(crate) const BLAKE3_HASH_2TO1: &str = "blake3_hash_2to1"; +pub(crate) const BLAKE3_HASH_1TO1: &str = "hash_1to1"; +pub(crate) const BLAKE3_HASH_2TO1: &str = "hash_2to1"; pub(crate) fn signatures() -> ModuleFunctionTypeMap { let mut m: ModuleFunctionTypeMap = Default::default(); - let mut crypto: FunctionTypeMap = Default::default(); - crypto.insert( + let mut blake3: FunctionTypeMap = Default::default(); + blake3.insert( BLAKE3_HASH_1TO1, //Accepts and returns a 8 Felt elements FunctionType::new( - [Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt], - [Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt], + [I32, I32, I32, I32, I32, I32, I32, I32], + [I32, I32, I32, I32, I32, I32, I32, I32], ), ); - crypto.insert( + blake3.insert( BLAKE3_HASH_2TO1, // Accepts 16 and returns a 8 Felt elements FunctionType::new( - [ - Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, - Felt, Felt, - ], - [Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt], + [I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32], + [I32, I32, I32, I32, I32, I32, I32, I32], ), ); - m.insert("std::crypto_hashes", crypto); + m.insert("std::crypto::hashes::blake3", blake3); m } diff --git a/frontend-wasm/src/miden_abi/stdlib/mem.rs b/frontend-wasm/src/miden_abi/stdlib/mem.rs index 6441de3a..71c0dc71 100644 --- a/frontend-wasm/src/miden_abi/stdlib/mem.rs +++ b/frontend-wasm/src/miden_abi/stdlib/mem.rs @@ -40,6 +40,6 @@ pub(crate) fn signatures() -> ModuleFunctionTypeMap { ], ), ); - m.insert("miden:stdlib/std_mem", funcs); + m.insert("std::mem", funcs); m } diff --git a/frontend-wasm/src/miden_abi/transform.rs b/frontend-wasm/src/miden_abi/transform.rs index 038c841a..6b67e2dc 100644 --- a/frontend-wasm/src/miden_abi/transform.rs +++ b/frontend-wasm/src/miden_abi/transform.rs @@ -1,5 +1,9 @@ -use miden_diagnostics::DiagnosticsHandler; -use midenc_hir::{FunctionIdent, Immediate, InstBuilder, SourceSpan, Type::*, Value}; +use midenc_hir::{ + diagnostics::{DiagnosticsHandler, SourceSpan}, + FunctionIdent, Immediate, InstBuilder, + Type::*, + Value, +}; use super::{stdlib, tx_kernel}; use crate::module::function_builder_ext::FunctionBuilderExt; @@ -15,20 +19,40 @@ enum TransformStrategy { } /// Get the transformation strategy for a function name -fn get_transform_strategy(function_id: &str) -> TransformStrategy { - match function_id { - tx_kernel::note::GET_INPUTS => TransformStrategy::ListReturn, - tx_kernel::account::ADD_ASSET => TransformStrategy::ReturnViaPointer, - tx_kernel::account::REMOVE_ASSET => TransformStrategy::ReturnViaPointer, - tx_kernel::account::GET_ID => TransformStrategy::NoTransform, - tx_kernel::tx::CREATE_NOTE => TransformStrategy::NoTransform, - stdlib::crypto::hashes::BLAKE3_HASH_1TO1 => TransformStrategy::ReturnViaPointer, - stdlib::crypto::hashes::BLAKE3_HASH_2TO1 => TransformStrategy::ReturnViaPointer, - stdlib::crypto::dsa::RPO_FALCON512_VERIFY => TransformStrategy::NoTransform, - stdlib::mem::PIPE_WORDS_TO_MEMORY => TransformStrategy::ReturnViaPointer, - stdlib::mem::PIPE_DOUBLE_WORDS_TO_MEMORY => TransformStrategy::ReturnViaPointer, - _ => panic!("No transform strategy found for function {}", function_id), +fn get_transform_strategy(module_id: &str, function_id: &str) -> TransformStrategy { + #[allow(clippy::single_match)] + match module_id { + "std::mem" => match function_id { + stdlib::mem::PIPE_WORDS_TO_MEMORY => return TransformStrategy::ReturnViaPointer, + stdlib::mem::PIPE_DOUBLE_WORDS_TO_MEMORY => return TransformStrategy::ReturnViaPointer, + _ => (), + }, + "std::crypto::hashes::blake3" => match function_id { + stdlib::crypto::hashes::BLAKE3_HASH_1TO1 => return TransformStrategy::ReturnViaPointer, + stdlib::crypto::hashes::BLAKE3_HASH_2TO1 => return TransformStrategy::ReturnViaPointer, + _ => (), + }, + "std::crypto::dsa::rpo_falcon512" => match function_id { + stdlib::crypto::dsa::RPO_FALCON512_VERIFY => return TransformStrategy::NoTransform, + _ => (), + }, + "miden::note" => match function_id { + tx_kernel::note::GET_INPUTS => return TransformStrategy::ListReturn, + _ => (), + }, + "miden::account" => match function_id { + tx_kernel::account::ADD_ASSET => return TransformStrategy::ReturnViaPointer, + tx_kernel::account::REMOVE_ASSET => return TransformStrategy::ReturnViaPointer, + tx_kernel::account::GET_ID => return TransformStrategy::NoTransform, + _ => (), + }, + "miden::tx" => match function_id { + tx_kernel::tx::CREATE_NOTE => return TransformStrategy::NoTransform, + _ => (), + }, + _ => (), } + panic!("No transform strategy found for function '{function_id}' in module '{module_id}'"); } /// Transform a function call based on the transformation strategy @@ -40,7 +64,7 @@ pub fn transform_miden_abi_call( diagnostics: &DiagnosticsHandler, ) -> Vec { use TransformStrategy::*; - match get_transform_strategy(func_id.function.as_symbol().as_str()) { + match get_transform_strategy(func_id.module.as_str(), func_id.function.as_str()) { ListReturn => list_return(func_id, args, builder, span, diagnostics), ReturnViaPointer => return_via_pointer(func_id, args, builder, span, diagnostics), NoTransform => no_transform(func_id, args, builder, span, diagnostics), diff --git a/frontend-wasm/src/module/build_ir.rs b/frontend-wasm/src/module/build_ir.rs index 35f10817..61a74172 100644 --- a/frontend-wasm/src/module/build_ir.rs +++ b/frontend-wasm/src/module/build_ir.rs @@ -1,8 +1,11 @@ use core::mem; -use miden_diagnostics::{DiagnosticsHandler, SourceSpan}; -use midenc_hir::{CallConv, ConstantData, Linkage, MidenAbiImport, ModuleBuilder, Symbol}; -use wasmparser::{Validator, WasmFeatures}; +use midenc_hir::{ + diagnostics::{DiagnosticsHandler, IntoDiagnostic, Severity, SourceSpan}, + CallConv, ConstantData, Linkage, MidenAbiImport, ModuleBuilder, Symbol, +}; +use midenc_session::Session; +use wasmparser::Validator; use super::{module_translation_state::ModuleTranslationState, Module}; use crate::{ @@ -14,7 +17,7 @@ use crate::{ module_env::{FunctionBodyData, ModuleEnvironment, ParsedModule}, types::{ir_func_sig, ir_func_type, ir_type, ModuleTypes}, }, - WasmError, WasmTranslationConfig, + WasmTranslationConfig, }; /// Translate a valid Wasm core module binary into Miden IR component building @@ -26,10 +29,9 @@ use crate::{ pub fn translate_module_as_component( wasm: &[u8], config: &WasmTranslationConfig, - diagnostics: &DiagnosticsHandler, + session: &Session, ) -> WasmResult { - let wasm_features = WasmFeatures::default(); - let mut validator = Validator::new_with_features(wasm_features); + let mut validator = Validator::new_with_features(crate::supported_features()); let parser = wasmparser::Parser::new(0); let mut module_types_builder = Default::default(); let mut parsed_module = ModuleEnvironment::new( @@ -37,18 +39,22 @@ pub fn translate_module_as_component( &mut validator, &mut module_types_builder, ) - .parse(parser, wasm, diagnostics)?; + .parse(parser, wasm, &session.diagnostics)?; parsed_module.module.set_name_fallback(config.source_name.clone()); if let Some(name_override) = config.override_name.as_ref() { parsed_module.module.set_name_override(name_override.clone()); } let module_types = module_types_builder.finish(); - let mut module_state = - ModuleTranslationState::new(&parsed_module.module, &module_types, vec![]); + let mut module_state = ModuleTranslationState::new( + &parsed_module.module, + &module_types, + vec![], + &session.diagnostics, + ); let module = - build_ir_module(&mut parsed_module, &module_types, &mut module_state, config, diagnostics)?; - let mut cb = midenc_hir::ComponentBuilder::new(diagnostics); + build_ir_module(&mut parsed_module, &module_types, &mut module_state, config, session)?; + let mut cb = midenc_hir::ComponentBuilder::new(&session.diagnostics); let module_imports = module.imports(); for import_module_id in module_imports.iter_module_names() { if let Some(imports) = module_imports.imported(import_module_id) { @@ -82,12 +88,29 @@ pub fn build_ir_module( module_types: &ModuleTypes, module_state: &mut ModuleTranslationState, _config: &WasmTranslationConfig, - diagnostics: &DiagnosticsHandler, + session: &Session, ) -> WasmResult { let name = parsed_module.module.name(); let mut module_builder = ModuleBuilder::new(name.as_str()); - build_globals(&parsed_module.module, &mut module_builder, diagnostics)?; - build_data_segments(parsed_module, &mut module_builder, diagnostics)?; + build_globals(&parsed_module.module, &mut module_builder, &session.diagnostics)?; + build_data_segments(parsed_module, &mut module_builder, &session.diagnostics)?; + let addr2line = addr2line::Context::from_dwarf(gimli::Dwarf { + debug_abbrev: parsed_module.debuginfo.dwarf.debug_abbrev, + debug_addr: parsed_module.debuginfo.dwarf.debug_addr, + debug_aranges: parsed_module.debuginfo.dwarf.debug_aranges, + debug_info: parsed_module.debuginfo.dwarf.debug_info, + debug_line: parsed_module.debuginfo.dwarf.debug_line, + debug_line_str: parsed_module.debuginfo.dwarf.debug_line_str, + debug_str: parsed_module.debuginfo.dwarf.debug_str, + debug_str_offsets: parsed_module.debuginfo.dwarf.debug_str_offsets, + debug_types: parsed_module.debuginfo.dwarf.debug_types, + locations: parsed_module.debuginfo.dwarf.locations, + ranges: parsed_module.debuginfo.dwarf.ranges, + file_type: parsed_module.debuginfo.dwarf.file_type, + sup: parsed_module.debuginfo.dwarf.sup.clone(), + ..Default::default() + }) + .into_diagnostic()?; let mut func_translator = FuncTranslator::new(); // Although this renders this parsed module invalid(without functiong // bodies), we don't support multiple module instances. Thus, this @@ -98,7 +121,7 @@ pub fn build_ir_module( let func_type = &parsed_module.module.functions[*func_index]; let func_name = &parsed_module.module.func_name(*func_index); let wasm_func_type = module_types[func_type.signature].clone(); - let ir_func_type = ir_func_type(&wasm_func_type)?; + let ir_func_type = ir_func_type(&wasm_func_type, &session.diagnostics)?; let sig = ir_func_sig(&ir_func_type, CallConv::SystemV, Linkage::External); let mut module_func_builder = module_builder.function(func_name.as_str(), sig.clone())?; let FunctionBodyData { validator, body } = body_data; @@ -107,14 +130,13 @@ pub fn build_ir_module( &body, &mut module_func_builder, module_state, - &parsed_module.module, + parsed_module, module_types, - diagnostics, + &addr2line, + session, &mut func_validator, )?; - module_func_builder - .build(diagnostics) - .map_err(|_| WasmError::InvalidFunctionError)?; + module_func_builder.build(&session.diagnostics)?; } let module = module_builder.build(); Ok(*module) @@ -124,7 +146,7 @@ fn build_globals( wasm_module: &Module, module_builder: &mut ModuleBuilder, diagnostics: &DiagnosticsHandler, -) -> Result<(), WasmError> { +) -> WasmResult<()> { for (global_idx, global) in &wasm_module.globals { let global_name = wasm_module .name_section @@ -136,7 +158,7 @@ fn build_globals( let init = ConstantData::from(global_init.to_le_bytes(wasm_module, diagnostics)?); if let Err(e) = module_builder.declare_global_variable( global_name.as_str(), - ir_type(global.ty)?, + ir_type(global.ty, diagnostics)?, Linkage::External, Some(init.clone()), SourceSpan::default(), @@ -146,11 +168,10 @@ fn build_globals( error: {:?}", e ); - diagnostics - .diagnostic(miden_diagnostics::Severity::Error) + return Err(diagnostics + .diagnostic(Severity::Error) .with_message(message.clone()) - .emit(); - return Err(WasmError::Unexpected(message)); + .into_report()); } } Ok(()) @@ -160,7 +181,7 @@ fn build_data_segments( translation: &ParsedModule, module_builder: &mut ModuleBuilder, diagnostics: &DiagnosticsHandler, -) -> Result<(), WasmError> { +) -> WasmResult<()> { for (data_segment_idx, data_segment) in &translation.data_segments { let data_segment_name = translation.module.name_section.data_segment_names[&data_segment_idx]; @@ -174,11 +195,10 @@ fn build_data_segments( '{offset}' with error: {:?}", e ); - diagnostics - .diagnostic(miden_diagnostics::Severity::Error) + return Err(diagnostics + .diagnostic(Severity::Error) .with_message(message.clone()) - .emit(); - return Err(WasmError::Unexpected(message)); + .into_report()); } } Ok(()) diff --git a/frontend-wasm/src/module/func_translation_state.rs b/frontend-wasm/src/module/func_translation_state.rs index ea066a92..1ad78bda 100644 --- a/frontend-wasm/src/module/func_translation_state.rs +++ b/frontend-wasm/src/module/func_translation_state.rs @@ -5,8 +5,7 @@ //! //! Based on Cranelift's Wasm -> CLIF translator v11.0.0 -use miden_diagnostics::SourceSpan; -use midenc_hir::{Block, Inst, InstBuilder, Signature, Value}; +use midenc_hir::{diagnostics::SourceSpan, Block, Inst, InstBuilder, Signature, Value}; use midenc_hir_type::Type; use super::function_builder_ext::FunctionBuilderExt; diff --git a/frontend-wasm/src/module/func_translator.rs b/frontend-wasm/src/module/func_translator.rs index 75228173..1f9177f3 100644 --- a/frontend-wasm/src/module/func_translator.rs +++ b/frontend-wasm/src/module/func_translator.rs @@ -6,17 +6,22 @@ //! //! Based on Cranelift's Wasm -> CLIF translator v11.0.0 -use miden_diagnostics::{DiagnosticsHandler, SourceSpan}; -use midenc_hir::{cranelift_entity::EntityRef, Block, InstBuilder, ModuleFunctionBuilder}; -use wasmparser::{BinaryReader, FuncValidator, FunctionBody, WasmModuleResources}; +use midenc_hir::{ + cranelift_entity::EntityRef, + diagnostics::{DiagnosticsHandler, IntoDiagnostic, SourceManagerExt, SourceSpan}, + Block, InstBuilder, ModuleFunctionBuilder, +}; +use midenc_session::Session; +use wasmparser::{FuncValidator, FunctionBody, WasmModuleResources}; -use super::{module_translation_state::ModuleTranslationState, Module}; +use super::{module_env::ParsedModule, module_translation_state::ModuleTranslationState}; use crate::{ code_translator::translate_operator, error::WasmResult, module::{ func_translation_state::FuncTranslationState, function_builder_ext::{FunctionBuilderContext, FunctionBuilderExt}, + module_env::DwarfReader, types::{convert_valtype, ir_type, ModuleTypes}, }, ssa::Variable, @@ -49,13 +54,12 @@ impl FuncTranslator { body: &FunctionBody<'_>, mod_func_builder: &mut ModuleFunctionBuilder, module_state: &mut ModuleTranslationState, - module: &Module, + module: &ParsedModule<'_>, mod_types: &ModuleTypes, - diagnostics: &DiagnosticsHandler, + addr2line: &addr2line::Context>, + session: &Session, func_validator: &mut FuncValidator, ) -> WasmResult<()> { - let mut reader = body.get_binary_reader(); - let mut builder = FunctionBuilderExt::new(mod_func_builder, &mut self.func_ctx); let entry_block = builder.current_block(); builder.seal_block(entry_block); // Declare all predecessors known. @@ -68,15 +72,26 @@ impl FuncTranslator { builder.append_block_params_for_function_returns(exit_block); self.state.initialize(builder.signature(), exit_block); - parse_local_decls(&mut reader, &mut builder, num_params, func_validator)?; + let mut reader = body.get_locals_reader().into_diagnostic()?; + + parse_local_decls( + &mut reader, + &mut builder, + num_params, + func_validator, + &session.diagnostics, + )?; + + let mut reader = body.get_operators_reader().into_diagnostic()?; parse_function_body( - reader, + &mut reader, &mut builder, &mut self.state, module_state, module, mod_types, - diagnostics, + addr2line, + session, func_validator, )?; @@ -107,20 +122,20 @@ fn declare_parameters(builder: &mut FunctionBuilderExt, entry_block: Block) -> u /// /// Declare local variables, starting from `num_params`. fn parse_local_decls( - reader: &mut BinaryReader, + reader: &mut wasmparser::LocalsReader<'_>, builder: &mut FunctionBuilderExt, num_params: usize, validator: &mut FuncValidator, + diagnostics: &DiagnosticsHandler, ) -> WasmResult<()> { let mut next_local = num_params; - let local_count = reader.read_var_u32()?; + let local_count = reader.get_count(); for _ in 0..local_count { let pos = reader.original_position(); - let count = reader.read_var_u32()?; - let ty = reader.read()?; - validator.define_locals(pos, count, ty)?; - declare_locals(builder, count, ty, &mut next_local)?; + let (count, ty) = reader.read().into_diagnostic()?; + validator.define_locals(pos, count, ty).into_diagnostic()?; + declare_locals(builder, count, ty, &mut next_local, diagnostics)?; } Ok(()) @@ -134,10 +149,11 @@ fn declare_locals( count: u32, wasm_type: wasmparser::ValType, next_local: &mut usize, + diagnostics: &DiagnosticsHandler, ) -> WasmResult<()> { - let ty = ir_type(convert_valtype(wasm_type))?; + let ty = ir_type(convert_valtype(wasm_type), diagnostics)?; // All locals are initialized to 0. - let init = emit_zero(&ty, builder)?; + let init = emit_zero(&ty, builder, diagnostics)?; for _ in 0..count { let local = Variable::new(*next_local); builder.declare_var(local, ty.clone()); @@ -153,35 +169,71 @@ fn declare_locals( /// arguments and locals are declared in the builder. #[allow(clippy::too_many_arguments)] fn parse_function_body( - mut reader: BinaryReader, + reader: &mut wasmparser::OperatorsReader<'_>, builder: &mut FunctionBuilderExt, state: &mut FuncTranslationState, module_state: &mut ModuleTranslationState, - module: &Module, + module: &ParsedModule<'_>, mod_types: &ModuleTypes, - diagnostics: &DiagnosticsHandler, + addr2line: &addr2line::Context>, + session: &Session, func_validator: &mut FuncValidator, ) -> WasmResult<()> { // The control stack is initialized with a single block representing the whole function. debug_assert_eq!(state.control_stack.len(), 1, "State not initialized"); + let mut end_span = SourceSpan::default(); while !reader.eof() { let pos = reader.original_position(); - let op = reader.read_operator()?; - func_validator.op(pos, &op)?; + let (op, offset) = reader.read_with_offset().into_diagnostic()?; + func_validator.op(pos, &op).into_diagnostic()?; + + let offset = (offset as u64) + .checked_sub(module.wasm_file.code_section_offset) + .expect("offset occurs before start of code section"); + let mut span = SourceSpan::default(); + if let Some(loc) = addr2line.find_location(offset).into_diagnostic()? { + if let Some(file) = loc.file { + let path = std::path::Path::new(file); + let path = path.canonicalize().unwrap_or_else(|_| path.to_path_buf()); + if path.exists() { + let source_file = session.source_manager.load_file(&path).into_diagnostic()?; + let line = loc.line.and_then(|line| line.checked_sub(1)).unwrap_or(0); + let column = loc.column.and_then(|col| col.checked_sub(1)).unwrap_or(0); + span = source_file.line_column_to_span(line, column).unwrap_or_default(); + } else { + log::debug!( + "failed to locate span for instruction at offset {offset} in function {}", + builder.id() + ); + } + } + } else { + log::debug!( + "failed to locate span for instruction at offset {offset} in function {}", + builder.id() + ); + } + + // Track the span of every END we observe, so we have a span to assign to the return we + // place in the final exit block + if let wasmparser::Operator::End = op { + end_span = span; + } + translate_operator( &op, builder, state, module_state, - module, + &module.module, mod_types, - diagnostics, - SourceSpan::default(), + &session.diagnostics, + span, )?; } let pos = reader.original_position(); - func_validator.finish(pos)?; + func_validator.finish(pos).into_diagnostic()?; // The final `End` operator left us in the exit block where we need to manually add a return // instruction. @@ -189,7 +241,7 @@ fn parse_function_body( // If the exit block is unreachable, it may not have the correct arguments, so we would // generate a return instruction that doesn't match the signature. if state.reachable && !builder.is_unreachable() { - builder.ins().ret(state.stack.first().cloned(), SourceSpan::default()); + builder.ins().ret(state.stack.first().cloned(), end_span); } // Discard any remaining values on the stack. Either we just returned them, diff --git a/frontend-wasm/src/module/function_builder_ext.rs b/frontend-wasm/src/module/function_builder_ext.rs index 0e548312..f5e41e4c 100644 --- a/frontend-wasm/src/module/function_builder_ext.rs +++ b/frontend-wasm/src/module/function_builder_ext.rs @@ -1,6 +1,6 @@ -use miden_diagnostics::SourceSpan; use midenc_hir::{ cranelift_entity::{EntitySet, SecondaryMap}, + diagnostics::SourceSpan, Block, Br, CondBr, DataFlowGraph, InsertionPoint, Inst, InstBuilderBase, Instruction, ModuleFunctionBuilder, ProgramPoint, Switch, Value, }; @@ -70,6 +70,10 @@ impl<'a, 'b, 'c> FunctionBuilderExt<'a, 'b, 'c> { self.inner.data_flow_graph_mut() } + pub fn id(&self) -> midenc_hir::FunctionIdent { + self.inner.id() + } + pub fn signature(&self) -> &midenc_hir::Signature { self.inner.signature() } @@ -341,22 +345,21 @@ impl<'a, 'b, 'c> FunctionBuilderExt<'a, 'b, 'c> { /// other jump instructions. pub fn change_jump_destination(&mut self, inst: Inst, old_block: Block, new_block: Block) { self.func_ctx.ssa.remove_block_predecessor(old_block, inst); - match self.data_flow_graph_mut().insts[inst].data.item { + match &mut *self.data_flow_graph_mut().insts[inst].data { Instruction::Br(Br { - ref mut destination, - .. - }) if destination == &old_block => { - *destination = new_block; + ref mut successor, .. + }) if successor.destination == old_block => { + successor.destination = new_block; } Instruction::CondBr(CondBr { - then_dest: (ref mut then_dest, _), - else_dest: (ref mut else_dest, _), + ref mut then_dest, + ref mut else_dest, .. }) => { - if then_dest == &old_block { - *then_dest = new_block; - } else if else_dest == &old_block { - *else_dest = new_block; + if then_dest.destination == old_block { + then_dest.destination = new_block; + } else if else_dest.destination == old_block { + else_dest.destination = new_block; } } Instruction::Switch(Switch { @@ -365,13 +368,13 @@ impl<'a, 'b, 'c> FunctionBuilderExt<'a, 'b, 'c> { ref mut arms, ref mut default, }) => { - for (_, ref mut dest_block) in arms { - if dest_block == &old_block { - *dest_block = new_block; + for arm in arms.iter_mut() { + if arm.successor.destination == old_block { + arm.successor.destination = new_block; } } - if default == &old_block { - *default = new_block; + if default.destination == old_block { + default.destination = new_block; } } _ => panic!("{} must be a branch instruction", inst), @@ -445,38 +448,45 @@ impl<'a, 'b, 'c, 'd> InstBuilderBase<'a> for FuncInstBuilderExt<'a, 'b, 'c, 'd> let opcode = data.opcode(); let inst = self.builder.data_flow_graph_mut().insert_inst(self.ip, data, ty, span); - match &self.builder.inner.data_flow_graph().insts[inst].data.item { - Instruction::Br(Br { destination, .. }) => { + match self.builder.inner.data_flow_graph().insts[inst].data.inner() { + Instruction::Br(Br { successor, .. }) => { // If the user has supplied jump arguments we must adapt the arguments of // the destination block - self.builder.func_ctx.ssa.declare_block_predecessor(*destination, inst); + self.builder.func_ctx.ssa.declare_block_predecessor(successor.destination, inst); } Instruction::CondBr(CondBr { - then_dest: (block_then, _), - else_dest: (block_else, _), + then_dest, + else_dest, .. }) => { - self.builder.func_ctx.ssa.declare_block_predecessor(*block_then, inst); - if block_then != block_else { - self.builder.func_ctx.ssa.declare_block_predecessor(*block_else, inst); + self.builder.func_ctx.ssa.declare_block_predecessor(then_dest.destination, inst); + if then_dest.destination != else_dest.destination { + self.builder + .func_ctx + .ssa + .declare_block_predecessor(else_dest.destination, inst); } } Instruction::Switch(Switch { op: _, arg: _, ref arms, - default: _, + default: default_successor, }) => { // Unlike all other jumps/branches, arms are // capable of having the same successor appear // multiple times, so we must deduplicate. let mut unique = EntitySet::::new(); - for (_, dest_block) in arms { - if !unique.insert(*dest_block) { + let blocks = arms + .iter() + .map(|arm| arm.successor.destination) + .chain([default_successor.destination]); + for block in blocks { + if !unique.insert(block) { continue; } - self.builder.func_ctx.ssa.declare_block_predecessor(*dest_block, inst); + self.builder.func_ctx.ssa.declare_block_predecessor(block, inst); } } inst => debug_assert!(!inst.opcode().is_branch()), diff --git a/frontend-wasm/src/module/mod.rs b/frontend-wasm/src/module/mod.rs index 89eeee7f..04bcb621 100644 --- a/frontend-wasm/src/module/mod.rs +++ b/frontend-wasm/src/module/mod.rs @@ -6,9 +6,9 @@ use std::{borrow::Cow, collections::BTreeMap, ops::Range}; use indexmap::IndexMap; -use miden_diagnostics::DiagnosticsHandler; use midenc_hir::{ cranelift_entity::{packed_option::ReservedValue, EntityRef, PrimaryMap}, + diagnostics::{DiagnosticsHandler, Severity}, Ident, Symbol, }; use rustc_hash::FxHashMap; @@ -179,11 +179,6 @@ pub struct ModuleImport { } impl Module { - /// Allocates the module data structures. - pub fn new() -> Self { - Module::default() - } - /// Convert a `DefinedFuncIndex` into a `FuncIndex`. #[inline] pub fn func_index(&self, defined_func: DefinedFuncIndex) -> FuncIndex { diff --git a/frontend-wasm/src/module/module_env.rs b/frontend-wasm/src/module/module_env.rs index f71a13b0..7cd7e45e 100644 --- a/frontend-wasm/src/module/module_env.rs +++ b/frontend-wasm/src/module/module_env.rs @@ -1,14 +1,14 @@ use std::{ops::Range, path::PathBuf, sync::Arc}; -use miden_diagnostics::DiagnosticsHandler; use midenc_hir::{ cranelift_entity::{packed_option::ReservedValue, PrimaryMap}, + diagnostics::{DiagnosticsHandler, IntoDiagnostic, Report, Severity}, Ident, Symbol, }; use wasmparser::{ - types::CoreTypeId, CompositeType, CustomSectionReader, DataKind, ElementItems, ElementKind, - Encoding, ExternalKind, FuncToValidate, FunctionBody, NameSectionReader, Naming, Operator, - Parser, Payload, TypeRef, Validator, ValidatorResources, + types::CoreTypeId, CustomSectionReader, DataKind, ElementItems, ElementKind, Encoding, + ExternalKind, FuncToValidate, FunctionBody, NameSectionReader, Naming, Operator, Parser, + Payload, TypeRef, Validator, ValidatorResources, }; use super::{ @@ -27,7 +27,7 @@ use crate::{ }, FuncRefIndex, Module, ModuleType, TableSegment, }, - unsupported_diag, WasmError, WasmTranslationConfig, + unsupported_diag, WasmTranslationConfig, }; /// Object containing the standalone environment information. @@ -60,6 +60,9 @@ pub struct ParsedModule<'data> { /// module, or those that can possibly be called. pub exported_signatures: Vec, + /// Metadata about the source Wasm file + pub wasm_file: WasmFileInfo, + /// DWARF debug information, if enabled, parsed from the module. pub debuginfo: DebugInfoData<'data>, @@ -83,19 +86,18 @@ pub struct FunctionBodyData<'a> { pub validator: FuncToValidate, } -#[derive(Debug, Default)] +#[derive(Default)] pub struct DebugInfoData<'a> { pub dwarf: Dwarf<'a>, - pub wasm_file: WasmFileInfo, - debug_loc: gimli::DebugLoc>, - debug_loclists: gimli::DebugLocLists>, - pub debug_ranges: gimli::DebugRanges>, - pub debug_rnglists: gimli::DebugRngLists>, + debug_loc: gimli::DebugLoc>, + debug_loclists: gimli::DebugLocLists>, + pub debug_ranges: gimli::DebugRanges>, + pub debug_rnglists: gimli::DebugRngLists>, } -pub type Dwarf<'input> = gimli::Dwarf>; +pub type Dwarf<'input> = gimli::Dwarf>; -type Reader<'input> = gimli::EndianSlice<'input, gimli::LittleEndian>; +pub type DwarfReader<'input> = gimli::EndianSlice<'input, gimli::LittleEndian>; #[derive(Debug, Default)] pub struct WasmFileInfo { @@ -140,7 +142,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { diagnostics: &DiagnosticsHandler, ) -> WasmResult> { for payload in parser.parse_all(data) { - self.parse_payload(payload?, diagnostics)?; + self.parse_payload(payload.into_diagnostic()?, diagnostics)?; } Ok(self.result) } @@ -157,11 +159,14 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { encoding, range, } => { - self.validator.version(num, encoding, &range)?; + self.validator.version(num, encoding, &range).into_diagnostic()?; match encoding { Encoding::Module => {} Encoding::Component => { - return Err(WasmError::Unsupported("component model".to_string())); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("wasm error: component model is not supported") + .into_report()); } } } @@ -169,25 +174,25 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { Payload::TypeSection(types) => self.type_section(types)?, Payload::ImportSection(imports) => self.import_section(imports)?, Payload::FunctionSection(functions) => self.function_section(functions)?, - Payload::TableSection(tables) => self.table_section(tables)?, + Payload::TableSection(tables) => self.table_section(tables, diagnostics)?, Payload::MemorySection(memories) => self.memory_section(memories)?, Payload::TagSection(tags) => { - self.validator.tag_section(&tags)?; + self.validator.tag_section(&tags).into_diagnostic()?; // This feature isn't enabled at this time, so we should // never get here. unreachable!(); } - Payload::GlobalSection(globals) => self.global_section(globals)?, + Payload::GlobalSection(globals) => self.global_section(globals, diagnostics)?, Payload::ExportSection(exports) => self.export_section(exports)?, Payload::StartSection { func, range } => self.start_section(func, range)?, - Payload::ElementSection(elements) => self.element_section(elements)?, + Payload::ElementSection(elements) => self.element_section(elements, diagnostics)?, Payload::CodeSectionStart { count, range, .. } => { self.code_section_start(count, range)? } Payload::CodeSectionEntry(body) => self.code_section_entry(body)?, Payload::DataSection(data) => self.data_section(data, diagnostics)?, Payload::DataCountSection { count, range } => { - self.validator.data_count_section(count, &range)?; + self.validator.data_count_section(count, &range).into_diagnostic()?; // Note: the count passed in here is the *total* segment count // There is no way to reserve for just the passive segments as // they are discovered when iterating the data section entries @@ -195,7 +200,12 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { // the passive count, do not reserve anything here. } Payload::CustomSection(s) if s.name() == "name" => { - let result = self.name_section(NameSectionReader::new(s.data(), s.data_offset())); + let reader = wasmparser::BinaryReader::new( + s.data(), + s.data_offset(), + *self.validator.features(), + ); + let result = self.name_section(NameSectionReader::new(reader)); if let Err(e) = result { log::warn!("failed to parse name section {:?}", e); } @@ -205,15 +215,15 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { // payloads such as `UnknownSection` or those related to the // component model. other => { - self.validator.payload(&other)?; - unsupported_diag!(diagnostics, "unsupported section in wasm file {:?}", other); + self.validator.payload(&other).into_diagnostic()?; + unsupported_diag!(diagnostics, "wasm error: unsupported section {:?}", other); } } Ok(()) } - fn payload_end(&mut self, offset: usize) -> Result<(), WasmError> { - self.validator.end(offset)?; + fn payload_end(&mut self, offset: usize) -> Result<(), Report> { + self.validator.end(offset).into_diagnostic()?; self.result.exported_signatures = self .result .module @@ -232,11 +242,8 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { Ok(()) } - fn type_section( - &mut self, - types: wasmparser::TypeSectionReader<'data>, - ) -> Result<(), WasmError> { - self.validator.type_section(&types)?; + fn type_section(&mut self, types: wasmparser::TypeSectionReader<'data>) -> Result<(), Report> { + self.validator.type_section(&types).into_diagnostic()?; let num = usize::try_from(types.count()).unwrap(); self.result.module.types.reserve(num); self.types.reserve_wasm_signatures(num); @@ -251,18 +258,18 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { fn import_section( &mut self, imports: wasmparser::ImportSectionReader<'data>, - ) -> Result<(), WasmError> { - self.validator.import_section(&imports)?; + ) -> Result<(), Report> { + self.validator.import_section(&imports).into_diagnostic()?; let cnt = usize::try_from(imports.count()).unwrap(); self.result.module.imports.reserve(cnt); for entry in imports { - let import = entry?; + let import = entry.into_diagnostic()?; let ty = match import.ty { TypeRef::Func(index) => { let index = TypeIndex::from_u32(index); let sig_index = self.result.module.types[index].unwrap_function(); self.result.module.num_imported_funcs += 1; - self.result.debuginfo.wasm_file.imported_func_count += 1; + self.result.wasm_file.imported_func_count += 1; EntityType::Function(sig_index) } TypeRef::Memory(ty) => { @@ -289,12 +296,12 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { fn function_section( &mut self, functions: wasmparser::FunctionSectionReader<'data>, - ) -> Result<(), WasmError> { - self.validator.function_section(&functions)?; + ) -> Result<(), Report> { + self.validator.function_section(&functions).into_diagnostic()?; let cnt = usize::try_from(functions.count()).unwrap(); self.result.module.functions.reserve_exact(cnt); for entry in functions { - let sigindex = entry?; + let sigindex = entry.into_diagnostic()?; let ty = TypeIndex::from_u32(sigindex); let sig_index = self.result.module.types[ty].unwrap_function(); self.result.module.push_function(sig_index); @@ -305,12 +312,13 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { fn table_section( &mut self, tables: wasmparser::TableSectionReader<'data>, - ) -> Result<(), WasmError> { - self.validator.table_section(&tables)?; + diagnostics: &DiagnosticsHandler, + ) -> Result<(), Report> { + self.validator.table_section(&tables).into_diagnostic()?; let cnt = usize::try_from(tables.count()).unwrap(); self.result.module.tables.reserve_exact(cnt); for entry in tables { - let wasmparser::Table { ty, init } = entry?; + let wasmparser::Table { ty, init } = entry.into_diagnostic()?; let table = convert_table_type(&ty); self.result.module.tables.push(table); let init = match init { @@ -319,7 +327,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { }, wasmparser::TableInit::Expr(cexpr) => { let mut init_expr_reader = cexpr.get_binary_reader(); - match init_expr_reader.read_operator()? { + match init_expr_reader.read_operator().into_diagnostic()? { Operator::RefNull { hty: _ } => TableInitialValue::Null { precomputed: Vec::new(), }, @@ -329,10 +337,11 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { TableInitialValue::FuncRef(index) } s => { - return Err(WasmError::Unsupported(format!( - "unsupported init expr in table section: {:?}", + unsupported_diag!( + diagnostics, + "wasm error: unsupported init expr in table section: {:?}", s - ))); + ); } } } @@ -345,8 +354,8 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { fn memory_section( &mut self, memories: wasmparser::MemorySectionReader<'data>, - ) -> Result<(), WasmError> { - self.validator.memory_section(&memories)?; + ) -> Result<(), Report> { + self.validator.memory_section(&memories).into_diagnostic()?; let cnt = usize::try_from(memories.count()).unwrap(); assert_eq!(cnt, 1, "only one memory per module is supported"); Ok(()) @@ -355,14 +364,15 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { fn global_section( &mut self, globals: wasmparser::GlobalSectionReader<'data>, - ) -> Result<(), WasmError> { - self.validator.global_section(&globals)?; + diagnostics: &DiagnosticsHandler, + ) -> Result<(), Report> { + self.validator.global_section(&globals).into_diagnostic()?; let cnt = usize::try_from(globals.count()).unwrap(); self.result.module.globals.reserve_exact(cnt); for entry in globals { - let wasmparser::Global { ty, init_expr } = entry?; + let wasmparser::Global { ty, init_expr } = entry.into_diagnostic()?; let mut init_expr_reader = init_expr.get_binary_reader(); - let initializer = match init_expr_reader.read_operator()? { + let initializer = match init_expr_reader.read_operator().into_diagnostic()? { Operator::I32Const { value } => GlobalInit::I32Const(value), Operator::I64Const { value } => GlobalInit::I64Const(value), Operator::F32Const { value } => GlobalInit::F32Const(value.bits()), @@ -374,10 +384,11 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { GlobalInit::GetGlobal(GlobalIndex::from_u32(global_index)) } s => { - return Err(WasmError::Unsupported(format!( - "unsupported init expr in global section: {:?}", + unsupported_diag!( + diagnostics, + "wasm error: unsupported init expr in global section: {:?}", s - ))); + ); } }; let ty = convert_global_type(&ty); @@ -390,12 +401,12 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { fn export_section( &mut self, exports: wasmparser::ExportSectionReader<'data>, - ) -> Result<(), WasmError> { - self.validator.export_section(&exports)?; + ) -> Result<(), Report> { + self.validator.export_section(&exports).into_diagnostic()?; let cnt = usize::try_from(exports.count()).unwrap(); self.result.module.exports.reserve(cnt); for entry in exports { - let wasmparser::Export { name, kind, index } = entry?; + let wasmparser::Export { name, kind, index } = entry.into_diagnostic()?; let entity = match kind { ExternalKind::Func => { let index = FuncIndex::from_u32(index); @@ -414,8 +425,8 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { Ok(()) } - fn start_section(&mut self, func: u32, range: Range) -> Result<(), WasmError> { - self.validator.start_section(func, &range)?; + fn start_section(&mut self, func: u32, range: Range) -> Result<(), Report> { + self.validator.start_section(func, &range).into_diagnostic()?; let func_index = FuncIndex::from_u32(func); self.flag_func_escaped(func_index); debug_assert!(self.result.module.start_func.is_none()); @@ -426,14 +437,15 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { fn element_section( &mut self, elements: wasmparser::ElementSectionReader<'data>, - ) -> Result<(), WasmError> { - self.validator.element_section(&elements)?; + diagnostics: &DiagnosticsHandler, + ) -> Result<(), Report> { + self.validator.element_section(&elements).into_diagnostic()?; for (index, entry) in elements.into_iter().enumerate() { let wasmparser::Element { kind, items, range: _, - } = entry?; + } = entry.into_diagnostic()?; // Build up a list of `FuncIndex` corresponding to all the // entries listed in this segment. Note that it's not @@ -445,7 +457,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { ElementItems::Functions(funcs) => { elements.reserve(usize::try_from(funcs.count()).unwrap()); for func in funcs { - let func = FuncIndex::from_u32(func?); + let func = FuncIndex::from_u32(func.into_diagnostic()?); self.flag_func_escaped(func); elements.push(func); } @@ -453,7 +465,12 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { ElementItems::Expressions(_ty, funcs) => { elements.reserve(usize::try_from(funcs.count()).unwrap()); for func in funcs { - let func = match func?.get_binary_reader().read_operator()? { + let func = match func + .into_diagnostic()? + .get_binary_reader() + .read_operator() + .into_diagnostic()? + { Operator::RefNull { .. } => FuncIndex::reserved_value(), Operator::RefFunc { function_index } => { let func = FuncIndex::from_u32(function_index); @@ -461,10 +478,11 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { func } s => { - return Err(WasmError::Unsupported(format!( - "unsupported init expr in element section: {:?}", + unsupported_diag!( + diagnostics, + "wasm error: unsupported init expr in element section: {:?}", s - ))); + ); } }; elements.push(func); @@ -479,18 +497,20 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { } => { let table_index = TableIndex::from_u32(table_index.unwrap_or(0)); let mut offset_expr_reader = offset_expr.get_binary_reader(); - let (base, offset) = match offset_expr_reader.read_operator()? { - Operator::I32Const { value } => (None, value as u32), - Operator::GlobalGet { global_index } => { - (Some(GlobalIndex::from_u32(global_index)), 0) - } - ref s => { - return Err(WasmError::Unsupported(format!( - "unsupported init expr in element section: {:?}", - s - ))); - } - }; + let (base, offset) = + match offset_expr_reader.read_operator().into_diagnostic()? { + Operator::I32Const { value } => (None, value as u32), + Operator::GlobalGet { global_index } => { + (Some(GlobalIndex::from_u32(global_index)), 0) + } + ref s => { + unsupported_diag!( + diagnostics, + "wasm error: unsupported init expr in element section: {:?}", + s + ); + } + }; self.result.module.table_initialization.segments.push(TableSegment { table_index, @@ -513,33 +533,32 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { Ok(()) } - fn code_section_start(&mut self, count: u32, range: Range) -> Result<(), WasmError> { - self.validator.code_section_start(count, &range)?; + fn code_section_start(&mut self, count: u32, range: Range) -> Result<(), Report> { + self.validator.code_section_start(count, &range).into_diagnostic()?; let cnt = usize::try_from(count).unwrap(); self.result.function_body_inputs.reserve_exact(cnt); - self.result.debuginfo.wasm_file.code_section_offset = range.start as u64; + self.result.wasm_file.code_section_offset = range.start as u64; Ok(()) } - fn code_section_entry(&mut self, mut body: FunctionBody<'data>) -> Result<(), WasmError> { - let validator = self.validator.code_section_entry(&body)?; + fn code_section_entry(&mut self, body: FunctionBody<'data>) -> Result<(), Report> { + let validator = self.validator.code_section_entry(&body).into_diagnostic()?; let func_index = self.result.code_index + self.result.module.num_imported_funcs as u32; let func_index = FuncIndex::from_u32(func_index); if self.config.generate_native_debuginfo { let sig_index = self.result.module.functions[func_index].signature; let sig = &self.types[sig_index]; let mut locals = Vec::new(); - for pair in body.get_locals_reader()? { - let (cnt, ty) = pair?; + for pair in body.get_locals_reader().into_diagnostic()? { + let (cnt, ty) = pair.into_diagnostic()?; let ty = convert_valtype(ty); locals.push((cnt, ty)); } - self.result.debuginfo.wasm_file.funcs.push(FunctionMetadata { + self.result.wasm_file.funcs.push(FunctionMetadata { locals: locals.into_boxed_slice(), params: sig.params().into(), }); } - body.allow_memarg64(false); self.result.function_body_inputs.push(FunctionBodyData { validator, body }); self.result.code_index += 1; Ok(()) @@ -550,7 +569,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { data_section: wasmparser::DataSectionReader<'data>, diagnostics: &DiagnosticsHandler, ) -> WasmResult<()> { - self.validator.data_section(&data_section)?; + self.validator.data_section(&data_section).into_diagnostic()?; let cnt = usize::try_from(data_section.count()).unwrap(); self.result.data_segments.reserve_exact(cnt); for entry in data_section.into_iter() { @@ -558,7 +577,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { kind, data, range: _, - } = entry?; + } = entry.into_diagnostic()?; match kind { DataKind::Active { memory_index, @@ -570,7 +589,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { supported)" ); let mut offset_expr_reader = offset_expr.get_binary_reader(); - let offset = match offset_expr_reader.read_operator()? { + let offset = match offset_expr_reader.read_operator().into_diagnostic()? { Operator::I32Const { value } => DataSegmentOffset::I32Const(value), Operator::GlobalGet { global_index } => { DataSegmentOffset::GetGlobal(GlobalIndex::from_u32(global_index)) @@ -578,7 +597,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { ref s => { unsupported_diag!( diagnostics, - "unsupported init expr in data section offset: {:?}", + "wasm error: unsupported init expr in data section offset: {:?}", s ); } @@ -587,9 +606,10 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { self.result.data_segments.push(segment); } DataKind::Passive => { - return Err(WasmError::Unsupported( - "unsupported passive data segment in data section".to_string(), - )); + unsupported_diag!( + diagnostics, + "wasm error: unsupported passive data segment in data section" + ); } } } @@ -599,10 +619,10 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { /// Parses the Name section of the wasm module. fn name_section(&mut self, names: NameSectionReader<'data>) -> WasmResult<()> { for subsection in names { - match subsection? { + match subsection.into_diagnostic()? { wasmparser::Name::Function(names) => { for name in names { - let Naming { index, name } = name?; + let Naming { index, name } = name.into_diagnostic()?; // Skip this naming if it's naming a function that // doesn't actually exist. if (index as usize) >= self.result.module.functions.len() { @@ -632,14 +652,14 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { continue; } for f in reader { - let f = f?; + let f = f.into_diagnostic()?; // Skip this naming if it's naming a function that // doesn't actually exist. if (f.index as usize) >= self.result.module.functions.len() { continue; } for name in f.names { - let Naming { index, name } = name?; + let Naming { index, name } = name.into_diagnostic()?; self.result .module @@ -653,8 +673,8 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { } wasmparser::Name::Global(names) => { for name in names { - let Naming { index, name } = name?; - if index != u32::max_value() { + let Naming { index, name } = name.into_diagnostic()?; + if index != u32::MAX { self.result .module .name_section @@ -665,8 +685,8 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { } wasmparser::Name::Data(names) => { for name in names { - let Naming { index, name } = name?; - if index != u32::max_value() { + let Naming { index, name } = name.into_diagnostic()?; + if index != u32::MAX { self.result .module .name_section @@ -680,6 +700,8 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { | wasmparser::Name::Table(_) | wasmparser::Name::Memory(_) | wasmparser::Name::Element(_) + | wasmparser::Name::Field(_) + | wasmparser::Name::Tag(_) | wasmparser::Name::Unknown { .. } => {} } } @@ -770,17 +792,19 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { } fn declare_type(&mut self, id: CoreTypeId) -> WasmResult<()> { + use wasmparser::CompositeInnerType; + let types = self.validator.types(0).unwrap(); let ty = &types[id]; assert!(ty.is_final); assert!(ty.supertype_idx.is_none()); - match &ty.composite_type { - CompositeType::Func(ty) => { + match &ty.composite_type.inner { + CompositeInnerType::Func(ty) => { let wasm = convert_func_type(ty); let sig_index = self.types.wasm_func_type(id, wasm); self.result.module.types.push(ModuleType::Function(sig_index)); } - CompositeType::Array(_) | CompositeType::Struct(_) => unimplemented!(), + CompositeInnerType::Array(_) | CompositeInnerType::Struct(_) => unimplemented!(), } Ok(()) } diff --git a/frontend-wasm/src/module/module_translation_state.rs b/frontend-wasm/src/module/module_translation_state.rs index 12ebb48a..ac26f685 100644 --- a/frontend-wasm/src/module/module_translation_state.rs +++ b/frontend-wasm/src/module/module_translation_state.rs @@ -1,6 +1,8 @@ use miden_core::crypto::hash::RpoDigest; -use miden_diagnostics::DiagnosticsHandler; -use midenc_hir::{AbiParam, CallConv, DataFlowGraph, FunctionIdent, Ident, Linkage, Signature}; +use midenc_hir::{ + diagnostics::{DiagnosticsHandler, Severity}, + AbiParam, CallConv, DataFlowGraph, FunctionIdent, Ident, Linkage, Signature, +}; use rustc_hash::FxHashMap; use super::{instance::ModuleArgument, ir_func_type, EntityIndex, FuncIndex, Module, ModuleTypes}; @@ -9,7 +11,6 @@ use crate::{ intrinsics::is_miden_intrinsics_module, miden_abi::{is_miden_abi_module, miden_abi_function_type, parse_import_function_digest}, translation_utils::sig_from_func_type, - WasmError, }; pub struct ModuleTranslationState { @@ -24,7 +25,12 @@ pub struct ModuleTranslationState { } impl ModuleTranslationState { - pub fn new(module: &Module, mod_types: &ModuleTypes, module_args: Vec) -> Self { + pub fn new( + module: &Module, + mod_types: &ModuleTypes, + module_args: Vec, + diagnostics: &DiagnosticsHandler, + ) -> Self { let mut function_import_subst = FxHashMap::default(); if module.imports.len() == module_args.len() { for (import, arg) in module.imports.iter().zip(module_args) { @@ -51,7 +57,7 @@ impl ModuleTranslationState { let mut digests = FxHashMap::default(); for (index, func_type) in &module.functions { let wasm_func_type = mod_types[func_type.signature].clone(); - let ir_func_type = ir_func_type(&wasm_func_type).unwrap(); + let ir_func_type = ir_func_type(&wasm_func_type, diagnostics).unwrap(); let sig = sig_from_func_type(&ir_func_type, CallConv::SystemV, Linkage::External); if let Some(subst) = function_import_subst.get(&index) { functions.insert(index, (*subst, sig)); @@ -135,11 +141,7 @@ impl ModuleTranslationState { imported (function call) with a different signature", func_id.function, func_id.module ); - diagnostics - .diagnostic(miden_diagnostics::Severity::Error) - .with_message(message.clone()) - .emit(); - WasmError::Unexpected(message) + diagnostics.diagnostic(Severity::Error).with_message(message).into_report() })?; } Ok(func_id) diff --git a/frontend-wasm/src/module/types.rs b/frontend-wasm/src/module/types.rs index a520335a..ad130de7 100644 --- a/frontend-wasm/src/module/types.rs +++ b/frontend-wasm/src/module/types.rs @@ -3,15 +3,15 @@ use core::fmt; use std::{collections::HashMap, ops::Index}; -use hir::Abi; -use miden_diagnostics::DiagnosticsHandler; -use midenc_hir::{cranelift_entity::PrimaryMap, AbiParam, CallConv, Linkage, Signature}; -use midenc_hir_type as hir; +use midenc_hir::{ + cranelift_entity::PrimaryMap, + diagnostics::{DiagnosticsHandler, Severity}, + AbiParam, CallConv, Linkage, Signature, +}; +use midenc_hir_type::{self as hir, Abi}; use wasmparser::types::CoreTypeId; -use crate::{ - component::SignatureIndex, error::WasmResult, module::Module, unsupported_diag, WasmError, -}; +use crate::{component::SignatureIndex, error::WasmResult, module::Module, unsupported_diag}; /// Generates a new index type for each entity. #[macro_export] @@ -410,16 +410,15 @@ impl DataSegmentOffset { DataSegmentOffset::GetGlobal(global_idx) => { let global_init = &module.try_global_initializer(*global_idx, diagnostics)?; match global_init.as_i32(module, diagnostics) { - Err(e) => { - diagnostics - .diagnostic(miden_diagnostics::Severity::Error) + Err(_) => { + return Err(diagnostics + .diagnostic(Severity::Error) .with_message(format!( "Failed to get data segment offset from global init {:?} with \ global index {global_idx:?}", global_init, )) - .emit(); - return Err(e); + .into_report()); } Ok(v) => v, } @@ -448,24 +447,25 @@ impl BlockType { pub fn from_wasm( block_ty: &wasmparser::BlockType, mod_types: &ModuleTypes, + diagnostics: &DiagnosticsHandler, ) -> WasmResult { Ok(match block_ty { wasmparser::BlockType::Empty => Self::default(), wasmparser::BlockType::Type(ty) => Self { params: vec![], - results: vec![ir_type(convert_valtype(*ty))?], + results: vec![ir_type(convert_valtype(*ty), diagnostics)?], }, wasmparser::BlockType::FuncType(ty_index) => { let func_type = &mod_types[SignatureIndex::from_u32(*ty_index)]; let params = func_type .params() .iter() - .map(|t| ir_type(*t)) + .map(|t| ir_type(*t, diagnostics)) .collect::>>()?; let results = func_type .returns() .iter() - .map(|t| ir_type(*t)) + .map(|t| ir_type(*t, diagnostics)) .collect::>>()?; Self { params, results } } @@ -554,16 +554,19 @@ where } /// Converts a Wasm function type into a Miden IR function type -pub fn ir_func_type(ty: &WasmFuncType) -> WasmResult { +pub fn ir_func_type( + ty: &WasmFuncType, + diagnostics: &DiagnosticsHandler, +) -> WasmResult { let params = ty .params() .iter() - .map(|t| ir_type(*t)) + .map(|t| ir_type(*t, diagnostics)) .collect::>>()?; let results = ty .returns() .iter() - .map(|t| ir_type(*t)) + .map(|t| ir_type(*t, diagnostics)) .collect::>>()?; Ok(hir::FunctionType { abi: Abi::Canonical, @@ -573,17 +576,13 @@ pub fn ir_func_type(ty: &WasmFuncType) -> WasmResult { } /// Converts a Wasm type into a Miden IR type -pub fn ir_type(ty: WasmType) -> WasmResult { +pub fn ir_type(ty: WasmType, diagnostics: &DiagnosticsHandler) -> WasmResult { Ok(match ty { WasmType::I32 => hir::Type::I32, WasmType::I64 => hir::Type::I64, WasmType::F32 => hir::Type::Felt, - WasmType::F64 => return Err(WasmError::Unsupported("no f64 type in Miden IR".to_string())), - WasmType::V128 => { - return Err(WasmError::Unsupported("V128 type is not supported".to_string())); - } - WasmType::Ref(_) => { - return Err(WasmError::Unsupported("Ref type is not supported".to_string())); + ty @ (WasmType::F64 | WasmType::V128 | WasmType::Ref(_)) => { + unsupported_diag!(diagnostics, "wasm error: unsupported type '{}'", ty) } }) } @@ -612,10 +611,12 @@ pub fn convert_global_type(ty: &wasmparser::GlobalType) -> Global { /// Converts a wasmparser table type pub fn convert_table_type(ty: &wasmparser::TableType) -> Table { + assert!(!ty.table64, "64-bit tables are not supported"); + Table { wasm_ty: convert_ref_type(ty.element_type), - minimum: ty.initial, - maximum: ty.maximum, + minimum: ty.initial as u32, + maximum: ty.maximum.map(|n| n as u32), } } @@ -648,19 +649,15 @@ pub fn convert_ref_type(ty: wasmparser::RefType) -> WasmRefType { /// Converts a wasmparser heap type pub fn convert_heap_type(ty: wasmparser::HeapType) -> WasmHeapType { + use wasmparser::AbstractHeapType; match ty { - wasmparser::HeapType::Func => WasmHeapType::Func, - wasmparser::HeapType::Extern => WasmHeapType::Extern, - wasmparser::HeapType::Concrete(_) - | wasmparser::HeapType::Any - | wasmparser::HeapType::None - | wasmparser::HeapType::NoExtern - | wasmparser::HeapType::NoFunc - | wasmparser::HeapType::Eq - | wasmparser::HeapType::Struct - | wasmparser::HeapType::Array - | wasmparser::HeapType::I31 => { - unimplemented!("unsupported heap type {ty:?}"); + wasmparser::HeapType::Abstract { ty, shared: _ } => match ty { + AbstractHeapType::Func => WasmHeapType::Func, + AbstractHeapType::Extern => WasmHeapType::Extern, + ty => unimplemented!("unsupported abstract heap type {ty:?}"), + }, + wasmparser::HeapType::Concrete(_) => { + unimplemented!("user-defined types are not supported yet") } } } diff --git a/frontend-wasm/src/ssa.rs b/frontend-wasm/src/ssa.rs index 5975aa97..7c1a27a7 100644 --- a/frontend-wasm/src/ssa.rs +++ b/frontend-wasm/src/ssa.rs @@ -11,11 +11,11 @@ use core::mem; -use miden_diagnostics::SourceSpan; use midenc_hir::{ cranelift_entity::{ entity_impl, packed_option::PackedOption, EntityList, EntitySet, ListPool, SecondaryMap, }, + diagnostics::SourceSpan, Block, DataFlowGraph, Inst, Value, }; use midenc_hir_type::Type; diff --git a/frontend-wasm/src/test_utils.rs b/frontend-wasm/src/test_utils.rs index a1505b10..fe6b1697 100644 --- a/frontend-wasm/src/test_utils.rs +++ b/frontend-wasm/src/test_utils.rs @@ -1,25 +1,13 @@ use std::sync::Arc; -use miden_diagnostics::{ - term::termcolor::ColorChoice, CodeMap, DiagnosticsConfig, DiagnosticsHandler, Emitter, - NullEmitter, Verbosity, +use midenc_hir::{ + diagnostics::{ColorChoice, NullEmitter}, + testing::TestContext, }; +use midenc_session::Options; -pub fn default_emitter(color: ColorChoice) -> Arc { - Arc::new(NullEmitter::new(color)) -} - -pub fn test_diagnostics() -> DiagnosticsHandler { - let codemap = Arc::new(CodeMap::new()); - - DiagnosticsHandler::new( - DiagnosticsConfig { - verbosity: Verbosity::Debug, - warnings_as_errors: false, - no_warn: false, - display: Default::default(), - }, - codemap, - default_emitter(ColorChoice::Auto), - ) +pub fn test_context() -> TestContext { + let options = Options::default().with_verbosity(midenc_session::Verbosity::Debug); + let emitter = Arc::new(NullEmitter::new(ColorChoice::Auto)); + TestContext::default_with_opts_and_emitter(options, Some(emitter)) } diff --git a/frontend-wasm/src/translation_utils.rs b/frontend-wasm/src/translation_utils.rs index 5817ea64..067ee278 100644 --- a/frontend-wasm/src/translation_utils.rs +++ b/frontend-wasm/src/translation_utils.rs @@ -1,11 +1,15 @@ //! Helper functions and structures for the translation. -use miden_diagnostics::SourceSpan; -use midenc_hir::{AbiParam, CallConv, Felt, FieldElement, InstBuilder, Linkage, Signature, Value}; +use midenc_hir::{ + diagnostics::{DiagnosticsHandler, Severity, SourceSpan}, + AbiParam, CallConv, Felt, FieldElement, InstBuilder, Linkage, Signature, Value, +}; use midenc_hir_type::{FunctionType, Type}; use rustc_hash::FxHasher; -use crate::{error::WasmResult, module::function_builder_ext::FunctionBuilderExt, WasmError}; +use crate::{ + error::WasmResult, module::function_builder_ext::FunctionBuilderExt, unsupported_diag, +}; pub type BuildFxHasher = std::hash::BuildHasherDefault; @@ -101,7 +105,11 @@ const fn ceiling_divide(n: usize, d: usize) -> usize { } /// Emit instructions to produce a zero value in the given type. -pub fn emit_zero(ty: &Type, builder: &mut FunctionBuilderExt) -> WasmResult { +pub fn emit_zero( + ty: &Type, + builder: &mut FunctionBuilderExt, + diagnostics: &DiagnosticsHandler, +) -> WasmResult { Ok(match ty { Type::I1 => builder.ins().i1(false, SourceSpan::default()), Type::I8 => builder.ins().i8(0, SourceSpan::default()), @@ -125,10 +133,7 @@ pub fn emit_zero(ty: &Type, builder: &mut FunctionBuilderExt) -> WasmResult { - return Err(WasmError::Unsupported(format!( - "cannot emit zero value for type: {:?}", - ty - ))); + unsupported_diag!(diagnostics, "cannot emit zero value for type: {:?}", ty); } }) } diff --git a/frontend-wasm/tests/expected/array.hir b/frontend-wasm/tests/expected/array.hir index 77d101e8..0eb582d5 100644 --- a/frontend-wasm/tests/expected/array.hir +++ b/frontend-wasm/tests/expected/array.hir @@ -34,9 +34,9 @@ (br (block 4 v0 v4 v1))) (block 4 (param v8 i32) (param v13 i32) (param v17 i32) - (let (v9 u32) (cast v8)) - (let (v10 u32) (mod.unchecked v9 2)) - (assertz v10) + (let (v9 u32) (bitcast v8)) + (let (v10 u32) (mod.unchecked v9 4)) + (assertz 250 v10) (let (v11 (ptr i32)) (inttoptr v9)) (let (v12 i32) (load v11)) (let (v14 i32) (add.wrapping v12 v13)) diff --git a/frontend-wasm/tests/expected/enum.hir b/frontend-wasm/tests/expected/enum.hir index a263b466..da794dd9 100644 --- a/frontend-wasm/tests/expected/enum.hir +++ b/frontend-wasm/tests/expected/enum.hir @@ -20,7 +20,7 @@ (0 . (block 4)) (1 . (block 3)) (2 . (block 2)) - (_ . (block4)))) + (_ . (block 4)))) (block 1 (param v3 i32) (ret v3)) diff --git a/frontend-wasm/tests/expected/static_mut.hir b/frontend-wasm/tests/expected/static_mut.hir index df53775f..d57f4c17 100644 --- a/frontend-wasm/tests/expected/static_mut.hir +++ b/frontend-wasm/tests/expected/static_mut.hir @@ -19,18 +19,19 @@ (block 0 (let (v0 i32) (const.i32 0)) (let (v1 i32) (const.i32 0)) - (let (v2 u32) (cast v1)) + (let (v2 u32) (bitcast v1)) (let (v3 u32) (add.checked v2 1048577)) (let (v4 (ptr u8)) (inttoptr v3)) (let (v5 u8) (load v4)) (let (v6 i32) (zext v5)) (let (v7 i32) (const.i32 1)) (let (v8 i32) (add.wrapping v6 v7)) - (let (v9 u8) (trunc v8)) - (let (v10 u32) (cast v0)) - (let (v11 u32) (add.checked v10 1048576)) - (let (v12 (ptr u8)) (inttoptr v11)) - (store v12 v9) + (let (v9 u32) (bitcast v8)) + (let (v10 u8) (trunc v9)) + (let (v11 u32) (bitcast v0)) + (let (v12 u32) (add.checked v11 1048576)) + (let (v13 (ptr u8)) (inttoptr v12)) + (store v13 v10) (br (block 1))) (block 1 @@ -51,7 +52,7 @@ (block 2 (param v4 i32) (param v11 i32) (let (v5 i32) (const.i32 1048585)) (let (v6 i32) (add.wrapping v4 v5)) - (let (v7 u32) (cast v6)) + (let (v7 u32) (bitcast v6)) (let (v8 (ptr u8)) (inttoptr v7)) (let (v9 u8) (load v8)) (let (v10 i32) (zext v9)) diff --git a/hir-analysis/Cargo.toml b/hir-analysis/Cargo.toml index 418d9557..624f321c 100644 --- a/hir-analysis/Cargo.toml +++ b/hir-analysis/Cargo.toml @@ -17,7 +17,6 @@ cranelift-entity.workspace = true cranelift-bforest.workspace = true inventory.workspace = true intrusive-collections.workspace = true -miden-diagnostics.workspace = true midenc-hir.workspace = true midenc-session.workspace = true rustc-hash.workspace = true diff --git a/hir-analysis/src/control_flow.rs b/hir-analysis/src/control_flow.rs index 59586ee8..efc80b3e 100644 --- a/hir-analysis/src/control_flow.rs +++ b/hir-analysis/src/control_flow.rs @@ -222,30 +222,28 @@ pub(crate) fn visit_block_succs( if let Some(inst) = dfg.last_inst(block) { match &dfg[inst] { - Instruction::Br(Br { - destination: dest, .. - }) => { - visit(inst, *dest, false); + Instruction::Br(Br { successor, .. }) => { + visit(inst, successor.destination, false); } Instruction::CondBr(CondBr { - then_dest: (block_then, _), - else_dest: (block_else, _), + then_dest, + else_dest, .. }) => { - visit(inst, *block_then, false); - visit(inst, *block_else, false); + visit(inst, then_dest.destination, false); + visit(inst, else_dest.destination, false); } Instruction::Switch(Switch { ref arms, - default: default_block, + default: default_succ, .. }) => { - visit(inst, *default_block, false); + visit(inst, default_succ.destination, false); - for (_, dest) in arms.as_slice() { - visit(inst, *dest, true); + for arm in arms.as_slice() { + visit(inst, arm.successor.destination, true); } } @@ -256,11 +254,6 @@ pub(crate) fn visit_block_succs( #[cfg(test)] mod tests { - use std::sync::Arc; - - use miden_diagnostics::{ - term::termcolor::ColorChoice, CodeMap, DefaultEmitter, DiagnosticsHandler, - }; use midenc_hir::*; use super::*; @@ -294,9 +287,7 @@ mod tests { #[test] fn cfg_branches_and_jumps() { - let codemap = Arc::new(CodeMap::new()); - let emitter = Arc::new(DefaultEmitter::new(ColorChoice::Auto)); - let diagnostics = DiagnosticsHandler::new(Default::default(), codemap.clone(), emitter); + let diagnostics = diagnostics::DiagnosticsHandler::default(); // Define the 'test' module let mut builder = ModuleBuilder::new("test"); diff --git a/hir-analysis/src/def_use.rs b/hir-analysis/src/def_use.rs index f958c63d..25fad327 100644 --- a/hir-analysis/src/def_use.rs +++ b/hir-analysis/src/def_use.rs @@ -122,9 +122,11 @@ impl DefUseGraph { args[index as usize] = replacement; } Use::BlockArgument { succ, index } => match dfg.insts[current_use.inst].as_mut() { - Instruction::Br(ref mut b) => { + Instruction::Br(midenc_hir::Br { + ref mut successor, .. + }) => { assert_eq!(succ, 0); - let args = b.args.as_mut_slice(&mut dfg.value_lists); + let args = successor.args.as_mut_slice(&mut dfg.value_lists); args[index as usize] = replacement; } Instruction::CondBr(midenc_hir::CondBr { @@ -133,16 +135,31 @@ impl DefUseGraph { .. }) => { let args = match succ { - 0 => then_dest.1.as_mut_slice(&mut dfg.value_lists), - 1 => else_dest.1.as_mut_slice(&mut dfg.value_lists), + 0 => then_dest.args.as_mut_slice(&mut dfg.value_lists), + 1 => else_dest.args.as_mut_slice(&mut dfg.value_lists), n => unreachable!( "unexpected successor index {n} for conditional branch" ), }; args[index as usize] = replacement; } - Instruction::Switch(_) => { - unimplemented!("support for switch arms with arguments is not implemented") + Instruction::Switch(midenc_hir::Switch { + ref mut arms, + default: ref mut default_succ, + .. + }) => { + let succ = succ as usize; + assert!( + succ < arms.len() + 1, + "invalid successor index {succ}: but only {} arms plus fallback", + arms.len() + ); + let args = if arms.len() == succ { + default_succ.args.as_mut_slice(&mut dfg.value_lists) + } else { + arms[succ].successor.args.as_mut_slice(&mut dfg.value_lists) + }; + args[index as usize] = replacement; } _ => unreachable!(), }, @@ -180,14 +197,14 @@ impl DefUseGraph { } graph.insert_operand_uses(inst, dfg, domtree); } - BranchInfo::SingleDest(_, args) => { + BranchInfo::SingleDest(successor) => { debug_assert_eq!( dfg.inst_results(inst), &[], "branch instructions cannot have results" ); graph.insert_operand_uses(inst, dfg, domtree); - for (index, value) in args.iter().copied().enumerate() { + for (index, value) in successor.args.iter().copied().enumerate() { debug_assert!(def_dominates_use(value, inst, dfg, domtree)); let user = Box::new(User { link: Default::default(), @@ -201,16 +218,16 @@ impl DefUseGraph { graph.insert_use(user); } } - BranchInfo::MultiDest(ref jts) => { + BranchInfo::MultiDest(ref successors) => { debug_assert_eq!( dfg.inst_results(inst), &[], "branch instructions cannot have results" ); graph.insert_operand_uses(inst, dfg, domtree); - for (succ, jt) in jts.iter().enumerate() { + for (succ, successor) in successors.iter().enumerate() { let succ = u16::try_from(succ).expect("too many successors"); - for (index, value) in jt.args.iter().copied().enumerate() { + for (index, value) in successor.args.iter().copied().enumerate() { debug_assert!(def_dominates_use(value, inst, dfg, domtree)); let user = Box::new(User { link: Default::default(), diff --git a/hir-analysis/src/dominance.rs b/hir-analysis/src/dominance.rs index db645290..bd48a22e 100644 --- a/hir-analysis/src/dominance.rs +++ b/hir-analysis/src/dominance.rs @@ -355,15 +355,15 @@ impl DominatorTree { // consumers of the postorder we cache here. match func.dfg.analyze_branch(inst) { BranchInfo::NotABranch => (), - BranchInfo::SingleDest(dest, _) => { - if self.nodes[dest].rpo_number == 0 { - self.stack.push((Visit::First, dest)); + BranchInfo::SingleDest(successor) => { + if self.nodes[successor.destination].rpo_number == 0 { + self.stack.push((Visit::First, successor.destination)); } } - BranchInfo::MultiDest(ref jt) => { - for dest in jt.iter().rev().map(|entry| entry.destination) { - if self.nodes[dest].rpo_number == 0 { - self.stack.push((Visit::First, dest)); + BranchInfo::MultiDest(ref successors) => { + for successor in successors.iter().rev() { + if self.nodes[successor.destination].rpo_number == 0 { + self.stack.push((Visit::First, successor.destination)); } } } diff --git a/hir-analysis/src/lib.rs b/hir-analysis/src/lib.rs index e84ea63f..98c2af98 100644 --- a/hir-analysis/src/lib.rs +++ b/hir-analysis/src/lib.rs @@ -1,3 +1,5 @@ +extern crate alloc; + mod control_flow; mod data; mod def_use; diff --git a/hir-analysis/src/liveness.rs b/hir-analysis/src/liveness.rs index 2d69806e..3915dea3 100644 --- a/hir-analysis/src/liveness.rs +++ b/hir-analysis/src/liveness.rs @@ -442,7 +442,7 @@ fn compute_liveness( BranchInfo::NotABranch => { flow_sensitive.insert(block, false); } - BranchInfo::SingleDest(succ, _) => { + BranchInfo::SingleDest(succ) => { // If the successor is flow-sensitive, by definition so must the predecessor. // // If the successor's sensitivity is not yet known, then that means control can @@ -458,18 +458,19 @@ fn compute_liveness( // Putting this all together - it must be the case that we either know that `succ` // is flow-insensitive, or we know that it is flow-sensitive, either explicitly or // by implication. - flow_sensitive.insert(block, flow_sensitive.get(&succ).copied().unwrap_or(true)); + flow_sensitive + .insert(block, flow_sensitive.get(&succ.destination).copied().unwrap_or(true)); } - BranchInfo::MultiDest(jts) => { + BranchInfo::MultiDest(succs) => { // Must like the single-successor case, we derive flow-sensitivity for predecessors // from their successors. // // The primary difference in this situation, is that the only possible way for // `block` to be flow-insensitive, is if all successors are explicitly flow- // insensitive. - let is_flow_sensitive = jts + let is_flow_sensitive = succs .iter() - .any(|jt| flow_sensitive.get(&jt.destination).copied().unwrap_or(true)); + .any(|succ| flow_sensitive.get(&succ.destination).copied().unwrap_or(true)); flow_sensitive.insert(block, is_flow_sensitive); } } @@ -618,7 +619,10 @@ fn compute_liveness( // This is a branch instruction, so get the next-use set at the entry of each // successor, increment the distances in those sets based on the distance of the // edge, and then take the join of those sets as the initial next-use set for `inst` - BranchInfo::SingleDest(succ, succ_args) => { + BranchInfo::SingleDest(SuccessorInfo { + destination: succ, + args: succ_args, + }) => { let mut inst_next_uses = liveness .live_in .get(&ProgramPoint::Block(succ)) @@ -690,7 +694,7 @@ fn compute_liveness( // graph have been split, as we cannot proceed correctly otherwise. It is expected // that either no critical edges exist, or that they have been split by a prior // transformation. - BranchInfo::MultiDest(jts) => { + BranchInfo::MultiDest(succs) => { let mut inst_next_uses = NextUseSet::default(); let mut inst_next_uses_after = NextUseSet::default(); @@ -703,10 +707,10 @@ fn compute_liveness( } let mut max_branch_operand_stack_pressure = operand_stack_pressure; - for JumpTable { + for SuccessorInfo { destination, args: succ_args, - } in jts.iter() + } in succs.iter() { let destination = *destination; // If the successor block has multiple predecessors, this is a critical diff --git a/hir-analysis/src/spill.rs b/hir-analysis/src/spill.rs index ea23a544..00e88c70 100644 --- a/hir-analysis/src/spill.rs +++ b/hir-analysis/src/spill.rs @@ -1004,12 +1004,12 @@ fn compute_control_flow_edge_spills_and_reloads( // parameters, with the corresponding source values in W^exit(P) (issuing reloads if the value // given as argument in the predecessor is not in W^exit(P)) let pred_args = match function.dfg.analyze_branch(pred.inst) { - BranchInfo::SingleDest(_, pred_args) => pred_args, - BranchInfo::MultiDest(jts) => jts + BranchInfo::SingleDest(successor) => successor.args, + BranchInfo::MultiDest(successors) => successors .iter() - .find_map(|jt| { - if jt.destination == block_info.block_id { - Some(jt.args) + .find_map(|successor| { + if successor.destination == block_info.block_id { + Some(successor.args) } else { None } @@ -1272,14 +1272,15 @@ fn min( w.retain(|o| liveness.is_live_after(&o.value, current_pp)); w.extend(results.iter().map(|v| Operand::new(*v, function))); } - BranchInfo::SingleDest(_, succ_args) => { + BranchInfo::SingleDest(successor) => { w.retain(|o| { - succ_args.contains(&o.value) || liveness.is_live_after(&o.value, current_pp) + successor.args.contains(&o.value) + || liveness.is_live_after(&o.value, current_pp) }); } - BranchInfo::MultiDest(jts) => { + BranchInfo::MultiDest(successors) => { w.retain(|o| { - let is_succ_arg = jts.iter().any(|jt| jt.args.contains(&o.value)); + let is_succ_arg = successors.iter().any(|s| s.args.contains(&o.value)); is_succ_arg || liveness.is_live_after(&o.value, current_pp) }); } diff --git a/hir-analysis/src/validation/block.rs b/hir-analysis/src/validation/block.rs index 010526ea..1f0234ab 100644 --- a/hir-analysis/src/validation/block.rs +++ b/hir-analysis/src/validation/block.rs @@ -1,9 +1,11 @@ -use miden_diagnostics::{DiagnosticsHandler, Severity, Spanned}; -use midenc_hir::*; +use midenc_hir::{ + diagnostics::{DiagnosticsHandler, Report, Severity, Spanned}, + *, +}; use rustc_hash::FxHashSet; use smallvec::SmallVec; -use super::{Rule, ValidationError}; +use super::Rule; use crate::DominatorTree; /// This validation rule ensures that all values definitions dominate their uses. @@ -27,7 +29,7 @@ impl<'a> Rule for DefsDominateUses<'a> { &mut self, block_data: &BlockData, diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { let current_block = block_data.id; let mut uses = FxHashSet::::default(); let mut defs = FxHashSet::::default(); @@ -47,27 +49,31 @@ impl<'a> Rule for DefsDominateUses<'a> { uses.extend(node.arguments(&self.dfg.value_lists).iter().copied()); match node.analyze_branch(&self.dfg.value_lists) { BranchInfo::NotABranch => (), - BranchInfo::SingleDest(_, args) => { - uses.extend(args.iter().copied()); + BranchInfo::SingleDest(info) => { + uses.extend(info.args.iter().copied()); } - BranchInfo::MultiDest(ref jts) => { - for jt in jts.iter() { - uses.extend(jt.args.iter().copied()); + BranchInfo::MultiDest(ref infos) => { + for info in infos.iter() { + uses.extend(info.args.iter().copied()); } } } // Make sure there are no uses of the instructions own results if !defs.is_disjoint(&uses) { - invalid_instruction!( - diagnostics, - node.key, - span, - "an instruction may not use its own results as arguments", - "This situation can only arise if one has manually modified the arguments of \ - an instruction, incorrectly inserting a value obtained from the set of \ - instruction results." - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + "an instruction may not use its own results as arguments", + ) + .with_help( + "This situation can only arise if one has manually modified the arguments \ + of an instruction, incorrectly inserting a value obtained from the set \ + of instruction results.", + ) + .into_report()); } // Next, ensure that all used values are dominated by their definition @@ -96,16 +102,20 @@ impl<'a> Rule for DefsDominateUses<'a> { // If we reach here, the use of `value` is not dominated by its definition, // so this use is invalid - invalid_instruction!( - diagnostics, - node.key, - span, - "an argument of this instruction, {value}, is not defined on all paths \ - leading to this point", - "All uses of a value must be dominated by its definition, i.e. all control \ - flow paths from the function entry to the point of each use must flow \ - through the point where that value is defined." - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + "an argument of this instruction, {value}, is not defined on all paths \ + leading to this point", + ) + .with_help( + "All uses of a value must be dominated by its definition, i.e. all \ + control flow paths from the function entry to the point of each use must \ + flow through the point where that value is defined.", + ) + .into_report()); } } @@ -138,7 +148,7 @@ impl<'a> Rule for BlockValidator<'a> { &mut self, block_data: &BlockData, diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { // Ignore blocks which are not attached to the function body if !self.dfg.is_block_linked(block_data.id) { return Ok(()); @@ -149,85 +159,90 @@ impl<'a> Rule for BlockValidator<'a> { let terminator = block_data.insts.back().get(); if terminator.is_none() { // This block is empty - invalid_block!( - diagnostics, - id, - self.span, - "block cannot be empty", - "Empty blocks are only valid when detached from the function body" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid block") + .with_primary_label(self.span, "block cannot be empty") + .with_help("Empty blocks are only valid when detached from the function body") + .into_report()); } let terminator = terminator.unwrap(); let op = terminator.opcode(); if !op.is_terminator() { - invalid_block!( - diagnostics, - id, - self.span, - "invalid block terminator", - format!( + // This block is empty + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid block") + .with_primary_label(self.span, "invalid block terminator") + .with_help(format!( "The last instruction in a block must be a terminator, but {id} ends with \ {op} which is not a valid terminator" - ) - ); + )) + .into_report()); } match terminator.analyze_branch(&self.dfg.value_lists) { - BranchInfo::SingleDest(destination, _) => { - if !self.dfg.is_block_linked(destination) { - invalid_instruction!( - diagnostics, - terminator.key, - terminator.span(), - "invalid successor", - format!( + BranchInfo::SingleDest(info) => { + if !self.dfg.is_block_linked(info.destination) { + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid block") + .with_primary_label(terminator.span(), "invalid successor") + .with_help(format!( "A block reference is only valid if the referenced block is present \ in the function layout. {id} references {destination}, but the \ - latter is not in the layout" - ) - ); + latter is not in the layout", + destination = info.destination + )) + .into_report()); } } - BranchInfo::MultiDest(ref jts) => { - if jts.is_empty() { - invalid_instruction!( - diagnostics, - terminator.key, - terminator.span(), - "incomplete {op} instruction", - "This instruction normally has 2 or more successors, but none were given." - ); + BranchInfo::MultiDest(ref infos) => { + if infos.is_empty() { + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid block") + .with_primary_label( + terminator.span(), + format!("incomplete '{op}' instruction"), + ) + .with_help( + "This instruction normally has 2 or more successors, but none were \ + given.", + ) + .into_report()); } let mut seen = SmallVec::<[Block; 4]>::default(); - for jt in jts.iter() { - let destination = jt.destination; + for info in infos.iter() { + let destination = info.destination; if !self.dfg.is_block_linked(destination) { - invalid_instruction!( - diagnostics, - terminator.key, - terminator.span(), - "invalid successor", - format!( + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid block") + .with_primary_label(terminator.span(), "invalid successor") + .with_help(format!( "A block reference is only valid if the referenced block is \ present in the function layout. {id} references {destination}, \ but the latter is not in the layout" - ) - ); + )) + .into_report()); } if seen.contains(&destination) { - invalid_instruction!( - diagnostics, - terminator.key, - terminator.span(), - "invalid {op} instruction", - format!( + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid block") + .with_primary_label( + terminator.span(), + format!("invalid '{op}' instruction"), + ) + .with_help(format!( "A given block may only be a successor along a single control \ flow path, but {id} uses {destination} as a successor for more \ than one path" - ) - ); + )) + .into_report()); } seen.push(destination); @@ -240,16 +255,15 @@ impl<'a> Rule for BlockValidator<'a> { for node in block_data.insts.iter() { let op = node.opcode(); if op.is_terminator() && node.key != terminator.key { - invalid_block!( - diagnostics, - id, - self.span, - "terminator found in middle of block", - format!( + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid block") + .with_primary_label(self.span, "terminator found in middle of block") + .with_help(format!( "A block may only have a terminator instruction as the last instruction \ in the block, but {id} uses {op} before the end of the block" - ) - ); + )) + .into_report()); } } diff --git a/hir-analysis/src/validation/function.rs b/hir-analysis/src/validation/function.rs index 141a4ea6..2ad9262f 100644 --- a/hir-analysis/src/validation/function.rs +++ b/hir-analysis/src/validation/function.rs @@ -1,9 +1,9 @@ -use miden_diagnostics::{DiagnosticsHandler, Severity, Spanned}; -use midenc_hir::*; - -use super::{ - BlockValidator, DefsDominateUses, NamingConventions, Rule, TypeCheck, ValidationError, +use midenc_hir::{ + diagnostics::{DiagnosticsHandler, Report, Severity, Spanned}, + *, }; + +use super::{BlockValidator, DefsDominateUses, NamingConventions, Rule, TypeCheck}; use crate::{ControlFlowGraph, DominatorTree}; /// This validation rule ensures that function-local invariants are upheld: @@ -26,7 +26,7 @@ impl Rule for FunctionValidator { &mut self, function: &Function, diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { // Validate the function declaration let mut rules = NamingConventions.chain(CoherentSignature::new(self.in_kernel_module)); rules.validate(function, diagnostics)?; @@ -76,18 +76,21 @@ impl Rule for CoherentSignature { &mut self, function: &Function, diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { let span = function.id.span(); // 1 let linkage = function.signature.linkage; if !matches!(linkage, Linkage::External | Linkage::Internal) { - invalid_function!( - diagnostics, - function.id, - "the signature of this function specifies '{linkage}' linkage, but only \ - 'external' or 'internal' are valid" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "the signature of this function specifies '{linkage}' linkage, but only \ + 'external' or 'internal' are valid", + ) + .into_report()); } // 2 @@ -96,34 +99,48 @@ impl Rule for CoherentSignature { if self.in_kernel_module { let is_public = function.signature.is_public(); if is_public && !is_kernel_function { - invalid_function!( - diagnostics, - function.id, - function.id.span(), - "the '{cc}' calling convention may only be used with 'internal' linkage in \ - kernel modules", - "This function is declared with 'external' linkage in a kernel module, so it \ - must use the 'kernel' calling convention" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + format!( + "the '{cc}' calling convention may only be used with 'internal' \ + linkage in kernel modules", + ), + ) + .with_help( + "This function is declared with 'external' linkage in a kernel module, so \ + it must use the 'kernel' calling convention", + ) + .into_report()); } else if !is_public && is_kernel_function { - invalid_function!( - diagnostics, - function.id, - function.id.span(), - "the 'kernel' calling convention may only be used with 'external' linkage", - "This function has 'internal' linkage, so it must either be made 'external', \ - or a different calling convention must be used" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "the 'kernel' calling convention may only be used with 'external' linkage", + ) + .with_help( + "This function has 'internal' linkage, so it must either be made \ + 'external', or a different calling convention must be used", + ) + .into_report()); } } else if is_kernel_function { - invalid_function!( - diagnostics, - function.id, - function.id.span(), - "the 'kernel' calling convention may only be used in kernel modules", - "Kernel functions may only be declared in kernel modules, so you must either \ - change the module type, or change the calling convention of this function" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "the 'kernel' calling convention may only be used in kernel modules", + ) + .with_help( + "Kernel functions may only be declared in kernel modules, so you must either \ + change the module type, or change the calling convention of this function", + ) + .into_report()); } // 3 @@ -147,15 +164,19 @@ impl Rule for CoherentSignature { let mut effective_stack_usage = 0; let params = function.dfg.block_args(function.dfg.entry_block()); if params.len() != function.signature.arity() { - invalid_function!( - diagnostics, - function.id, - function.id.span(), - "function signature and entry block have different arities", - "This happens if the signature or entry block are modified without updating the \ - other, make sure the number and types of all parameters are the same in both the \ - signature and the entry block" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "function signature and entry block have different arities", + ) + .with_help( + "This happens if the signature or entry block are modified without updating \ + the other, make sure the number and types of all parameters are the same in \ + both the signature and the entry block", + ) + .into_report()); } for (i, param) in function.signature.params.iter().enumerate() { let is_first = i == 0; @@ -165,40 +186,50 @@ impl Rule for CoherentSignature { let value_ty = function.dfg.value_type(value); if param_ty != value_ty { - invalid_function!( - diagnostics, - function.id, - span, - "parameter type mismatch between signature and entry block", - format!( + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "parameter type mismatch between signature and entry block", + ) + .with_help(format!( "The function declares this parameter as having type {param_ty}, but the \ actual type is {value_ty}" - ) - ); + )) + .into_report()); } let is_integer = param_ty.is_integer(); let is_signed_integer = param_ty.is_signed_integer(); match param.extension { ArgumentExtension::Zext if is_signed_integer => { - invalid_function!( - diagnostics, - function.id, - span, - "signed integer parameters may not be combined with zero-extension", - "Zero-extending a signed-integer loses the signedness, you should use \ - signed-extension instead" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "signed integer parameters may not be combined with zero-extension", + ) + .with_help( + "Zero-extending a signed-integer loses the signedness, you should use \ + signed-extension instead", + ) + .into_report()); } ArgumentExtension::Sext | ArgumentExtension::Zext if !is_integer => { - invalid_function!( - diagnostics, - function.id, - span, - "non-integer parameters may not be combined with argument extension \ - attributes", - "Argument extension has no meaning for types other than integers" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "non-integer parameters may not be combined with argument extension \ + attributes", + ) + .with_help( + "Argument extension has no meaning for types other than integers", + ) + .into_report()); } _ => (), } @@ -210,69 +241,85 @@ impl Rule for CoherentSignature { } if is_kernel_function && (is_sret || is_pointer) { - invalid_function!( - diagnostics, - function.id, - span, - "functions using the 'kernel' calling convention may not use sret or \ - pointer-typed parameters", - "Kernel functions are invoked in a different memory context, so they may not \ - pass or return values by reference" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "functions using the 'kernel' calling convention may not use sret or \ + pointer-typed parameters", + ) + .with_help( + "Kernel functions are invoked in a different memory context, so they may \ + not pass or return values by reference", + ) + .into_report()); } if !is_kernel_function { if is_sret { if sret_count > 1 || !is_first { - invalid_function!( - diagnostics, - function.id, - span, - "a function may only have a single sret parameter, and it must be the \ - first parameter", - "The sret parameter type is used to return a large value from a \ - function, but it may only be used for functions with a single return \ - value" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "a function may only have a single sret parameter, and it must be \ + the first parameter", + ) + .with_help( + "The sret parameter type is used to return a large value from a \ + function, but it may only be used for functions with a single \ + return value", + ) + .into_report()); } if !is_pointer { - invalid_function!( - diagnostics, - function.id, - span, - "sret parameters must be pointer-typed, but got {param_ty}", - format!( + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "sret parameters must be pointer-typed, but got {param_ty}", + ) + .with_help(format!( "Did you mean to define this parameter with type {}?", &Type::Ptr(Box::new(param_ty.clone())) - ) - ); + )) + .into_report()); } if !function.signature.results.is_empty() { - invalid_function!( - diagnostics, - function.id, - span, - "functions with an sret parameter must have no results", - "An sret parameter is used in place of normal return values, but this \ - function uses both, which is not valid. You should remove the \ - results from the function signature." - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "functions with an sret parameter must have no results", + ) + .with_help( + "An sret parameter is used in place of normal return values, but \ + this function uses both, which is not valid. You should remove \ + the results from the function signature.", + ) + .into_report()); } } let size_in_bytes = param_ty.size_in_bytes(); if !is_pointer && size_in_bytes > 8 { - invalid_function!( - diagnostics, - function.id, - span, - "this parameter type is too large to pass by value", - format!( + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "this parameter type is too large to pass by value", + ) + .with_help(format!( "This parameter has type {param_ty}, you must refactor this function \ to pass it by reference instead" - ) - ); + )) + .into_report()); } } @@ -281,49 +328,59 @@ impl Rule for CoherentSignature { } if effective_stack_usage > 16 { - invalid_function!( - diagnostics, - function.id, - span, - "this function has a signature with too many parameters", - "Due to the constraints of the Miden VM, all function parameters must fit on the \ - operand stack, which is 16 elements (each of which is effectively 4 bytes, a \ - maximum of 64 bytes). The layout of the parameter list of this function requires \ - more than this limit. You should either remove parameters, or combine some of \ - them into a struct which is then passed by reference." - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label(span, "this function has a signature with too many parameters") + .with_help( + "Due to the constraints of the Miden VM, all function parameters must fit on \ + the operand stack, which is 16 elements (each of which is effectively 4 \ + bytes, a maximum of 64 bytes). The layout of the parameter list of this \ + function requires more than this limit. You should either remove parameters, \ + or combine some of them into a struct which is then passed by reference.", + ) + .into_report()); } for (i, result) in function.signature.results.iter().enumerate() { if result.purpose == ArgumentPurpose::StructReturn { - invalid_function!( - diagnostics, - function.id, - "the sret attribute is only permitted on function parameters" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "the sret attribute is only permitted on function parameters", + ) + .into_report()); } if result.extension != ArgumentExtension::None { - invalid_function!( - diagnostics, - function.id, - "the argument extension attributes are only permitted on function parameters" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + span, + "the argument extension attributes are only permitted on function \ + parameters", + ) + .into_report()); } let size_in_bytes = result.ty.size_in_bytes(); if !result.ty.is_pointer() && size_in_bytes > 8 { - invalid_function!( - diagnostics, - function.id, - function.id.span(), - "This function specifies a result type which is too large to pass by value", - format!( + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function signature") + .with_primary_label( + function.id.span(), + "This function specifies a result type which is too large to pass by value", + ) + .with_help(format!( "The parameter at index {} has type {}, you must refactor this function \ to pass it by reference instead", i, &result.ty - ) - ); + )) + .into_report()); } } diff --git a/hir-analysis/src/validation/mod.rs b/hir-analysis/src/validation/mod.rs index 43ab3372..59fa947f 100644 --- a/hir-analysis/src/validation/mod.rs +++ b/hir-analysis/src/validation/mod.rs @@ -1,180 +1,15 @@ -macro_rules! bug { - ($diagnostics:ident, $msg:literal) => {{ - diagnostic!($diagnostics, Severity::Bug, $msg); - }}; - - ($diagnostics:ident, $msg:literal, $span:expr, $label:expr) => {{ - diagnostic!($diagnostics, Severity::Bug, $msg, $span, $label); - }}; - - ($diagnostics:ident, $msg:literal, $span:expr, $label:expr, $note:expr) => {{ - diagnostic!($diagnostics, Severity::Bug, $msg, $span, $label, $note); - }}; - - ($diagnostics:ident, $msg:literal, $span:expr, $label:expr, $span2:expr, $label2:expr) => {{ - diagnostic!($diagnostics, Severity::Bug, $msg, $span, $label, $span2, $label2); - }}; -} - -macro_rules! error { - ($diagnostics:ident, $msg:literal) => {{ - diagnostic!($diagnostics, Severity::Error, $msg); - }}; - - ($diagnostics:ident, $msg:literal, $span:expr, $label:expr) => {{ - diagnostic!($diagnostics, Severity::Error, $msg, $span, $label); - }}; - - ($diagnostics:ident, $msg:literal, $span:expr, $label:expr, $note:expr) => {{ - diagnostic!($diagnostics, Severity::Error, $msg, $span, $label, $note); - }}; - - ($diagnostics:ident, $msg:literal, $span:expr, $label:expr, $span2:expr, $label2:expr) => {{ - diagnostic!($diagnostics, Severity::Error, $msg, $span, $label, $span2, $label2); - }}; -} - -macro_rules! invalid_instruction { - ($diagnostics:ident, $inst:expr, $span:expr, $label:expr) => {{ - let span = $span; - let reason = format!($label); - bug!($diagnostics, "invalid instruction", span, reason.as_str()); - return Err(crate::validation::ValidationError::InvalidInstruction { - span, - inst: $inst, - reason, - }); - }}; - - ($diagnostics:ident, $inst:expr, $span:expr, $label:expr, $note:expr) => {{ - let span = $span; - let reason = format!($label); - bug!($diagnostics, "invalid instruction", span, reason.as_str(), $note); - return Err(crate::validation::ValidationError::InvalidInstruction { - span, - inst: $inst, - reason, - }); - }}; -} - -macro_rules! invalid_block { - ($diagnostics:ident, $block:expr, $span:expr, $label:expr) => {{ - let reason = format!($label); - bug!($diagnostics, "invalid block", $span, reason.as_str()); - return Err(crate::validation::ValidationError::InvalidBlock { - block: $block, - reason, - }); - }}; - - ($diagnostics:ident, $block:expr, $span:expr, $label:expr, $note:expr) => {{ - let reason = format!($label); - bug!($diagnostics, "invalid block", $span, reason.as_str(), $note); - return Err(crate::validation::ValidationError::InvalidBlock { - block: $block, - reason, - }); - }}; -} - -macro_rules! invalid_module { - ($diagnostics:ident, $module:expr, $label:expr) => {{ - invalid_module!($diagnostics, $module, $module.span(), $label); - }}; - - ($diagnostics:ident, $module:expr, $span:expr, $label:expr) => {{ - let span = $span; - let reason = format!($label); - error!($diagnostics, "invalid module", span, reason.as_str()); - return Err(crate::validation::ValidationError::InvalidModule { - module: $module, - reason, - }); - }}; - - ($diagnostics:ident, $module:expr, $span:expr, $label:expr, $note:expr) => {{ - let span = $span; - let reason = format!($label); - error!($diagnostics, "invalid module", span, reason.as_str(), $note); - return Err(crate::validation::ValidationError::InvalidModule { - module: $module, - reason, - }); - }}; -} - -macro_rules! invalid_function { - ($diagnostics:ident, $function:expr, $label:expr) => {{ - invalid_function!($diagnostics, $function, $function.span(), $label); - }}; - - ($diagnostics:ident, $function:expr, $span:expr, $label:expr) => {{ - let span = $span; - let reason = format!($label); - error!($diagnostics, "invalid function", span, reason.as_str()); - return Err(crate::validation::ValidationError::InvalidFunction { - function: $function, - reason, - }); - }}; - - ($diagnostics:ident, $function:expr, $span:expr, $label:expr, $note:expr) => {{ - let span = $span; - let reason = format!($label); - error!($diagnostics, "invalid function", span, reason.as_str(), $note); - return Err(crate::validation::ValidationError::InvalidFunction { - function: $function, - reason, - }); - }}; - - ($diagnostics:ident, $function:expr, $span:expr, $label:expr, $span2:expr, $label2:expr) => {{ - let span = $span; - let reason = format!($label); - error!($diagnostics, "invalid function", span, reason.as_str()); - $diagnostics - .diagnostic(miden_diagnostics::Severity::Error) - .with_message("invalid function") - .with_primary_label(span, reason.as_str()) - .with_secondary_label($span2, $label2) - .emit(); - return Err(crate::validation::ValidationError::InvalidFunction { - function: $function, - reason, - }); - }}; -} - -macro_rules! invalid_global { - ($diagnostics:ident, $name:expr, $label:expr) => {{ - invalid_global!($diagnostics, $name, $name.span(), $label); - }}; - - ($diagnostics:ident, $name:expr, $span:expr, $label:expr) => {{ - let span = $span; - let reason = format!($label); - error!($diagnostics, "invalid global variable", span, reason.as_str()); - return Err(crate::validation::ValidationError::InvalidGlobalVariable { - name: $name, - reason, - }); - }}; -} - mod block; mod function; mod naming; mod typecheck; -use miden_diagnostics::DiagnosticsHandler; use midenc_hir::{ + diagnostics::{DiagnosticsHandler, Report}, pass::{Analysis, AnalysisManager, AnalysisResult}, *, }; use midenc_session::Session; -pub use self::typecheck::TypeError; use self::{ block::{BlockValidator, DefsDominateUses}, function::FunctionValidator, @@ -182,101 +17,6 @@ use self::{ typecheck::TypeCheck, }; -/// This error is produced by validation rules run against the IR -#[derive(Debug, thiserror::Error)] -pub enum ValidationError { - /// A validation rule indicates a module is invalid - #[error("invalid module '{module}': {reason}")] - InvalidModule { module: Ident, reason: String }, - /// A validation rule indicates a global variable is invalid - #[error("invalid global variable '{name}': {reason}")] - InvalidGlobalVariable { name: Ident, reason: String }, - /// A validation rule indicates a function is invalid - #[error("invalid function '{function}': {reason}")] - InvalidFunction { - function: FunctionIdent, - reason: String, - }, - /// A validation rule indicates a block is invalid - #[error("invalid block '{block}': {reason}")] - InvalidBlock { block: Block, reason: String }, - /// A validation rule indicates an instruction is invalid - #[error("invalid instruction '{inst}': {reason}")] - InvalidInstruction { - span: SourceSpan, - inst: Inst, - reason: String, - }, - /// A type error was found - #[error("type error: {0}")] - TypeError(#[from] TypeError), - /// An unknown validation error occurred - #[error(transparent)] - Failed(#[from] anyhow::Error), -} -#[cfg(test)] -impl PartialEq for ValidationError { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - ( - Self::InvalidModule { - module: am, - reason: ar, - }, - Self::InvalidModule { - module: bm, - reason: br, - }, - ) => am == bm && ar == br, - ( - Self::InvalidGlobalVariable { - name: an, - reason: ar, - }, - Self::InvalidGlobalVariable { - name: bn, - reason: br, - }, - ) => an == bn && ar == br, - ( - Self::InvalidFunction { - function: af, - reason: ar, - }, - Self::InvalidFunction { - function: bf, - reason: br, - }, - ) => af == bf && ar == br, - ( - Self::InvalidBlock { - block: ab, - reason: ar, - }, - Self::InvalidBlock { - block: bb, - reason: br, - }, - ) => ab == bb && ar == br, - ( - Self::InvalidInstruction { - inst: ai, - reason: ar, - .. - }, - Self::InvalidInstruction { - inst: bi, - reason: br, - .. - }, - ) => ai == bi && ar == br, - (Self::TypeError(a), Self::TypeError(b)) => a == b, - (Self::Failed(a), Self::Failed(b)) => a.to_string() == b.to_string(), - (..) => false, - } - } -} - inventory::submit! { midenc_session::CompileFlag::new("validate") .long("no-validate") @@ -288,11 +28,7 @@ inventory::submit! { /// A [Rule] validates some specific type of behavior on an item of type `T` pub trait Rule { /// Validate `item`, using `diagnostics` to emit relevant diagnostics. - fn validate( - &mut self, - item: &T, - diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError>; + fn validate(&mut self, item: &T, diagnostics: &DiagnosticsHandler) -> Result<(), Report>; /// Combine two rules into one rule fn chain(self, rule: R) -> RuleSet @@ -307,11 +43,7 @@ impl Rule for &mut R where R: Rule, { - fn validate( - &mut self, - item: &T, - diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + fn validate(&mut self, item: &T, diagnostics: &DiagnosticsHandler) -> Result<(), Report> { (*self).validate(item, diagnostics) } } @@ -319,21 +51,13 @@ impl Rule for Box where R: Rule, { - fn validate( - &mut self, - item: &T, - diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + fn validate(&mut self, item: &T, diagnostics: &DiagnosticsHandler) -> Result<(), Report> { (**self).validate(item, diagnostics) } } -impl Rule for dyn FnMut(&T, &DiagnosticsHandler) -> Result<(), ValidationError> { +impl Rule for dyn FnMut(&T, &DiagnosticsHandler) -> Result<(), Report> { #[inline] - fn validate( - &mut self, - item: &T, - diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + fn validate(&mut self, item: &T, diagnostics: &DiagnosticsHandler) -> Result<(), Report> { self(item, diagnostics) } } @@ -369,11 +93,7 @@ where A: Rule, B: Rule, { - fn validate( - &mut self, - item: &T, - diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + fn validate(&mut self, item: &T, diagnostics: &DiagnosticsHandler) -> Result<(), Report> { self.a .validate(item, diagnostics) .and_then(|_| self.b.validate(item, diagnostics)) @@ -384,7 +104,7 @@ where /// /// This validates all rules which apply to items at/within module scope. #[derive(PassInfo)] -pub struct ModuleValidationAnalysis(Result<(), ValidationError>); +pub struct ModuleValidationAnalysis(Result<(), Report>); impl Analysis for ModuleValidationAnalysis { type Entity = Module; @@ -397,15 +117,11 @@ impl Analysis for ModuleValidationAnalysis { return Ok(Self(Ok(()))); } - match Self::validate(module, session) { - // If an unexpected error occurs, treat it as a failure of the pass itself - Err(ValidationError::Failed(err)) => Err(err.into()), - result => Ok(Self(result)), - } + Ok(Self(Self::validate(module, session))) } } impl ModuleValidationAnalysis { - fn validate(module: &Module, session: &Session) -> Result<(), ValidationError> { + fn validate(module: &Module, session: &Session) -> Result<(), Report> { // Apply module-scoped rules let mut rules = NamingConventions; rules.validate(module, &session.diagnostics)?; @@ -425,7 +141,7 @@ impl ModuleValidationAnalysis { Ok(()) } } -impl From for Result<(), ValidationError> { +impl From for Result<(), Report> { fn from(analysis: ModuleValidationAnalysis) -> Self { analysis.0 } diff --git a/hir-analysis/src/validation/naming.rs b/hir-analysis/src/validation/naming.rs index b1078e04..66800a71 100644 --- a/hir-analysis/src/validation/naming.rs +++ b/hir-analysis/src/validation/naming.rs @@ -1,7 +1,9 @@ -use miden_diagnostics::{DiagnosticsHandler, Severity, Spanned}; -use midenc_hir::*; +use midenc_hir::{ + diagnostics::{DiagnosticsHandler, Report, Severity, Spanned}, + *, +}; -use super::{Rule, ValidationError}; +use super::Rule; /// This validation rule ensures that all identifiers adhere to the rules of their respective items. pub struct NamingConventions; @@ -10,7 +12,7 @@ impl Rule for NamingConventions { &mut self, module: &Module, diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { // Make sure all functions in this module have the same module name in their id for function in module.functions() { let id = function.id; @@ -19,30 +21,43 @@ impl Rule for NamingConventions { module: module.name, function: id.function, }; - invalid_function!( - diagnostics, - function.id, - function.id.span(), - "the fully-qualified name of this function is '{id}'", - module.name.span(), - format!("but we expected '{expected_name}' because it belongs to this module") - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function name") + .with_primary_label( + function.id.span(), + format!("the fully-qualified name of this function is '{id}'"), + ) + .with_secondary_label( + module.name.span(), + format!( + "but we expected '{expected_name}' because it belongs to this module" + ), + ) + .into_report()); } } // 1. Must not be empty let name = module.name.as_str(); if name.is_empty() { - invalid_module!(diagnostics, module.name, "module name cannot be empty"); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid module name") + .with_primary_label(module.name.span, "module name cannot be empty") + .into_report()); } // 2. Must begin with a lowercase ASCII alphabetic character if !name.starts_with(is_lower_ascii_alphabetic) { - invalid_module!( - diagnostics, - module.name, - "module name must start with a lowercase, ascii-alphabetic character" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid module name") + .with_primary_label( + module.name.span(), + "module name must start with a lowercase, ascii-alphabetic character", + ) + .into_report()); } // 3. May otherwise consist of any number of characters of the following classes: @@ -54,6 +69,7 @@ impl Rule for NamingConventions { let mut char_indices = name.char_indices().peekable(); let mut is_namespaced = false; while let Some((offset, c)) = char_indices.next() { + let offset = offset as u32; match c { c if c.is_ascii_alphanumeric() => continue, '_' | '-' | '+' | '$' | '@' => continue, @@ -64,33 +80,39 @@ impl Rule for NamingConventions { continue; } _ => { - let pos = module.name.span().start() + offset; - let span = SourceSpan::new(pos, pos); - invalid_module!( - diagnostics, - module.name, - span, - "module name contains invalid character ':'", - "Did you mean to use the namespacing operator '::'?" - ); + let module_name_span = module.name.span(); + let source_id = module_name_span.source_id(); + let pos = module_name_span.start() + offset; + let span = SourceSpan::at(source_id, pos); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid module name") + .with_primary_label(span, "module name contains invalid character ':'") + .with_help("Did you mean to use the namespacing operator '::'?") + .into_report()); } }, c if c.is_whitespace() => { - invalid_module!( - diagnostics, - module.name, - "module names may not contain whitespace" - ); + let module_name_span = module.name.span(); + let source_id = module_name_span.source_id(); + let pos = module_name_span.start() + offset; + let span = SourceSpan::at(source_id, pos); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid module name") + .with_primary_label(span, "module names may not contain whitespace") + .into_report()); } c => { - let pos = module.name.span().start() + offset; - let span = SourceSpan::new(pos, pos); - invalid_module!( - diagnostics, - module.name, - span, - "{c} is not valid in module names" - ); + let module_name_span = module.name.span(); + let source_id = module_name_span.source_id(); + let pos = module_name_span.start() + offset; + let span = SourceSpan::at(source_id, pos); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid module name") + .with_primary_label(span, format!("'{c}' is not valid in module names")) + .into_report()); } } } @@ -98,27 +120,31 @@ impl Rule for NamingConventions { // 5. The namespacing operator may only appear between two valid module identifiers // 6. Namespaced module names must adhere to the above rules in each submodule identifier if is_namespaced { - let mut offset = 0; + let mut offset = 0u32; for component in name.split("::") { - let len = component.as_bytes().len(); - let start = module.name.span().start() + offset; - let span = SourceSpan::new(start, start + len); + let len = component.as_bytes().len() as u32; + let module_name_span = module.name.span(); + let source_id = module_name_span.source_id(); + let start = module_name_span.start() + offset; + let span = SourceSpan::new(source_id, start..(start + len)); if component.is_empty() { - invalid_module!( - diagnostics, - module.name, - span, - "submodule names cannot be empty" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid module namespace") + .with_primary_label(span, "submodule names cannot be empty") + .into_report()); } if !name.starts_with(is_lower_ascii_alphabetic) { - invalid_module!( - diagnostics, - module.name, - span, - "submodule name must start with a lowercase, ascii-alphabetic character" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid module namespace") + .with_primary_label( + span, + "submodule name must start with a lowercase, ascii-alphabetic \ + character", + ) + .into_report()); } offset += len + 2; @@ -133,13 +159,17 @@ impl Rule for NamingConventions { &mut self, function: &Function, diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { let name = function.id.function.as_str(); let span = function.id.function.span(); // 1. Must not be empty if name.is_empty() { - invalid_function!(diagnostics, function.id, "function names cannot be empty"); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function name") + .with_primary_label(span, "function names cannot be empty") + .into_report()); } // 2. Must start with an ASCII-alphabetic character, underscore, `$` or `@` @@ -149,25 +179,29 @@ impl Rule for NamingConventions { // 3. Otherwise, no restrictions, but may not contain whitespace if let Err((offset, c)) = is_valid_identifier(name, name_starts_with, char::is_whitespace) { + let offset = offset as u32; if c.is_whitespace() { + let source_id = span.source_id(); let pos = span.start() + offset; - let span = SourceSpan::new(pos, pos); - invalid_function!( - diagnostics, - function.id, - span, - "function names may not contain whitespace" - ); + let span = SourceSpan::at(source_id, pos); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function name") + .with_primary_label(span, "function names may not contain whitespace") + .into_report()); } else { debug_assert_eq!(offset, 0); - let span = SourceSpan::new(span.start(), span.start()); - invalid_function!( - diagnostics, - function.id, - span, - "function names must start with an ascii-alphabetic character, '_', '$', or \ - '@'" - ); + let source_id = span.source_id(); + let span = SourceSpan::at(source_id, span.start()); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid function name") + .with_primary_label( + span, + "function names must start with an ascii-alphabetic character, '_', '$', \ + or '@'", + ) + .into_report()); } } @@ -179,13 +213,17 @@ impl Rule for NamingConventions { &mut self, global: &GlobalVariableData, diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { let span = global.name.span(); let name = global.name.as_str(); // 1. Must not be empty if name.is_empty() { - invalid_global!(diagnostics, global.name, "global variable names cannot be empty"); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid global variable name") + .with_primary_label(span, "global variable names cannot be empty") + .into_report()); } // 2. Must start with an ASCII-alphabetic character, underscore, `.`, `$` or `@` @@ -195,25 +233,29 @@ impl Rule for NamingConventions { // 3. Otherwise, no restrictions, but may not contain whitespace if let Err((offset, c)) = is_valid_identifier(name, name_starts_with, char::is_whitespace) { + let offset = offset as u32; if c.is_whitespace() { + let source_id = span.source_id(); let pos = span.start() + offset; - let span = SourceSpan::new(pos, pos); - invalid_global!( - diagnostics, - global.name, - span, - "global variable names may not contain whitespace" - ); + let span = SourceSpan::at(source_id, pos); + + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid global variable name") + .with_primary_label(span, "global variable names may not contain whitespace") + .into_report()); } else { debug_assert_eq!(offset, 0); - let span = SourceSpan::new(span.start(), span.start()); - invalid_global!( - diagnostics, - global.name, - span, - "global variable names must start with an ascii-alphabetic character, '_', \ - '.', '$', or '@'" - ); + let span = SourceSpan::at(span.source_id(), span.start()); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid global variable name") + .with_primary_label( + span, + "global variable names must start with an ascii-alphabetic character, \ + '_', '.', '$', or '@'", + ) + .into_report()); } } diff --git a/hir-analysis/src/validation/typecheck.rs b/hir-analysis/src/validation/typecheck.rs index 89a08f8e..b31e5580 100644 --- a/hir-analysis/src/validation/typecheck.rs +++ b/hir-analysis/src/validation/typecheck.rs @@ -1,13 +1,15 @@ +use alloc::collections::BTreeMap; use core::fmt; -use miden_diagnostics::{DiagnosticsHandler, Severity, Spanned}; -use midenc_hir::*; -use rustc_hash::FxHashMap; +use midenc_hir::{ + diagnostics::{DiagnosticsHandler, Report, Severity, Spanned}, + *, +}; -use super::{Rule, ValidationError}; +use super::Rule; /// This error is produced when type checking the IR for function or module -#[derive(Debug, thiserror::Error, PartialEq, Eq)] +#[derive(Debug, thiserror::Error)] pub enum TypeError { /// The number of arguments given does not match what is expected by the instruction #[error("expected {expected} arguments, but {actual} are given")] @@ -29,22 +31,6 @@ pub enum TypeError { actual: Type, index: usize, }, - /// The number of arguments given to a successor block does not match what is expected by the - /// block - #[error("{successor} expected {expected} arguments, but {actual} are given")] - IncorrectSuccessorArgumentCount { - successor: Block, - expected: usize, - actual: usize, - }, - /// One of the arguments to a successor block is not of the correct type - #[error("{successor} expected argument of {expected} type at index {index}, got {actual}")] - IncorrectSuccessorArgumentType { - successor: Block, - expected: Type, - actual: Type, - index: usize, - }, /// An attempt was made to cast from a larger integer type to a smaller one via widening cast, /// e.g. `zext` #[error("expected result to be an integral type larger than {expected}, but got {actual}")] @@ -86,7 +72,7 @@ impl<'a> Rule for TypeCheck<'a> { &mut self, block_data: &BlockData, diagnostics: &DiagnosticsHandler, - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { // Traverse the block, checking each instruction in turn for node in block_data.insts.iter() { let span = node.span(); @@ -106,36 +92,51 @@ impl<'a> Rule for TypeCheck<'a> { | Opcode::ImmU64 | Opcode::ImmI64 | Opcode::ImmFelt - | Opcode::ImmF64 => invalid_instruction!( - diagnostics, - node.key, - span, - "immediate opcode '{opcode}' cannot be used with non-immediate argument" - ), + | Opcode::ImmF64 => { + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "immediate opcode '{opcode}' cannot be used with \ + non-immediate argument" + ), + ) + .into_report()); + } _ => { typechecker.check(&[*arg], results)?; } }, Instruction::UnaryOpImm(UnaryOpImm { imm, .. }) => match opcode { - Opcode::PtrToInt => invalid_instruction!( - diagnostics, - node.key, - span, - "'{opcode}' cannot be used with an immediate value" - ), + Opcode::PtrToInt => { + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!("'{opcode}' cannot be used with an immediate value"), + ) + .into_report()); + } _ => { typechecker.check_immediate(&[], imm, results)?; } }, Instruction::Load(LoadOp { ref ty, addr, .. }) => { if ty.size_in_felts() > 4 { - invalid_instruction!( - diagnostics, - node.key, - span, - "cannot load a value of type {ty} on the stack, as it is larger than \ - 16 bytes" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "cannot load a value of type {ty} on the stack, as it is \ + larger than 16 bytes" + ), + ) + .into_report()); } typechecker.check(&[*addr], results)?; } @@ -153,60 +154,80 @@ impl<'a> Rule for TypeCheck<'a> { let expected_ty = self.dfg.local_type(*local); let actual_ty = self.dfg.value_type(args[0]); if actual_ty != expected_ty { - return Err(ValidationError::TypeError( - TypeError::IncorrectArgumentType { - expected: expected_ty.clone().into(), - actual: actual_ty.clone(), - index: 0, - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label( + span, + format!( + "local type is {expected_ty}, but argument is \ + {actual_ty}" + ), + ) + .into_report()); } typechecker.check(args, results)?; } Opcode::Load => { if !args.is_empty() { - invalid_instruction!( - diagnostics, - node.key, - span, - "local.load does not accept any arguments" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + "local.load does not accept any arguments", + ) + .into_report()); } if results.len() != 1 { - invalid_instruction!( - diagnostics, - node.key, - span, - "local.load should have exactly one result" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + "local.load should have exactly one result", + ) + .into_report()); } let local_ty = self.dfg.local_type(*local); if local_ty.size_in_felts() > 4 { - invalid_instruction!( - diagnostics, - node.key, - span, - "cannot load a value of type {local_ty} on the stack, as it \ - is larger than 16 bytes" - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + "cannot load a value of type {local_ty} on the stack, as \ + it is larger than 16 bytes", + ) + .into_report()); } let result_ty = self.dfg.value_type(results[0]); if local_ty != result_ty { - return Err(ValidationError::TypeError( - TypeError::IncorrectArgumentType { - expected: local_ty.clone().into(), - actual: result_ty.clone(), - index: 0, - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label( + span, + format!( + "local type is {local_ty}, but result of load is \ + {result_ty}" + ), + ) + .into_report()); } } - opcode => invalid_instruction!( - diagnostics, - node.key, - span, - "opcode '{opcode}' cannot be used with local variables" - ), + opcode => { + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "opcode '{opcode}' cannot be used with local variables" + ), + ) + .into_report()); + } } } Instruction::GlobalValue(_) @@ -221,63 +242,95 @@ impl<'a> Rule for TypeCheck<'a> { Instruction::Ret(Ret { ref args, .. }) => { let args = args.as_slice(&self.dfg.value_lists); if args.len() != self.signature.results.len() { - return Err(ValidationError::TypeError( - TypeError::IncorrectArgumentCount { - expected: self.signature.results.len(), - actual: args.len(), - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "the function signature states that {} results should be \ + returned, but {} were given", + self.signature.results.len(), + args.len() + ), + ) + .into_report()); } for (index, (expected, arg)) in self.signature.results.iter().zip(args.iter().copied()).enumerate() { let actual = self.dfg.value_type(arg); if actual != &expected.ty { - return Err(ValidationError::TypeError( - TypeError::IncorrectArgumentType { - expected: expected.ty.clone().into(), - actual: actual.clone(), - index, - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label( + span, + format!( + "result at index {index} is {actual}, but function \ + signature expects {}", + &expected.ty + ), + ) + .into_report()); } } } Instruction::RetImm(RetImm { ref arg, .. }) => { if self.signature.results.len() != 1 { - return Err(ValidationError::TypeError( - TypeError::IncorrectArgumentCount { - expected: self.signature.results.len(), - actual: 1, - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "the function signature states that {} results should be \ + returned, but {} were given", + self.signature.results.len(), + 1 + ), + ) + .into_report()); } let expected = &self.signature.results[0].ty; let actual = arg.ty(); if &actual != expected { - return Err(ValidationError::TypeError(TypeError::IncorrectArgumentType { - expected: expected.clone().into(), - actual, - index: 0, - })); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label( + span, + format!( + "result is {actual}, but function signature expects {expected}" + ), + ) + .into_report()); } } Instruction::Br(Br { - ref args, - destination, + successor: + Successor { + destination, + ref args, + }, .. }) => { let successor = *destination; let expected = self.dfg.block_args(successor); let args = args.as_slice(&self.dfg.value_lists); if args.len() != expected.len() { - return Err(ValidationError::TypeError( - TypeError::IncorrectSuccessorArgumentCount { - successor, - expected: expected.len(), - actual: args.len(), - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "{successor} expects {} arguments, but is being given {}", + expected.len(), + args.len() + ), + ) + .into_report()); } for (index, (param, arg)) in expected.iter().copied().zip(args.iter().copied()).enumerate() @@ -285,40 +338,45 @@ impl<'a> Rule for TypeCheck<'a> { let expected = self.dfg.value_type(param); let actual = self.dfg.value_type(arg); if actual != expected { - return Err(ValidationError::TypeError( - TypeError::IncorrectSuccessorArgumentType { - successor, - expected: expected.clone(), - actual: actual.clone(), - index, - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label( + span, + format!( + "{successor} argument at index {index} is expected to be \ + {expected}, but got {actual}" + ), + ) + .into_report()); } } } Instruction::CondBr(CondBr { cond, - then_dest: (then_dest, then_args), - else_dest: (else_dest, else_args), + ref then_dest, + ref else_dest, .. }) => { typechecker.check(&[*cond], results)?; - let then_dest = *then_dest; - let else_dest = *else_dest; - for (successor, dest_args) in - [(then_dest, then_args), (else_dest, else_args)].into_iter() - { - let expected = self.dfg.block_args(successor); - let args = dest_args.as_slice(&self.dfg.value_lists); + for successor in [then_dest, else_dest].into_iter() { + let expected = self.dfg.block_args(successor.destination); + let args = successor.args.as_slice(&self.dfg.value_lists); if args.len() != expected.len() { - return Err(ValidationError::TypeError( - TypeError::IncorrectSuccessorArgumentCount { - successor, - expected: expected.len(), - actual: args.len(), - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "{successor} expects {} arguments, but is being given {}", + expected.len(), + args.len(), + successor = successor.destination, + ), + ) + .into_report()); } for (index, (param, arg)) in expected.iter().copied().zip(args.iter().copied()).enumerate() @@ -326,14 +384,18 @@ impl<'a> Rule for TypeCheck<'a> { let expected = self.dfg.value_type(param); let actual = self.dfg.value_type(arg); if actual != expected { - return Err(ValidationError::TypeError( - TypeError::IncorrectSuccessorArgumentType { - successor, - expected: expected.clone(), - actual: actual.clone(), - index, - }, - )); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label( + span, + format!( + "{successor} argument at index {index} is expected to \ + be {expected}, but got {actual}", + successor = successor.destination + ), + ) + .into_report()); } } } @@ -346,45 +408,69 @@ impl<'a> Rule for TypeCheck<'a> { }) => { typechecker.check(&[*arg], results)?; - let mut seen = FxHashMap::::default(); - for (i, (key, successor)) in arms.iter().enumerate() { - if let Some(prev) = seen.insert(*key, i) { - return Err(ValidationError::InvalidInstruction { - span, - inst: node.key, - reason: format!( - "all arms of a 'switch' must have a unique discriminant, but \ - the arm at index {i} has the same discriminant as the arm at \ - {prev}" - ), - }); + let mut seen = BTreeMap::::default(); + for (i, arm) in arms.iter().enumerate() { + if let Some(prev) = seen.insert(arm.value, i) { + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "all arms of a 'switch' must have a unique discriminant, \ + but the arm at index {i} has the same discriminant as \ + the arm at {prev}" + ), + ) + .into_report()); } + } - let expected = self.dfg.block_args(*successor); - if !expected.is_empty() { - return Err(ValidationError::InvalidInstruction { - span, - inst: node.key, - reason: format!( - "all successors of a 'switch' must not have block parameters, \ - but {successor}, the successor for discriminant {key}, has \ - {} arguments", - expected.len() - ), - }); + for (i, successor) in arms + .iter() + .map(|arm| &arm.successor) + .chain(core::iter::once(fallback)) + .enumerate() + { + let expected = self.dfg.block_args(successor.destination); + let args = successor.args.as_slice(&self.dfg.value_lists); + if args.len() != expected.len() { + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!( + "the destination for the arm at index {i}, {successor}, \ + expects {} arguments, but is being given {}", + expected.len(), + args.len(), + successor = successor.destination, + ), + ) + .into_report()); + } + for (index, (param, arg)) in + expected.iter().copied().zip(args.iter().copied()).enumerate() + { + let expected = self.dfg.value_type(param); + let actual = self.dfg.value_type(arg); + if actual != expected { + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label( + span, + format!( + "invalid switch arm at index {i}: {successor} \ + argument at index {index} is expected to be \ + {expected}, but got {actual}", + successor = successor.destination + ), + ) + .into_report()); + } } - } - let expected = self.dfg.block_args(*fallback); - if !expected.is_empty() { - return Err(ValidationError::InvalidInstruction { - span, - inst: node.key, - reason: format!( - "all successors of a 'switch' must not have block parameters, but \ - {fallback}, the default successor, has {} arguments", - expected.len() - ), - }); } } } @@ -407,6 +493,7 @@ pub enum TypePattern { /// Matches any unsigned integer type Uint, /// Matches any signed integer type + #[allow(dead_code)] Sint, /// Matches any pointer type Pointer, @@ -1048,7 +1135,6 @@ struct InstTypeChecker<'a> { diagnostics: &'a DiagnosticsHandler, dfg: &'a DataFlowGraph, span: SourceSpan, - opcode: Opcode, pattern: InstPattern, } impl<'a> InstTypeChecker<'a> { @@ -1057,10 +1143,10 @@ impl<'a> InstTypeChecker<'a> { diagnostics: &'a DiagnosticsHandler, dfg: &'a DataFlowGraph, node: &InstNode, - ) -> Result { + ) -> Result { let span = node.span(); let opcode = node.opcode(); - let is_local_op = matches!(node.data.as_ref(), Instruction::LocalVar(_)); + let is_local_op = matches!(&*node.data, Instruction::LocalVar(_)); let pattern = match opcode { Opcode::Assert | Opcode::Assertz => InstPattern::UnaryNoResult(Type::I1.into()), Opcode::AssertEq => InstPattern::BinaryMatchingNoResult(Type::I1.into()), @@ -1164,13 +1250,17 @@ impl<'a> InstTypeChecker<'a> { .collect(); InstPattern::Exact(args, results) } else { - invalid_instruction!( - diagnostics, - node.key, - span, - "no signature is available for {callee}", - "Make sure you import functions before building calls to them." - ); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("invalid instruction") + .with_primary_label( + span, + format!("no signature is available for {callee}"), + ) + .with_help( + "Make sure you import functions before building calls to them.", + ) + .into_report()); } } inst => panic!("invalid opcode '{opcode}' for {inst:#?}"), @@ -1187,28 +1277,22 @@ impl<'a> InstTypeChecker<'a> { diagnostics, dfg, span: node.span(), - opcode, pattern, }) } /// Checks that the given `operands` and `results` match the types represented by this /// [InstTypeChecker] - pub fn check(self, operands: &[Value], results: &[Value]) -> Result<(), ValidationError> { + pub fn check(self, operands: &[Value], results: &[Value]) -> Result<(), Report> { let diagnostics = self.diagnostics; let dfg = self.dfg; match self.pattern.into_match(dfg, operands, results) { Ok(_) => Ok(()), - Err(err) => { - let opcode = self.opcode; - let message = format!("validation failed for {opcode} instruction"); - diagnostics - .diagnostic(Severity::Error) - .with_message(message.as_str()) - .with_primary_label(self.span, format!("{err}")) - .emit(); - Err(ValidationError::TypeError(err)) - } + Err(err) => Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label(self.span, err) + .into_report()), } } @@ -1219,21 +1303,16 @@ impl<'a> InstTypeChecker<'a> { operands: &[Value], imm: &Immediate, results: &[Value], - ) -> Result<(), ValidationError> { + ) -> Result<(), Report> { let diagnostics = self.diagnostics; let dfg = self.dfg; match self.pattern.into_match_with_immediate(dfg, operands, imm, results) { Ok(_) => Ok(()), - Err(err) => { - let opcode = self.opcode; - let message = format!("validation failed for {opcode} instruction"); - diagnostics - .diagnostic(Severity::Error) - .with_message(message.as_str()) - .with_primary_label(self.span, format!("{err}")) - .emit(); - Err(ValidationError::TypeError(err)) - } + Err(err) => Err(diagnostics + .diagnostic(Severity::Error) + .with_message("type error") + .with_primary_label(self.span, err) + .into_report()), } } } diff --git a/hir-macros/Cargo.toml b/hir-macros/Cargo.toml index 20d59cd1..37c2d488 100644 --- a/hir-macros/Cargo.toml +++ b/hir-macros/Cargo.toml @@ -23,4 +23,4 @@ quote = "1.0" [dependencies.syn] version = "2.0" -features = ["full", "parsing", "derive"] +features = ["full", "parsing", "derive", "extra-traits", "printing"] diff --git a/hir-macros/src/lib.rs b/hir-macros/src/lib.rs index 0d51d9d6..f1f1491f 100644 --- a/hir-macros/src/lib.rs +++ b/hir-macros/src/lib.rs @@ -1,6 +1,29 @@ +extern crate proc_macro; + +mod spanned; + use inflector::cases::kebabcase::to_kebab_case; use quote::quote; -use syn::{parse_macro_input, spanned::Spanned, DeriveInput, Ident, Token}; +use syn::{parse_macro_input, spanned::Spanned, Data, DeriveInput, Error, Ident, Token}; + +#[proc_macro_derive(Spanned, attributes(span))] +pub fn derive_spanned(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + // Parse into syntax tree + let derive = parse_macro_input!(input as DeriveInput); + // Structure name + let name = derive.ident; + let result = match derive.data { + Data::Struct(data) => spanned::derive_spanned_struct(name, data, derive.generics), + Data::Enum(data) => spanned::derive_spanned_enum(name, data, derive.generics), + Data::Union(_) => { + Err(Error::new(name.span(), "deriving Spanned on unions is not currently supported")) + } + }; + match result { + Ok(ts) => ts, + Err(err) => err.into_compile_error().into(), + } +} #[proc_macro_derive(PassInfo)] pub fn derive_pass_info(item: proc_macro::TokenStream) -> proc_macro::TokenStream { @@ -141,9 +164,71 @@ pub fn derive_analysis_key(item: proc_macro::TokenStream) -> proc_macro::TokenSt pub fn derive_rewrite_pass_registration(item: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive_input = parse_macro_input!(item as DeriveInput); let id = derive_input.ident.clone(); + let generics = derive_input.generics; + let mut params = syn::punctuated::Punctuated::<_, Token![,]>::new(); + for gp in generics.params.iter() { + match gp { + syn::GenericParam::Lifetime(ref lt) => { + if !lt.bounds.empty_or_trailing() { + return syn::Error::new( + gp.span(), + "cannot derive RewritePassRegistration on a type with lifetime bounds", + ) + .into_compile_error() + .into(); + } + params.push(syn::GenericArgument::Lifetime(syn::Lifetime { + apostrophe: lt.span(), + ident: Ident::new("_", lt.span()), + })); + } + syn::GenericParam::Type(ref ty) => { + if !ty.bounds.empty_or_trailing() { + return syn::Error::new( + gp.span(), + "cannot derive RewritePassRegistration on a generic type with type bounds", + ) + .into_compile_error() + .into(); + } + let param_ty: syn::Type = syn::parse_quote_spanned! { ty.span() => () }; + params.push(syn::GenericArgument::Type(param_ty)); + } + syn::GenericParam::Const(_) => { + return syn::Error::new( + gp.span(), + "cannot derive RewritePassRegistration on a generic type with const arguments", + ) + .into_compile_error() + .into(); + } + } + } - let quoted = quote! { - inventory::submit!(midenc_hir::pass::RewritePassRegistration::new::<#id>()); + let quoted = if params.empty_or_trailing() { + quote! { + inventory::submit!(midenc_hir::pass::RewritePassRegistration::new::<#id>()); + inventory::submit! { + midenc_session::CompileFlag::new(<#id as PassInfo>::FLAG) + .long(<#id as PassInfo>::FLAG) + .help(<#id as PassInfo>::SUMMARY) + .help_heading("Rewrites") + .action(midenc_session::FlagAction::SetTrue) + .hide(true) + } + } + } else { + quote! { + inventory::submit!(midenc_hir::pass::RewritePassRegistration::new::<#id<#params>>()); + inventory::submit! { + midenc_session::CompileFlag::new(<#id<#params> as PassInfo>::FLAG) + .long(<#id<#params> as PassInfo>::FLAG) + .help(<#id<#params> as PassInfo>::SUMMARY) + .help_heading("Rewrites") + .action(midenc_session::FlagAction::SetTrue) + .hide(true) + } + } }; proc_macro::TokenStream::from(quoted) @@ -220,6 +305,7 @@ pub fn derive_conversion_pass_registration( .help(<#id as PassInfo>::SUMMARY) .help_heading("Conversions") .action(midenc_session::FlagAction::SetTrue) + .hide(true) } } } else { @@ -230,6 +316,7 @@ pub fn derive_conversion_pass_registration( .help(<#id<#params> as PassInfo>::SUMMARY) .help_heading("Conversions") .action(midenc_session::FlagAction::SetTrue) + .hide(true) } } }; diff --git a/hir-macros/src/spanned.rs b/hir-macros/src/spanned.rs new file mode 100644 index 00000000..e88a6fce --- /dev/null +++ b/hir-macros/src/spanned.rs @@ -0,0 +1,413 @@ +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::quote; +use syn::{ + punctuated::Punctuated, spanned::Spanned, Arm, Attribute, Error, Expr, ExprField, ExprMatch, + ExprMethodCall, ExprPath, ExprUnary, FieldPat, Ident, Index, Member, Pat, PatIdent, PatRest, + PatStruct, PatTupleStruct, PatWild, Path, PathArguments, PathSegment, Token, UnOp, +}; + +pub fn derive_spanned_struct( + name: Ident, + data: syn::DataStruct, + generics: syn::Generics, +) -> Result { + let access = extract_span_fields(name.span(), None, &data.fields)?; + let span_expr = match access { + SpanAccess::Field(member) => make_member_access(make_self_expr(member.span()), member), + SpanAccess::Delegated(member) => { + let base = make_member_access(make_self_expr(member.span()), member); + make_delegated_member_access(base) + } + _ => unreachable!(), + }; + + let (impl_gen, ty_gen, where_clause) = generics.split_for_impl(); + let quoted = quote! { + impl #impl_gen Spanned for #name #ty_gen #where_clause { + #[inline] + fn span(&self) -> SourceSpan { + #span_expr + } + } + }; + + Ok(TokenStream::from(quoted)) +} + +pub fn derive_spanned_enum( + name: Ident, + data: syn::DataEnum, + generics: syn::Generics, +) -> Result { + let mut variants = Vec::with_capacity(data.variants.len()); + for variant in data.variants.iter() { + let span = variant.span(); + let access = extract_span_fields(span, Some(variant.ident.clone()), &variant.fields)?; + variants.push(access); + } + + // Generate match patterns for each variant, where the body of the match arm returns the span + let arms = variants + .drain(..) + .map(|access| match access { + SpanAccess::Variant(variant, Member::Named(id)) => { + let span = variant.span(); + let pat = Pat::Struct(PatStruct { + attrs: vec![], + path: make_path(&[Ident::new("Self", span), variant]), + brace_token: Default::default(), + fields: Punctuated::from_iter(core::iter::once(FieldPat { + attrs: vec![], + member: Member::Named(id.clone()), + colon_token: None, + pat: Box::new(Pat::Ident(PatIdent { + attrs: vec![], + by_ref: None, + mutability: None, + ident: id.clone(), + subpat: None, + })), + })), + rest: Some(syn::PatRest { + attrs: vec![], + dot2_token: Token![..](span), + }), + qself: None, + }); + Arm { + attrs: vec![], + pat, + guard: None, + fat_arrow_token: Token![=>](span), + body: Box::new(make_deref_expr(make_var_expr(id))), + comma: Some(Token![,](span)), + } + } + SpanAccess::Variant(variant, Member::Unnamed(idx)) => { + let span = variant.span(); + let mut elems = Punctuated::new(); + let index = idx.index; + for i in 0..=index { + if i == index { + elems.push(Pat::Ident(PatIdent { + attrs: vec![], + by_ref: None, + mutability: None, + ident: Ident::new("span", span), + subpat: None, + })) + } else { + elems.push(Pat::Wild(PatWild { + attrs: vec![], + underscore_token: Token![_](span), + })); + } + } + elems.push(Pat::Rest(PatRest { + attrs: vec![], + dot2_token: Token![..](span), + })); + let pat = Pat::TupleStruct(PatTupleStruct { + attrs: vec![], + path: make_path(&[Ident::new("Self", span), variant]), + paren_token: Default::default(), + elems, + qself: None, + }); + Arm { + attrs: vec![], + pat, + guard: None, + fat_arrow_token: Token![=>](span), + body: Box::new(make_deref_expr(make_var_expr(Ident::new("span", span)))), + comma: Some(Token![,](span)), + } + } + SpanAccess::DelegatedVariant(variant, Member::Named(id)) => { + let span = variant.span(); + let pat = Pat::Struct(PatStruct { + attrs: vec![], + path: make_path(&[Ident::new("Self", span), variant]), + brace_token: Default::default(), + fields: Punctuated::from_iter(core::iter::once(FieldPat { + attrs: vec![], + member: Member::Named(id.clone()), + colon_token: None, + pat: Box::new(Pat::Ident(PatIdent { + attrs: vec![], + by_ref: None, + mutability: None, + ident: id.clone(), + subpat: None, + })), + })), + rest: Some(syn::PatRest { + attrs: vec![], + dot2_token: Token![..](span), + }), + qself: None, + }); + let body = make_delegated_member_access(make_var_expr(id)); + Arm { + attrs: vec![], + pat, + guard: None, + fat_arrow_token: Token![=>](span), + body: Box::new(body), + comma: Some(Token![,](span)), + } + } + SpanAccess::DelegatedVariant(variant, Member::Unnamed(idx)) => { + let span = variant.span(); + let mut elems = Punctuated::new(); + let index = idx.index; + for i in 0..=index { + if i == index { + elems.push(Pat::Ident(PatIdent { + attrs: vec![], + by_ref: None, + mutability: None, + ident: Ident::new("span", span), + subpat: None, + })) + } else { + elems.push(Pat::Wild(PatWild { + attrs: vec![], + underscore_token: Token![_](span), + })); + } + } + elems.push(Pat::Rest(PatRest { + attrs: vec![], + dot2_token: Token![..](span), + })); + let pat = Pat::TupleStruct(PatTupleStruct { + attrs: vec![], + path: make_path(&[Ident::new("Self", span), variant]), + paren_token: Default::default(), + elems, + qself: None, + }); + let body = make_delegated_member_access(make_var_expr(Ident::new("span", span))); + Arm { + attrs: vec![], + pat, + guard: None, + fat_arrow_token: Token![=>](span), + body: Box::new(body), + comma: Some(Token![,](span)), + } + } + _ => unreachable!(), + }) + .collect(); + + let span = name.span(); + let span_expr = Expr::Match(ExprMatch { + attrs: vec![], + match_token: Token![match](span), + expr: Box::new(make_self_expr(span)), + brace_token: Default::default(), + arms, + }); + + let (impl_gen, ty_gen, where_clause) = generics.split_for_impl(); + let quoted = quote! { + impl #impl_gen Spanned for #name #ty_gen #where_clause { + fn span(&self) -> SourceSpan { + #span_expr + } + } + }; + + Ok(TokenStream::from(quoted)) +} + +enum SpanAccess { + Field(Member), + Variant(Ident, Member), + Delegated(Member), + DelegatedVariant(Ident, Member), +} + +fn make_path(idents: &[Ident]) -> Path { + let mut segments = Punctuated::new(); + for ident in idents.iter().cloned() { + segments.push(PathSegment { + ident, + arguments: PathArguments::None, + }); + } + Path { + leading_colon: None, + segments, + } +} + +fn make_self_expr(span: Span) -> Expr { + make_var_expr(Ident::new("self", span)) +} + +fn make_var_expr(ident: Ident) -> Expr { + Expr::Path(ExprPath { + attrs: vec![], + qself: None, + path: make_path(&[ident]), + }) +} + +fn make_deref_expr(expr: Expr) -> Expr { + let span = expr.span(); + Expr::Unary(ExprUnary { + attrs: vec![], + op: UnOp::Deref(Token![*](span)), + expr: Box::new(expr), + }) +} + +fn make_member_access(base: Expr, member: Member) -> Expr { + let span = member.span(); + Expr::Field(ExprField { + attrs: vec![], + base: Box::new(base), + dot_token: Token![.](span), + member, + }) +} + +fn make_delegated_member_access(receiver: Expr) -> Expr { + let span = receiver.span(); + Expr::MethodCall(ExprMethodCall { + attrs: vec![], + receiver: Box::new(receiver), + dot_token: Token![.](span), + method: Ident::new("span", span), + turbofish: None, + paren_token: Default::default(), + args: Punctuated::new(), + }) +} + +fn has_span_attr(attrs: &[Attribute]) -> bool { + attrs.iter().any(|attr| attr.path().is_ident("span")) +} + +fn extract_span_fields( + span: Span, + variant: Option, + fields: &syn::Fields, +) -> Result { + match fields { + syn::Fields::Named(fields) => { + let mut spanned = fields + .named + .iter() + .filter_map(|f| { + if has_span_attr(f.attrs.as_slice()) { + let delegated = !is_source_span(&f.ty); + Some((delegated, Member::Named(f.ident.clone().unwrap()))) + } else { + None + } + }) + .collect::>(); + if spanned.is_empty() { + Err(Error::new( + span, + "Spanned requires at least one field to be marked with the #[span] attribute", + )) + } else if spanned.len() > 1 { + Err(Error::new( + span, + "Spanned requires one field tagged with #[span], but multiple were found", + )) + } else { + let (delegated, member) = spanned.pop().unwrap(); + match variant { + None if delegated => Ok(SpanAccess::Delegated(member)), + None => Ok(SpanAccess::Field(member)), + Some(variant) if delegated => Ok(SpanAccess::DelegatedVariant(variant, member)), + Some(variant) => Ok(SpanAccess::Variant(variant, member)), + } + } + } + syn::Fields::Unnamed(fields) => { + let mut spanned = fields + .unnamed + .iter() + .enumerate() + .filter_map(|(i, f)| { + if has_span_attr(f.attrs.as_slice()) { + let delegated = !is_source_span(&f.ty); + Some(( + delegated, + Member::Unnamed(Index { + index: i as u32, + span: f.span(), + }), + )) + } else { + None + } + }) + .collect::>(); + if spanned.is_empty() { + // If there are multiple fields, then we can't make a selection, so raise an error + if fields.unnamed.len() > 1 { + return Err(Error::new( + span, + "Spanned requires at least one field to be marked with the #[span] \ + attribute", + )); + } + // Otherwise, we can infer the only field to contain a Spanned impl + match variant { + None => Ok(SpanAccess::Delegated(Member::Unnamed(Index { index: 0, span }))), + Some(variant) => Ok(SpanAccess::DelegatedVariant( + variant, + Member::Unnamed(Index { index: 0, span }), + )), + } + } else if spanned.len() > 1 { + Err(Error::new( + span, + "Spanned requires one field tagged with #[span], but multiple were found", + )) + } else { + let (delegated, member) = spanned.pop().unwrap(); + match variant { + None if delegated => Ok(SpanAccess::Delegated(member)), + None => Ok(SpanAccess::Field(member)), + Some(variant) if delegated => Ok(SpanAccess::DelegatedVariant(variant, member)), + Some(variant) => Ok(SpanAccess::Variant(variant, member)), + } + } + } + syn::Fields::Unit if variant.is_some() => { + Err(Error::new(span, "Spanned cannot be derived on enums with unit variants")) + } + syn::Fields::Unit => { + Err(Error::new(span, "Spanned requires a struct with at least one SourceSpan field")) + } + } +} + +fn is_source_span(ty: &syn::Type) -> bool { + match ty { + syn::Type::Path(tpath) => { + if tpath.path.is_ident("SourceSpan") { + return true; + } + match tpath.path.segments.len() { + 1 if tpath.path.leading_colon.is_none() => false, + 1 => { + let first = tpath.path.segments.first().unwrap(); + first.ident == "SourceSpan" && first.arguments == PathArguments::None + } + _ => false, + } + } + _ => false, + } +} diff --git a/hir-transform/src/inline_blocks.rs b/hir-transform/src/inline_blocks.rs index fd6d8765..76624255 100644 --- a/hir-transform/src/inline_blocks.rs +++ b/hir-transform/src/inline_blocks.rs @@ -87,13 +87,15 @@ impl RewritePass for InlineBlocks { // If inlining can proceed, do so until we reach a point where the inlined terminator // returns from the function, has multiple successors, or branches to a block with // multiple predecessors. - while let BranchInfo::SingleDest(b, args) = + while let BranchInfo::SingleDest(succ) = function.dfg.analyze_branch(function.dfg.last_inst(p).unwrap()) { + let destination = succ.destination; + // If this successor has other predecessors, it can't be inlined, so // add it to the work list and move on - if cfg.num_predecessors(b) > 1 { - worklist.push_back(b); + if cfg.num_predecessors(destination) > 1 { + worklist.push_back(destination); break; } @@ -103,16 +105,20 @@ impl RewritePass for InlineBlocks { // as we must visit all uses of the block arguments and update them. This // is left as a future extension of this pass should we find that it is // valuable as an optimization. - if !args.is_empty() { + if !succ.args.is_empty() { // Compute the set of values to rewrite - for (from, to) in - function.dfg.block_params(b).iter().copied().zip(args.iter().copied()) + for (from, to) in function + .dfg + .block_params(destination) + .iter() + .copied() + .zip(succ.args.iter().copied()) { rewrites.insert(from, to); } } - inline(b, p, function, &mut worklist, &rewrites, &mut cfg); + inline(destination, p, function, &mut worklist, &rewrites, &mut cfg); // Mark that the control flow graph as modified changed = true; @@ -167,16 +173,24 @@ fn inline( // Append the cloned terminator back to the inlined block before we detach it let from_terminator = from_terminator.expect("a block must have a terminator"); match (*from_terminator).as_ref() { - Instruction::Br(Br { destination, .. }) => { - worklist.push_back(*destination); + Instruction::Br(Br { successor, .. }) => { + worklist.push_back(successor.destination); } Instruction::CondBr(CondBr { - then_dest: (then_blk, _), - else_dest: (else_blk, _), + then_dest, + else_dest, + .. + }) => { + worklist.push_back(then_dest.destination); + worklist.push_back(else_dest.destination); + } + Instruction::Switch(hir::Switch { + arms, + default: default_dest, .. }) => { - worklist.push_back(*then_blk); - worklist.push_back(*else_blk); + worklist.extend(arms.iter().map(|arm| arm.successor.destination)); + worklist.push_back(default_dest.destination); } _ => (), } @@ -226,12 +240,10 @@ fn rewrite_use( let mut worklist = SmallVec::<[Block; 2]>::default(); match inst { Instruction::Br(Br { - destination, - ref mut args, - .. + ref mut successor, .. }) => { - worklist.push(*destination); - for arg in args.as_mut_slice(pool) { + worklist.push(successor.destination); + for arg in successor.args.as_mut_slice(pool) { if let Some(replacement) = rewrites.get(arg).copied() { *arg = replacement; } @@ -239,26 +251,50 @@ fn rewrite_use( } Instruction::CondBr(CondBr { ref mut cond, - then_dest: (then_dest, ref mut then_args), - else_dest: (else_dest, ref mut else_args), + ref mut then_dest, + ref mut else_dest, .. }) => { - worklist.push(*then_dest); - worklist.push(*else_dest); + worklist.push(then_dest.destination); + worklist.push(else_dest.destination); if let Some(replacement) = rewrites.get(cond).copied() { *cond = replacement; } - for arg in then_args.as_mut_slice(pool) { + for arg in then_dest.args.as_mut_slice(pool) { if let Some(replacement) = rewrites.get(arg).copied() { *arg = replacement; } } - for arg in else_args.as_mut_slice(pool) { + for arg in else_dest.args.as_mut_slice(pool) { if let Some(replacement) = rewrites.get(arg).copied() { *arg = replacement; } } } + Instruction::Switch(hir::Switch { + ref mut arg, + ref mut arms, + default: ref mut default_dest, + .. + }) => { + worklist.extend(arms.iter().map(|arm| arm.successor.destination)); + worklist.push(default_dest.destination); + if let Some(replacement) = rewrites.get(arg).copied() { + *arg = replacement; + } + for arg in default_dest.args.as_mut_slice(pool) { + if let Some(replacement) = rewrites.get(arg).copied() { + *arg = replacement; + } + } + for arm in arms.iter_mut() { + for arg in arm.successor.args.as_mut_slice(pool) { + if let Some(replacement) = rewrites.get(arg).copied() { + *arg = replacement; + } + } + } + } op => { for arg in op.arguments_mut(pool) { if let Some(replacement) = rewrites.get(arg).copied() { diff --git a/hir-transform/src/spill.rs b/hir-transform/src/spill.rs index 73579f24..bd98c072 100644 --- a/hir-transform/src/spill.rs +++ b/hir-transform/src/spill.rs @@ -13,9 +13,11 @@ use midenc_hir_analysis::{ use midenc_session::Session; use rustc_hash::FxHashSet; -/// This pass handles orchestrating the [InsertSpills] and [RewriteSpills] passes, and should be -/// preferred over using those two passes directly. See their respective documentation to better -/// understand what this pass does. +/// This pass places spills of SSA values to temporaries to cap the depth of the operand stack. +/// +/// Internally it handles orchestrating the [InsertSpills] and [RewriteSpills] passes, and should +/// be preferred over using those two passes directly. See their respective documentation to better +/// understand what this pass does as a whole. /// /// In addition to running the two passes, and maintaining the [AnalysisManager] state between them, /// this pass also handles applying an additional run of [crate::InlineBlocks] if spills were @@ -111,7 +113,7 @@ impl RewritePass for ApplySpills { /// /// **TL;DR:** Unless testing or debugging, always apply [InsertSpills] and [RewriteSpills] /// consecutively! -#[derive(Default, PassInfo, ModuleRewritePassAdapter)] +#[derive(Default)] pub struct InsertSpills; impl RewritePass for InsertSpills { type Entity = hir::Function; @@ -156,40 +158,28 @@ impl RewritePass for InsertSpills { let ix = builder.func.dfg.inst_mut(split_info.predecessor.inst); let args = match ix { Instruction::Br(Br { - ref mut destination, - args, - .. + ref mut successor, .. }) => { - assert_eq!(*destination, split_info.block); - *destination = split; - args.take() + assert_eq!(successor.destination, split_info.block); + successor.destination = split; + successor.args.take() } Instruction::CondBr(CondBr { - then_dest, - else_dest, + ref mut then_dest, + ref mut else_dest, .. }) => { - if then_dest.0 == split_info.block { - then_dest.0 = split; - then_dest.1.take() + if then_dest.destination == split_info.block { + then_dest.destination = split; + then_dest.args.take() } else { - assert_eq!(else_dest.0, split_info.block); - else_dest.0 = split; - else_dest.1.take() + assert_eq!(else_dest.destination, split_info.block); + else_dest.destination = split; + else_dest.args.take() } } - Instruction::Switch(Switch { - arms, r#default, .. - }) => { - if r#default == &split_info.block { - *r#default = split; - } - for (_, arm) in arms.iter_mut() { - if arm == &split_info.block { - *arm = split; - } - } - ValueList::default() + Instruction::Switch(_) => { + panic!("expected switch instructions to have been rewritten prior to this pass") } ix => unimplemented!("unhandled branch instruction: {}", ix.opcode()), }; @@ -309,7 +299,7 @@ impl RewritePass for InsertSpills { /// only place greater constraints on backend scheduling, but also ensure that more live ranges /// are split, and thus operands will spend less time on the operand stack overall. Time will /// tell whether this holds true or not. -#[derive(Default, PassInfo, ModuleRewritePassAdapter)] +#[derive(Default)] pub struct RewriteSpills; impl RewritePass for RewriteSpills { type Entity = hir::Function; @@ -485,7 +475,7 @@ fn find_inst_uses( // If `current_inst` is a branch or terminator, it cannot define a value, so // we simply record any uses, and move on. match function.dfg.analyze_branch(current_inst) { - BranchInfo::SingleDest(_, args) => { + BranchInfo::SingleDest(SuccessorInfo { args, .. }) => { for (index, arg) in args.iter().enumerate() { if spills.is_spilled(arg) { used.entry(*arg).or_default().insert(User::new( @@ -499,9 +489,9 @@ fn find_inst_uses( } } } - BranchInfo::MultiDest(ref jts) => { - for (succ_index, jt) in jts.iter().enumerate() { - for (index, arg) in jt.args.iter().enumerate() { + BranchInfo::MultiDest(infos) => { + for (succ_index, info) in infos.into_iter().enumerate() { + for (index, arg) in info.args.iter().enumerate() { if spills.is_spilled(arg) { used.entry(*arg).or_default().insert(User::new( current_inst, diff --git a/hir-transform/src/split_critical_edges.rs b/hir-transform/src/split_critical_edges.rs index 7a046c73..7db009d1 100644 --- a/hir-transform/src/split_critical_edges.rs +++ b/hir-transform/src/split_critical_edges.rs @@ -90,24 +90,22 @@ impl RewritePass for SplitCriticalEdges { let args: ValueList; match ix { Instruction::Br(hir::Br { - ref mut destination, - args: ref mut orig_args, - .. + ref mut successor, .. }) => { - args = orig_args.take(); - *destination = split; + args = successor.args.take(); + successor.destination = split; } Instruction::CondBr(hir::CondBr { - then_dest: (ref mut then_dest, ref mut then_args), - else_dest: (ref mut else_dest, ref mut else_args), + ref mut then_dest, + ref mut else_dest, .. }) => { - if *then_dest == b { - *then_dest = split; - args = then_args.take(); + if then_dest.destination == b { + then_dest.destination = split; + args = then_dest.args.take(); } else { - *else_dest = split; - args = else_args.take(); + else_dest.destination = split; + args = else_dest.args.take(); } } Instruction::Switch(_) => unimplemented!(), @@ -120,8 +118,10 @@ impl RewritePass for SplitCriticalEdges { }, Instruction::Br(hir::Br { op: hir::Opcode::Br, - destination: b, - args, + successor: hir::Successor { + destination: b, + args, + }, }), Type::Unknown, span, diff --git a/hir-transform/src/treeify.rs b/hir-transform/src/treeify.rs index 7368b903..b51a94e4 100644 --- a/hir-transform/src/treeify.rs +++ b/hir-transform/src/treeify.rs @@ -5,6 +5,7 @@ use std::{ use midenc_hir::{ self as hir, + diagnostics::Report, pass::{AnalysisManager, RewritePass, RewriteResult}, Block as BlockId, Value as ValueId, *, }; @@ -443,7 +444,7 @@ fn treeify( block_q: &mut VecDeque, mut value_map: ScopedMap, mut block_map: ScopedMap, -) -> anyhow::Result<()> { +) -> Result<(), Report> { // Check if we're dealing with a loop header let is_loop = block_infos.is_loop_header(b).is_some(); @@ -472,14 +473,15 @@ fn treeify( } } else { match function.dfg.analyze_branch(p.inst) { - BranchInfo::SingleDest(_, args) => { - value_map - .extend(function.dfg.block_args(b).iter().copied().zip(args.iter().copied())); + BranchInfo::SingleDest(info) => { + value_map.extend( + function.dfg.block_args(b).iter().copied().zip(info.args.iter().copied()), + ); } - BranchInfo::MultiDest(ref jts) => { - let jt = jts.iter().find(|jt| jt.destination == b).unwrap(); + BranchInfo::MultiDest(ref infos) => { + let info = infos.iter().find(|info| info.destination == b).unwrap(); value_map.extend( - function.dfg.block_args(b).iter().copied().zip(jt.args.iter().copied()), + function.dfg.block_args(b).iter().copied().zip(info.args.iter().copied()), ); } BranchInfo::NotABranch => unreachable!(), @@ -489,12 +491,12 @@ fn treeify( // 3. Update the predecessor instruction to reference the new block, remove block arguments if // this is not a loop header. let mut seen = false; // Only update the first occurrance of this predecessor - update_predecessor(function, p, |dest, dest_args, pool| { - if *dest == b && !seen { + update_predecessor(function, p, |successor, pool| { + if successor.destination == b && !seen { seen = true; - *dest = b_prime; + successor.destination = b_prime; if !is_loop { - dest_args.clear(pool); + successor.args.clear(pool); } } }); @@ -517,16 +519,16 @@ fn copy_children( block_q: &mut VecDeque, value_map: ScopedMap, block_map: ScopedMap, -) -> anyhow::Result<()> { +) -> Result<(), Report> { let pred = BlockPredecessor { inst: function.dfg.last_inst(b_prime).expect("expected non-empty block"), block: b_prime, }; let successors = match function.dfg.analyze_branch(function.dfg.last_inst(b).unwrap()) { BranchInfo::NotABranch => return Ok(()), - BranchInfo::SingleDest(dest, _) => smallvec![dest], - BranchInfo::MultiDest(ref jts) => { - SmallVec::<[_; 2]>::from_iter(jts.iter().map(|jt| jt.destination)) + BranchInfo::SingleDest(info) => smallvec![info.destination], + BranchInfo::MultiDest(infos) => { + SmallVec::<[_; 2]>::from_iter(infos.into_iter().map(|info| info.destination)) } }; let value_map = Rc::new(value_map); @@ -534,9 +536,9 @@ fn copy_children( for succ in successors { if let Some(succ_prime) = block_map.get(&succ) { - update_predecessor(function, &pred, |dest, _, _| { - if dest == &succ { - *dest = *succ_prime; + update_predecessor(function, &pred, |successor, _| { + if successor.destination == succ { + successor.destination = *succ_prime; } }); } @@ -585,14 +587,12 @@ fn copy_instructions( // Second, we need to rewrite value/block references contained in the instruction match data.as_mut() { Instruction::Br(hir::Br { - ref mut destination, - ref mut args, - .. + ref mut successor, .. }) => { - if let Some(new_dest) = block_map.get(destination) { - *destination = *new_dest; + if let Some(new_dest) = block_map.get(&successor.destination) { + successor.destination = *new_dest; } - let args = args.as_mut_slice(&mut function.dfg.value_lists); + let args = successor.args.as_mut_slice(&mut function.dfg.value_lists); for arg in args.iter_mut() { if let Some(arg_prime) = value_map.get(arg) { *arg = *arg_prime; @@ -601,32 +601,62 @@ fn copy_instructions( } Instruction::CondBr(hir::CondBr { ref mut cond, - then_dest: (ref mut then_dest, ref mut then_args), - else_dest: (ref mut else_dest, ref mut else_args), + ref mut then_dest, + ref mut else_dest, .. }) => { if let Some(cond_prime) = value_map.get(cond) { *cond = *cond_prime; } - if let Some(new_dest) = block_map.get(then_dest) { - *then_dest = *new_dest; + if let Some(new_dest) = block_map.get(&then_dest.destination) { + then_dest.destination = *new_dest; } - let then_args = then_args.as_mut_slice(&mut function.dfg.value_lists); + let then_args = then_dest.args.as_mut_slice(&mut function.dfg.value_lists); for arg in then_args.iter_mut() { if let Some(arg_prime) = value_map.get(arg) { *arg = *arg_prime; } } - if let Some(new_dest) = block_map.get(else_dest) { - *else_dest = *new_dest; + if let Some(new_dest) = block_map.get(&else_dest.destination) { + else_dest.destination = *new_dest; } - let else_args = else_args.as_mut_slice(&mut function.dfg.value_lists); + let else_args = else_dest.args.as_mut_slice(&mut function.dfg.value_lists); for arg in else_args.iter_mut() { if let Some(arg_prime) = value_map.get(arg) { *arg = *arg_prime; } } } + Instruction::Switch(hir::Switch { + ref mut arg, + ref mut arms, + default: ref mut default_succ, + .. + }) => { + if let Some(arg_prime) = value_map.get(arg) { + *arg = *arg_prime; + } + if let Some(new_default_dest) = block_map.get(&default_succ.destination) { + default_succ.destination = *new_default_dest; + } + let default_args = default_succ.args.as_mut_slice(&mut function.dfg.value_lists); + for arg in default_args.iter_mut() { + if let Some(arg_prime) = value_map.get(arg) { + *arg = *arg_prime; + } + } + for arm in arms.iter_mut() { + if let Some(new_dest) = block_map.get(&arm.successor.destination) { + arm.successor.destination = *new_dest; + } + let args = arm.successor.args.as_mut_slice(&mut function.dfg.value_lists); + for arg in args.iter_mut() { + if let Some(arg_prime) = value_map.get(arg) { + *arg = *arg_prime; + } + } + } + } other => { for arg in other.arguments_mut(&mut function.dfg.value_lists).iter_mut() { if let Some(arg_prime) = value_map.get(arg) { @@ -669,25 +699,23 @@ impl CopyBlock { #[inline] fn update_predecessor(function: &mut hir::Function, p: &BlockPredecessor, mut callback: F) where - F: FnMut(&mut BlockId, &mut ValueList, &mut ValueListPool), + F: FnMut(&mut hir::Successor, &mut ValueListPool), { - match &mut function.dfg.insts[p.inst].data.item { + match &mut *function.dfg.insts[p.inst].data { Instruction::Br(hir::Br { - ref mut destination, - ref mut args, - .. + ref mut successor, .. }) => { - callback(destination, args, &mut function.dfg.value_lists); + callback(successor, &mut function.dfg.value_lists); } Instruction::CondBr(hir::CondBr { - then_dest: (ref mut then_dest, ref mut then_args), - else_dest: (ref mut else_dest, ref mut else_args), + ref mut then_dest, + ref mut else_dest, .. }) => { - assert_ne!(then_dest, else_dest, "unexpected critical edge"); + assert_ne!(then_dest.destination, else_dest.destination, "unexpected critical edge"); let value_lists = &mut function.dfg.value_lists; - callback(then_dest, then_args, value_lists); - callback(else_dest, else_args, value_lists); + callback(then_dest, value_lists); + callback(else_dest, value_lists); } Instruction::Switch(_) => { panic!("expected switch instructions to have been simplified prior to treeification") diff --git a/hir/Cargo.toml b/hir/Cargo.toml index c6aa0deb..f5d30333 100644 --- a/hir/Cargo.toml +++ b/hir/Cargo.toml @@ -13,7 +13,7 @@ edition.workspace = true [features] default = ["std"] -std = [] +std = ["rustc-demangle/std"] [build-dependencies] lalrpop = { version = "0.20", default-features = false } @@ -25,9 +25,9 @@ cranelift-entity.workspace = true intrusive-collections.workspace = true inventory.workspace = true lalrpop-util = "0.20" +log.workspace = true miden-core.workspace = true miden-assembly.workspace = true -miden-diagnostics.workspace = true midenc-hir-symbol.workspace = true midenc-hir-type.workspace = true midenc-hir-macros.workspace = true @@ -38,6 +38,7 @@ num-traits = "0.2" petgraph.workspace = true paste.workspace = true rustc-hash.workspace = true +rustc-demangle = "0.1.19" smallvec.workspace = true thiserror.workspace = true typed-arena = "2.0" diff --git a/hir/src/asm/assertions.rs b/hir/src/asm/assertions.rs new file mode 100644 index 00000000..0ce6e4fc --- /dev/null +++ b/hir/src/asm/assertions.rs @@ -0,0 +1,4 @@ +//! This module contains the set of compiler-emitted assertion codes, along with their explanations + +/// This assertion fails when a pointer address does not meet minimum alignment for the type +pub const ASSERT_FAILED_ALIGNMENT: u32 = 0xfa; diff --git a/hir/src/asm/builder.rs b/hir/src/asm/builder.rs index 961aea70..b8e519a4 100644 --- a/hir/src/asm/builder.rs +++ b/hir/src/asm/builder.rs @@ -2,7 +2,8 @@ use smallvec::smallvec; use super::*; use crate::{ - CallConv, Felt, FunctionIdent, Inst, InstBuilder, Instruction, Overflow, SourceSpan, Value, + diagnostics::{SourceSpan, Span}, + CallConv, Felt, FunctionIdent, Inst, InstBuilder, Instruction, Overflow, Value, }; /// Used to construct an [InlineAsm] instruction, while checking the input/output types, @@ -137,43 +138,43 @@ pub struct MasmOpBuilder<'a> { } impl<'a> MasmOpBuilder<'a> { /// Pads the stack with four zero elements - pub fn padw(mut self) { - self.build(self.ip, MasmOp::Padw); + pub fn padw(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Padw, span); } /// Pushes an element on the stack - pub fn push(mut self, imm: Felt) { - self.build(self.ip, MasmOp::Push(imm)); + pub fn push(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::Push(imm), span); } /// Pushes a word on the stack - pub fn pushw(mut self, word: [Felt; 4]) { - self.build(self.ip, MasmOp::Pushw(word)); + pub fn pushw(mut self, word: [Felt; 4], span: SourceSpan) { + self.build(self.ip, MasmOp::Pushw(word), span); } /// Pushes an element representing an unsigned 8-bit integer on the stack - pub fn push_u8(mut self, imm: u8) { - self.build(self.ip, MasmOp::PushU8(imm)); + pub fn push_u8(mut self, imm: u8, span: SourceSpan) { + self.build(self.ip, MasmOp::PushU8(imm), span); } /// Pushes an element representing an unsigned 16-bit integer on the stack - pub fn push_u16(mut self, imm: u16) { - self.build(self.ip, MasmOp::PushU16(imm)); + pub fn push_u16(mut self, imm: u16, span: SourceSpan) { + self.build(self.ip, MasmOp::PushU16(imm), span); } /// Pushes an element representing an unsigned 32-bit integer on the stack - pub fn push_u32(mut self, imm: u32) { - self.build(self.ip, MasmOp::PushU32(imm)); + pub fn push_u32(mut self, imm: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::PushU32(imm), span); } /// Drops the element on the top of the stack - pub fn drop(mut self) { - self.build(self.ip, MasmOp::Drop); + pub fn drop(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Drop, span); } /// Drops the word (first four elements) on the top of the stack - pub fn dropw(mut self) { - self.build(self.ip, MasmOp::Dropw); + pub fn dropw(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Dropw, span); } /// Duplicates the `n`th element from the top of the stack, to the top of the stack @@ -181,8 +182,8 @@ impl<'a> MasmOpBuilder<'a> { /// A `n` of zero, duplicates the element on top of the stack /// /// The valid range for `n` is 0..=15 - pub fn dup(mut self, n: usize) { - self.build(self.ip, MasmOp::Dup(n as u8)); + pub fn dup(mut self, n: usize, span: SourceSpan) { + self.build(self.ip, MasmOp::Dup(n as u8), span); } /// Duplicates the `n`th word from the top of the stack, to the top of the stack @@ -190,156 +191,156 @@ impl<'a> MasmOpBuilder<'a> { /// A `n` of zero, duplicates the word on top of the stack /// /// The valid range for `n` is 0..=3 - pub fn dupw(mut self, n: usize) { - self.build(self.ip, MasmOp::Dupw(n as u8)); + pub fn dupw(mut self, n: usize, span: SourceSpan) { + self.build(self.ip, MasmOp::Dupw(n as u8), span); } /// Swaps the `n`th element and the element on top of the stack /// /// The valid range for `n` is 1..=15 - pub fn swap(mut self, n: usize) { - self.build(self.ip, MasmOp::Swap(n as u8)); + pub fn swap(mut self, n: usize, span: SourceSpan) { + self.build(self.ip, MasmOp::Swap(n as u8), span); } /// Swaps the `n`th word and the word on top of the stack /// /// The valid range for `n` is 1..=3 - pub fn swapw(mut self, n: usize) { - self.build(self.ip, MasmOp::Swapw(n as u8)); + pub fn swapw(mut self, n: usize, span: SourceSpan) { + self.build(self.ip, MasmOp::Swapw(n as u8), span); } /// Swaps the top 2 and bottom 2 words on the stack - pub fn swapdw(mut self) { - self.build(self.ip, MasmOp::Swapdw); + pub fn swapdw(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Swapdw, span); } /// Moves the `n`th element to the top of the stack /// /// The valid range for `n` is 2..=15 - pub fn movup(mut self, idx: usize) { - self.build(self.ip, MasmOp::Movup(idx as u8)); + pub fn movup(mut self, idx: usize, span: SourceSpan) { + self.build(self.ip, MasmOp::Movup(idx as u8), span); } /// Moves the `n`th word to the top of the stack /// /// The valid range for `n` is 2..=3 - pub fn movupw(mut self, idx: usize) { - self.build(self.ip, MasmOp::Movupw(idx as u8)); + pub fn movupw(mut self, idx: usize, span: SourceSpan) { + self.build(self.ip, MasmOp::Movupw(idx as u8), span); } /// Moves the element on top of the stack, making it the `n`th element /// /// The valid range for `n` is 2..=15 - pub fn movdn(mut self, idx: usize) { - self.build(self.ip, MasmOp::Movdn(idx as u8)); + pub fn movdn(mut self, idx: usize, span: SourceSpan) { + self.build(self.ip, MasmOp::Movdn(idx as u8), span); } /// Moves the word on top of the stack, making it the `n`th word /// /// The valid range for `n` is 2..=3 - pub fn movdnw(mut self, idx: usize) { - self.build(self.ip, MasmOp::Movdnw(idx as u8)); + pub fn movdnw(mut self, idx: usize, span: SourceSpan) { + self.build(self.ip, MasmOp::Movdnw(idx as u8), span); } /// Pops a boolean element off the stack, and swaps the top two elements /// on the stack if that boolean is true. /// /// Traps if the conditional is not 0 or 1. - pub fn cswap(mut self) { - self.build(self.ip, MasmOp::Cswap); + pub fn cswap(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Cswap, span); } /// Pops a boolean element off the stack, and swaps the top two words /// on the stack if that boolean is true. /// /// Traps if the conditional is not 0 or 1. - pub fn cswapw(mut self) { - self.build(self.ip, MasmOp::Cswapw); + pub fn cswapw(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Cswapw, span); } /// Pops a boolean element off the stack, and drops the top element on the /// stack if the boolean is true, otherwise it drops the next element down. /// /// Traps if the conditional is not 0 or 1. - pub fn cdrop(mut self) { - self.build(self.ip, MasmOp::Cdrop); + pub fn cdrop(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Cdrop, span); } /// Pops a boolean element off the stack, and drops the top word on the /// stack if the boolean is true, otherwise it drops the next word down. /// /// Traps if the conditional is not 0 or 1. - pub fn cdropw(mut self) { - self.build(self.ip, MasmOp::Cdropw); + pub fn cdropw(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Cdropw, span); } /// Pops the top element on the stack, and traps if that element is != 1. - pub fn assert(mut self, error_code: Option) { + pub fn assert(mut self, error_code: Option, span: SourceSpan) { let op = error_code.map(MasmOp::AssertWithError).unwrap_or(MasmOp::Assert); - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Pops the top element on the stack, and traps if that element is != 0. - pub fn assertz(mut self, error_code: Option) { + pub fn assertz(mut self, error_code: Option, span: SourceSpan) { let op = error_code.map(MasmOp::AssertzWithError).unwrap_or(MasmOp::Assertz); - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Pops the top two elements on the stack, and traps if they are not equal. - pub fn assert_eq(mut self, error_code: Option) { + pub fn assert_eq(mut self, error_code: Option, span: SourceSpan) { let op = error_code.map(MasmOp::AssertEqWithError).unwrap_or(MasmOp::AssertEq); - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Pops the top two words on the stack, and traps if they are not equal. - pub fn assert_eqw(mut self, error_code: Option) { + pub fn assert_eqw(mut self, error_code: Option, span: SourceSpan) { let op = error_code.map(MasmOp::AssertEqwWithError).unwrap_or(MasmOp::AssertEqw); - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Pops an element containing a memory address from the top of the stack, /// and loads the first element of the word at that address to the top of the stack. - pub fn load(mut self) { - self.build(self.ip, MasmOp::MemLoad); + pub fn load(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::MemLoad, span); } /// Loads the first element of the word at the given address to the top of the stack. - pub fn load_imm(mut self, addr: u32) { - self.build(self.ip, MasmOp::MemLoadImm(addr)); + pub fn load_imm(mut self, addr: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::MemLoadImm(addr), span); } /// Pops an element containing a memory address from the top of the stack, /// and loads the word at that address to the top of the stack. - pub fn loadw(mut self) { - self.build(self.ip, MasmOp::MemLoadw); + pub fn loadw(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::MemLoadw, span); } /// Loads the word at the given address to the top of the stack. - pub fn loadw_imm(mut self, addr: u32) { - self.build(self.ip, MasmOp::MemLoadwImm(addr)); + pub fn loadw_imm(mut self, addr: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::MemLoadwImm(addr), span); } /// Pops two elements, the first containing a memory address from the top of the stack, /// the second the value to be stored as the first element of the word at that address. - pub fn store(mut self) { - self.build(self.ip, MasmOp::MemStore); + pub fn store(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::MemStore, span); } /// Pops an element from the top of the stack, and stores it as the first element of /// the word at the given address. - pub fn store_imm(mut self, addr: u32) { - self.build(self.ip, MasmOp::MemStoreImm(addr)); + pub fn store_imm(mut self, addr: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::MemStoreImm(addr), span); } /// Pops an element containing a memory address from the top of the stack, /// and then pops a word from the stack and stores it as the word at that address. - pub fn storew(mut self) { - self.build(self.ip, MasmOp::MemStorew); + pub fn storew(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::MemStorew, span); } /// Pops a word from the stack and stores it as the word at the given address. - pub fn storew_imm(mut self, addr: u32) { - self.build(self.ip, MasmOp::MemStorewImm(addr)); + pub fn storew_imm(mut self, addr: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::MemStorewImm(addr), span); } /// Begins construction of a `if.true` statement. @@ -355,7 +356,7 @@ impl<'a> MasmOpBuilder<'a> { /// in the same abstract state, so that when control resumes after the `if.true`, the remaining /// program is well-formed. This will be validated automatically for you, but if validation /// fails, the builder will panic. - pub fn if_true(self) -> IfTrueBuilder<'a> { + pub fn if_true(self, span: SourceSpan) -> IfTrueBuilder<'a> { let cond = self.stack.pop().expect("operand stack is empty"); assert_eq!(cond, Type::I1, "expected while.true condition to be a boolean value"); let out_stack = self.stack.clone(); @@ -364,6 +365,7 @@ impl<'a> MasmOpBuilder<'a> { asm: self.asm, in_stack: self.stack, out_stack, + span, ip: self.ip, then_blk: None, else_blk: None, @@ -390,7 +392,7 @@ impl<'a> MasmOpBuilder<'a> { /// on the operand stack. /// /// Both of these are validated by [LoopBuilder], and a panic is raised if validation fails. - pub fn while_true(self) -> LoopBuilder<'a> { + pub fn while_true(self, span: SourceSpan) -> LoopBuilder<'a> { let cond = self.stack.pop().expect("operand stack is empty"); assert_eq!(cond, Type::I1, "expected while.true condition to be a boolean value"); let out_stack = self.stack.clone(); @@ -400,6 +402,7 @@ impl<'a> MasmOpBuilder<'a> { asm: self.asm, in_stack: self.stack, out_stack, + span, ip: self.ip, body, style: LoopType::While, @@ -412,7 +415,7 @@ impl<'a> MasmOpBuilder<'a> { /// times. /// /// NOTE: The iteration count must be non-zero, or this function will panic. - pub fn repeat(self, n: u16) -> LoopBuilder<'a> { + pub fn repeat(self, n: u16, span: SourceSpan) -> LoopBuilder<'a> { assert!(n > 0, "invalid iteration count for `repeat.n`, must be non-zero"); let out_stack = self.stack.clone(); let body = self.asm.create_block(); @@ -421,6 +424,7 @@ impl<'a> MasmOpBuilder<'a> { asm: self.asm, in_stack: self.stack, out_stack, + span, ip: self.ip, body, style: LoopType::Repeat(n), @@ -428,315 +432,315 @@ impl<'a> MasmOpBuilder<'a> { } /// Executes the named procedure as a regular function. - pub fn exec(mut self, id: FunctionIdent) { - self.build(self.ip, MasmOp::Exec(id)); + pub fn exec(mut self, id: FunctionIdent, span: SourceSpan) { + self.build(self.ip, MasmOp::Exec(id), span); } /// Execute a procedure indirectly. /// /// Expects the hash of a function's MAST root on the stack, see `procref` - pub fn dynexec(mut self) { - self.build(self.ip, MasmOp::DynExec) + pub fn dynexec(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::DynExec, span) } /// Call a procedure indirectly. /// /// Expects the hash of a function's MAST root on the stack, see `procref` - pub fn dyncall(mut self) { - self.build(self.ip, MasmOp::DynCall) + pub fn dyncall(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::DynCall, span) } /// Executes the named procedure as a call. - pub fn call(mut self, id: FunctionIdent) { - self.build(self.ip, MasmOp::Call(id)); + pub fn call(mut self, id: FunctionIdent, span: SourceSpan) { + self.build(self.ip, MasmOp::Call(id), span); } /// Executes the named procedure as a syscall. - pub fn syscall(mut self, id: FunctionIdent) { - self.build(self.ip, MasmOp::Syscall(id)); + pub fn syscall(mut self, id: FunctionIdent, span: SourceSpan) { + self.build(self.ip, MasmOp::Syscall(id), span); } /// Push the hash of the named function on the stack for use with dyn(exec|call) - pub fn procref(mut self, id: FunctionIdent) { - self.build(self.ip, MasmOp::ProcRef(id)) + pub fn procref(mut self, id: FunctionIdent, span: SourceSpan) { + self.build(self.ip, MasmOp::ProcRef(id), span) } /// Pops two field elements from the stack, adds them, and places the result on the stack. - pub fn add(mut self) { - self.build(self.ip, MasmOp::Add); + pub fn add(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Add, span); } /// Pops a field element from the stack, adds the given value to it, and places the result on /// the stack. - pub fn add_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::AddImm(imm)); + pub fn add_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::AddImm(imm), span); } /// Pops two field elements from the stack, subtracts the second from the first, and places the /// result on the stack. - pub fn sub(mut self) { - self.build(self.ip, MasmOp::Sub); + pub fn sub(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Sub, span); } /// Pops a field element from the stack, subtracts the given value from it, and places the /// result on the stack. - pub fn sub_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::SubImm(imm)); + pub fn sub_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::SubImm(imm), span); } /// Pops two field elements from the stack, multiplies them, and places the result on the stack. - pub fn mul(mut self) { - self.build(self.ip, MasmOp::Mul); + pub fn mul(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Mul, span); } /// Pops a field element from the stack, multiplies it by the given value, and places the result /// on the stack. - pub fn mul_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::MulImm(imm)); + pub fn mul_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::MulImm(imm), span); } /// Pops two field elements from the stack, divides the first by the second, and places the /// result on the stack. - pub fn div(mut self) { - self.build(self.ip, MasmOp::Div); + pub fn div(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Div, span); } /// Pops a field element from the stack, divides it by the given value, and places the result on /// the stack. - pub fn div_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::DivImm(imm)); + pub fn div_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::DivImm(imm), span); } /// Negates the field element on top of the stack - pub fn neg(mut self) { - self.build(self.ip, MasmOp::Neg); + pub fn neg(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Neg, span); } /// Replaces the field element on top of the stack with it's multiplicative inverse, i.e. `a^-1 /// mod p` - pub fn inv(mut self) { - self.build(self.ip, MasmOp::Inv); + pub fn inv(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Inv, span); } /// Increments the field element on top of the stack - pub fn incr(mut self) { - self.build(self.ip, MasmOp::Incr); + pub fn incr(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Incr, span); } /// Pops an element, `a`, from the top of the stack, and places the integral base 2 logarithm /// of that value on the stack. /// /// Traps if `a` is 0. - pub fn ilog2(mut self) { - self.build(self.ip, MasmOp::Ilog2); + pub fn ilog2(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Ilog2, span); } /// Pops an element, `a`, from the top of the stack, and places the result of `2^a` on the /// stack. /// /// Traps if `a` is not in the range 0..=63 - pub fn pow2(mut self) { - self.build(self.ip, MasmOp::Pow2); + pub fn pow2(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Pow2, span); } /// Pops two elements from the stack, `b` and `a` respectively, and places the result of `a^b` /// on the stack. /// /// Traps if `b` is not in the range 0..=63 - pub fn exp(mut self) { - self.build(self.ip, MasmOp::Exp); + pub fn exp(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Exp, span); } /// Pops an element from the stack, `a`, and places the result of `a^b` on the stack, where `b` /// is the given immediate value. /// /// Traps if `b` is not in the range 0..=63 - pub fn exp_imm(mut self, exponent: u8) { - self.build(self.ip, MasmOp::ExpImm(exponent)); + pub fn exp_imm(mut self, exponent: u8, span: SourceSpan) { + self.build(self.ip, MasmOp::ExpImm(exponent), span); } /// Pops a value off the stack, and applies logical NOT, and places the result back on the /// stack. /// /// Traps if the value is not 0 or 1. - pub fn not(mut self) { - self.build(self.ip, MasmOp::Not); + pub fn not(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Not, span); } /// Pops two values off the stack, applies logical AND, and places the result back on the stack. /// /// Traps if either value is not 0 or 1. - pub fn and(mut self) { - self.build(self.ip, MasmOp::And); + pub fn and(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::And, span); } /// Pops a value off the stack, applies logical AND with the given immediate, and places the /// result back on the stack. /// /// Traps if the value is not 0 or 1. - pub fn and_imm(mut self, imm: bool) { - self.build(self.ip, MasmOp::AndImm(imm)); + pub fn and_imm(mut self, imm: bool, span: SourceSpan) { + self.build(self.ip, MasmOp::AndImm(imm), span); } /// Pops two values off the stack, applies logical OR, and places the result back on the stack. /// /// Traps if either value is not 0 or 1. - pub fn or(mut self) { - self.build(self.ip, MasmOp::Or); + pub fn or(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Or, span); } /// Pops a value off the stack, applies logical OR with the given immediate, and places the /// result back on the stack. /// /// Traps if the value is not 0 or 1. - pub fn or_imm(mut self, imm: bool) { - self.build(self.ip, MasmOp::OrImm(imm)); + pub fn or_imm(mut self, imm: bool, span: SourceSpan) { + self.build(self.ip, MasmOp::OrImm(imm), span); } /// Pops two values off the stack, applies logical XOR, and places the result back on the stack. /// /// Traps if either value is not 0 or 1. - pub fn xor(mut self) { - self.build(self.ip, MasmOp::Xor); + pub fn xor(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Xor, span); } /// Pops a value off the stack, applies logical XOR with the given immediate, and places the /// result back on the stack. /// /// Traps if the value is not 0 or 1. - pub fn xor_imm(mut self, imm: bool) { - self.build(self.ip, MasmOp::XorImm(imm)); + pub fn xor_imm(mut self, imm: bool, span: SourceSpan) { + self.build(self.ip, MasmOp::XorImm(imm), span); } /// Pops two elements off the stack, and pushes 1 on the stack if they are equal, else 0. - pub fn eq(mut self) { - self.build(self.ip, MasmOp::Eq); + pub fn eq(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Eq, span); } /// Pops an element off the stack, and pushes 1 on the stack if that value and the given /// immediate are equal, else 0. - pub fn eq_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::EqImm(imm)); + pub fn eq_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::EqImm(imm), span); } /// Pops two words off the stack, and pushes 1 on the stack if they are equal, else 0. - pub fn eqw(mut self) { - self.build(self.ip, MasmOp::Eqw); + pub fn eqw(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Eqw, span); } /// Pops two elements off the stack, and pushes 1 on the stack if they are not equal, else 0. - pub fn neq(mut self) { - self.build(self.ip, MasmOp::Neq); + pub fn neq(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Neq, span); } /// Pops an element off the stack, and pushes 1 on the stack if that value and the given /// immediate are not equal, else 0. - pub fn neq_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::NeqImm(imm)); + pub fn neq_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::NeqImm(imm), span); } /// Pops two elements off the stack, and pushes 1 on the stack if the first is greater than the /// second, else 0. - pub fn gt(mut self) { - self.build(self.ip, MasmOp::Gt); + pub fn gt(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Gt, span); } /// Pops an element off the stack, and pushes 1 on the stack if that value is greater than the /// given immediate, else 0. - pub fn gt_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::GtImm(imm)); + pub fn gt_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::GtImm(imm), span); } /// Pops two elements off the stack, and pushes 1 on the stack if the first is greater than or /// equal to the second, else 0. - pub fn gte(mut self) { - self.build(self.ip, MasmOp::Gte); + pub fn gte(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Gte, span); } /// Pops an element off the stack, and pushes 1 on the stack if that value is greater than or /// equal to the given immediate, else 0. - pub fn gte_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::GteImm(imm)); + pub fn gte_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::GteImm(imm), span); } /// Pops two elements off the stack, and pushes 1 on the stack if the first is less than the /// second, else 0. - pub fn lt(mut self) { - self.build(self.ip, MasmOp::Lt); + pub fn lt(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Lt, span); } /// Pops an element off the stack, and pushes 1 on the stack if that value is less than the /// given immediate, else 0. - pub fn lt_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::LtImm(imm)); + pub fn lt_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::LtImm(imm), span); } /// Pops two elements off the stack, and pushes 1 on the stack if the first is less than or /// equal to the second, else 0. - pub fn lte(mut self) { - self.build(self.ip, MasmOp::Lte); + pub fn lte(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Lte, span); } /// Pops an element off the stack, and pushes 1 on the stack if that value is less than or equal /// to the given immediate, else 0. - pub fn lte_imm(mut self, imm: Felt) { - self.build(self.ip, MasmOp::LteImm(imm)); + pub fn lte_imm(mut self, imm: Felt, span: SourceSpan) { + self.build(self.ip, MasmOp::LteImm(imm), span); } /// Pops an element off the stack, and pushes 1 on the stack if that value is an odd number, /// else 0. - pub fn is_odd(mut self) { - self.build(self.ip, MasmOp::IsOdd); + pub fn is_odd(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::IsOdd, span); } /// Pushes the current value of the cycle counter (clock) on the stack - pub fn clk(mut self) { - self.build(self.ip, MasmOp::Clk); + pub fn clk(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Clk, span); } /// Pushes the hash of the caller on the stack - pub fn caller(mut self) { - self.build(self.ip, MasmOp::Caller); + pub fn caller(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Caller, span); } /// Pushes the current stack depth on the stack - pub fn current_stack_depth(mut self) { - self.build(self.ip, MasmOp::Sdepth); + pub fn current_stack_depth(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::Sdepth, span); } /// Pushes 1 on the stack if the element on top of the stack is less than 2^32, else 0. - pub fn test_u32(mut self) { - self.build(self.ip, MasmOp::U32Test); + pub fn test_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Test, span); } /// Pushes 1 on the stack if every element of the word on top of the stack is less than 2^32, /// else 0. - pub fn testw_u32(mut self) { - self.build(self.ip, MasmOp::U32Testw); + pub fn testw_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Testw, span); } /// Traps if the element on top of the stack is greater than or equal to 2^32 - pub fn assert_u32(mut self, error_code: Option) { + pub fn assert_u32(mut self, error_code: Option, span: SourceSpan) { let op = error_code.map(MasmOp::U32AssertWithError).unwrap_or(MasmOp::U32Assert); - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Traps if either of the first two elements on top of the stack are greater than or equal to /// 2^32 - pub fn assert2_u32(mut self, error_code: Option) { + pub fn assert2_u32(mut self, error_code: Option, span: SourceSpan) { let op = error_code.map(MasmOp::U32Assert2WithError).unwrap_or(MasmOp::U32Assert2); - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Traps if any element of the first word on the stack are greater than or equal to 2^32 - pub fn assertw_u32(mut self, error_code: Option) { + pub fn assertw_u32(mut self, error_code: Option, span: SourceSpan) { let op = error_code.map(MasmOp::U32AssertwWithError).unwrap_or(MasmOp::U32Assertw); - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Casts the element on top of the stack, `a`, to a valid u32 value, by computing `a mod 2^32` - pub fn cast_u32(mut self) { - self.build(self.ip, MasmOp::U32Cast); + pub fn cast_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Cast, span); } /// Pops an element, `a`, from the stack, and splits it into two elements, `b` and `c`, each of @@ -744,136 +748,166 @@ impl<'a> MasmOpBuilder<'a> { /// /// The value for `b` is given by `a mod 2^32`, and the value for `c` by `a / 2^32`. They are /// pushed on the stack in that order, i.e. `c` will be on top of the stack afterwards. - pub fn split_u32(mut self) { - self.build(self.ip, MasmOp::U32Split); + pub fn split_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Split, span); } /// Performs unsigned addition of the top two elements on the stack, `b` and `a` respectively, /// which are expected to be valid u32 values. /// /// See the [Overflow] enum for how `overflow` modifies the semantics of this instruction. - pub fn add_u32(mut self, overflow: Overflow) { + pub fn add_u32(mut self, overflow: Overflow, span: SourceSpan) { let op = match overflow { Overflow::Unchecked => MasmOp::Add, Overflow::Checked => { - return self - .build_many(self.ip, [MasmOp::U32Assert2, MasmOp::Add, MasmOp::U32Assert]); + return self.build_many( + self.ip, + [ + Span::new(span, MasmOp::U32Assert2), + Span::new(span, MasmOp::Add), + Span::new(span, MasmOp::U32Assert), + ], + ); } Overflow::Overflowing => MasmOp::U32OverflowingAdd, Overflow::Wrapping => MasmOp::U32WrappingAdd, }; - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Same as above, but `a` is provided by the given immediate. - pub fn add_imm_u32(mut self, imm: u32, overflow: Overflow) { + pub fn add_imm_u32(mut self, imm: u32, overflow: Overflow, span: SourceSpan) { let op = match overflow { Overflow::Unchecked if imm == 1 => MasmOp::Incr, Overflow::Unchecked => MasmOp::AddImm(Felt::new(imm as u64)), Overflow::Checked => { return self.build_many( self.ip, - [MasmOp::U32Assert, MasmOp::AddImm(Felt::new(imm as u64)), MasmOp::U32Assert], + [ + Span::new(span, MasmOp::U32Assert), + Span::new(span, MasmOp::AddImm(Felt::new(imm as u64))), + Span::new(span, MasmOp::U32Assert), + ], ); } Overflow::Overflowing => MasmOp::U32OverflowingAddImm(imm), Overflow::Wrapping => MasmOp::U32WrappingAddImm(imm), }; - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Pops three elements from the stack, `c`, `b`, and `a`, and computes `a + b + c` using the /// overflowing semantics of `add_u32`. The first two elements on the stack after this /// instruction will be a boolean indicating whether addition overflowed, and the result /// itself, mod 2^32. - pub fn add3_overflowing_u32(mut self) { - self.build(self.ip, MasmOp::U32OverflowingAdd3); + pub fn add3_overflowing_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32OverflowingAdd3, span); } /// Pops three elements from the stack, `c`, `b`, and `a`, and computes `a + b + c` using the /// wrapping semantics of `add_u32`. The result will be on top of the stack afterwards, mod /// 2^32. - pub fn add3_wrapping_u32(mut self) { - self.build(self.ip, MasmOp::U32WrappingAdd3); + pub fn add3_wrapping_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32WrappingAdd3, span); } /// Performs unsigned subtraction of the top two elements on the stack, `b` and `a` /// respectively, which are expected to be valid u32 values. /// /// See the [Overflow] enum for how `overflow` modifies the semantics of this instruction. - pub fn sub_u32(mut self, overflow: Overflow) { + pub fn sub_u32(mut self, overflow: Overflow, span: SourceSpan) { let op = match overflow { Overflow::Unchecked => MasmOp::Sub, Overflow::Checked => { - return self - .build_many(self.ip, [MasmOp::U32Assert2, MasmOp::Sub, MasmOp::U32Assert]); + return self.build_many( + self.ip, + [ + Span::new(span, MasmOp::U32Assert2), + Span::new(span, MasmOp::Sub), + Span::new(span, MasmOp::U32Assert), + ], + ); } Overflow::Overflowing => MasmOp::U32OverflowingSub, Overflow::Wrapping => MasmOp::U32WrappingSub, }; - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Same as above, but `a` is provided by the given immediate. - pub fn sub_imm_u32(mut self, imm: u32, overflow: Overflow) { + pub fn sub_imm_u32(mut self, imm: u32, overflow: Overflow, span: SourceSpan) { let op = match overflow { Overflow::Unchecked => MasmOp::SubImm(Felt::new(imm as u64)), Overflow::Checked => { return self.build_many( self.ip, - [MasmOp::U32Assert, MasmOp::SubImm(Felt::new(imm as u64)), MasmOp::U32Assert], + [ + Span::new(span, MasmOp::U32Assert), + Span::new(span, MasmOp::SubImm(Felt::new(imm as u64))), + Span::new(span, MasmOp::U32Assert), + ], ); } Overflow::Overflowing => MasmOp::U32OverflowingSubImm(imm), Overflow::Wrapping => MasmOp::U32WrappingSubImm(imm), }; - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Performs unsigned multiplication of the top two elements on the stack, `b` and `a` /// respectively, which are expected to be valid u32 values. /// /// See the [Overflow] enum for how `overflow` modifies the semantics of this instruction. - pub fn mul_u32(mut self, overflow: Overflow) { + pub fn mul_u32(mut self, overflow: Overflow, span: SourceSpan) { let op = match overflow { Overflow::Unchecked => MasmOp::Mul, Overflow::Checked => { - return self - .build_many(self.ip, [MasmOp::U32Assert2, MasmOp::Mul, MasmOp::U32Assert]); + return self.build_many( + self.ip, + [ + Span::new(span, MasmOp::U32Assert2), + Span::new(span, MasmOp::Mul), + Span::new(span, MasmOp::U32Assert), + ], + ); } Overflow::Overflowing => MasmOp::U32OverflowingMul, Overflow::Wrapping => MasmOp::U32WrappingMul, }; - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Same as above, but `a` is provided by the given immediate. - pub fn mul_imm_u32(mut self, imm: u32, overflow: Overflow) { + pub fn mul_imm_u32(mut self, imm: u32, overflow: Overflow, span: SourceSpan) { let op = match overflow { Overflow::Unchecked => MasmOp::MulImm(Felt::new(imm as u64)), Overflow::Checked => { return self.build_many( self.ip, - [MasmOp::U32Assert, MasmOp::MulImm(Felt::new(imm as u64)), MasmOp::U32Assert], + [ + Span::new(span, MasmOp::U32Assert), + Span::new(span, MasmOp::MulImm(Felt::new(imm as u64))), + Span::new(span, MasmOp::U32Assert), + ], ); } Overflow::Overflowing => MasmOp::U32OverflowingMulImm(imm), Overflow::Wrapping => MasmOp::U32WrappingMulImm(imm), }; - self.build(self.ip, op); + self.build(self.ip, op, span); } /// Pops three elements from the stack, `b`, `a`, and `c`, and computes `a * b + c`, using /// overflowing semantics, i.e. the result is wrapped mod 2^32, and a flag is pushed on the /// stack if the result overflowed the u32 range. - pub fn madd_overflowing_u32(mut self) { - self.build(self.ip, MasmOp::U32OverflowingMadd); + pub fn madd_overflowing_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32OverflowingMadd, span); } /// Pops three elements from the stack, `b`, `a`, and `c`, and computes `a * b + c`, using /// wrapping semantics, i.e. the result is wrapped mod 2^32. - pub fn madd_wrapping_u32(mut self) { - self.build(self.ip, MasmOp::U32WrappingMadd); + pub fn madd_wrapping_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32WrappingMadd, span); } /// Performs unsigned division of the top two elements on the stack, `b` and `a` respectively, @@ -882,13 +916,13 @@ impl<'a> MasmOpBuilder<'a> { /// This operation is unchecked, so if either operand is >= 2^32, the result is undefined. /// /// Traps if `b` is 0. - pub fn div_u32(mut self) { - self.build(self.ip, MasmOp::U32Div); + pub fn div_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Div, span); } /// Same as above, but `b` is provided by the given immediate - pub fn div_imm_u32(mut self, imm: u32) { - self.build(self.ip, MasmOp::U32DivImm(imm)); + pub fn div_imm_u32(mut self, imm: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::U32DivImm(imm), span); } /// Pops two elements off the stack, `b` and `a` respectively, and computes `a mod b`. @@ -896,13 +930,13 @@ impl<'a> MasmOpBuilder<'a> { /// This operation is unchecked, so if either operand is >= 2^32, the result is undefined. /// /// Traps if `b` is 0. - pub fn mod_u32(mut self) { - self.build(self.ip, MasmOp::U32Mod); + pub fn mod_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Mod, span); } /// Same as above, but `b` is provided by the given immediate - pub fn mod_imm_u32(mut self, imm: u32) { - self.build(self.ip, MasmOp::U32ModImm(imm)); + pub fn mod_imm_u32(mut self, imm: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::U32ModImm(imm), span); } /// Pops two elements off the stack, `b` and `a` respectively, and computes `a / b`, and `a mod @@ -911,192 +945,192 @@ impl<'a> MasmOpBuilder<'a> { /// This operation is unchecked, so if either operand is >= 2^32, the results are undefined. /// /// Traps if `b` is 0. - pub fn divmod_u32(mut self) { - self.build(self.ip, MasmOp::U32DivMod); + pub fn divmod_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32DivMod, span); } /// Same as above, but `b` is provided by the given immediate - pub fn divmod_imm_u32(mut self, imm: u32) { - self.build(self.ip, MasmOp::U32DivModImm(imm)); + pub fn divmod_imm_u32(mut self, imm: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::U32DivModImm(imm), span); } /// Pops two elements off the stack, and computes the bitwise AND of those values, placing the /// result on the stack. /// /// Traps if either element is not a valid u32 value. - pub fn band_u32(mut self) { - self.build(self.ip, MasmOp::U32And); + pub fn band_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32And, span); } /// Pops two elements off the stack, and computes the bitwise OR of those values, placing the /// result on the stack. /// /// Traps if either element is not a valid u32 value. - pub fn bor_u32(mut self) { - self.build(self.ip, MasmOp::U32Or); + pub fn bor_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Or, span); } /// Pops two elements off the stack, and computes the bitwise XOR of those values, placing the /// result on the stack. /// /// Traps if either element is not a valid u32 value. - pub fn bxor_u32(mut self) { - self.build(self.ip, MasmOp::U32Xor); + pub fn bxor_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Xor, span); } /// Pops an element off the stack, and computes the bitwise NOT of that value, placing the /// result on the stack. /// /// Traps if the element is not a valid u32 value. - pub fn bnot_u32(mut self) { - self.build(self.ip, MasmOp::U32Not); + pub fn bnot_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Not, span); } /// Pops two elements off the stack, `b` and `a` respectively, and shifts `a` left by `b` bits. /// More precisely, the result is computed as `(a * 2^b) mod 2^32`. /// /// The result is undefined if `a` is not a valid u32, or `b` is > 31. - pub fn shl_u32(mut self) { - self.build(self.ip, MasmOp::U32Shl); + pub fn shl_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Shl, span); } /// Same as `shl_u32`, but `b` is provided by immediate. - pub fn shl_imm_u32(mut self, imm: u32) { - self.build(self.ip, MasmOp::U32ShlImm(imm)); + pub fn shl_imm_u32(mut self, imm: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::U32ShlImm(imm), span); } /// Pops two elements off the stack, `b` and `a` respectively, and shifts `a` right by `b` bits. /// More precisely, the result is computed as `a / 2^b`. /// /// The result is undefined if `a` is not a valid u32, or `b` is > 31. - pub fn shr_u32(mut self) { - self.build(self.ip, MasmOp::U32Shr); + pub fn shr_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Shr, span); } /// Same as `shr_u32`, but `b` is provided by immediate. - pub fn shr_imm_u32(mut self, imm: u32) { - self.build(self.ip, MasmOp::U32ShrImm(imm)); + pub fn shr_imm_u32(mut self, imm: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::U32ShrImm(imm), span); } /// Pops two elements off the stack, `b` and `a` respectively, and rotates the binary /// representation of `a` left by `b` bits. /// /// The result is undefined if `a` is not a valid u32, or `b` is > 31. - pub fn rotl_u32(mut self) { - self.build(self.ip, MasmOp::U32Rotl); + pub fn rotl_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Rotl, span); } /// Same as `rotl_u32`, but `b` is provided by immediate. - pub fn rotl_imm_u32(mut self, imm: u32) { - self.build(self.ip, MasmOp::U32RotlImm(imm)); + pub fn rotl_imm_u32(mut self, imm: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::U32RotlImm(imm), span); } /// Pops two elements off the stack, `b` and `a` respectively, and rotates the binary /// representation of `a` right by `b` bits. /// /// The result is undefined if `a` is not a valid u32, or `b` is > 31. - pub fn rotr_u32(mut self) { - self.build(self.ip, MasmOp::U32Rotr); + pub fn rotr_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Rotr, span); } /// Same as `rotr_u32`, but `b` is provided by immediate. - pub fn rotr_imm_u32(mut self, imm: u32) { - self.build(self.ip, MasmOp::U32RotrImm(imm)); + pub fn rotr_imm_u32(mut self, imm: u32, span: SourceSpan) { + self.build(self.ip, MasmOp::U32RotrImm(imm), span); } /// Pops an element off the stack, and computes the number of set bits in its binary /// representation, i.e. its hamming weight, and places the result on the stack. /// /// The result is undefined if the input value is not a valid u32. - pub fn popcnt_u32(mut self) { - self.build(self.ip, MasmOp::U32Popcnt); + pub fn popcnt_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Popcnt, span); } /// Pops an element off the stack, and computes the number of leading zeros in its binary /// representation, and places the result on the stack. /// /// The result is undefined if the input value is not a valid u32. - pub fn clz_u32(mut self) { - self.build(self.ip, MasmOp::U32Clz); + pub fn clz_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Clz, span); } /// Pops an element off the stack, and computes the number of trailing zeros in its binary /// representation, and places the result on the stack. /// /// The result is undefined if the input value is not a valid u32. - pub fn ctz_u32(mut self) { - self.build(self.ip, MasmOp::U32Ctz); + pub fn ctz_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Ctz, span); } /// Pops an element off the stack, and computes the number of leading ones in its binary /// representation, and places the result on the stack. /// /// The result is undefined if the input value is not a valid u32. - pub fn clo_u32(mut self) { - self.build(self.ip, MasmOp::U32Clo); + pub fn clo_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Clo, span); } /// Pops an element off the stack, and computes the number of trailing ones in its binary /// representation, and places the result on the stack. /// /// The result is undefined if the input value is not a valid u32. - pub fn cto_u32(mut self) { - self.build(self.ip, MasmOp::U32Cto); + pub fn cto_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Cto, span); } /// Pushes a boolean on the stack by computing `a < b` for `[b, a]` /// /// The result is undefined if either operand is not a valid u32 value. - pub fn lt_u32(mut self) { - self.build(self.ip, MasmOp::U32Lt); + pub fn lt_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Lt, span); } /// Pushes a boolean on the stack by computing `a <= b` for `[b, a]` /// /// The result is undefined if either operand is not a valid u32 value. - pub fn lte_u32(mut self) { - self.build(self.ip, MasmOp::U32Lte); + pub fn lte_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Lte, span); } /// Pushes a boolean on the stack by computing `a > b` for `[b, a]` /// /// The result is undefined if either operand is not a valid u32 value. - pub fn gt_u32(mut self) { - self.build(self.ip, MasmOp::U32Gt); + pub fn gt_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Gt, span); } /// Pushes a boolean on the stack by computing `a >= b` for `[b, a]` /// /// The result is undefined if either operand is not a valid u32 value. - pub fn gte_u32(mut self) { - self.build(self.ip, MasmOp::U32Gte); + pub fn gte_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Gte, span); } /// Computes the minimum of the two elements on top of the stack. /// /// The result is undefined if either operand is not a valid u32 value. - pub fn min_u32(mut self) { - self.build(self.ip, MasmOp::U32Min); + pub fn min_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Min, span); } /// Computes the maximum of the two elements on top of the stack. /// /// The result is undefined if either operand is not a valid u32 value. - pub fn max_u32(mut self) { - self.build(self.ip, MasmOp::U32Max); + pub fn max_u32(mut self, span: SourceSpan) { + self.build(self.ip, MasmOp::U32Max, span); } #[inline(never)] - fn build(&mut self, ip: MasmBlockId, op: MasmOp) { + fn build(&mut self, ip: MasmBlockId, op: MasmOp, span: SourceSpan) { apply_op_stack_effects(&op, self.stack, self.dfg, self.asm); - self.asm.push(ip, op); + self.asm.push(ip, op, span); } #[inline(never)] - fn build_many(&mut self, ip: MasmBlockId, ops: impl IntoIterator) { + fn build_many(&mut self, ip: MasmBlockId, ops: impl IntoIterator>) { for op in ops.into_iter() { apply_op_stack_effects(&op, self.stack, self.dfg, self.asm); - self.asm.push(ip, op); + self.asm.push(ip, op.into_inner(), op.span()); } } } @@ -1159,6 +1193,8 @@ pub struct IfTrueBuilder<'a> { /// will be used as the expected state of the operand stack when we finish /// constructing the second branch and validate the `if.true`. out_stack: OperandStack, + /// The source span associated with the conditional + span: SourceSpan, /// This is the block to which the `if.true` will be appended ip: MasmBlockId, /// The block id for the then branch, unset until it has been finalized @@ -1202,7 +1238,7 @@ impl<'f> IfTrueBuilder<'f> { pub fn build(mut self) { let then_blk = self.then_blk.expect("missing 'then' block"); let else_blk = self.else_blk.expect("missing 'else' block"); - self.asm.push(self.ip, MasmOp::If(then_blk, else_blk)); + self.asm.push(self.ip, MasmOp::If(then_blk, else_blk), self.span); // Update the operand stack to represent the state after execution of the `if.true` let in_stack = self.in_stack.stack_mut(); in_stack.clear(); @@ -1380,6 +1416,8 @@ pub struct LoopBuilder<'a> { /// as otherwise program behavior is undefined based on whether the loop is /// entered or not. out_stack: OperandStack, + /// The source span associated with the loop + span: SourceSpan, /// The block to which the loop instruction will be appended ip: MasmBlockId, /// The top-level block for the loop @@ -1419,7 +1457,7 @@ impl<'f> LoopBuilder<'f> { "expected the operand stack to be in the same abstract state whether the \ while.true loop is taken or skipped" ); - self.asm.push(self.ip, MasmOp::While(self.body)); + self.asm.push(self.ip, MasmOp::While(self.body), self.span); } LoopType::Repeat(1) => { // This is an edge case, but a single iteration `repeat` is no different than @@ -1461,7 +1499,7 @@ impl<'f> LoopBuilder<'f> { apply_op_stack_effects(op, &mut self.out_stack, self.dfg, self.asm); } } - self.asm.push(self.ip, MasmOp::Repeat(n, self.body)); + self.asm.push(self.ip, MasmOp::Repeat(n, self.body), self.span); } } diff --git a/hir/src/asm/display.rs b/hir/src/asm/display.rs index 3e8ea0d3..9cf78593 100644 --- a/hir/src/asm/display.rs +++ b/hir/src/asm/display.rs @@ -330,14 +330,3 @@ impl<'a> fmt::Display for DisplayOp<'a> { self.pretty_print(f) } } - -struct Address(u32); -impl fmt::Display for Address { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "0x")?; - for byte in self.0.to_be_bytes() { - write!(f, "{:02x}", byte)?; - } - Ok(()) - } -} diff --git a/hir/src/asm/events.rs b/hir/src/asm/events.rs new file mode 100644 index 00000000..d9538ce0 --- /dev/null +++ b/hir/src/asm/events.rs @@ -0,0 +1,53 @@ +//! This module contains the set of compiler-emitted event codes, and their explanations +use core::num::NonZeroU32; + +/// This event is emitted via `trace`, and indicates that a procedure call frame is entered +/// +/// The mnemonic here is F = frame, 0 = open +pub const TRACE_FRAME_START: u32 = 0xf0; + +/// This event is emitted via `trace`, and indicates that a procedure call frame is exited +/// +/// The mnemonic here is F = frame, C = close +pub const TRACE_FRAME_END: u32 = 0xfc; + +/// A typed wrapper around the raw trace events known to the compiler +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u32)] +pub enum TraceEvent { + FrameStart, + FrameEnd, + AssertionFailed(Option), + Unknown(u32), +} +impl TraceEvent { + #[inline(always)] + pub fn is_frame_start(&self) -> bool { + matches!(self, Self::FrameStart) + } + + #[inline(always)] + pub fn is_frame_end(&self) -> bool { + matches!(self, Self::FrameEnd) + } +} +impl From for TraceEvent { + fn from(raw: u32) -> Self { + match raw { + TRACE_FRAME_START => Self::FrameStart, + TRACE_FRAME_END => Self::FrameEnd, + _ => Self::Unknown(raw), + } + } +} +impl From for u32 { + fn from(event: TraceEvent) -> Self { + match event { + TraceEvent::FrameStart => TRACE_FRAME_START, + TraceEvent::FrameEnd => TRACE_FRAME_END, + TraceEvent::AssertionFailed(None) => 0, + TraceEvent::AssertionFailed(Some(code)) => code.get(), + TraceEvent::Unknown(code) => code, + } + } +} diff --git a/hir/src/asm/import.rs b/hir/src/asm/import.rs index 23474de7..2a0a2f84 100644 --- a/hir/src/asm/import.rs +++ b/hir/src/asm/import.rs @@ -5,10 +5,12 @@ use core::{ }; use anyhow::bail; -use miden_diagnostics::{SourceSpan, Spanned}; use rustc_hash::{FxHashMap, FxHashSet}; -use crate::{FunctionIdent, Ident, Symbol}; +use crate::{ + diagnostics::{SourceSpan, Spanned}, + FunctionIdent, Ident, Symbol, +}; #[derive(Default, Debug, Clone)] pub struct ModuleImportInfo { diff --git a/hir/src/asm/isa.rs b/hir/src/asm/isa.rs index 8a11dfb6..f365ff1b 100644 --- a/hir/src/asm/isa.rs +++ b/hir/src/asm/isa.rs @@ -4,7 +4,10 @@ use cranelift_entity::entity_impl; pub use miden_assembly::ast::{AdviceInjectorNode, DebugOptions}; use smallvec::{smallvec, SmallVec}; -use crate::{Felt, FunctionIdent, Ident, LocalId}; +use crate::{ + diagnostics::{SourceSpan, Span}, + Felt, FunctionIdent, Ident, LocalId, +}; /// A handle that refers to a MASM code block #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -15,7 +18,7 @@ entity_impl!(MasmBlockId, "blk"); #[derive(Debug, Clone, PartialEq)] pub struct MasmBlock { pub id: MasmBlockId, - pub ops: SmallVec<[MasmOp; 4]>, + pub ops: SmallVec<[Span; 4]>, } impl MasmBlock { /// Returns true if there are no instructions in this block @@ -26,19 +29,20 @@ impl MasmBlock { /// Returns the instructions contained in this block as a slice #[inline(always)] - pub fn ops(&self) -> &[MasmOp] { + pub fn ops(&self) -> &[Span] { self.ops.as_slice() } /// Appends `op` to this code block #[inline(always)] - pub fn push(&mut self, op: MasmOp) { - self.ops.push(op); + pub fn push(&mut self, op: MasmOp, span: SourceSpan) { + self.ops.push(Span::new(span, op)); } /// Append `n` copies of `op` to the current block #[inline] - pub fn push_n(&mut self, count: usize, op: MasmOp) { + pub fn push_n(&mut self, count: usize, op: MasmOp, span: SourceSpan) { + let op = Span::new(span, op); for _ in 0..count { self.ops.push(op); } @@ -46,7 +50,7 @@ impl MasmBlock { /// Append `n` copies of the sequence `ops` to this block #[inline] - pub fn push_repeat(&mut self, ops: &[MasmOp], count: usize) { + pub fn push_repeat(&mut self, ops: &[Span], count: usize) { for _ in 0..count { self.ops.extend_from_slice(ops); } @@ -56,7 +60,7 @@ impl MasmBlock { #[inline] pub fn push_template(&mut self, count: usize, template: F) where - F: Fn(usize) -> [MasmOp; N], + F: Fn(usize) -> [Span; N], { for n in 0..count { self.ops.extend_from_slice(&template(n)); @@ -65,13 +69,13 @@ impl MasmBlock { /// Appends instructions from `slice` to the end of this block #[inline] - pub fn extend_from_slice(&mut self, slice: &[MasmOp]) { + pub fn extend_from_slice(&mut self, slice: &[Span]) { self.ops.extend_from_slice(slice); } /// Appends instructions from `slice` to the end of this block #[inline] - pub fn extend(&mut self, ops: impl IntoIterator) { + pub fn extend(&mut self, ops: impl IntoIterator>) { self.ops.extend(ops); } @@ -79,7 +83,7 @@ impl MasmBlock { #[inline] pub fn append(&mut self, other: &mut SmallVec) where - B: smallvec::Array, + B: smallvec::Array>, { self.ops.append(other); } @@ -1455,7 +1459,6 @@ impl MasmOp { locals: &BTreeSet, ) -> SmallVec<[miden_assembly::ast::Instruction; 2]> { use miden_assembly::{ - self as masm, ast::{Instruction, InvocationTarget, ProcedureName}, LibraryPath, }; @@ -1622,19 +1625,23 @@ impl MasmOp { | Self::Syscall(ref callee) | Self::ProcRef(ref callee)) => { let target = if locals.contains(callee) { - let callee = ProcedureName::new(callee.function.as_str()) - .expect("invalid procedure name"); + let callee = ProcedureName::new_unchecked(super::utils::translate_ident( + callee.function, + )); InvocationTarget::ProcedureName(callee) } else if let Some(alias) = imports.alias(&callee.module) { - let name = ProcedureName::new(callee.function.as_str()) - .expect("invalid procedure name"); + let alias = super::utils::translate_ident(alias); + let name = ProcedureName::new_unchecked(super::utils::translate_ident( + callee.function, + )); InvocationTarget::ProcedurePath { name, - module: masm::ast::Ident::new(alias.as_str()).expect("invalid module path"), + module: alias, } } else { - let name = ProcedureName::new(callee.function.as_str()) - .expect("invalid procedure name"); + let name = ProcedureName::new_unchecked(super::utils::translate_ident( + callee.function, + )); let path = LibraryPath::new(callee.module.as_str()).expect("invalid procedure path"); InvocationTarget::AbsoluteProcedurePath { name, path } @@ -1780,15 +1787,15 @@ impl MasmOp { Self::U32GtImm(imm) => return smallvec![Instruction::PushU32(imm), Instruction::U32Gt], Self::U32Gte => Instruction::U32Gte, Self::U32GteImm(imm) => { - return smallvec![Instruction::PushU32(imm), Instruction::U32Gte] + return smallvec![Instruction::PushU32(imm), Instruction::U32Gte]; } Self::U32Min => Instruction::U32Min, Self::U32MinImm(imm) => { - return smallvec![Instruction::PushU32(imm), Instruction::U32Min] + return smallvec![Instruction::PushU32(imm), Instruction::U32Min]; } Self::U32Max => Instruction::U32Max, Self::U32MaxImm(imm) => { - return smallvec![Instruction::PushU32(imm), Instruction::U32Max] + return smallvec![Instruction::PushU32(imm), Instruction::U32Max]; } Self::Breakpoint => Instruction::Breakpoint, Self::DebugStack => Instruction::Debug(DebugOptions::StackAll), diff --git a/hir/src/asm/mod.rs b/hir/src/asm/mod.rs index 4ae668cf..179574b8 100644 --- a/hir/src/asm/mod.rs +++ b/hir/src/asm/mod.rs @@ -1,20 +1,25 @@ +mod assertions; mod builder; mod display; +mod events; mod import; mod isa; mod stack; +pub mod utils; use cranelift_entity::PrimaryMap; use smallvec::smallvec; pub use self::{ + assertions::*, builder::*, display::{DisplayInlineAsm, DisplayMasmBlock}, + events::*, import::{MasmImport, ModuleImportInfo}, isa::*, stack::{OperandStack, Stack, StackElement}, }; -use super::{DataFlowGraph, Opcode, Type, ValueList}; +use crate::{diagnostics::SourceSpan, DataFlowGraph, Opcode, Type, ValueList}; /// Represents Miden Assembly (MASM) directly in the IR /// @@ -78,8 +83,8 @@ impl InlineAsm { } /// Appends `op` to the end of `block` - pub fn push(&mut self, block: MasmBlockId, op: MasmOp) { - self.blocks[block].push(op); + pub fn push(&mut self, block: MasmBlockId, op: MasmOp, span: SourceSpan) { + self.blocks[block].push(op, span); } pub fn display<'a, 'b: 'a>( diff --git a/hir/src/asm/stack.rs b/hir/src/asm/stack.rs index 7e4bf148..0f4dd268 100644 --- a/hir/src/asm/stack.rs +++ b/hir/src/asm/stack.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ fmt, ops::{Index, IndexMut}, }; diff --git a/hir/src/asm/utils.rs b/hir/src/asm/utils.rs new file mode 100644 index 00000000..50806183 --- /dev/null +++ b/hir/src/asm/utils.rs @@ -0,0 +1,9 @@ +use alloc::sync::Arc; + +use crate::diagnostics::Span; + +/// Obtain a [miden_assembly::ast::Ident] from a [crate::Ident], with source span intact. +pub fn translate_ident(id: crate::Ident) -> miden_assembly::ast::Ident { + let name = Arc::from(id.as_str().to_string().into_boxed_str()); + miden_assembly::ast::Ident::new_unchecked(Span::new(id.span, name)) +} diff --git a/hir/src/attribute.rs b/hir/src/attribute.rs index 122f2224..12f09044 100644 --- a/hir/src/attribute.rs +++ b/hir/src/attribute.rs @@ -1,4 +1,5 @@ -use std::{borrow::Borrow, collections::BTreeMap, fmt}; +use alloc::collections::BTreeMap; +use core::{borrow::Borrow, fmt}; use crate::Symbol; diff --git a/hir/src/builder.rs b/hir/src/builder.rs index e411bd88..1f9a481f 100644 --- a/hir/src/builder.rs +++ b/hir/src/builder.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::{diagnostics::Span, *}; pub struct FunctionBuilder<'f> { pub func: &'f mut Function, @@ -181,8 +181,6 @@ impl<'f> InstBuilderBase<'f> for ReplaceBuilder<'f> { ctrl_typevar: Type, span: SourceSpan, ) -> (Inst, &'f mut DataFlowGraph) { - use miden_diagnostics::Span; - // Splat the new instruction on top of the old one. self.dfg.insts[self.inst].replace(Span::new(span, data)); // The old result values, if any, were either detached or non-existent. @@ -1419,9 +1417,9 @@ pub trait InstBuilder<'f>: InstBuilderBase<'f> { self.CondBr(cond, then_dest, then_vlist, else_dest, else_vlist, span).0 } - fn switch(self, arg: Value, arms: Vec<(u32, Block)>, default: Block, span: SourceSpan) -> Inst { + fn switch(self, arg: Value, span: SourceSpan) -> SwitchBuilder<'f, Self> { require_integer!(self, arg, Type::U32); - self.Switch(arg, arms, default, span).0 + SwitchBuilder::new(self, arg, span) } fn ret(mut self, returning: Option, span: SourceSpan) -> Inst { @@ -1471,8 +1469,14 @@ pub trait InstBuilder<'f>: InstBuilderBase<'f> { let data = Instruction::CondBr(CondBr { op: Opcode::CondBr, cond, - then_dest: (then_dest, then_args), - else_dest: (else_dest, else_args), + then_dest: Successor { + destination: then_dest, + args: then_args, + }, + else_dest: Successor { + destination: else_dest, + args: else_args, + }, }); self.build(data, Type::Unit, span) } @@ -1488,8 +1492,7 @@ pub trait InstBuilder<'f>: InstBuilderBase<'f> { ) -> (Inst, &'f mut DataFlowGraph) { let data = Instruction::Br(Br { op, - destination, - args, + successor: Successor { destination, args }, }); self.build(data, ty, span) } @@ -1498,8 +1501,8 @@ pub trait InstBuilder<'f>: InstBuilderBase<'f> { fn Switch( self, arg: Value, - arms: Vec<(u32, Block)>, - default: Block, + arms: Vec, + default: Successor, span: SourceSpan, ) -> (Inst, &'f mut DataFlowGraph) { let data = Instruction::Switch(Switch { @@ -1726,3 +1729,63 @@ pub trait InstBuilder<'f>: InstBuilderBase<'f> { } impl<'f, T: InstBuilderBase<'f>> InstBuilder<'f> for T {} + +/// An instruction builder for `switch`, to ensure it is validated during construction +pub struct SwitchBuilder<'f, T: InstBuilder<'f>> { + builder: T, + arg: Value, + span: SourceSpan, + arms: Vec, + _marker: core::marker::PhantomData<&'f Function>, +} +impl<'f, T: InstBuilder<'f>> SwitchBuilder<'f, T> { + fn new(builder: T, arg: Value, span: SourceSpan) -> Self { + Self { + builder, + arg, + span, + arms: Default::default(), + _marker: core::marker::PhantomData, + } + } + + /// Specify to what block a specific discriminant value should be dispatched + pub fn case(mut self, discriminant: u32, target: Block, args: &[Value]) -> Self { + assert_eq!( + self.arms + .iter() + .find(|arm| arm.value == discriminant) + .map(|arm| arm.successor.destination), + None, + "duplicate switch case value '{discriminant}': already matched" + ); + let mut vlist = ValueList::default(); + { + let pool = &mut self.builder.data_flow_graph_mut().value_lists; + vlist.extend(args.iter().copied(), pool); + } + let arm = SwitchArm { + value: discriminant, + successor: Successor { + destination: target, + args: vlist, + }, + }; + self.arms.push(arm); + self + } + + /// Build the `switch` by specifying the fallback destination if none of the arms match + pub fn or_else(mut self, target: Block, args: &[Value]) -> Inst { + let mut vlist = ValueList::default(); + { + let pool = &mut self.builder.data_flow_graph_mut().value_lists; + vlist.extend(args.iter().copied(), pool); + } + let fallback = Successor { + destination: target, + args: vlist, + }; + self.builder.Switch(self.arg, self.arms, fallback, self.span).0 + } +} diff --git a/hir/src/component/interface.rs b/hir/src/component/interface.rs index 095b2c82..3a3f3fbb 100644 --- a/hir/src/component/interface.rs +++ b/hir/src/component/interface.rs @@ -6,7 +6,7 @@ use crate::formatter::PrettyPrint; /// A fully-qualified identifier for the interface being imported, e.g. /// `namespace::package/interface@version` -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct InterfaceIdent { /// A fully-qualified identifier for the interface being imported, e.g. /// `namespace::package/interface@version` @@ -23,6 +23,11 @@ impl InterfaceIdent { } } +impl fmt::Debug for InterfaceIdent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fmt::Display::fmt(&self.full_name, f) + } +} impl fmt::Display for InterfaceIdent { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "\"{}\"", self.full_name.as_str().escape_default()) @@ -30,7 +35,7 @@ impl fmt::Display for InterfaceIdent { } /// An identifier for a function in an interface -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct InterfaceFunctionIdent { /// An interface identifier for the interface being imported (e.g. /// `namespace::package/interface@version`) @@ -50,6 +55,11 @@ impl InterfaceFunctionIdent { } } +impl fmt::Debug for InterfaceFunctionIdent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{} @ {:?}", &self.function, &self.interface) + } +} impl fmt::Display for InterfaceFunctionIdent { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.pretty_print(f) diff --git a/hir/src/component/mod.rs b/hir/src/component/mod.rs index 405fee28..d7425092 100644 --- a/hir/src/component/mod.rs +++ b/hir/src/component/mod.rs @@ -5,7 +5,10 @@ use indexmap::IndexMap; use miden_core::crypto::hash::RpoDigest; use self::formatter::PrettyPrint; -use super::*; +use crate::{ + diagnostics::{DiagnosticsHandler, Report}, + *, +}; mod interface; @@ -255,10 +258,10 @@ pub struct ComponentBuilder<'a> { imports: BTreeMap, exports: BTreeMap, entry: Option, - diagnostics: &'a miden_diagnostics::DiagnosticsHandler, + diagnostics: &'a DiagnosticsHandler, } impl<'a> ComponentBuilder<'a> { - pub fn new(diagnostics: &'a miden_diagnostics::DiagnosticsHandler) -> Self { + pub fn new(diagnostics: &'a DiagnosticsHandler) -> Self { Self { modules: Default::default(), entry: None, @@ -291,7 +294,7 @@ impl<'a> ComponentBuilder<'a> { pub fn add_module(&mut self, module: Box) -> Result<(), ModuleConflictError> { let module_name = module.name; if self.modules.contains_key(&module_name) { - return Err(ModuleConflictError(module_name)); + return Err(ModuleConflictError::new(module_name)); } self.modules.insert(module_name, module); @@ -394,15 +397,15 @@ impl<'a, 'b: 'a> AsMut for ComponentModuleBuilder<'a, 'b> { /// This is used to build a [Function] from a [ComponentModuleBuilder]. /// /// It is basically just a wrapper around [ModuleFunctionBuilder], but overrides -/// `build` to use the [miden_diagnostics::DiagnosticsHandler] of the parent +/// `build` to use the [DiagnosticsHandler] of the parent /// [ComponentBuilder]. pub struct ComponentFunctionBuilder<'a, 'b: 'a> { - diagnostics: &'b miden_diagnostics::DiagnosticsHandler, + diagnostics: &'b DiagnosticsHandler, fb: ModuleFunctionBuilder<'a>, } impl<'a, 'b: 'a> ComponentFunctionBuilder<'a, 'b> { /// Build the current function - pub fn build(self) -> Result { + pub fn build(self) -> Result { let diagnostics = self.diagnostics; self.fb.build(diagnostics) } diff --git a/hir/src/constants.rs b/hir/src/constants.rs index b8288af8..2bbb1f51 100644 --- a/hir/src/constants.rs +++ b/hir/src/constants.rs @@ -68,6 +68,16 @@ impl ConstantData { self.0.resize(expected_size, 0); self } + + /// Attempt to convert this constant data to a `u32` value + pub fn as_u32(&self) -> Option { + let bytes = self.as_slice(); + if bytes.len() != 4 { + return None; + } + let bytes = bytes.as_ptr() as *const [u8; 4]; + Some(u32::from_le_bytes(unsafe { bytes.read() })) + } } impl FromIterator for ConstantData { fn from_iter>(iter: T) -> Self { diff --git a/hir/src/dataflow.rs b/hir/src/dataflow.rs index fdd5d81a..1f5d5a4e 100644 --- a/hir/src/dataflow.rs +++ b/hir/src/dataflow.rs @@ -1,11 +1,13 @@ -use std::ops::{Deref, Index, IndexMut}; +use core::ops::{Deref, DerefMut, Index, IndexMut}; use cranelift_entity::{PrimaryMap, SecondaryMap}; -use miden_diagnostics::{Span, Spanned}; use rustc_hash::FxHashMap; use smallvec::SmallVec; -use super::*; +use crate::{ + diagnostics::{SourceSpan, Span, Spanned}, + *, +}; pub struct DataFlowGraph { pub entry: Block, @@ -424,9 +426,11 @@ impl DataFlowGraph { /// Replace uses of `value` with `replacement` in the arguments of `inst` pub fn replace_uses(&mut self, inst: Inst, value: Value, replacement: Value) { let ix = &mut self.insts[inst]; - match &mut ix.data.item { - Instruction::Br(Br { ref mut args, .. }) => { - let args = args.as_mut_slice(&mut self.value_lists); + match ix.data.deref_mut() { + Instruction::Br(Br { + ref mut successor, .. + }) => { + let args = successor.args.as_mut_slice(&mut self.value_lists); for arg in args.iter_mut() { if arg == &value { *arg = replacement; @@ -435,26 +439,50 @@ impl DataFlowGraph { } Instruction::CondBr(CondBr { ref mut cond, - then_dest: (_, ref mut then_args), - else_dest: (_, ref mut else_args), + ref mut then_dest, + ref mut else_dest, .. }) => { if cond == &value { *cond = replacement; } - let then_args = then_args.as_mut_slice(&mut self.value_lists); + let then_args = then_dest.args.as_mut_slice(&mut self.value_lists); for arg in then_args.iter_mut() { if arg == &value { *arg = replacement; } } - let else_args = else_args.as_mut_slice(&mut self.value_lists); + let else_args = else_dest.args.as_mut_slice(&mut self.value_lists); for arg in else_args.iter_mut() { if arg == &value { *arg = replacement; } } } + Instruction::Switch(Switch { + ref mut arg, + ref mut arms, + default: default_succ, + .. + }) => { + if arg == &value { + *arg = replacement; + } + let default_args = default_succ.args.as_mut_slice(&mut self.value_lists); + for arg in default_args.iter_mut() { + if arg == &value { + *arg = replacement; + } + } + for arm in arms.iter_mut() { + let args = arm.successor.args.as_mut_slice(&mut self.value_lists); + for arg in args.iter_mut() { + if arg == &value { + *arg = replacement; + } + } + } + } ix => { for arg in ix.arguments_mut(&mut self.value_lists) { if arg == &value { @@ -483,28 +511,38 @@ impl DataFlowGraph { replacement: Value, ) { let ix = &mut self.insts[inst]; - match ix.data.as_mut() { - Instruction::Br(Br { ref mut args, .. }) => { + match ix.data.deref_mut() { + Instruction::Br(Br { + ref mut successor, .. + }) => { debug_assert_eq!(succ_index, 0); - args.as_mut_slice(&mut self.value_lists)[index] = replacement; + successor.args.as_mut_slice(&mut self.value_lists)[index] = replacement; } Instruction::CondBr(CondBr { - then_dest: (_, ref mut then_args), - else_dest: (_, ref mut else_args), + ref mut then_dest, + ref mut else_dest, .. }) => match succ_index { 0 => { - then_args.as_mut_slice(&mut self.value_lists)[index] = replacement; + then_dest.args.as_mut_slice(&mut self.value_lists)[index] = replacement; } 1 => { - else_args.as_mut_slice(&mut self.value_lists)[index] = replacement; + else_dest.args.as_mut_slice(&mut self.value_lists)[index] = replacement; } _ => unreachable!("expected valid successor index for cond_br, got {succ_index}"), }, - Instruction::Switch(_) => unimplemented!( - "invalid instruction: cannot replace successor arguments for 'switch': arms \ - cannot have arguments yet" - ), + Instruction::Switch(Switch { + ref mut arms, + default: ref mut default_succ, + .. + }) => { + debug_assert!(succ_index < arms.len() + 1); + if succ_index == arms.len() { + default_succ.args.as_mut_slice(&mut self.value_lists)[index] = replacement; + } + arms[succ_index].successor.args.as_mut_slice(&mut self.value_lists)[index] = + replacement; + } ix => panic!("invalid instruction: expected branch instruction, got {ix:#?}"), } } @@ -552,7 +590,7 @@ impl DataFlowGraph { self.insts[inst].analyze_call(&self.value_lists) } - pub fn analyze_branch(&self, inst: Inst) -> BranchInfo { + pub fn analyze_branch(&self, inst: Inst) -> BranchInfo<'_> { self.insts[inst].analyze_branch(&self.value_lists) } @@ -750,32 +788,38 @@ impl DataFlowGraph { dest: Block, value: Value, ) { - match self.insts[branch_inst].data.as_mut() { + match self.insts[branch_inst].data.deref_mut() { Instruction::Br(Br { - destination, - ref mut args, - .. + ref mut successor, .. }) => { - debug_assert_eq!(*destination, dest); - args.push(value, &mut self.value_lists); + debug_assert_eq!(successor.destination, dest); + successor.args.push(value, &mut self.value_lists); } Instruction::CondBr(CondBr { - then_dest: (then_dest, ref mut then_args), - else_dest: (else_dest, ref mut else_args), + ref mut then_dest, + ref mut else_dest, .. }) => { - if *then_dest == dest { - then_args.push(value, &mut self.value_lists); + if then_dest.destination == dest { + then_dest.args.push(value, &mut self.value_lists); } - if *else_dest == dest { - else_args.push(value, &mut self.value_lists); + if else_dest.destination == dest { + else_dest.args.push(value, &mut self.value_lists); } } - Instruction::Switch(_) => { - panic!( - "cannot append argument {value} to Switch destination block {dest}, since it \ - has no block arguments support" - ); + Instruction::Switch(Switch { + ref mut arms, + default: ref mut default_succ, + .. + }) => { + if default_succ.destination == dest { + default_succ.args.push(value, &mut self.value_lists); + } + for arm in arms.iter_mut() { + if arm.successor.destination == dest { + arm.successor.args.push(value, &mut self.value_lists); + } + } } _ => panic!("{} must be a branch instruction", branch_inst), } diff --git a/hir/src/display.rs b/hir/src/display.rs index a5045865..eeeed507 100644 --- a/hir/src/display.rs +++ b/hir/src/display.rs @@ -1,4 +1,4 @@ -use std::{cell::Cell, fmt}; +use core::{cell::Cell, fmt}; use super::{Block, Inst}; diff --git a/hir/src/function.rs b/hir/src/function.rs index 78dd91c9..3e4654c3 100644 --- a/hir/src/function.rs +++ b/hir/src/function.rs @@ -1,13 +1,16 @@ use cranelift_entity::entity_impl; use intrusive_collections::{intrusive_adapter, LinkedList, LinkedListLink}; -use miden_diagnostics::Spanned; use self::formatter::PrettyPrint; -use super::*; +use crate::{ + diagnostics::{miette, Diagnostic, Spanned}, + *, +}; /// This error is raised when two function declarations conflict with the same symbol name -#[derive(Debug, thiserror::Error)] -#[error("item with this name has already been declared, or cannot be merged")] +#[derive(Debug, thiserror::Error, Diagnostic)] +#[error("item named '{}' has already been declared, or cannot be merged", .0)] +#[diagnostic()] pub struct SymbolConflictError(pub FunctionIdent); /// A handle that refers to an [ExternalFunction] @@ -644,24 +647,24 @@ impl<'a> fmt::Display for CfgPrinter<'a> { let opcode = self.function.dfg.inst(last_inst).opcode(); writeln!(f, " {block_id} --> {opcode}")?; } - BranchInfo::SingleDest(succ, _) => { + BranchInfo::SingleDest(info) => { assert!( - self.function.dfg.is_block_linked(succ), + self.function.dfg.is_block_linked(info.destination), "reference to detached block in attached block {}", - succ + info.destination ); - writeln!(f, " {block_id} --> {succ}")?; - block_q.push_back(succ); + writeln!(f, " {block_id} --> {}", info.destination)?; + block_q.push_back(info.destination); } - BranchInfo::MultiDest(ref jts) => { - for jt in jts { + BranchInfo::MultiDest(ref infos) => { + for info in infos { assert!( - self.function.dfg.is_block_linked(jt.destination), + self.function.dfg.is_block_linked(info.destination), "reference to detached block in attached block {}", - jt.destination + info.destination ); - writeln!(f, " {block_id} --> {}", jt.destination)?; - block_q.push_back(jt.destination); + writeln!(f, " {block_id} --> {}", info.destination)?; + block_q.push_back(info.destination); } } } diff --git a/hir/src/globals.rs b/hir/src/globals.rs index 198863e5..ea775fe2 100644 --- a/hir/src/globals.rs +++ b/hir/src/globals.rs @@ -1,15 +1,16 @@ -use std::{ - alloc::Layout, - collections::{hash_map::DefaultHasher, BTreeMap}, +use alloc::{alloc::Layout, collections::BTreeMap}; +use core::{ fmt::{self, Write}, hash::{Hash, Hasher}, }; use cranelift_entity::entity_impl; use intrusive_collections::{intrusive_adapter, LinkedList, LinkedListLink}; -use miden_diagnostics::Spanned; -use super::*; +use crate::{ + diagnostics::{miette, Diagnostic, Spanned}, + *, +}; /// The policy to apply to a global variable (or function) when linking /// together a program during code generation. @@ -79,21 +80,24 @@ intrusive_adapter!(pub GlobalVariableAdapter = UnsafeRef: Gl /// For example, two global variables with the same name, but differing /// types will result in this error, as there is no way to resolve the /// conflict. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, Diagnostic)] pub enum GlobalVariableError { /// There are multiple conflicting definitions of the given global symbol #[error( "invalid global variable: there are multiple conflicting definitions for symbol '{0}'" )] + #[diagnostic()] NameConflict(Ident), /// An attempt was made to set the initializer for a global that already has one #[error("cannot set an initializer for '{0}', it is already initialized")] + #[diagnostic()] AlreadyInitialized(Ident), /// The initializer data is invalid for the declared type of the given global, e.g. size /// mismatch. #[error( "invalid global variable initializer for '{0}': the data does not match the declared type" )] + #[diagnostic()] InvalidInit(Ident), } @@ -389,7 +393,7 @@ impl GlobalVariableTable { let unique_id = self.next_unique_id; self.next_unique_id += 1; // Calculate the hash of the global variable data - let mut hasher = DefaultHasher::new(); + let mut hasher = rustc_hash::FxHasher::default(); data.hash(&mut hasher); unique_id.hash(&mut hasher); let hash = hasher.finish(); @@ -675,7 +679,8 @@ impl Default for GlobalValue { /// known statically, we instructions which manipulate globals are converted to /// loads/stores using constant addresses when translated to MASM. /// -/// Like other entities, globals may also have a [SourceSpan] associated with them. +/// Like other entities, globals may also have a [crate::diagnostics::SourceSpan] associated with +/// them. #[derive(Debug, Clone)] pub enum GlobalValueData { /// A symbolic reference to a global variable symbol diff --git a/hir/src/ident.rs b/hir/src/ident.rs index 2bf846b2..6f5b0926 100644 --- a/hir/src/ident.rs +++ b/hir/src/ident.rs @@ -6,13 +6,27 @@ use core::{ }; use anyhow::anyhow; -use miden_diagnostics::{SourceSpan, Spanned}; -use super::{ +use crate::{ + diagnostics::{SourceSpan, Spanned}, formatter::{self, PrettyPrint}, symbols, Symbol, }; +/// Demangle `name`, where `name` was mangled using Rust's mangling scheme +#[inline] +pub fn demangle>(name: S) -> String { + demangle_impl(name.as_ref()) +} + +fn demangle_impl(name: &str) -> String { + let mut input = name.as_bytes(); + let mut demangled = Vec::with_capacity(input.len() * 2); + rustc_demangle::demangle_stream(&mut input, &mut demangled, /* include_hash= */ false) + .expect("failed to write demangled identifier"); + String::from_utf8(demangled).expect("demangled identifier contains invalid utf-8") +} + /// Represents a globally-unique module/function name pair, with corresponding source spans. #[derive(Copy, Clone, PartialEq, Eq, Hash, Spanned)] pub struct FunctionIdent { @@ -20,6 +34,17 @@ pub struct FunctionIdent { #[span] pub function: Ident, } +impl FunctionIdent { + pub fn display(&self) -> impl fmt::Display + '_ { + use crate::formatter::*; + + flatten( + const_text(self.module.as_str()) + + const_text("::") + + const_text(self.function.as_str()), + ) + } +} impl FromStr for FunctionIdent { type Err = anyhow::Error; diff --git a/hir/src/immediates.rs b/hir/src/immediates.rs index 4b7b05f1..1c211bdf 100644 --- a/hir/src/immediates.rs +++ b/hir/src/immediates.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ fmt, hash::{Hash, Hasher}, }; diff --git a/hir/src/instruction.rs b/hir/src/instruction.rs index 1dc3e197..36eae627 100644 --- a/hir/src/instruction.rs +++ b/hir/src/instruction.rs @@ -1,12 +1,15 @@ use core::ops::{Deref, DerefMut}; +use std::collections::BTreeSet; use cranelift_entity::entity_impl; use intrusive_collections::{intrusive_adapter, LinkedListLink}; -use miden_diagnostics::{Span, Spanned}; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use self::formatter::PrettyPrint; -use super::*; +use crate::{ + diagnostics::{Span, Spanned}, + *, +}; /// A handle to a single instruction #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -125,15 +128,26 @@ impl Instruction { ..call.clone() }), Self::Br(br) => Self::Br(Br { - args: br.args.deep_clone(value_lists), + successor: br.successor.deep_clone(value_lists), ..br.clone() }), Self::CondBr(br) => Self::CondBr(CondBr { - then_dest: (br.then_dest.0, br.then_dest.1.deep_clone(value_lists)), - else_dest: (br.else_dest.0, br.else_dest.1.deep_clone(value_lists)), + then_dest: br.then_dest.deep_clone(value_lists), + else_dest: br.else_dest.deep_clone(value_lists), ..br.clone() }), - Self::Switch(op) => Self::Switch(op.clone()), + Self::Switch(op) => Self::Switch(Switch { + arms: op + .arms + .iter() + .map(|arm| SwitchArm { + value: arm.value, + successor: arm.successor.deep_clone(value_lists), + }) + .collect(), + default: op.default.deep_clone(value_lists), + ..op.clone() + }), Self::Ret(op) => Self::Ret(Ret { args: op.args.deep_clone(value_lists), ..op.clone() @@ -255,23 +269,27 @@ impl Instruction { pub fn analyze_branch<'a>(&'a self, pool: &'a ValueListPool) -> BranchInfo<'a> { match self { - Self::Br(ref b) => BranchInfo::SingleDest(b.destination, b.args.as_slice(pool)), + Self::Br(Br { successor, .. }) => { + BranchInfo::SingleDest(SuccessorInfo::new(successor, pool)) + } Self::CondBr(CondBr { ref then_dest, ref else_dest, .. }) => BranchInfo::MultiDest(vec![ - JumpTable::new(then_dest.0, then_dest.1.as_slice(pool)), - JumpTable::new(else_dest.0, else_dest.1.as_slice(pool)), + SuccessorInfo::new(then_dest, pool), + SuccessorInfo::new(else_dest, pool), ]), Self::Switch(Switch { ref arms, ref default, .. }) => { - let mut targets = - arms.iter().map(|(_, b)| JumpTable::new(*b, &[])).collect::>(); - targets.push(JumpTable::new(*default, &[])); + let mut targets = arms + .iter() + .map(|succ| SuccessorInfo::new(&succ.successor, pool)) + .collect::>(); + targets.push(SuccessorInfo::new(default, pool)); BranchInfo::MultiDest(targets) } _ => BranchInfo::NotABranch, @@ -289,19 +307,8 @@ impl Instruction { #[derive(Debug)] pub enum BranchInfo<'a> { NotABranch, - SingleDest(Block, &'a [Value]), - MultiDest(Vec>), -} - -#[derive(Debug)] -pub struct JumpTable<'a> { - pub destination: Block, - pub args: &'a [Value], -} -impl<'a> JumpTable<'a> { - pub fn new(destination: Block, args: &'a [Value]) -> Self { - Self { destination, args } - } + SingleDest(SuccessorInfo<'a>), + MultiDest(Vec>), } pub enum CallInfo<'a> { @@ -1007,10 +1014,7 @@ pub struct Call { #[derive(Debug, Clone)] pub struct Br { pub op: Opcode, - pub destination: Block, - /// NOTE: Block arguments are always in stack order, i.e. the top operand on - /// the stack is the first block argument - pub args: ValueList, + pub successor: Successor, } /// Conditional Branch @@ -1018,12 +1022,8 @@ pub struct Br { pub struct CondBr { pub op: Opcode, pub cond: Value, - /// NOTE: Block arguments are always in stack order, i.e. the top operand on - /// the stack is the first block argument - pub then_dest: (Block, ValueList), - /// NOTE: Block arguments are always in stack order, i.e. the top operand on - /// the stack is the first block argument - pub else_dest: (Block, ValueList), + pub then_dest: Successor, + pub else_dest: Successor, } /// Multi-way Branch w/Selector @@ -1031,8 +1031,82 @@ pub struct CondBr { pub struct Switch { pub op: Opcode, pub arg: Value, - pub arms: Vec<(u32, Block)>, - pub default: Block, + pub arms: Vec, + pub default: Successor, +} + +#[derive(Debug, Clone)] +pub struct SwitchArm { + pub value: u32, + pub successor: Successor, +} + +#[derive(Debug, Clone)] +pub struct Successor { + pub destination: Block, + /// NOTE: Block arguments are always in stack order, i.e. the top operand on + /// the stack is the first block argument + pub args: ValueList, +} +impl Successor { + pub fn deep_clone(&self, pool: &mut ValueListPool) -> Self { + Self { + destination: self.destination, + args: self.args.deep_clone(pool), + } + } +} + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct SuccessorInfo<'a> { + pub destination: Block, + pub args: &'a [Value], +} +impl<'a> SuccessorInfo<'a> { + pub fn new(successor: &Successor, pool: &'a ValueListPool) -> Self { + Self { + destination: successor.destination, + args: successor.args.as_slice(pool), + } + } +} +impl<'a> formatter::PrettyPrint for SuccessorInfo<'a> { + fn render(&self) -> miden_core::prettier::Document { + use crate::formatter::*; + + if self.args.is_empty() { + return self.destination.render(); + } + + let args = self + .args + .iter() + .copied() + .map(display) + .reduce(|acc, arg| acc + const_text(" ") + arg) + .map(|args| const_text(" ") + args) + .unwrap_or_default(); + const_text("(") + + const_text("block") + + const_text(" ") + + display(self.destination.as_u32()) + + args + + const_text(")") + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct SuccessorInfoMut<'a> { + pub destination: Block, + pub args: &'a mut [Value], +} +impl<'a> SuccessorInfoMut<'a> { + pub fn new(successor: &'a mut Successor, pool: &'a mut ValueListPool) -> Self { + Self { + destination: successor.destination, + args: successor.args.as_mut_slice(pool), + } + } } /// Return @@ -1122,20 +1196,31 @@ impl<'a> PartialEq for InstructionWithValueListPool<'a> { && l.args.as_slice(self.value_lists) == r.args.as_slice(self.value_lists) } (Instruction::Br(l), Instruction::Br(r)) => { - l.destination == r.destination - && l.args.as_slice(self.value_lists) == r.args.as_slice(other.value_lists) + let l = SuccessorInfo::new(&l.successor, self.value_lists); + let r = SuccessorInfo::new(&r.successor, self.value_lists); + l == r } (Instruction::CondBr(l), Instruction::CondBr(r)) => { - l.cond == r.cond - && l.then_dest.0 == r.then_dest.0 - && l.else_dest.0 == r.else_dest.0 - && l.then_dest.1.as_slice(self.value_lists) - == r.then_dest.1.as_slice(other.value_lists) - && l.else_dest.1.as_slice(self.value_lists) - == r.else_dest.1.as_slice(other.value_lists) + let l_then = SuccessorInfo::new(&l.then_dest, self.value_lists); + let l_else = SuccessorInfo::new(&l.else_dest, self.value_lists); + let r_then = SuccessorInfo::new(&r.then_dest, self.value_lists); + let r_else = SuccessorInfo::new(&r.else_dest, self.value_lists); + l.cond == r.cond && l_then == r_then && l_else == r_else } (Instruction::Switch(l), Instruction::Switch(r)) => { - l.arg == r.arg && l.default == r.default && l.arms == r.arms + if l.arg != r.arg { + return false; + } + let l_arms = BTreeSet::from_iter( + l.arms.iter().map(|arm| SuccessorInfo::new(&arm.successor, self.value_lists)), + ); + let r_arms = BTreeSet::from_iter( + r.arms.iter().map(|arm| SuccessorInfo::new(&arm.successor, self.value_lists)), + ); + let same_arms = l_arms == r_arms; + let same_default = SuccessorInfo::new(&l.default, self.value_lists) + == SuccessorInfo::new(&r.default, self.value_lists); + same_arms && same_default } (Instruction::Ret(l), Instruction::Ret(r)) => { l.args.as_slice(self.value_lists) == r.args.as_slice(other.value_lists) @@ -1286,94 +1371,42 @@ impl<'a> formatter::PrettyPrint for InstPrettyPrinter<'a> { } Instruction::CondBr(CondBr { cond, - then_dest, - else_dest, + ref then_dest, + ref else_dest, .. - }) => { - let then_dest = if then_dest.1.is_empty() { - then_dest.0.render() - } else { - let then_args = then_dest - .1 - .as_slice(&self.dfg.value_lists) - .iter() - .copied() - .map(display) - .reduce(|acc, arg| acc + const_text(" ") + arg) - .map(|args| const_text(" ") + args) - .unwrap_or_default(); - const_text("(") - + const_text("block") - + const_text(" ") - + display(then_dest.0.as_u32()) - + then_args - + const_text(")") - }; - let else_dest = if else_dest.1.is_empty() { - else_dest.0.render() - } else { - let else_args = else_dest - .1 - .as_slice(&self.dfg.value_lists) - .iter() - .copied() - .map(display) - .reduce(|acc, arg| acc + const_text(" ") + arg) - .map(|args| const_text(" ") + args) - .unwrap_or_default(); - const_text("(") - + const_text("block") - + const_text(" ") - + display(else_dest.0.as_u32()) - + else_args - + const_text(")") - }; - (vec![], vec![display(*cond), then_dest, else_dest]) - } - Instruction::Br(Br { - destination, args, .. - }) => { - if args.is_empty() { - (vec![], vec![destination.render()]) - } else { - let dest_args = args - .as_slice(&self.dfg.value_lists) - .iter() - .copied() - .map(display) - .reduce(|acc, e| acc + const_text(" ") + e) - .map(|args| const_text(" ") + args) - .unwrap_or_default(); - let dest = const_text("(") - + const_text("block") - + const_text(" ") - + display(destination.as_u32()) - + dest_args - + const_text(")"); - (vec![], vec![dest]) - } + }) => ( + vec![], + vec![ + display(*cond), + SuccessorInfo::new(then_dest, &self.dfg.value_lists).render(), + SuccessorInfo::new(else_dest, &self.dfg.value_lists).render(), + ], + ), + Instruction::Br(Br { ref successor, .. }) => { + (vec![], vec![SuccessorInfo::new(successor, &self.dfg.value_lists).render()]) } Instruction::Switch(Switch { - arg, arms, default, .. + arg, + arms, + ref default, + .. }) => { let default = const_text("(") + const_text("_") + const_text(" ") + const_text(".") + const_text(" ") - + const_text("(") - + display(*default) - + const_text(")") + + SuccessorInfo::new(default, &self.dfg.value_lists).render() + const_text(")"); let arms = arms .iter() - .map(|(value, dest)| { + .map(|arm| { const_text("(") - + display(*value) + + display(arm.value) + const_text(" ") + const_text(".") + const_text(" ") - + dest.render() + + SuccessorInfo::new(&arm.successor, &self.dfg.value_lists).render() + const_text(")") }) .chain(core::iter::once(default)) diff --git a/hir/src/layout.rs b/hir/src/layout.rs index 8a558e6d..729dc7e8 100644 --- a/hir/src/layout.rs +++ b/hir/src/layout.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ ops::{Index, IndexMut}, ptr::NonNull, }; diff --git a/hir/src/lib.rs b/hir/src/lib.rs index 6cd6578d..d13cb94d 100644 --- a/hir/src/lib.rs +++ b/hir/src/lib.rs @@ -20,10 +20,10 @@ extern crate lalrpop_util; pub use intrusive_collections::UnsafeRef; pub use miden_core::{FieldElement, StarkField}; -pub use miden_diagnostics::SourceSpan; pub use midenc_hir_macros::*; pub use midenc_hir_symbol::{symbols, Symbol}; pub use midenc_hir_type::{AddressSpace, Alignable, FunctionType, StructType, Type, TypeRepr}; +pub use midenc_session::diagnostics::{self, SourceSpan}; /// Represents a field element in Miden pub type Felt = miden_core::Felt; @@ -80,66 +80,44 @@ macro_rules! diagnostic { ($diagnostics:ident, $severity:expr, $msg:literal, $span:expr, $label:expr) => {{ let span = $span; - if span.is_unknown() { - $diagnostics.diagnostic($severity).with_message($msg).with_note($label).emit(); - } else { - $diagnostics - .diagnostic($severity) - .with_message($msg) - .with_primary_label($span, $label) - .emit(); - } + $diagnostics + .diagnostic($severity) + .with_message($msg) + .with_primary_label($span, $label) + .emit(); }}; ($diagnostics:ident, $severity:expr, $msg:literal, $span:expr, $label:expr, $note:expr) => {{ let span = $span; - if span.is_unknown() { - $diagnostics - .diagnostic($severity) - .with_message($msg) - .with_note($label) - .with_note($note) - .emit(); - } else { - $diagnostics - .diagnostic($severity) - .with_message($msg) - .with_primary_label(span, $label) - .with_note($note) - .emit(); - } + $diagnostics + .diagnostic($severity) + .with_message($msg) + .with_primary_label(span, $label) + .with_note($note) + .emit(); }}; ($diagnostics:ident, $severity:expr, $msg:literal, $span:expr, $label:expr, $span2:expr, $label2:expr) => {{ let span = $span; let span2 = $span2; - let diag = $diagnostics.diagnostic($severity).with_message($msg); - if span.is_unknown() { - diag.with_note($label); - } else { - diag.with_primary_label(span, $label); - } - if span2.is_unknown() { - diag.with_note($label2).emit(); - } else { - diag.with_secondary_label(span2, $label2).emit(); - } + $diagnostics + .diagnostic($severity) + .with_message($msg) + .with_primary_label(span, $label) + .with_secondary_label(span2, $label2) + .emit(); }}; ($diagnostics:ident, $severity:expr, $msg:literal, $span:expr, $label:expr, $span2:expr, $label2:expr, $note:expr) => {{ let span = $span; let span2 = $span2; - let diag = $diagnostics.diagnostic($severity).with_message($msg); - if span.is_unknown() { - diag.with_note($label); - } else { - diag.with_primary_label(span, $label); - } - if span2.is_unknown() { - diag.with_note($label2).with_note($note).emit(); - } else { - diag.with_secondary_label(span2, $label2).with_note($note).emit(); - } + $diagnostics + .diagnostic($severity) + .with_message($msg) + .with_primary_label(span, $label) + .with_secondary_label(span2, $label2) + .with_help($note) + .emit(); }}; } @@ -186,7 +164,7 @@ pub use self::{ display::{Decorator, DisplayValues}, function::*, globals::*, - ident::{FunctionIdent, Ident}, + ident::{demangle, FunctionIdent, Ident}, immediates::Immediate, insert::{Insert, InsertionPoint}, instruction::*, @@ -197,7 +175,7 @@ pub use self::{ AnalysisKey, ConversionPassRegistration, ModuleRewritePassAdapter, PassInfo, RewritePassRegistration, }, - program::{Linker, LinkerError, Program, ProgramAnalysisKey, ProgramBuilder}, + program::{Linker, Program, ProgramAnalysisKey, ProgramBuilder}, segments::{DataSegment, DataSegmentAdapter, DataSegmentError, DataSegmentTable}, value::{Value, ValueData, ValueList, ValueListPool}, }; diff --git a/hir/src/locals.rs b/hir/src/locals.rs index fc67d09c..31431e7d 100644 --- a/hir/src/locals.rs +++ b/hir/src/locals.rs @@ -1,4 +1,5 @@ -use std::{alloc::Layout, fmt}; +use alloc::alloc::Layout; +use core::fmt; use super::Type; diff --git a/hir/src/module.rs b/hir/src/module.rs index 4a5d5599..bf4e7153 100644 --- a/hir/src/module.rs +++ b/hir/src/module.rs @@ -3,19 +3,38 @@ use alloc::collections::BTreeMap; use intrusive_collections::{ intrusive_adapter, linked_list::{Cursor, CursorMut}, - LinkedList, RBTreeLink, + LinkedList, LinkedListLink, RBTreeLink, }; -use miden_diagnostics::{DiagnosticsHandler, Severity, Spanned}; use rustc_hash::FxHashSet; use self::formatter::PrettyPrint; -use super::*; +use crate::{ + diagnostics::{miette, Diagnostic, DiagnosticsHandler, Report, Severity, Spanned}, + *, +}; /// This error is raised when two modules conflict with the same symbol name -#[derive(Debug, thiserror::Error)] -#[error("module {} has already been declared", .0)] -pub struct ModuleConflictError(pub Ident); +#[derive(Debug, thiserror::Error, Diagnostic)] +#[error("module {} has already been declared", .name)] +#[diagnostic()] +pub struct ModuleConflictError { + #[label("duplicate declaration occurs here")] + pub span: SourceSpan, + pub name: Symbol, +} +impl ModuleConflictError { + pub fn new(name: Ident) -> Self { + Self { + span: name.span, + name: name.as_symbol(), + } + } +} + +pub type ModuleTree = intrusive_collections::RBTree; +pub type ModuleList = intrusive_collections::LinkedList; +intrusive_adapter!(pub ModuleListAdapter = Box: Module { list_link: LinkedListLink }); intrusive_adapter!(pub ModuleTreeAdapter = Box: Module { link: RBTreeLink }); impl<'a> intrusive_collections::KeyAdapter<'a> for ModuleTreeAdapter { type Key = Ident; @@ -38,6 +57,8 @@ impl<'a> intrusive_collections::KeyAdapter<'a> for ModuleTreeAdapter { pub struct Module { /// The link used to attach this module to a [Program] link: RBTreeLink, + /// The link used to store this module in a list of modules + list_link: LinkedListLink, /// The name of this module #[span] #[analysis_key] @@ -176,11 +197,21 @@ impl midenc_session::Emit for Module { Some(self.name.as_symbol()) } - fn output_type(&self) -> midenc_session::OutputType { + fn output_type(&self, _mode: midenc_session::OutputMode) -> midenc_session::OutputType { midenc_session::OutputType::Hir } - fn write_to(&self, mut writer: W) -> std::io::Result<()> { + fn write_to( + &self, + mut writer: W, + mode: midenc_session::OutputMode, + _session: &midenc_session::Session, + ) -> std::io::Result<()> { + assert_eq!( + mode, + midenc_session::OutputMode::Text, + "binary mode is not supported for HIR modules" + ); writer.write_fmt(format_args!("{}", self)) } } @@ -271,6 +302,7 @@ impl Module { fn make(name: Ident, is_kernel: bool) -> Self { Self { link: Default::default(), + list_link: Default::default(), name, docs: None, segments: Default::default(), @@ -804,23 +836,20 @@ impl<'m> ModuleFunctionBuilder<'m> { DefaultInstBuilder::new(&mut self.function.dfg, self.position) } - pub fn build( - self, - diagnostics: &DiagnosticsHandler, - ) -> Result { + pub fn build(self, diagnostics: &DiagnosticsHandler) -> Result { let sig = self.function.signature(); match sig.linkage { Linkage::External | Linkage::Internal => (), linkage => { - diagnostics + return Err(diagnostics .diagnostic(Severity::Error) - .with_message(format!( - "invalid linkage ('{}') for function '{}'", - linkage, &self.function.id - )) - .with_note("Only 'external' and 'internal' linkage are valid for functions") - .emit(); - return Err(InvalidFunctionError); + .with_message("invalid function definition") + .with_primary_label( + self.function.span(), + format!("invalid linkage: '{linkage}'"), + ) + .with_help("Only 'external' and 'internal' linkage are valid for functions") + .into_report()); } } @@ -830,47 +859,47 @@ impl<'m> ModuleFunctionBuilder<'m> { match sig.cc { CallConv::Kernel if is_kernel_module => { if !is_public { - diagnostics + return Err(diagnostics .diagnostic(Severity::Error) - .with_message(format!( - "expected external linkage for kernel function '{}'", - &self.function.id - )) - .with_note( - "This function is private, but uses the 'kernel' calling convention. \ - It must either be made public, or use a different convention", + .with_message("invalid function definition") + .with_primary_label( + self.function.span(), + format!("expected 'external' linkage, but got '{}'", &sig.linkage), + ) + .with_help( + "Functions declared with the 'kernel' calling convention must have \ + 'external' linkage", ) - .emit(); - return Err(InvalidFunctionError); + .into_report()); } } CallConv::Kernel => { - diagnostics + return Err(diagnostics .diagnostic(Severity::Error) - .with_message(format!( - "invalid calling convention for function '{}'", - &self.function.id - )) - .with_note( + .with_message("invalid function definition") + .with_primary_label( + self.function.span(), + "unsupported use of 'kernel' calling convention", + ) + .with_help( "The 'kernel' calling convention is only allowed in kernel modules, on \ functions with external linkage", ) - .emit(); - return Err(InvalidFunctionError); + .into_report()); } - _ if is_kernel_module && is_public => { - diagnostics + cc if is_kernel_module && is_public => { + return Err(diagnostics .diagnostic(Severity::Error) - .with_message(format!( - "invalid calling convention for function '{}'", - &self.function.id - )) - .with_note( + .with_message("invalid function definition") + .with_primary_label( + self.function.span(), + format!("unsupported use of '{cc}' calling convention"), + ) + .with_help( "Functions with external linkage, must use the 'kernel' calling \ convention when defined in a kernel module", ) - .emit(); - return Err(InvalidFunctionError); + .into_report()); } _ => (), } @@ -881,6 +910,3 @@ impl<'m> ModuleFunctionBuilder<'m> { Ok(id) } } - -#[derive(Debug)] -pub struct InvalidFunctionError; diff --git a/hir/src/parser/ast/convert.rs b/hir/src/parser/ast/convert.rs index ecc43a20..30a75c24 100644 --- a/hir/src/parser/ast/convert.rs +++ b/hir/src/parser/ast/convert.rs @@ -7,8 +7,7 @@ use midenc_session::Session; use super::*; use crate::{ - parser::ParseError, - pass::{AnalysisManager, ConversionError, ConversionPass, ConversionResult}, + pass::{AnalysisManager, ConversionPass, ConversionResult}, Immediate, Opcode, PassInfo, Signature, Type, }; @@ -43,7 +42,7 @@ impl ConversionPass for ConvertAstToHir { let mut remapped_constants = RemappedConstants::default(); for (constant_id, constant_data) in constants_by_id.into_iter() { if let Entry::Vacant(entry) = remapped_constants.entry(constant_id) { - let new_constant_id = module.globals.insert_constant(constant_data.item); + let new_constant_id = module.globals.insert_constant(constant_data.into_inner()); entry.insert(new_constant_id); } } @@ -55,7 +54,7 @@ impl ConversionPass for ConvertAstToHir { for (_, gv_data) in globals_by_id.into_iter() { unsafe { - module.globals.insert(gv_data.item); + module.globals.insert(gv_data.into_inner()); } } @@ -202,7 +201,7 @@ impl ConversionPass for ConvertAstToHir { "expected that {id} is always ahead of, or equal to {next_id}" ); if raw_id == next_raw_id { - f.dfg.values.push(data.item); + f.dfg.values.push(data.into_inner()); continue; } @@ -215,7 +214,7 @@ impl ConversionPass for ConvertAstToHir { inst: crate::Inst::reserved_value(), }); } - assert_eq!(f.dfg.values.push(data.item), id); + assert_eq!(f.dfg.values.push(data.into_inner()), id); } // Also record all of the instruction results @@ -233,7 +232,7 @@ impl ConversionPass for ConvertAstToHir { if used_imports.contains(id) { None } else { - Some((*id, ext.item.clone())) + Some((*id, ext.inner().clone())) } })); module.functions.push_back(function); @@ -245,7 +244,12 @@ impl ConversionPass for ConvertAstToHir { if is_valid { Ok(module) } else { - Err(ConversionError::Failed(ParseError::InvalidModule.into())) + Err(session + .diagnostics + .diagnostic(Severity::Error) + .with_message(format!("failed to validate '{}'", module.name)) + .with_help("One or more diagnostics have been emitted, see them for details") + .into_report()) } } } @@ -281,7 +285,7 @@ fn try_insert_inst( } => Some(Instruction::BinaryOp(BinaryOp { op, overflow, - args: [rhs.item, lhs.item], + args: [rhs.into_inner(), lhs.into_inner()], })), InstType::BinaryOp { opcode: op, @@ -293,7 +297,7 @@ fn try_insert_inst( Instruction::BinaryOpImm(BinaryOpImm { op, overflow, - arg: rhs.item, + arg: rhs.into_inner(), imm, }) }) @@ -319,7 +323,7 @@ fn try_insert_inst( } => Some(Instruction::UnaryOp(UnaryOp { op, overflow, - arg: operand.item, + arg: operand.into_inner(), })), InstType::UnaryOp { opcode: op, @@ -380,13 +384,15 @@ fn try_insert_inst( blockq.push_back(next); } let args = crate::ValueList::from_iter( - successor.args.iter().map(|arg| arg.item), + successor.args.iter().map(|arg| arg.into_inner()), &mut function.dfg.value_lists, ); Some(Instruction::Br(crate::Br { op, - destination: successor.id, - args, + successor: crate::Successor { + destination: successor.id, + args, + }, })) } Err(_) => None, @@ -438,18 +444,24 @@ fn try_insert_inst( if is_valid { let then_args = crate::ValueList::from_iter( - then_dest.args.iter().map(|arg| arg.item), + then_dest.args.iter().map(|arg| arg.into_inner()), &mut function.dfg.value_lists, ); let else_args = crate::ValueList::from_iter( - else_dest.args.iter().map(|arg| arg.item), + else_dest.args.iter().map(|arg| arg.into_inner()), &mut function.dfg.value_lists, ); Some(Instruction::CondBr(crate::CondBr { op, - cond: cond.item, - then_dest: (then_dest.id, then_args), - else_dest: (else_dest.id, else_args), + cond: cond.into_inner(), + then_dest: crate::Successor { + destination: then_dest.id, + args: then_args, + }, + else_dest: crate::Successor { + destination: else_dest.id, + args: else_args, + }, })) } else { None @@ -467,7 +479,7 @@ fn try_insert_inst( let mut arms = Vec::with_capacity(successors.len()); for arm in successors.into_iter() { let arm_span = arm.span(); - let discriminant = arm.item.0; + let discriminant = arm.inner().0; if !used_discriminants.insert(Span::new(arm_span, discriminant)) { let prev = used_discriminants .get(&Span::new(SourceSpan::UNKNOWN, discriminant)) @@ -484,8 +496,18 @@ fn try_insert_inst( .emit(); is_valid = false; } - let successor = arm.item.1; - arms.push((discriminant, successor.id)); + let successor = arm.into_inner().1; + let successor_args = crate::ValueList::from_iter( + successor.args.iter().map(|arg| arg.into_inner()), + &mut function.dfg.value_lists, + ); + arms.push(crate::SwitchArm { + value: discriminant, + successor: crate::Successor { + destination: successor.id, + args: successor_args, + }, + }); match is_valid_successor( &successor, span, @@ -504,6 +526,11 @@ fn try_insert_inst( } } } + + let fallback_args = crate::ValueList::from_iter( + fallback.args.iter().map(|arg| arg.into_inner()), + &mut function.dfg.value_lists, + ); match is_valid_successor( &fallback, span, @@ -525,9 +552,12 @@ fn try_insert_inst( if is_valid { Some(Instruction::Switch(crate::Switch { op, - arg: selector.item, + arg: selector.into_inner(), arms, - default: fallback.id, + default: crate::Successor { + destination: fallback.id, + args: fallback_args, + }, })) } else { None @@ -562,7 +592,7 @@ fn try_insert_inst( Operand::Value(v) => { if is_valid_value_reference(&v, span, values_by_id, diagnostics) { let args = crate::ValueList::from_slice( - &[v.item], + &[v.into_inner()], &mut function.dfg.value_lists, ); Some(Instruction::Ret(crate::Ret { op, args })) @@ -582,7 +612,7 @@ fn try_insert_inst( let mut args = crate::ValueList::new(); for operand in operands.iter() { if let Operand::Value(ref v) = operand { - args.push(v.item, &mut function.dfg.value_lists); + args.push(v.into_inner(), &mut function.dfg.value_lists); is_valid &= is_valid_value_reference(v, span, values_by_id, diagnostics); } else { @@ -624,7 +654,7 @@ fn try_insert_inst( if let Entry::Vacant(entry) = function.dfg.imports.entry(callee) { entry.insert(ExternalFunction { id: callee, - signature: sig.item.clone(), + signature: sig.inner().clone(), }); } } else { @@ -646,7 +676,7 @@ fn try_insert_inst( used_imports.insert(external); if let Entry::Vacant(entry) = function.dfg.imports.entry(external) { if let Some(ef) = imports_by_id.get(&external) { - entry.insert(ef.item.clone()); + entry.insert(ef.inner().clone()); } else { diagnostics .diagnostic(Severity::Error) @@ -669,7 +699,7 @@ fn try_insert_inst( is_valid_value_references(operands.as_slice(), span, values_by_id, diagnostics); if is_valid { let args = crate::ValueList::from_iter( - operands.iter().map(|arg| arg.item), + operands.iter().map(|arg| arg.into_inner()), &mut function.dfg.value_lists, ); Some(Instruction::Call(crate::Call { op, callee, args })) @@ -699,13 +729,13 @@ fn try_insert_inst( Operand::Value(v) => { is_valid &= is_valid_value_reference(&v, span, values_by_id, diagnostics); - args.push(v.item, &mut function.dfg.value_lists); + args.push(v.into_inner(), &mut function.dfg.value_lists); } operand @ (Operand::Int(_) | Operand::BigInt(_)) if is_first => { imm = match op { Opcode::AssertEq => { if let Some(value) = operands[i + 1].as_value() { - match values_by_id.get(&value.item).map(|vd| vd.ty()) { + match values_by_id.get(value.inner()).map(|vd| vd.ty()) { Some(ty) => { operand_to_immediate(operand, ty, diagnostics) } @@ -883,7 +913,7 @@ fn is_valid_value_reference( values_by_id: &ValuesById, diagnostics: &DiagnosticsHandler, ) -> bool { - let is_valid = values_by_id.contains_key(&value.item); + let is_valid = values_by_id.contains_key(value.inner()); if !is_valid { diagnostics .diagnostic(Severity::Error) @@ -969,8 +999,8 @@ fn operand_to_immediate( diagnostics: &DiagnosticsHandler, ) -> Option { match operand { - Operand::Int(i) => smallint_to_immediate(i.span(), i.item, ty, diagnostics), - Operand::BigInt(i) => bigint_to_immediate(i.span(), i.item, ty, diagnostics), + Operand::Int(i) => smallint_to_immediate(i.span(), i.into_inner(), ty, diagnostics), + Operand::BigInt(i) => bigint_to_immediate(i.span(), i.into_inner(), ty, diagnostics), Operand::Value(_) => panic!("cannot convert ssa values to immediate"), } } diff --git a/hir/src/parser/ast/functions.rs b/hir/src/parser/ast/functions.rs index 2d438ad2..dd566b76 100644 --- a/hir/src/parser/ast/functions.rs +++ b/hir/src/parser/ast/functions.rs @@ -1,5 +1,5 @@ use super::*; -use crate::{AttributeSet, Signature}; +use crate::{diagnostics::DiagnosticsHandler, AttributeSet, Signature}; /// Represents the declaration of a function in a [Module] #[derive(Spanned)] @@ -29,10 +29,7 @@ impl FunctionDeclaration { } /// Returns true if the entry block and signature match for this declaration - pub fn is_declaration_valid( - &self, - diagnostics: &miden_diagnostics::DiagnosticsHandler, - ) -> bool { + pub fn is_declaration_valid(&self, diagnostics: &DiagnosticsHandler) -> bool { let entry_block = &self.blocks[0]; if entry_block.params.len() != self.signature.arity() { let num_expected = entry_block.params.len(); @@ -82,7 +79,7 @@ impl FunctionDeclaration { pub(super) fn populate_block_map( &mut self, - diagnostics: &miden_diagnostics::DiagnosticsHandler, + diagnostics: &DiagnosticsHandler, ) -> Result { use alloc::collections::btree_map::Entry; diff --git a/hir/src/parser/ast/globals.rs b/hir/src/parser/ast/globals.rs index a8d6f2c4..b7978895 100644 --- a/hir/src/parser/ast/globals.rs +++ b/hir/src/parser/ast/globals.rs @@ -1,7 +1,6 @@ use core::fmt; -use miden_diagnostics::{SourceSpan, Spanned}; - +use super::{SourceSpan, Spanned}; use crate::{ConstantData, Ident, Linkage, Type}; /// This represents the declaration of a global variable diff --git a/hir/src/parser/ast/mod.rs b/hir/src/parser/ast/mod.rs index 47d33a1d..0ecd8ef4 100644 --- a/hir/src/parser/ast/mod.rs +++ b/hir/src/parser/ast/mod.rs @@ -7,10 +7,11 @@ mod instruction; use alloc::collections::BTreeMap; use core::fmt; -use miden_diagnostics::{DiagnosticsHandler, Severity, SourceSpan, Span, Spanned}; - pub use self::{block::*, convert::ConvertAstToHir, functions::*, globals::*, instruction::*}; -use crate::{ExternalFunction, FunctionIdent, Ident}; +use crate::{ + diagnostics::{DiagnosticsHandler, Severity, SourceSpan, Span, Spanned}, + ExternalFunction, FunctionIdent, Ident, +}; /// This represents the parsed contents of a single Miden IR module #[derive(Spanned)] @@ -43,11 +44,21 @@ impl midenc_session::Emit for Module { Some(self.name.as_symbol()) } - fn output_type(&self) -> midenc_session::OutputType { + fn output_type(&self, _mode: midenc_session::OutputMode) -> midenc_session::OutputType { midenc_session::OutputType::Ast } - fn write_to(&self, mut writer: W) -> std::io::Result<()> { + fn write_to( + &self, + mut writer: W, + mode: midenc_session::OutputMode, + _session: &midenc_session::Session, + ) -> std::io::Result<()> { + assert_eq!( + mode, + midenc_session::OutputMode::Text, + "binary mode is not supported for HIR syntax trees" + ); writer.write_fmt(format_args!("{:#?}", self)) } } diff --git a/hir/src/parser/error.rs b/hir/src/parser/error.rs index 0b3ec496..0d2b8529 100644 --- a/hir/src/parser/error.rs +++ b/hir/src/parser/error.rs @@ -1,47 +1,78 @@ -use miden_diagnostics::{Diagnostic, Label, SourceIndex, SourceSpan, ToDiagnostic}; - use super::lexer::{LexicalError, Token}; +use crate::{ + diagnostics::{miette, ByteIndex, Diagnostic, SourceSpan}, + DisplayValues, +}; -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, Diagnostic)] pub enum ParseError { + #[diagnostic(transparent)] #[error(transparent)] Lexer(#[from] LexicalError), #[error("error reading {path:?}: {source}")] + #[diagnostic()] FileError { + #[source] source: std::io::Error, path: std::path::PathBuf, }, #[error("invalid token")] - InvalidToken(SourceIndex), + #[diagnostic()] + InvalidToken(#[label] SourceSpan), #[error("unexpected end of file")] + #[diagnostic()] UnexpectedEof { - at: SourceIndex, + #[label("expected one of: {}", DisplayValues::new(expected.iter()))] + at: SourceSpan, expected: Vec, }, #[error("unrecognized token '{token}'")] UnrecognizedToken { + #[label("expected one of: {}", DisplayValues::new(expected.iter()))] span: SourceSpan, token: Token, expected: Vec, }, #[error("extraneous token '{token}'")] - ExtraToken { span: SourceSpan, token: Token }, + ExtraToken { + #[label] + span: SourceSpan, + token: Token, + }, #[error("expected valid u32 immediate value, got '{value}'")] - InvalidU32 { span: SourceSpan, value: isize }, + InvalidU32 { + #[label] + span: SourceSpan, + value: isize, + }, #[error("expected valid offset value, got '{value}'")] - InvalidOffset { span: SourceSpan, value: isize }, + InvalidOffset { + #[label] + span: SourceSpan, + value: isize, + }, #[error("expected valid alignment value, got '{value}'")] - InvalidAlignment { span: SourceSpan, value: isize }, + InvalidAlignment { + #[label] + span: SourceSpan, + value: isize, + }, #[error("expected valid address space, got '{value}'")] - InvalidAddrSpace { span: SourceSpan, value: isize }, - #[error("parsing succeeded, but validation failed, see diagnostics for details")] - InvalidModule, + InvalidAddrSpace { + #[label] + span: SourceSpan, + value: isize, + }, #[error("invalid function definition: cannot have empty body")] - EmptyFunction { span: SourceSpan }, + EmptyFunction { + #[label] + span: SourceSpan, + }, #[error("invalid function import declaration: cannot have body")] - ImportedFunctionWithBody { span: SourceSpan }, - #[error("parsing failed, see diagnostics for details")] - Failed, + ImportedFunctionWithBody { + #[label] + span: SourceSpan, + }, } impl Eq for ParseError {} impl PartialEq for ParseError { @@ -71,8 +102,6 @@ impl PartialEq for ParseError { }, ) => lt == rt && l == r, (Self::ExtraToken { token: l, .. }, Self::ExtraToken { token: r, .. }) => l == r, - (Self::InvalidModule, Self::InvalidModule) => true, - (Self::Failed, Self::Failed) => true, (Self::EmptyFunction { .. }, Self::EmptyFunction { .. }) => true, (Self::ImportedFunctionWithBody { .. }, Self::ImportedFunctionWithBody { .. }) => true, (Self::InvalidU32 { value: l, .. }, Self::InvalidU32 { value: r, .. }) => l == r, @@ -87,102 +116,36 @@ impl PartialEq for ParseError { } } } -impl From> for ParseError { - fn from(err: lalrpop_util::ParseError) -> Self { +impl From> for ParseError { + fn from(err: lalrpop_util::ParseError) -> Self { use lalrpop_util::ParseError as LError; match err { - LError::InvalidToken { location } => Self::InvalidToken(location), + LError::InvalidToken { location } => { + Self::InvalidToken(SourceSpan::at(Default::default(), location)) + } LError::UnrecognizedEof { location: at, expected, - } => Self::UnexpectedEof { at, expected }, + } => Self::UnexpectedEof { + at: SourceSpan::at(Default::default(), at), + expected, + }, LError::UnrecognizedToken { token: (l, token, r), expected, } => Self::UnrecognizedToken { - span: SourceSpan::new(l, r), + span: SourceSpan::new(Default::default(), l..r), token, expected, }, LError::ExtraToken { token: (l, token, r), } => Self::ExtraToken { - span: SourceSpan::new(l, r), + span: SourceSpan::new(Default::default(), l..r), token, }, LError::User { error } => error, } } } -impl ToDiagnostic for ParseError { - fn to_diagnostic(self) -> Diagnostic { - match self { - Self::Lexer(err) => err.to_diagnostic(), - Self::InvalidToken(start) => Diagnostic::error() - .with_message("invalid token") - .with_labels(vec![Label::primary( - start.source_id(), - SourceSpan::new(start, start), - )]), - Self::UnexpectedEof { at, ref expected } => { - let mut message = "expected one of: ".to_string(); - for (i, t) in expected.iter().enumerate() { - if i == 0 { - message.push_str(&format!("'{}'", t)); - } else { - message.push_str(&format!(", '{}'", t)); - } - } - - Diagnostic::error() - .with_message("unexpected eof") - .with_labels(vec![Label::primary(at.source_id(), SourceSpan::new(at, at)) - .with_message(message)]) - } - Self::UnrecognizedToken { - span, ref expected, .. - } => { - let mut message = "expected one of: ".to_string(); - for (i, t) in expected.iter().enumerate() { - if i == 0 { - message.push_str(&format!("'{}'", t)); - } else { - message.push_str(&format!(", '{}'", t)); - } - } - - Diagnostic::error() - .with_message("unexpected token") - .with_labels(vec![Label::primary(span.source_id(), span).with_message(message)]) - } - Self::ExtraToken { span, .. } => Diagnostic::error() - .with_message("extraneous token") - .with_labels(vec![Label::primary(span.source_id(), span)]), - Self::InvalidU32 { span, .. } => Diagnostic::error() - .with_message("expected valid unsigned 32-bit immediate value") - .with_labels(vec![Label::primary(span.source_id(), span)]), - Self::InvalidOffset { span, .. } => Diagnostic::error() - .with_message("expected valid 32-bit offset value") - .with_labels(vec![Label::primary(span.source_id(), span)]), - Self::InvalidAlignment { span, .. } => Diagnostic::error() - .with_message("expected valid alignment value") - .with_labels(vec![Label::primary(span.source_id(), span).with_message( - "alignment must be a non-zero, power of two, valid for a 32-bit address space", - )]), - Self::InvalidAddrSpace { span, .. } => Diagnostic::error() - .with_message("expected valid address space") - .with_labels(vec![Label::primary(span.source_id(), span) - .with_message("address space must be a value in 1..=65535")]), - Self::EmptyFunction { span } => Diagnostic::error() - .with_message("invalid function definition") - .with_labels(vec![Label::primary(span.source_id(), span) - .with_message("cannot have an empty body")]), - Self::ImportedFunctionWithBody { span } => Diagnostic::error() - .with_message("invalid function import declaration") - .with_labels(vec![Label::primary(span.source_id(), span) - .with_message("function import declarations cannot have a body")]), - err => Diagnostic::error().with_message(err.to_string()), - } - } -} diff --git a/hir/src/parser/grammar.lalrpop b/hir/src/parser/grammar.lalrpop index b699e4c7..03bf44d9 100644 --- a/hir/src/parser/grammar.lalrpop +++ b/hir/src/parser/grammar.lalrpop @@ -1,9 +1,8 @@ -use alloc::sync::Arc; use core::num::NonZeroU16; use either::Either::{self, Left, Right}; -use miden_diagnostics::{CodeMap, DiagnosticsHandler, Span, Spanned, SourceSpan}; +use crate::diagnostics::{Span, SourceId, SourceSpan, ByteIndex}; use crate::{AbiParam, ArgumentExtension, ArgumentPurpose}; use crate::{CallConv, ConstantData, ExternalFunction, FunctionIdent}; use crate::{Ident, Linkage, Opcode, Overflow, Signature, symbols, Symbol}; @@ -85,7 +84,7 @@ use crate::parser::{ /// BARE_NAME ::= [^[[:cntrl:]]:;,'"\s\\]+ -grammar(diagnostics: &DiagnosticsHandler, codemap: &Arc, next_var: &mut usize); +grammar(source_id: SourceId, next_var: &mut usize); // MACROS // ================================================================================================ @@ -116,7 +115,7 @@ CommaOpt: Vec = { pub Module: Module = { "(" "module" ")" => { let is_kernel = attrs.iter().any(|attr| attr.name == symbols::Kernel && attr.value.as_bool().unwrap_or_default()); - Module::new(span!(l, r), name, is_kernel, forms) + Module::new(span!(source_id, l, r), name, is_kernel, forms) }, } @@ -136,13 +135,13 @@ ModuleForm: Form = { ConstantDeclaration: ConstantDeclaration = { "(" "const" ")" - => ConstantDeclaration::new(span!(l, r), crate::Constant::from_u32(id), init), + => ConstantDeclaration::new(span!(source_id, l, r), crate::Constant::from_u32(id), init), } GlobalVarDeclaration: GlobalVarDeclaration = { "(" "global" ")" => { let (name, linkage) = name_and_linkage; - GlobalVarDeclaration::new(span!(l, r), crate::GlobalVariable::from_u32(id), name, ty, linkage, init) + GlobalVarDeclaration::new(span!(source_id, l, r), crate::GlobalVariable::from_u32(id), name, ty, linkage, init) } } @@ -150,7 +149,7 @@ DataSegmentDeclaration: DataSegmentDeclaration = { "(" "data" ")")> ")")?> ")" => { let readonly = is_mut.is_none(); let size = size.unwrap_or(data.len().try_into().expect("invalid data segment: data cannot be more than 2^32 bytes")); - DataSegmentDeclaration::new(span!(l, r), offset, size, readonly, data) + DataSegmentDeclaration::new(span!(source_id, l, r), offset, size, readonly, data) } } @@ -232,7 +231,7 @@ AddressSpace: AddressSpace = { match u16::try_from(i) { Ok(0) => Ok(AddressSpace::Root), Ok(v) => Ok(AddressSpace::Id(unsafe { NonZeroU16::new_unchecked(v) })), - Err(_) => Err(ParseError::InvalidAddrSpace { span: span!(l, r), value: i }.into()), + Err(_) => Err(ParseError::InvalidAddrSpace { span: span!(source_id, l, r), value: i }.into()), } } } @@ -279,13 +278,13 @@ FunctionDeclaration: Form = { linkage, }; match name { - Left(name) if blocks.is_empty() => Err(ParseError::EmptyFunction { span: span!(l, r) }.into()), + Left(name) if blocks.is_empty() => Err(ParseError::EmptyFunction { span: span!(source_id, l, r) }.into()), Left(name) => { - Ok(Form::Function(FunctionDeclaration::new(span!(l, r), name, signature, blocks, AttributeSet::default()))) + Ok(Form::Function(FunctionDeclaration::new(span!(source_id, l, r), name, signature, blocks, AttributeSet::default()))) } - Right(id) if !blocks.is_empty() => Err(ParseError::ImportedFunctionWithBody { span: span!(l, r) }.into()), + Right(id) if !blocks.is_empty() => Err(ParseError::ImportedFunctionWithBody { span: span!(source_id, l, r) }.into()), Right(id) => { - Ok(Form::ExternalFunction(Span::new(span!(l, r), ExternalFunction { + Ok(Form::ExternalFunction(Span::new(span!(source_id, l, r), ExternalFunction { id, signature, }))) @@ -335,19 +334,19 @@ ArgumentExtension: ArgumentExtension = { Block: Block = { "(" "block" ")" => { let id = crate::Block::from_u32(id); - Block::new(span!(l, r), id, params, insts) + Block::new(span!(source_id, l, r), id, params, insts) } } BlockParam: TypedValue = { - "(" "param" ")" => TypedValue::new(span!(l, r), id, ty), + "(" "param" ")" => TypedValue::new(span!(source_id, l, r), id, ty), } // INSTRUCTIONS // ================================================================================================ TypedValueId: TypedValue = { - "(" ")" => TypedValue::new(value.span(), value.item, ty), + "(" ")" => TypedValue::new(value.span(), value.into_inner(), ty), } Let: (TypedValue, Span) = { @@ -365,37 +364,37 @@ LetMany: (Vec, Span) = { Inst: Inst = { => { let (value, inst_ty) = let_expr; - Inst::new(span!(l, r), inst_ty.item, vec![value]) + Inst::new(span!(source_id, l, r), inst_ty.into_inner(), vec![value]) }, => { let (values, inst_ty) = let_expr; - Inst::new(span!(l, r), inst_ty.item, values) + Inst::new(span!(source_id, l, r), inst_ty.into_inner(), values) }, "(" "call" ")" => { - Inst::new(span!(l, r), InstType::Call { opcode: Opcode::Call, callee, operands }, vec![]) + Inst::new(span!(source_id, l, r), InstType::Call { opcode: Opcode::Call, callee, operands }, vec![]) }, "(" "syscall" ")" => { - Inst::new(span!(l, r), InstType::Call { opcode: Opcode::Syscall, callee, operands }, vec![]) + Inst::new(span!(source_id, l, r), InstType::Call { opcode: Opcode::Syscall, callee, operands }, vec![]) }, "(" "unreachable" ")" => { - Inst::new(span!(l, r), InstType::PrimOp { opcode: Opcode::Unreachable, operands: vec![] }, vec![]) + Inst::new(span!(source_id, l, r), InstType::PrimOp { opcode: Opcode::Unreachable, operands: vec![] }, vec![]) }, "(" "ret" ")" => { let operands = operand.map(|operand| vec![operand]).unwrap_or_default(); - Inst::new(span!(l, r), InstType::Ret { opcode: Opcode::Ret, operands }, vec![]) + Inst::new(span!(source_id, l, r), InstType::Ret { opcode: Opcode::Ret, operands }, vec![]) }, "(" "br" ")" => { - Inst::new(span!(l, r), InstType::Br { opcode: Opcode::Br, successor }, vec![]) + Inst::new(span!(source_id, l, r), InstType::Br { opcode: Opcode::Br, successor }, vec![]) }, "(" "condbr" ")" => { - Inst::new(span!(l, r), InstType::CondBr { opcode: Opcode::CondBr, cond, then_dest, else_dest }, vec![]) + Inst::new(span!(source_id, l, r), InstType::CondBr { opcode: Opcode::CondBr, cond, then_dest, else_dest }, vec![]) }, "(" "switch" ")" =>? { @@ -411,27 +410,27 @@ Inst: Inst = { (None, _, _) => panic!("invalid switch: only one default arm is allowed"), } } - Ok(Inst::new(span!(l, r), InstType::Switch { opcode: Opcode::Switch, selector, successors, fallback }, vec![])) + Ok(Inst::new(span!(source_id, l, r), InstType::Switch { opcode: Opcode::Switch, selector, successors, fallback }, vec![])) }, } InstWithResult: Span = { "(" ")" => { let (opcode, overflow) = op_and_overflow; - Span::new(span!(l, r), InstType::UnaryOp { opcode, overflow, operand }) + Span::new(span!(source_id, l, r), InstType::UnaryOp { opcode, overflow, operand }) }, "(" ")" => { let (opcode, overflow) = op_and_overflow; - Span::new(span!(l, r), InstType::BinaryOp { opcode, overflow, operands: [lhs, rhs] }) + Span::new(span!(source_id, l, r), InstType::BinaryOp { opcode, overflow, operands: [lhs, rhs] }) }, "(" "call" ")" => { - Span::new(span!(l, r), InstType::Call { opcode: Opcode::Call, callee, operands }) + Span::new(span!(source_id, l, r), InstType::Call { opcode: Opcode::Call, callee, operands }) }, "(" "syscall" ")" => { - Span::new(span!(l, r), InstType::Call { opcode: Opcode::Syscall, callee, operands }) + Span::new(span!(source_id, l, r), InstType::Call { opcode: Opcode::Syscall, callee, operands }) }, => Span::new(expr.span(), InstType::GlobalValue { opcode: Opcode::GlobalValue, expr }), @@ -440,27 +439,27 @@ InstWithResult: Span = { InstWithManyResults: Span = { "(" ")" => { let overflow = Some(Overflow::Overflowing); - Span::new(span!(l, r), InstType::UnaryOp { opcode, overflow, operand }) + Span::new(span!(source_id, l, r), InstType::UnaryOp { opcode, overflow, operand }) }, "(" ")" => { let overflow = Some(Overflow::Overflowing); - Span::new(span!(l, r), InstType::BinaryOp { opcode, overflow, operands: [lhs, rhs] }) + Span::new(span!(source_id, l, r), InstType::BinaryOp { opcode, overflow, operands: [lhs, rhs] }) }, "(" ")" => { - Span::new(span!(l, r), InstType::PrimOp { opcode, operands }) + Span::new(span!(source_id, l, r), InstType::PrimOp { opcode, operands }) } } Successor: Successor = { "(" "block" ")" - => Successor { span: span!(l, r), id: crate::Block::from_u32(id), args }, + => Successor { span: span!(source_id, l, r), id: crate::Block::from_u32(id), args }, } SwitchArm: (Option, Successor, SourceSpan) = { - "(" "." ")" => (Some(value), successor, span!(l, r)), - "(" "_" "." ")" => (None, successor, span!(l, r)), + "(" "." ")" => (Some(value), successor, span!(source_id, l, r)), + "(" "_" "." ")" => (None, successor, span!(source_id, l, r)), } UnaryOpcode: (Opcode, Option) = { @@ -563,23 +562,23 @@ PrimOpOpcode: Opcode = { } Operand: Operand = { - => Operand::Value(Span::new(span!(l, r), v)), - => Operand::Int(Span::new(span!(l, r), i)), - => Operand::BigInt(Span::new(span!(l, r), i)), + => Operand::Value(Span::new(span!(source_id, l, r), v)), + => Operand::Int(Span::new(span!(source_id, l, r), i)), + => Operand::BigInt(Span::new(span!(source_id, l, r), i)), } GlobalValueExpr: GlobalValueExpr = { "(" "global.symbol" ")" => { - GlobalValueExpr::Symbol { symbol, offset: offset.unwrap_or(0), span: span!(l, r) } + GlobalValueExpr::Symbol { symbol, offset: offset.unwrap_or(0), span: span!(source_id, l, r) } }, "(" "global.load" ")" => { let offset = offset.unwrap_or(0); - GlobalValueExpr::Load { base: Box::new(base), offset, ty: Some(ty), span: span!(l, r) } + GlobalValueExpr::Load { base: Box::new(base), offset, ty: Some(ty), span: span!(source_id, l, r) } }, "(" "global.iadd" "(" "offset" "." ")" ")" => { - GlobalValueExpr::IAddImm { base: Box::new(base), offset, ty, span: span!(l, r) } + GlobalValueExpr::IAddImm { base: Box::new(base), offset, ty, span: span!(source_id, l, r) } } } @@ -605,9 +604,9 @@ Index: u32 = { Align: NonZeroU16 = { =>? { match u16::try_from(i) { - Ok(0) => Err(ParseError::InvalidAlignment { span: span!(l, r), value: i }.into()), + Ok(0) => Err(ParseError::InvalidAlignment { span: span!(source_id, l, r), value: i }.into()), Ok(v) => Ok(unsafe { NonZeroU16::new_unchecked(v) }), - Err(_) => Err(ParseError::InvalidAlignment { span: span!(l, r), value: i }.into()), + Err(_) => Err(ParseError::InvalidAlignment { span: span!(source_id, l, r), value: i }.into()), } } } @@ -616,7 +615,7 @@ U32: u32 = { =>? { match u32::try_from(i) { Ok(v) => Ok(v), - Err(_) => Err(ParseError::InvalidU32 { span: span!(l, r), value: i }.into()), + Err(_) => Err(ParseError::InvalidU32 { span: span!(source_id, l, r), value: i }.into()), } } } @@ -625,17 +624,17 @@ RawOffset: i32 = { =>? { match i32::try_from(i) { Ok(v) => Ok(v), - Err(_) => Err(ParseError::InvalidOffset { span: span!(l, r), value: i }.into()), + Err(_) => Err(ParseError::InvalidOffset { span: span!(source_id, l, r), value: i }.into()), } } } Name: Ident = { - => Ident::new(id, span!(l, r)), + => Ident::new(id, span!(source_id, l, r)), } Id: Ident = { - => Ident::new(id, span!(l, r)), + => Ident::new(id, span!(source_id, l, r)), } NameOrId: Ident = { @@ -649,7 +648,7 @@ CalleeId: Either = { } SpannedValueId: Span = { - => Span::new(span!(l, r), v), + => Span::new(span!(source_id, l, r), v), } ValueId: crate::Value = { @@ -661,7 +660,7 @@ ValueId: crate::Value = { extern { type Error = ParseError; - type Location = miden_diagnostics::SourceIndex; + type Location = ByteIndex; enum Token { ident => Token::Ident(), diff --git a/hir/src/parser/lexer/error.rs b/hir/src/parser/lexer/error.rs index 9a3413e4..55a2319c 100644 --- a/hir/src/parser/lexer/error.rs +++ b/hir/src/parser/lexer/error.rs @@ -1,6 +1,6 @@ use core::{fmt, num::IntErrorKind}; -use miden_diagnostics::{Diagnostic, SourceIndex, SourceSpan, ToDiagnostic}; +use crate::diagnostics::{miette, Diagnostic, SourceSpan}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum InvalidEscapeKind { @@ -19,31 +19,57 @@ impl fmt::Display for InvalidEscapeKind { } /// Errors that may occur during lexing of the source -#[derive(Clone, Debug, thiserror::Error)] +#[derive(Clone, Debug, thiserror::Error, Diagnostic)] pub enum LexicalError { #[error("invalid integer value: {}", DisplayIntErrorKind(reason))] + #[diagnostic()] InvalidInt { + #[label] span: SourceSpan, reason: IntErrorKind, }, #[error("encountered unexpected character '{found}'")] - UnexpectedCharacter { start: SourceIndex, found: char }, + #[diagnostic()] + UnexpectedCharacter { + #[label] + start: SourceSpan, + found: char, + }, #[error("unclosed string")] - UnclosedString { span: SourceSpan }, + #[diagnostic()] + UnclosedString { + #[label] + span: SourceSpan, + }, #[error("invalid unicode escape: {kind}")] + #[diagnostic()] InvalidUnicodeEscape { + #[label] span: SourceSpan, kind: InvalidEscapeKind, }, #[error("invalid hex escape: {kind}")] + #[diagnostic()] InvalidHexEscape { + #[label] span: SourceSpan, kind: InvalidEscapeKind, }, #[error("invalid module identifier")] - InvalidModuleIdentifier { span: SourceSpan }, + #[diagnostic(help( + "module names must be non-empty, start with 'a-z', and only contain ascii alpha-numeric \ + characters, '_', or '::' as a namespacing operator", + ))] + InvalidModuleIdentifier { + #[label] + span: SourceSpan, + }, #[error("invalid function identifier")] - InvalidFunctionIdentifier { span: SourceSpan }, + #[diagnostic(help("function names must be non-empty, and start with '_' or 'a-z'"))] + InvalidFunctionIdentifier { + #[label] + span: SourceSpan, + }, } impl PartialEq for LexicalError { fn eq(&self, other: &Self) -> bool { @@ -71,47 +97,6 @@ impl PartialEq for LexicalError { } } } -impl ToDiagnostic for LexicalError { - fn to_diagnostic(self) -> Diagnostic { - use miden_diagnostics::Label; - - match self { - Self::InvalidInt { span, ref reason } => Diagnostic::error() - .with_message("invalid integer literal") - .with_labels(vec![Label::primary(span.source_id(), span) - .with_message(format!("{}", DisplayIntErrorKind(reason)))]), - Self::UnexpectedCharacter { start, .. } => { - Diagnostic::error().with_message("unexpected character").with_labels(vec![ - Label::primary(start.source_id(), SourceSpan::new(start, start)), - ]) - } - Self::UnclosedString { span, .. } => Diagnostic::error() - .with_message("unclosed string") - .with_labels(vec![Label::primary(span.source_id(), span)]), - Self::InvalidUnicodeEscape { span, kind } => { - Diagnostic::error().with_message("invalid unicode escape").with_labels(vec![ - Label::primary(span.source_id(), span).with_message(kind.to_string()), - ]) - } - Self::InvalidHexEscape { span, kind } => { - Diagnostic::error().with_message("invalid hex escape").with_labels(vec![ - Label::primary(span.source_id(), span).with_message(kind.to_string()), - ]) - } - Self::InvalidModuleIdentifier { span, .. } => Diagnostic::error() - .with_message("invalid module identifier") - .with_labels(vec![Label::primary(span.source_id(), span).with_message( - "module names must be non-empty, start with 'a-z', and only contain ascii \ - alpha-numeric characters, '_', or '::' as a namespacing operator", - )]), - Self::InvalidFunctionIdentifier { span, .. } => Diagnostic::error() - .with_message("invalid function identifier") - .with_labels(vec![Label::primary(span.source_id(), span).with_message( - "function names must be non-empty, and start with '_' or 'a-z'", - )]), - } - } -} struct DisplayIntErrorKind<'a>(&'a IntErrorKind); impl<'a> fmt::Display for DisplayIntErrorKind<'a> { diff --git a/hir/src/parser/lexer/mod.rs b/hir/src/parser/lexer/mod.rs index c23f3483..4b2923df 100644 --- a/hir/src/parser/lexer/mod.rs +++ b/hir/src/parser/lexer/mod.rs @@ -1,20 +1,24 @@ mod error; +mod scanner; mod token; use core::{num::IntErrorKind, ops::Range}; -use miden_diagnostics::{SourceIndex, SourceSpan}; -use miden_parsing::{Scanner, Source}; use num_traits::Num; pub use self::{ error::{InvalidEscapeKind, LexicalError}, + scanner::Scanner, token::Token, }; -use crate::{parser::ParseError, Symbol, Value}; +use crate::{ + diagnostics::{ByteIndex, ByteOffset, SourceId, SourceSpan}, + parser::ParseError, + Symbol, Value, +}; /// The value produced by the [Lexer] when iterated -pub type Lexed = Result<(SourceIndex, Token, SourceIndex), ParseError>; +pub type Lexed = Result<(ByteIndex, Token, ByteIndex), ParseError>; /// Pops a single token from the [Lexer] macro_rules! pop { @@ -53,10 +57,12 @@ macro_rules! pop2 { /// If an error is unrecoverable, the lexer will continue to produce tokens, but there is no /// guarantee that parsing them will produce meaningful results, it is primarily to assist in /// gathering as many errors as possible. -pub struct Lexer { +pub struct Lexer<'a> { + source_id: SourceId, + /// The scanner produces a sequence of chars + location, and can be controlled /// The location type is SourceIndex - scanner: Scanner, + scanner: Scanner<'a>, /// The most recent token to be lexed. /// At the start and end, this should be Token::Eof @@ -64,32 +70,28 @@ pub struct Lexer { /// The position in the input where the current token starts /// At the start this will be the byte index of the beginning of the input - token_start: SourceIndex, + token_start: ByteIndex, /// The position in the input where the current token ends /// At the start this will be the byte index of the beginning of the input - token_end: SourceIndex, + token_end: ByteIndex, /// When we have reached true Eof, this gets set to true, and the only token /// produced after that point is Token::Eof, or None, depending on how you are /// consuming the lexer eof: bool, } -impl Lexer -where - S: Source, -{ +impl<'a> Lexer<'a> { /// Produces an instance of the lexer with the lexical analysis to be performed on the `input` /// string. Note that no lexical analysis occurs until the lexer has been iterated over. - pub fn new(scanner: Scanner) -> Self { - use miden_diagnostics::ByteOffset; - - let start = scanner.start(); + pub fn new(source_id: SourceId, source: &'a str) -> Self { + let scanner = Scanner::new(source); let mut lexer = Lexer { + source_id, scanner, token: Token::Eof, - token_start: start + ByteOffset(0), - token_end: start + ByteOffset(0), + token_start: 0.into(), + token_end: 0.into(), eof: false, }; lexer.advance(); @@ -118,9 +120,9 @@ where #[inline] fn advance_start(&mut self) { - let mut position: SourceIndex; + let mut position: ByteIndex = self.scanner.position(); loop { - let (pos, c) = self.scanner.read(); + let (pos, c) = self.scanner.read().unwrap_or((position, '\0')); position = pos; @@ -130,7 +132,7 @@ where } if c.is_whitespace() { - self.scanner.advance(); + self.scanner.next(); continue; } @@ -142,26 +144,22 @@ where #[inline] fn pop(&mut self) -> char { - use miden_diagnostics::ByteOffset; - - let (pos, c) = self.scanner.pop(); + let (pos, c) = self.scanner.next().unwrap_or((self.token_start, '\0')); self.token_end = pos + ByteOffset::from_char_len(c); c } #[inline] fn peek(&mut self) -> char { - let (_, c) = self.scanner.peek(); - c + self.scanner.peek().map(|(_, c)| c).unwrap_or('\0') } #[inline] fn read(&mut self) -> char { - let (_, c) = self.scanner.read(); - c + self.scanner.read().map(|(_, c)| c).unwrap_or('\0') } - #[inline] + #[inline(always)] fn skip(&mut self) { self.pop(); } @@ -169,7 +167,7 @@ where /// Get the span for the current token in `Source`. #[inline] fn span(&self) -> SourceSpan { - SourceSpan::new(self.token_start, self.token_end) + SourceSpan::new(self.source_id, self.token_start..self.token_end) } #[inline] @@ -239,7 +237,7 @@ where 'a'..='z' => self.lex_keyword_or_special_ident(), '_' => pop!(self, Token::Underscore), c => Token::Error(LexicalError::UnexpectedCharacter { - start: self.span().start(), + start: self.span(), found: c, }), } @@ -349,7 +347,10 @@ where Some(escaped) => buf.push(escaped), None => { break Token::Error(LexicalError::InvalidHexEscape { - span: SourceSpan::new(start, self.token_end), + span: SourceSpan::new( + self.source_id, + start..self.token_end, + ), kind: InvalidEscapeKind::Invalid, }); } @@ -361,7 +362,7 @@ where self.skip(); if self.read() == '}' { break Token::Error(LexicalError::InvalidUnicodeEscape { - span: SourceSpan::new(start, self.token_end), + span: SourceSpan::new(self.source_id, start..self.token_end), kind: InvalidEscapeKind::Empty, }); } @@ -381,8 +382,8 @@ where return Token::Error( LexicalError::InvalidUnicodeEscape { span: SourceSpan::new( - self.token_end - 1, - self.token_end, + self.source_id, + (self.token_end - 1)..self.token_end, ), kind: InvalidEscapeKind::InvalidChars, }, @@ -398,7 +399,10 @@ where Some(escaped) => buf.push(escaped), None => { break Token::Error(LexicalError::InvalidUnicodeEscape { - span: SourceSpan::new(start, self.token_end), + span: SourceSpan::new( + self.source_id, + start..self.token_end, + ), kind: InvalidEscapeKind::Invalid, }); } @@ -406,7 +410,7 @@ where } _ => { break Token::Error(LexicalError::InvalidHexEscape { - span: SourceSpan::new(start, self.token_end), + span: SourceSpan::new(self.source_id, start..self.token_end), kind: InvalidEscapeKind::InvalidChars, }); } @@ -494,10 +498,7 @@ where } } -impl Iterator for Lexer -where - S: Source, -{ +impl<'a> Iterator for Lexer<'a> { type Item = Lexed; fn next(&mut self) -> Option { diff --git a/hir/src/parser/lexer/scanner.rs b/hir/src/parser/lexer/scanner.rs new file mode 100644 index 00000000..05038835 --- /dev/null +++ b/hir/src/parser/lexer/scanner.rs @@ -0,0 +1,85 @@ +use core::{ + iter::{FusedIterator, Peekable}, + ops::Range, +}; + +use crate::diagnostics::{ByteIndex, ByteOffset}; + +/// A simple raw character source for [super::Lexer]; +pub struct Scanner<'a> { + src: &'a str, + buf: Peekable>, + next: Option<(ByteIndex, char)>, + pos: ByteIndex, + eof: bool, +} +impl<'a> Scanner<'a> { + pub fn new(src: &'a str) -> Self { + let eof = src.is_empty(); + let mut buf = src.char_indices().peekable(); + let next = buf.next().map(|(i, c)| (ByteIndex::from(i as u32), c)); + Self { + src, + buf, + next, + pos: next.map(|(i, c)| i + ByteOffset::from_char_len(c)).unwrap_or_default(), + eof, + } + } + + #[inline(always)] + pub const fn read(&self) -> Option<(ByteIndex, char)> { + self.next + } + + pub fn peek(&mut self) -> Option<(ByteIndex, char)> { + self.buf.peek().and_then(|&(i, c)| match u32::try_from(i) { + Ok(i) => Some((ByteIndex::from(i), c)), + Err(_) => None, + }) + } + + #[inline] + fn advance(&mut self) { + match self.buf.next() { + Some((i, c)) if i < u32::MAX as usize => { + let i = ByteIndex::from(i as u32); + self.pos = i + ByteOffset::from_char_len(c); + self.next = Some((i, c)); + } + Some(_) => { + panic!("invalid source file: only files smaller than 2^32 bytes are supported") + } + None => { + self.eof = true; + self.next = None; + } + } + } + + pub fn position(&self) -> ByteIndex { + self.pos + } + + #[inline(always)] + pub fn slice(&self, span: impl Into>) -> &str { + &self.src[span.into()] + } +} + +impl<'a> Iterator for Scanner<'a> { + type Item = (ByteIndex, char); + + #[inline] + fn next(&mut self) -> Option { + if self.eof { + return None; + } + + let current = self.next.take(); + self.advance(); + current + } +} + +impl<'a> FusedIterator for Scanner<'a> {} diff --git a/hir/src/parser/mod.rs b/hir/src/parser/mod.rs index e43080ef..4ae9442c 100644 --- a/hir/src/parser/mod.rs +++ b/hir/src/parser/mod.rs @@ -1,10 +1,10 @@ /// Simple macro used in the grammar definition for constructing spans macro_rules! span { - ($l:expr, $r:expr) => { - miden_diagnostics::SourceSpan::new($l, $r) + ($source_id:expr, $l:expr, $r:expr) => { + SourceSpan::new($source_id, $l..$r) }; - ($i:expr) => { - miden_diagnostics::SourceSpan::new($i, $i) + ($source_id:expr, $i:expr) => { + SourceSpan::at($source_id, $i) }; } @@ -20,18 +20,17 @@ lalrpop_mod!( "/parser/grammar.rs" ); -use std::{path::Path, sync::Arc}; - -use miden_diagnostics::SourceFile; -use miden_parsing::{FileMapSource, Scanner, Source}; +use alloc::sync::Arc; +use std::path::Path; pub use self::error::ParseError; use self::{ ast::ConvertAstToHir, lexer::{Lexed, Lexer}, }; +use crate::diagnostics::{Report, SourceFile, SourceManagerExt}; -pub type ParseResult = Result; +pub type ParseResult = Result; /// This is the parser for HIR text format pub struct Parser<'a> { @@ -48,7 +47,7 @@ impl<'a> Parser<'a> { where T: Parse, { - ::parse(self, FileMapSource::new(source)) + ::parse(self, source) } /// Parse a `T` from a string @@ -56,8 +55,7 @@ impl<'a> Parser<'a> { where T: Parse, { - let id = self.session.codemap.add("nofile", source.as_ref().to_string()); - let file = self.session.codemap.get(id).unwrap(); + let file = self.session.source_manager.load("nofile", source.as_ref().to_string()); self.parse(file) } @@ -67,12 +65,9 @@ impl<'a> Parser<'a> { T: Parse, { let path = path.as_ref(); - let id = self - .session - .codemap - .add_file(path) - .map_err(|err| parse_file_error(err, path.to_owned()))?; - let file = self.session.codemap.get(id).unwrap(); + let file = self.session.source_manager.load_file(path).map_err(|err| { + Report::msg(err).wrap_err(format!("failed to load '{}' from disk", path.display())) + })?; self.parse(file) } } @@ -80,72 +75,71 @@ impl<'a> Parser<'a> { pub trait Parse: Sized { type Grammar; - fn parse(parser: &Parser, source: impl Source) -> ParseResult { - let scanner = Scanner::new(source); - let lexer = Lexer::new(scanner); + fn parse(parser: &Parser, source: Arc) -> ParseResult { + let lexer = Lexer::new(source.id(), source.as_str()); - Self::parse_tokens(parser, lexer) + Self::parse_tokens(parser, source.clone(), lexer) } - fn parse_tokens(parser: &Parser, tokens: impl IntoIterator) -> ParseResult; + fn parse_tokens( + parser: &Parser, + source: Arc, + tokens: impl IntoIterator, + ) -> ParseResult; } impl Parse for ast::Module { type Grammar = grammar::ModuleParser; - fn parse_tokens(parser: &Parser, tokens: impl IntoIterator) -> ParseResult { + fn parse_tokens( + _parser: &Parser, + source: Arc, + tokens: impl IntoIterator, + ) -> ParseResult { + let source_id = source.id(); let mut next_var = 0; - let result = ::Grammar::new().parse( - &parser.session.diagnostics, - &parser.session.codemap, - &mut next_var, - tokens, - ); + let result = ::Grammar::new().parse(source_id, &mut next_var, tokens); match result { - Ok(ast) => { - if parser.session.diagnostics.has_errors() { - return Err(ParseError::Failed); - } - Ok(ast) + Ok(ast) => Ok(ast), + Err(lalrpop_util::ParseError::User { error }) => { + Err(Report::from(error).with_source_code(source)) + } + Err(err) => { + let error = ParseError::from(err); + Err(Report::from(error).with_source_code(source)) } - Err(lalrpop_util::ParseError::User { error }) => Err(error), - Err(err) => Err(err.into()), } } } impl Parse for crate::Module { type Grammar = grammar::ModuleParser; - fn parse_tokens(parser: &Parser, tokens: impl IntoIterator) -> ParseResult { - use crate::pass::{AnalysisManager, ConversionError, ConversionPass}; + fn parse_tokens( + parser: &Parser, + source: Arc, + tokens: impl IntoIterator, + ) -> ParseResult { + use crate::pass::{AnalysisManager, ConversionPass}; + let source_id = source.id(); let mut next_var = 0; let result = ::Grammar::new() - .parse(&parser.session.diagnostics, &parser.session.codemap, &mut next_var, tokens) + .parse(source_id, &mut next_var, tokens) .map(Box::new); match result { Ok(ast) => { - if parser.session.diagnostics.has_errors() { - return Err(ParseError::Failed); - } let mut analyses = AnalysisManager::new(); let mut convert_to_hir = ConvertAstToHir; - convert_to_hir.convert(ast, &mut analyses, parser.session).map_err( - |err| match err { - ConversionError::Failed(err) => match err.downcast::() { - Ok(err) => err, - Err(_) => ParseError::InvalidModule, - }, - _ => ParseError::InvalidModule, - }, - ) + convert_to_hir + .convert(ast, &mut analyses, parser.session) + .map_err(|err| err.with_source_code(source)) + } + Err(lalrpop_util::ParseError::User { error }) => { + Err(Report::from(error).with_source_code(source)) + } + Err(err) => { + let error = ParseError::from(err); + Err(Report::from(error).with_source_code(source)) } - Err(lalrpop_util::ParseError::User { error }) => Err(error), - Err(err) => Err(err.into()), } } } - -#[inline] -fn parse_file_error(source: std::io::Error, path: std::path::PathBuf) -> ParseError { - ParseError::FileError { source, path } -} diff --git a/hir/src/parser/tests/mod.rs b/hir/src/parser/tests/mod.rs index 7ad8c9b5..c99ed3af 100644 --- a/hir/src/parser/tests/mod.rs +++ b/hir/src/parser/tests/mod.rs @@ -1,14 +1,15 @@ -use miden_diagnostics::{SourceSpan, Span}; use pretty_assertions::assert_eq; use crate::{ - parser::ast::*, AbiParam, ArgumentExtension, ArgumentPurpose, CallConv, ExternalFunction, - FunctionIdent, Ident, Linkage, Opcode, Overflow, Signature, StructType, Type, + diagnostics::{SourceSpan, Span}, + parser::ast::*, + AbiParam, ArgumentExtension, ArgumentPurpose, CallConv, ExternalFunction, FunctionIdent, Ident, + Linkage, Opcode, Overflow, Signature, StructType, Type, }; macro_rules! ident { ($name:ident) => { - Ident::new(crate::Symbol::intern(stringify!($name)), miden_diagnostics::SourceSpan::UNKNOWN) + Ident::new(crate::Symbol::intern(stringify!($name)), SourceSpan::UNKNOWN) }; } diff --git a/hir/src/parser/tests/utils.rs b/hir/src/parser/tests/utils.rs index 54cb988a..09165372 100644 --- a/hir/src/parser/tests/utils.rs +++ b/hir/src/parser/tests/utils.rs @@ -1,26 +1,26 @@ use std::{path::Path, sync::Arc}; -use miden_diagnostics::{Emitter, Verbosity}; -use midenc_session::{Options, Warnings}; +use midenc_session::{Options, Verbosity, Warnings}; use pretty_assertions::assert_eq; use crate::{ - parser::{ast::Module, ParseError, Parser}, + diagnostics::{self, CaptureEmitter, DefaultEmitter, Emitter, EmitterBuffer, Report}, + parser::{ast::Module, Parser}, testing::TestContext, }; struct SplitEmitter { - capture: miden_diagnostics::CaptureEmitter, - default: miden_diagnostics::DefaultEmitter, + capture: CaptureEmitter, + default: DefaultEmitter, } impl SplitEmitter { #[inline] pub fn new() -> Self { - use miden_diagnostics::term::termcolor::ColorChoice; + use diagnostics::ColorChoice; Self { capture: Default::default(), - default: miden_diagnostics::DefaultEmitter::new(ColorChoice::Auto), + default: DefaultEmitter::new(ColorChoice::Auto), } } @@ -31,12 +31,12 @@ impl SplitEmitter { } impl Emitter for SplitEmitter { #[inline] - fn buffer(&self) -> miden_diagnostics::term::termcolor::Buffer { + fn buffer(&self) -> EmitterBuffer { self.capture.buffer() } #[inline] - fn print(&self, buffer: miden_diagnostics::term::termcolor::Buffer) -> std::io::Result<()> { + fn print(&self, buffer: EmitterBuffer) -> std::io::Result<()> { use std::io::Write; let mut copy = self.capture.buffer(); @@ -61,10 +61,18 @@ pub struct ParseTest { impl ParseTest { /// Creates a new test, from the source string. pub fn new() -> Self { + use midenc_session::{ProjectType, TargetEnv}; + let emitter = Arc::new(SplitEmitter::new()); - let options = Options::new(std::env::current_dir().unwrap()) - .with_verbosity(Verbosity::Warning) - .with_warnings(Warnings::Error); + let options = Options::new( + None, + TargetEnv::Base, + ProjectType::Library, + std::env::current_dir().unwrap(), + None, + ) + .with_verbosity(Verbosity::Warning) + .with_warnings(Warnings::Error); let context = TestContext::default_with_opts_and_emitter(options, Some(emitter.clone())); Self { context, emitter } } @@ -75,31 +83,28 @@ impl ParseTest { /// disk #[allow(unused)] pub fn add_virtual_file>(&self, name: P, content: String) { - self.context.session.codemap.add(name.as_ref(), content); + use diagnostics::SourceManager; + + let name = name.as_ref().to_str().unwrap(); + self.context.session.source_manager.load(name, content); } - pub fn parse_module_ast_from_file>( - &self, - path: P, - ) -> Result { + pub fn parse_module_ast_from_file>(&self, path: P) -> Result { let parser = Parser::new(&self.context.session); parser.parse_file::(path) } - pub fn parse_module_ast(&self, source: &str) -> Result { + pub fn parse_module_ast(&self, source: &str) -> Result { let parser = Parser::new(&self.context.session); parser.parse_str::(source) } - pub fn parse_module_from_file>( - &self, - path: P, - ) -> Result { + pub fn parse_module_from_file>(&self, path: P) -> Result { let parser = Parser::new(&self.context.session); parser.parse_file::(path) } - pub fn parse_module(&self, source: &str) -> Result { + pub fn parse_module(&self, source: &str) -> Result { let parser = Parser::new(&self.context.session); parser.parse_str::(source) } diff --git a/hir/src/pass/analysis.rs b/hir/src/pass/analysis.rs index 3523728c..ab5a062b 100644 --- a/hir/src/pass/analysis.rs +++ b/hir/src/pass/analysis.rs @@ -1,24 +1,18 @@ -use std::{ +use alloc::rc::Rc; +use core::{ any::{Any, TypeId}, hash::Hash, - rc::Rc, }; use midenc_session::Session; use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; -type BuildFxHasher = std::hash::BuildHasherDefault; +use crate::diagnostics::Report; -/// This error type is produced when an [Analysis] fails -#[derive(Debug, thiserror::Error)] -pub enum AnalysisError { - /// The analysis failed for an unexpected reason - #[error(transparent)] - Failed(#[from] anyhow::Error), -} +type BuildFxHasher = std::hash::BuildHasherDefault; /// A convenient type alias for `Result` -pub type AnalysisResult = Result; +pub type AnalysisResult = Result; #[doc(hidden)] pub trait PreservableAnalysis: Any { diff --git a/hir/src/pass/conversion.rs b/hir/src/pass/conversion.rs index 44f45e1b..b3f43ec9 100644 --- a/hir/src/pass/conversion.rs +++ b/hir/src/pass/conversion.rs @@ -1,20 +1,10 @@ use midenc_session::Session; -use super::{AnalysisError, AnalysisManager, Chain, PassInfo}; - -/// This error is produced when a [ConversionPass] fails -#[derive(Debug, thiserror::Error)] -pub enum ConversionError { - /// Conversion failed due to an analysis error - #[error(transparent)] - Analysis(#[from] AnalysisError), - /// An unexpected error occurred during conversion - #[error(transparent)] - Failed(#[from] anyhow::Error), -} +use super::{AnalysisManager, Chain, PassInfo}; +use crate::diagnostics::Report; /// A convenient type alias for `Result` -pub type ConversionResult = Result; +pub type ConversionResult = Result; /// This is a marker trait for [ConversionPass] impls which also implement [PassInfo] /// diff --git a/hir/src/pass/mod.rs b/hir/src/pass/mod.rs index 3350a211..f91d6d02 100644 --- a/hir/src/pass/mod.rs +++ b/hir/src/pass/mod.rs @@ -12,7 +12,7 @@ macro_rules! register_function_rewrite { impl $ty { fn new( _options: std::sync::Arc, - _diagnostics: std::sync::Arc, + _diagnostics: std::sync::Arc, ) -> Box { Box::new(crate::ModuleRewritePassAdapter(Self)) } diff --git a/hir/src/pass/rewrite.rs b/hir/src/pass/rewrite.rs index ecb5e899..ffdcae5e 100644 --- a/hir/src/pass/rewrite.rs +++ b/hir/src/pass/rewrite.rs @@ -1,20 +1,10 @@ use midenc_session::Session; -use super::{AnalysisError, AnalysisKey, AnalysisManager, PassInfo}; - -/// This error is produced when an error occurs when applying a rewrite rule -#[derive(Debug, thiserror::Error)] -pub enum RewriteError { - /// The rewrite failed due to an analysis error - #[error(transparent)] - Analysis(#[from] AnalysisError), - /// An unexpected error occurred during this rewrite - #[error(transparent)] - Failed(#[from] anyhow::Error), -} +use super::{AnalysisKey, AnalysisManager, PassInfo}; +use crate::diagnostics::Report; -/// A convenient type alias for `Result<(), RewriteError>` -pub type RewriteResult = Result<(), RewriteError>; +/// A convenient type alias for `Result<(), Report>` +pub type RewriteResult = Result<(), Report>; /// A convenient type alias for closures which can be used as rewrite passes pub type RewriteFn = dyn FnMut(&mut T, &mut AnalysisManager, &Session) -> RewriteResult; diff --git a/hir/src/program/linker.rs b/hir/src/program/linker.rs index 5b37fb61..e81e5397 100644 --- a/hir/src/program/linker.rs +++ b/hir/src/program/linker.rs @@ -1,90 +1,15 @@ +use std::{ + borrow::Cow, + collections::{BTreeMap, BTreeSet}, +}; + +use miden_assembly::Library as CompiledLibrary; use petgraph::{prelude::DiGraphMap, Direction}; -use rustc_hash::FxHashMap; - -use crate::*; - -/// This represents the various types of errors which may be raised by a [Linker] -#[derive(Debug, thiserror::Error)] -pub enum LinkerError { - /// The given module has already been declared - #[error("duplicate module declaration for '{0}'")] - ModuleConflict(Ident), - /// The given identifier references a [Module] which is not present in the set of - /// modules to link. - #[error("encountered reference to undefined module '{0}'")] - MissingModule(Ident), - /// The given identifier references a [Function] which is not defined in any of the - /// modules being linked, and is not a standard library function whose definition is - /// expected to be provided by the Miden VM. - #[error("encountered reference to undefined function '{0}'")] - MissingFunction(FunctionIdent), - /// The given identifier references [GlobalVariableData] which has not been defined - /// in any of the modules being linked. - #[error("encountered reference to undefined global '{0}'")] - MissingGlobal(Ident), - /// The given function is referenced by an external declaration, but the actual definition - /// of that function has a different signature than was expected by the external reference. - /// - /// The types of mismatches that will cause this error are: - /// - /// * The calling convention is different - /// * The number and/or types of the arguments and results are not the same - /// * A special purpose parameter is declared in one signature but not the other - /// * Argument extension conflicts, i.e. one signature says a parameter is zero-extended, the - /// other sign-extended - #[error( - "signature mismatch for '{0}': external function declaration does not match definition" - )] - SignatureMismatch(FunctionIdent), - /// An external declaration for the given function was found in a different module than the - /// one in which the function is defined, and the actual definition does not have external - /// linkage. - /// - /// This error is a variant of `SignatureMismatch`, but occurs when the signature is otherwise - /// correct, but is ultimately an invalid declaration because the function should not be - /// visible outside its containing module. - #[error( - "invalid reference to '{0}': only functions with external linkage can be referenced from \ - other modules" - )] - LinkageMismatch(FunctionIdent), - /// A cycle in the call graph was found starting at the given function. - /// - /// This occurs due to recursion (self or mutual), and is not supported by Miden. - #[error( - "encountered an invalid cycle in the call graph caused by a call from '{caller}' to \ - '{callee}'" - )] - InvalidCycle { - caller: FunctionIdent, - callee: FunctionIdent, - }, - /// Occurs when the declared entrypoint does not have external linkage - #[error("invalid entrypoint '{0}': must have external linkage")] - InvalidEntryLinkage(FunctionIdent), - /// Occurs when attempting to set the program entrypoint when it has already been set - #[error( - "conflicting entrypoints: '{current}' conflicts with previously declared entrypoint \ - '{prev}'" - )] - InvalidMultipleEntry { - current: FunctionIdent, - prev: FunctionIdent, - }, - /// An error occurred when attempting to link segments declared by a module into the - /// set of segments already declared in the program. A segment might be valid in the - /// context of a single module, but invalid in the context of a whole program, either - /// due to conflicts, or an inability to allocate all segments without running out of - /// available heap memory. - #[error(transparent)] - SegmentError(#[from] DataSegmentError), - /// A conflict between two global variables with the same symbol was detected. - /// - /// When this occurs, the definitions must have been in separate modules, with external - /// linkage, and they disagree on the type of the value or its initializer. - #[error(transparent)] - GlobalVariableError(#[from] GlobalVariableError), -} + +use crate::{ + diagnostics::{DiagnosticsHandler, Report, Severity, Spanned}, + *, +}; /// Represents a node in the global variable dependency graph #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -95,6 +20,50 @@ enum Node { Function(FunctionIdent), } +/// Represents an object input to the [Linker] +pub enum Object { + /// The object is an HIR module + Hir(Box), + /// The object is a compiled Miden Assembly module + Masm { name: Ident, exports: Vec }, +} +impl Object { + /// Return the identifier associated with this object + pub fn id(&self) -> Ident { + match self { + Self::Hir(module) => module.name, + Self::Masm { name, .. } => *name, + } + } + + /// Return the set of exported functions/procedures from this object + pub fn exports(&self) -> Box<(dyn Iterator + '_)> { + match self { + Self::Hir(module) => Box::new(module.functions().map(|f| f.id)), + Self::Masm { name, ref exports } => { + let name = *name; + Box::new(exports.iter().copied().map(move |function| FunctionIdent { + module: name, + function, + })) + } + } + } +} +impl From> for Object { + fn from(module: Box) -> Self { + Self::Hir(module) + } +} +impl From<(Ident, Vec)> for Object { + fn from(module: (Ident, Vec)) -> Self { + Self::Masm { + name: module.0, + exports: module.1, + } + } +} + /// The [Linker] performs a similar role in conjunction with the Miden compiler, as the system /// linker does (e.g. `ld`) when used with compilers like `clang` or `rustc`. /// @@ -149,11 +118,19 @@ enum Node { /// context, and we do not provide instructions for executing calls in another context. However, we /// will eventually be linking programs which have a potentially unbounded number of address spaces, /// which is an additional complication that your typical linker doesn't have to deal with -pub struct Linker { +pub struct Linker<'a> { + diagnostics: &'a DiagnosticsHandler, /// This is the program being constructed by the linker program: Box, - /// This is the set of modules which have yet to be linked - pending: FxHashMap>, + /// This is the set of named objects which have yet to be linked + pending: BTreeMap, + /// This is the set of patterns that symbol names will be matched against when determining + /// whether or not to raise an error when a reference to any symbol whose name starts with + /// that pattern cannot be found. + /// + /// In practice, this is used to allow certain library modules to be referenced without + /// requiring them to be loaded into the linker. + allow_missing: BTreeSet>, /// This is the dependency graph for all functions in the program. /// /// This graph is used to obtain a topological ordering of the @@ -179,10 +156,11 @@ pub struct Linker { /// The set of renamed global symbols for a single module. /// /// This is only used when preprocessing a module, and is reset on each call to `add` - renamed: FxHashMap, + renamed: BTreeMap, } -impl Default for Linker { - fn default() -> Self { +impl<'a> Linker<'a> { + /// Create a [Linker] for a new, empty [Program]. + pub fn new(diagnostics: &'a DiagnosticsHandler) -> Self { let mut program = Box::new(Program::new()); // We reserve the first page of memory for the shadow stack @@ -192,28 +170,39 @@ impl Default for Linker { .expect("unexpected error declaring shadow stack segment"); Self { + diagnostics, program, pending: Default::default(), + allow_missing: BTreeSet::from_iter([ + "std::".into(), + "intrinsics::".into(), + "miden::account".into(), + "miden::tx".into(), + "miden::note".into(), + ]), callgraph: DiGraphMap::new(), local_callgraph: DiGraphMap::new(), globals: DiGraphMap::new(), renamed: Default::default(), } } -} -impl Linker { - /// Create a [Linker] for a new, empty [Program]. - pub fn new() -> Self { - Self::default() - } /// Set the entrypoint for the linked program /// - /// Returns a [LinkerError] if a different entrypoint was already declared. - pub fn with_entrypoint(&mut self, id: FunctionIdent) -> Result<(), LinkerError> { + /// Returns a [Report] if a different entrypoint was already declared. + pub fn with_entrypoint(&mut self, id: FunctionIdent) -> Result<(), Report> { if let Some(prev) = self.program.entrypoint() { if prev != id { - return Err(LinkerError::InvalidMultipleEntry { current: id, prev }); + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label( + id.function.span, + "this entrypoint conflicts with a previously declared entrypoint", + ) + .with_secondary_label(prev.function.span, "previous entrypoint declared here") + .into_report()); } } @@ -222,7 +211,82 @@ impl Linker { Ok(()) } - /// Add `module` to the set of modules to be linked + /// Specify a pattern that will be matched against undefined symbols that determines whether or + /// or not it should be treated as an error. It is assumed that the referenced symbol will be + /// resolved during assembly to MAST. + pub fn allow_missing(&mut self, name: impl Into>) { + self.allow_missing.insert(name.into()); + } + + /// Add a compiled library to the set of libraries to link against + pub fn add_library(&mut self, lib: CompiledLibrary) { + // Add all of the exported objects to the callgraph + for export in lib.exports() { + let module = Ident::with_empty_span(Symbol::intern(export.module.path())); + let name: &str = export.name.as_ref(); + let function = Ident::with_empty_span(Symbol::intern(name)); + self.callgraph.add_node(FunctionIdent { module, function }); + } + self.program.add_library(lib); + } + + /// Add multiple libraries to the set of libraries to link against + pub fn add_libraries(&mut self, libs: I) + where + I: IntoIterator, + { + for lib in libs { + self.add_library(lib); + } + } + + /// Add an object to link as part of the resulting [Program]. + /// + /// There are different types of objects, see [Object] for details. + /// + /// # Errors + /// + /// The following conditions can cause an error to be raised, if applicable to the object given: + /// + /// * The object is invalid + /// * The object introduces recursion into the call graph + /// * Two or more objects export a module with the same name + /// * Two or more objects contain conflicting data segment declarations + /// * Two or more objects contain conflicting global variable declarations + pub fn add_object(&mut self, object: impl Into) -> Result<(), Report> { + let object = object.into(); + let id = object.id(); + + // Raise an error if we've already got a module by this name pending + if self.pending.contains_key(&id) { + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label( + id.span, + "this module conflicts with a previous module of the same name", + ) + .into_report()); + } + + // Register functions in the callgraph + for export in object.exports() { + self.callgraph.add_node(export); + } + + match object { + Object::Hir(module) => self.add_hir_object(module), + object @ Object::Masm { .. } => { + // We're done preprocessing, so add the module to the pending set + self.pending.insert(object.id(), object); + + Ok(()) + } + } + } + + /// Add `module` to the set of objects to be linked /// /// This preprocesses the module for the linker, and will catch the following issues: /// @@ -231,8 +295,8 @@ impl Linker { /// * Conflicting global variable declarations /// * Recursion in the local call graph of the module (global analysis comes later) /// - /// If any of the above errors occurs, a [LinkerError] is returned. - pub fn add(&mut self, mut module: Box) -> Result<(), LinkerError> { + /// If any of the above errors occurs, a [Report] is returned. + fn add_hir_object(&mut self, mut module: Box) -> Result<(), Report> { let id = module.name; // Reset the auxiliary data structures used for preprocessing @@ -241,7 +305,15 @@ impl Linker { // Raise an error if we've already got a module by this name pending if self.pending.contains_key(&id) { - return Err(LinkerError::ModuleConflict(id)); + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label( + id.span, + "this module conflicts with a previous module of the same name", + ) + .into_report()); } // Import all data segments @@ -290,7 +362,7 @@ impl Linker { // the callee for our error diagnostics. To get it, we call the // call graph validation routine which does a traversal specifically // designed to obtain that information. - validate_callgraph(&self.local_callgraph) + validate_callgraph(&self.local_callgraph, self.diagnostics) .expect_err("expected call graph to contain a cycle") })?; @@ -339,14 +411,14 @@ impl Linker { } // We're done preprocessing, so add the module to the pending set - self.pending.insert(id, module); + self.pending.insert(id, Object::Hir(module)); Ok(()) } /// Links all of the modules which were added, producing a [Program] if no issues are found. /// - /// Returns a [LinkerError] if the link fails for any reason. + /// Returns a [Report] if the link fails for any reason. /// /// When called, all of the added modules have been preprocessed, and what remains are the /// following tasks: @@ -361,75 +433,151 @@ impl Linker { /// * TODO: If linking an executable program, garbage collect unused modules/functions /// /// Once linked, a [Program] can be emitted to Miden Assembly using the code generation passes. - pub fn link(mut self) -> Result, LinkerError> { - // Ensure linker-defined globals and intrinsics are present - self.populate_builtins(); - + pub fn link(mut self) -> Result, Report> { // Look for cycles in the call graph - validate_callgraph(&self.callgraph)?; + validate_callgraph(&self.callgraph, self.diagnostics)?; // Verify the entrypoint, if declared if let Some(entry) = self.program.entrypoint() { - let is_linked = self.pending.contains_key(&entry.module); - if !is_linked { - return Err(LinkerError::MissingModule(entry.module)); - } - - let module = &self.pending[&entry.module]; - let function = - module.function(entry.function).ok_or(LinkerError::MissingFunction(entry))?; - if !function.is_public() { - return Err(LinkerError::InvalidEntryLinkage(entry)); + // NOTE(pauls): Currently, we always raise an error here, but since we do allow + // missing symbols in other situations, perhaps we should allow it here as well. + // For now though, we assume this is a mistake, since presumably you are compiling + // the code that contains the entrypoint. + let object = self.pending.get(&entry.module).ok_or_else(|| { + self.diagnostics + .diagnostic(Severity::Error) + .with_message(format!("linker error: undefined module '{}'", &entry.module)) + .into_report() + })?; + match object { + Object::Hir(module) => { + let function = module.function(entry.function).ok_or_else(|| { + self.diagnostics + .diagnostic(Severity::Error) + .with_message(format!("linker error: undefined function '{}'", &entry)) + .into_report() + })?; + if !function.is_public() { + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label( + entry.function.span, + "entrypoint must have external linkage", + ) + .into_report()); + } + } + Object::Masm { ref exports, .. } => { + if !exports.contains(&entry.function) { + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message(format!("linker error: undefined function '{}'", &entry)) + .into_report()); + } + } } } // Verify module/function references for node in self.callgraph.nodes() { // If the module is pending, it is being linked - let is_linked = self.pending.contains_key(&node.module); - let is_stdlib = node.module.as_str().starts_with("std::"); - let is_intrinsic = node.module.as_str().starts_with("intrinsics::"); - - // If a referenced module is not being linked, raise an error - if !is_linked { - // However we ignore standard library/intrinsic modules in this check, - // as they are known to be provided at runtime. - // - // TODO: We need to validate that the given module/function - // is actually in the standard library though, and that the - // signature matches what is expected. - if is_stdlib || is_intrinsic { + let object = self.pending.get(&node.module); + let is_allowed_missing = self + .allow_missing + .iter() + .any(|pattern| node.module.as_str().starts_with(pattern.as_ref())); + + // If a referenced module is not present for the link, raise an error, unless it is + // specifically allowed to be missing at this point. + if object.is_none() { + if is_allowed_missing { continue; } - return Err(LinkerError::MissingModule(node.module)); + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message(format!("linker error: undefined module '{}'", &node.module)) + .into_report()); } // The module is present, so we must verify that the function is defined in that module - let module = &self.pending[&node.module]; - let function = - module.function(node.function).ok_or(LinkerError::MissingFunction(node))?; - let is_externally_linkable = function.is_public(); + let object = unsafe { object.unwrap_unchecked() }; + let (is_externally_linkable, signature) = match object { + Object::Hir(ref module) => match module.function(node.function) { + Some(function) => (function.is_public(), Some(&function.signature)), + None if is_allowed_missing => (true, None), + None => { + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message(format!("linker error: undefined function '{}'", &node)) + .into_report()) + } + }, + Object::Masm { ref exports, .. } => { + if !exports.contains(&node.function) && !is_allowed_missing { + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message(format!("linker error: undefined function '{}'", &node)) + .into_report()); + } + (true, None) + } + }; // Next, visit all of the dependent functions, and ensure their signatures match for dependent_id in self.callgraph.neighbors_directed(node, Direction::Incoming) { // If the dependent is in another module, but the function has internal linkage, // raise an error if dependent_id.module != node.module && !is_externally_linkable { - return Err(LinkerError::LinkageMismatch(node)); + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label( + dependent_id.function.span, + format!( + "this function contains an invalid reference to '{}'", + &node.function + ), + ) + .with_help( + "Only functions with external linkage can be referenced across modules", + ) + .into_report()); + } + // Otherwise, make sure the signatures match (if we have signatures available) + let dependent_object = &self.pending[&dependent_id.module]; + match (signature, dependent_object) { + (Some(signature), Object::Hir(ref dependent_module)) => { + let dependent_function = dependent_module + .function(dependent_id.function) + .expect("dependency graph is outdated"); + let external_ref = dependent_function + .dfg + .get_import(&node) + .expect("dependency graph is outdated"); + let external_span = external_ref.id.span(); + verify_matching_signature( + node, + external_span, + signature, + &external_ref.signature, + self.diagnostics, + )?; + } + // If we don't have a signature for the dependency, we presume it matches the + // dependent + (None, Object::Hir(_)) => (), + // If the dependent is MASM, we don't know what signature it used, so we + // presume it is correct + (_, Object::Masm { .. }) => (), } - // Otherwise, make sure the signatures match - let dependent_module = &self.pending[&dependent_id.module]; - let dependent_function = dependent_module - .function(dependent_id.function) - .expect("dependency graph is outdated"); - let external_ref = - dependent_function.dfg.get_import(&node).expect("dependency graph is outdated"); - verify_matching_signature( - function.id, - &function.signature, - &external_ref.signature, - )?; } } @@ -454,7 +602,11 @@ impl Linker { // If it has dependents, but isn't defined anywhere, raise an error if !self.program.globals.exists(name) { - return Err(LinkerError::MissingGlobal(name)); + return Err(self + .diagnostics + .diagnostic(Severity::Error) + .with_message(format!("linker error: undefined global variable '{name}'")) + .into_report()); } } @@ -462,57 +614,21 @@ impl Linker { self.garbage_collect(); // We're finished processing all pending modules, so add them to the program - for module in self.pending.into_values() { - self.program.modules.insert(module); + for object in self.pending.into_values() { + match object { + Object::Hir(module) => { + self.program.modules.insert(module); + } + Object::Masm { .. } => { + // These objects are provided to the assembler directly + continue; + } + } } Ok(self.program) } - /// Programs we construct may depend on one or more predefined globals/intrinsics - /// that are provided by the compiler in order to support common functionality, such - /// as memory management primitives. This function handles defining these prior to - /// linking the program. - fn populate_builtins(&mut self) { - // We provide three globals for managing the heap, based on the layout - // of the data segments and these globals. - let globals_offset = self.program.segments.next_available_offset(); - // Compute the start of the heap by finding the end of the globals segment, aligned to the - // nearest word boundary - let heap_base = globals_offset - .checked_add( - self.program - .globals - .size_in_bytes() - .try_into() - .expect("unable to allocate globals, unable to fit in linear memory"), - ) - .expect("unable to allocate globals, not enough unreserved space available") - .align_up(32); - let hp = heap_base.to_le_bytes(); - // Initialize all 3 globals with the computed heap pointer - let heap_ptr_ty = Type::Ptr(Box::new(Type::U8)); - self.program - .globals - .declare("HEAP_BASE".into(), heap_ptr_ty.clone(), Linkage::External, Some(hp.into())) - .expect( - "unable to declare HEAP_BASE, a conflicting global by that name was already \ - defined", - ); - self.program - .globals - .declare("HEAP_TOP".into(), heap_ptr_ty.clone(), Linkage::External, Some(hp.into())) - .expect( - "unable to declare HEAP_TOP, a conflicting global by that name was already defined", - ); - self.program - .globals - .declare("HEAP_END".into(), heap_ptr_ty, Linkage::External, Some(hp.into())) - .expect( - "unable to declare HEAP_END, a conflicting global by that name was already defined", - ); - } - /// If an executable is being linked, discover unused functions and garbage collect them. /// /// Once a function has been identified as dead and is collected, any transitive items it @@ -532,18 +648,37 @@ impl Linker { /// caller. fn verify_matching_signature( id: FunctionIdent, + expected_span: SourceSpan, actual: &Signature, expected: &Signature, -) -> Result<(), LinkerError> { + diagnostics: &DiagnosticsHandler, +) -> Result<(), Report> { // If the number of parameters differs, raise an error if expected.arity() != actual.arity() { - return Err(LinkerError::SignatureMismatch(id)); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label(id.span(), "the arity of this function declaration is incorrect") + .with_secondary_label( + expected_span, + format!("the actual arity of the definition is {}", expected.arity()), + ) + .into_report()); } // If the type or specification of any parameters differs, raise an error - for (ep, ap) in expected.params().iter().zip(actual.params().iter()) { + for (i, (ep, ap)) in expected.params().iter().zip(actual.params().iter()).enumerate() { if !is_matching_param(ep, ap) { - return Err(LinkerError::SignatureMismatch(id)); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label( + id.span(), + "the type signature of this function declaration is incorrect", + ) + .with_secondary_label(expected_span, "it does not match the signature defined here") + .with_help(format!("The parameter at index {i} is defined as {}", &ep.ty)) + .into_report()); } } @@ -551,13 +686,33 @@ fn verify_matching_signature( let expected_results = expected.results(); let actual_results = actual.results(); if expected_results.len() != actual_results.len() { - return Err(LinkerError::SignatureMismatch(id)); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label( + id.span(), + "the return arity of this function declaration is incorrect", + ) + .with_secondary_label( + expected_span, + format!("the actual number of return values is {}", expected_results.len()), + ) + .into_report()); } // If the type of results differs, raise an error - for (er, ar) in expected_results.iter().zip(actual_results.iter()) { + for (i, (er, ar)) in expected_results.iter().zip(actual_results.iter()).enumerate() { if !is_matching_param(er, ar) { - return Err(LinkerError::SignatureMismatch(id)); + return Err(diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label( + id.span(), + "the type signature of this function declaration is incorrect", + ) + .with_secondary_label(expected_span, "it does not match the signature defined here") + .with_help(format!("The result at index {i} is defined as {}", &er.ty)) + .into_report()); } } @@ -583,12 +738,24 @@ fn is_matching_param(expected: &AbiParam, actual: &AbiParam) -> bool { /// Validate the given call graph by looking for cycles caused by recursion. /// -/// Returns a [LinkerError] if a cycle is found. -fn validate_callgraph(callgraph: &DiGraphMap) -> Result<(), LinkerError> { +/// Returns a [Report] if a cycle is found. +fn validate_callgraph( + callgraph: &DiGraphMap, + diagnostics: &DiagnosticsHandler, +) -> Result<(), Report> { use petgraph::visit::{depth_first_search, DfsEvent, IntoNodeIdentifiers}; depth_first_search(callgraph, callgraph.node_identifiers(), |event| match event { - DfsEvent::BackEdge(caller, callee) => Err(LinkerError::InvalidCycle { caller, callee }), + DfsEvent::BackEdge(caller, callee) => Err(diagnostics + .diagnostic(Severity::Error) + .with_message("linker error") + .with_primary_label(caller.span(), "this function contains recursion") + .with_secondary_label(callee.span(), "due to one or more calls to this function") + .with_help( + "If you need to make the call recursive, you may need to use indirect calls to \ + acheive this", + ) + .into_report()), _ => Ok(()), }) } diff --git a/hir/src/program/mod.rs b/hir/src/program/mod.rs index 1dd2c0b6..61fa0e52 100644 --- a/hir/src/program/mod.rs +++ b/hir/src/program/mod.rs @@ -1,11 +1,17 @@ mod linker; +use alloc::collections::BTreeMap; use core::ops::{Deref, DerefMut}; use intrusive_collections::RBTree; +use miden_assembly::Library as CompiledLibrary; +use miden_core::crypto::hash::RpoDigest; -pub use self::linker::{Linker, LinkerError}; -use super::*; +pub use self::linker::Linker; +use crate::{ + diagnostics::{DiagnosticsHandler, Report}, + *, +}; /// A [Program] is a collection of [Module]s that are being compiled together as a package. /// @@ -27,6 +33,8 @@ use super::*; pub struct Program { /// This tree stores all of the modules being compiled as part of the current program. modules: RBTree, + /// The set of compiled libraries this program links against + libraries: BTreeMap, /// If set, this field is used to determine which function is the entrypoint for the program. /// /// When generating Miden Assembly, this will determine whether or not we're emitting @@ -52,9 +60,14 @@ impl Program { Self::default() } + /// Add to the set of libraries this [Program] will be assembled with + pub fn add_library(&mut self, lib: CompiledLibrary) { + self.libraries.insert(*lib.digest(), lib); + } + /// Returns true if this program has a defined entrypoint pub fn has_entrypoint(&self) -> bool { - self.entrypoint().is_none() + self.entrypoint().is_some() } /// Returns true if this program is executable. @@ -80,6 +93,16 @@ impl Program { &mut self.modules } + /// Return the set of libraries this program links against + pub fn libraries(&self) -> &BTreeMap { + &self.libraries + } + + /// Return the set of libraries this program links against as a mutable reference + pub fn libraries_mut(&mut self) -> &mut BTreeMap { + &mut self.libraries + } + /// Return a reference to the data segment table for this program pub fn segments(&self) -> &DataSegmentTable { &self.segments @@ -123,14 +146,21 @@ impl crate::pass::AnalysisKey for Program { /// Simply create the builder, add/build one or more modules, then call `link` to obtain a /// [Program]. pub struct ProgramBuilder<'a> { - modules: std::collections::BTreeMap>, + /// The set of HIR modules to link into the program + modules: BTreeMap>, + /// The set of modules defined externally, which will be linked during assembly + extern_modules: BTreeMap>, + /// The set of libraries we're linking against + libraries: BTreeMap, entry: Option, - diagnostics: &'a miden_diagnostics::DiagnosticsHandler, + diagnostics: &'a DiagnosticsHandler, } impl<'a> ProgramBuilder<'a> { - pub fn new(diagnostics: &'a miden_diagnostics::DiagnosticsHandler) -> Self { + pub fn new(diagnostics: &'a DiagnosticsHandler) -> Self { Self { modules: Default::default(), + extern_modules: Default::default(), + libraries: Default::default(), entry: None, diagnostics, } @@ -158,8 +188,9 @@ impl<'a> ProgramBuilder<'a> { /// Returns `Err` if a module with the same name already exists pub fn add_module(&mut self, module: Box) -> Result<(), ModuleConflictError> { let module_name = module.name; - if self.modules.contains_key(&module_name) { - return Err(ModuleConflictError(module_name)); + if self.modules.contains_key(&module_name) || self.extern_modules.contains_key(&module_name) + { + return Err(ModuleConflictError::new(module_name)); } self.modules.insert(module_name, module); @@ -167,6 +198,34 @@ impl<'a> ProgramBuilder<'a> { Ok(()) } + /// Make the linker aware that `module` (with the given set of exports), is available to be + /// linked against, but is already compiled to Miden Assembly, so has no HIR representation. + /// + /// Returns `Err` if a module with the same name already exists + pub fn add_extern_module( + &mut self, + module: Ident, + exports: E, + ) -> Result<(), ModuleConflictError> + where + E: IntoIterator, + { + if self.modules.contains_key(&module) || self.extern_modules.contains_key(&module) { + return Err(ModuleConflictError::new(module)); + } + + self.extern_modules.insert(module, exports.into_iter().collect()); + + Ok(()) + } + + /// Make the linker aware of the objects contained in the given library. + /// + /// Duplicate libraries/objects are ignored. + pub fn add_library(&mut self, library: CompiledLibrary) { + self.libraries.insert(*library.digest(), library); + } + /// Start building a [Module] with the given name. /// /// When the builder is done, the resulting [Module] will be inserted @@ -184,16 +243,18 @@ impl<'a> ProgramBuilder<'a> { } /// Link a [Program] from the current [ProgramBuilder] state - pub fn link(self) -> Result, LinkerError> { - let mut linker = Linker::new(); + pub fn link(self) -> Result, Report> { + let mut linker = Linker::new(self.diagnostics); + let entrypoint = self.entry.or_else(|| self.modules.values().find_map(|m| m.entrypoint())); if let Some(entry) = entrypoint { linker.with_entrypoint(entry)?; } - for (_, module) in self.modules.into_iter() { - linker.add(module)?; - } + linker.add_libraries(self.libraries.into_values()); + + self.extern_modules.into_iter().try_for_each(|obj| linker.add_object(obj))?; + self.modules.into_values().try_for_each(|obj| linker.add_object(obj))?; linker.link() } @@ -260,15 +321,15 @@ impl<'a, 'b: 'a> AsMut for ProgramModuleBuilder<'a, 'b> { /// This is used to build a [Function] from a [ProgramModuleBuilder]. /// /// It is basically just a wrapper around [ModuleFunctionBuilder], but overrides -/// `build` to use the [miden_diagnostics::DiagnosticsHandler] of the parent +/// `build` to use the [DiagnosticsHandler] of the parent /// [ProgramBuilder]. pub struct ProgramFunctionBuilder<'a, 'b: 'a> { - diagnostics: &'b miden_diagnostics::DiagnosticsHandler, + diagnostics: &'b DiagnosticsHandler, fb: ModuleFunctionBuilder<'a>, } impl<'a, 'b: 'a> ProgramFunctionBuilder<'a, 'b> { /// Build the current function - pub fn build(self) -> Result { + pub fn build(self) -> Result { let diagnostics = self.diagnostics; self.fb.build(diagnostics) } diff --git a/hir/src/segments.rs b/hir/src/segments.rs index dee52e84..7c709a34 100644 --- a/hir/src/segments.rs +++ b/hir/src/segments.rs @@ -7,17 +7,21 @@ use intrusive_collections::{intrusive_adapter, LinkedList, LinkedListLink, Unsaf intrusive_adapter!(pub DataSegmentAdapter = UnsafeRef: DataSegment { link: LinkedListLink }); -use crate::{formatter, Alignable, ConstantData, Offset}; +use crate::{ + diagnostics::{miette, Diagnostic}, + formatter, Alignable, ConstantData, Offset, +}; /// This error is raised when attempting to declare a [DataSegment] /// that in some way conflicts with previously declared data segments. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, Diagnostic)] pub enum DataSegmentError { /// The current segment overlaps with a previously allocated segment #[error( "invalid data segment: segment of {size1} bytes at {offset1:#x} overlaps with segment of \ {size2} bytes at {offset2:#x}" )] + #[diagnostic()] OverlappingSegments { offset1: Offset, size1: u32, @@ -31,6 +35,7 @@ pub enum DataSegmentError { "invalid data segment: segment at {0:#x} conflicts with a previous segment declaration at \ this address" )] + #[diagnostic()] Mismatch(Offset), /// The current segment and size do not fall in the boundaries of the heap /// which is allocatable to globals and other heap allocations. @@ -42,18 +47,21 @@ pub enum DataSegmentError { "invalid data segment: segment of {size} bytes at {offset:#x} would extend beyond the end \ of the usable heap" )] + #[diagnostic()] OutOfBounds { offset: Offset, size: u32 }, /// The initializer for the current segment has a size greater than `u32::MAX` bytes #[error( "invalid data segment: segment at {0:#x} was declared with an initializer larger than \ 2^32 bytes" )] + #[diagnostic()] InitTooLarge(Offset), /// The initializer for the current segment has a size greater than the declared segment size #[error( "invalid data segment: segment of {size} bytes at {offset:#x} has an initializer of \ {actual} bytes" )] + #[diagnostic()] InitOutOfBounds { offset: Offset, size: u32, @@ -210,6 +218,8 @@ pub struct DataSegment { init: ConstantData, /// Whether or not this segment is intended to be read-only data readonly: bool, + /// Whether or not this segment starts as all zeros + zeroed: bool, } impl fmt::Debug for DataSegment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -218,6 +228,7 @@ impl fmt::Debug for DataSegment { .field("size", &self.size) .field("init", &format_args!("{}", &self.init)) .field("readonly", &self.readonly) + .field("zeroed", &self.zeroed) .finish() } } @@ -288,12 +299,15 @@ impl DataSegment { let size = core::cmp::max(size, init_size); offset.checked_add(size).ok_or(DataSegmentError::OutOfBounds { offset, size })?; + let zeroed = init.is_empty() || init.as_slice().iter().all(|byte| byte == &0u8); + Ok(Self { link: Default::default(), offset, size, init, readonly, + zeroed, }) } @@ -316,6 +330,11 @@ impl DataSegment { pub const fn is_readonly(&self) -> bool { self.readonly } + + /// Returns true if this segment is zeroed at initialization + pub const fn is_zeroed(&self) -> bool { + self.zeroed + } } impl Eq for DataSegment {} impl PartialEq for DataSegment { diff --git a/hir/src/testing.rs b/hir/src/testing.rs index 3b6645ea..1eb65649 100644 --- a/hir/src/testing.rs +++ b/hir/src/testing.rs @@ -1,12 +1,27 @@ -use std::{mem, path::Path, slice, sync::Arc}; +use alloc::sync::Arc; +use core::{mem, slice}; +use std::path::Path; -use miden_diagnostics::Emitter; use midenc_session::{Options, Session}; -use super::*; +use crate::{ + diagnostics::{ + DefaultSourceManager, Emitter, SourceFile, SourceId, SourceManagerExt, SourceSpan, + }, + *, +}; const PAGE_SIZE: u32 = 64 * 1024; +fn setup_diagnostics() { + use crate::diagnostics::reporting::{self, ReportHandlerOpts}; + + let result = reporting::set_hook(Box::new(|_| Box::new(ReportHandlerOpts::new().build()))); + if result.is_ok() { + reporting::set_panic_hook(); + } +} + /// The base context used by all IR tests pub struct TestContext { pub session: Session, @@ -19,6 +34,8 @@ impl Default for TestContext { impl TestContext { /// Create a new test context with the given [Session] pub fn new(session: Session) -> Self { + setup_diagnostics(); + Self { session } } @@ -32,33 +49,41 @@ impl TestContext { ) -> Self { use midenc_session::InputFile; + setup_diagnostics(); + + let source_manager = Arc::new(DefaultSourceManager::default()); let session = Session::new( - Default::default(), - InputFile::from_path("test.hir").unwrap(), - None, + [InputFile::from_path("test.hir").unwrap()], None, None, + std::env::temp_dir(), options, emitter, + source_manager, ); Self { session } } /// Add a source file to this context - pub fn add>(&mut self, path: P) -> miden_diagnostics::SourceId { - self.session.codemap.add_file(path).expect("invalid source file") + pub fn add>(&self, path: P) -> Arc { + self.session + .source_manager + .load_file(path.as_ref()) + .expect("invalid source file") } /// Get a [SourceSpan] corresponding to the callsite of this function #[track_caller] #[inline(never)] - pub fn current_span(&self) -> miden_diagnostics::SourceSpan { + pub fn current_span(&self) -> SourceSpan { let caller = core::panic::Location::caller(); let caller_file = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().join(caller.file()); - let source_id = self.session.codemap.add_file(caller_file).expect("invalid source file"); - self.span(source_id, caller.line(), caller.column()) + let source_file = self.add(caller_file); + source_file + .line_column_to_span(caller.line(), caller.column()) + .expect("could not resolve source location") } /// Get a [SourceSpan] representing the location in the given source file (by id), line and @@ -66,16 +91,13 @@ impl TestContext { /// /// It is expected that line and column are 1-indexed, so they will be shifted to be 0-indexed, /// make sure to add 1 if you already have a 0-indexed line/column on hand - pub fn span( - &self, - source_id: miden_diagnostics::SourceId, - line: u32, - column: u32, - ) -> miden_diagnostics::SourceSpan { + pub fn span(&self, source_id: SourceId, line: u32, column: u32) -> SourceSpan { self.session - .codemap - .line_column_to_span(source_id, line - 1, column - 1) - .expect("invalid source location") + .source_manager + .get(source_id) + .ok() + .and_then(|file| file.line_column_to_span(line - 1, column - 1)) + .unwrap_or_default() } } @@ -88,8 +110,12 @@ macro_rules! current_file { #[macro_export] macro_rules! span { - ($codemap:ident, $src:ident) => { - $codemap.line_column_to_span($src, line!() - 1, column!() - 1).unwrap() + ($source_manager:ident, $src:ident) => { + $source_manager + .get($src) + .ok() + .and_then(|file| file.line_column_to_span(line!() - 1, column!() - 1)) + .unwrap() }; } @@ -507,6 +533,33 @@ pub fn mem_intrinsics(builder: &mut ProgramBuilder, _context: &TestContext) -> a ) .expect("unexpected global variable error"); + mb.declare_global_variable( + "HEAP_BASE", + Type::Ptr(Box::new(Type::U8)), + Linkage::External, + Some((2 * 65536u32).to_le_bytes().into()), + SourceSpan::UNKNOWN, + ) + .expect("unexpected global variable error"); + + mb.declare_global_variable( + "HEAP_TOP", + Type::Ptr(Box::new(Type::U8)), + Linkage::External, + Some((2 * 65536u32).to_le_bytes().into()), + SourceSpan::UNKNOWN, + ) + .expect("unexpected global variable error"); + + mb.declare_global_variable( + "HEAP_END", + Type::Ptr(Box::new(Type::U8)), + Linkage::External, + Some((4096 * 65536u32).to_le_bytes().into()), + SourceSpan::UNKNOWN, + ) + .expect("unexpected global variable error"); + // Define the alloc function let mut fb = mb.function("alloc", malloc_signature()).expect("unexpected symbol conflict"); diff --git a/hir/src/tests.rs b/hir/src/tests.rs index c043725b..2e1d44bf 100644 --- a/hir/src/tests.rs +++ b/hir/src/tests.rs @@ -38,68 +38,68 @@ fn inline_asm_builders_test() { }; let mut asm_builder = fb.ins().inline_asm(&[ptr, len], [Type::Felt], SourceSpan::UNKNOWN); - asm_builder.ins().push(Felt::ZERO); // [sum, ptr, len] - asm_builder.ins().push_u32(0); // [i, sum, ptr, len] - asm_builder.ins().dup(0); // [i, i, sum, ptr, len] - asm_builder.ins().dup(4); // [len, i, i, sum, ptr, len] - asm_builder.ins().lt_u32(); // [i < len, i, sum, ptr, len] + asm_builder.ins().push(Felt::ZERO, SourceSpan::UNKNOWN); // [sum, ptr, len] + asm_builder.ins().push_u32(0, SourceSpan::UNKNOWN); // [i, sum, ptr, len] + asm_builder.ins().dup(0, SourceSpan::UNKNOWN); // [i, i, sum, ptr, len] + asm_builder.ins().dup(4, SourceSpan::UNKNOWN); // [len, i, i, sum, ptr, len] + asm_builder.ins().lt_u32(SourceSpan::UNKNOWN); // [i < len, i, sum, ptr, len] // Now, build the loop body // // The state of the stack on entry is: [i, sum, ptr, len] - let mut lb = asm_builder.ins().while_true(); + let mut lb = asm_builder.ins().while_true(SourceSpan::UNKNOWN); // Calculate `i / 4` - lb.ins().dup(0); // [i, i, sum, ptr, len] - lb.ins().div_imm_u32(4); // [word_offset, i, sum, ptr, len] + lb.ins().dup(0, SourceSpan::UNKNOWN); // [i, i, sum, ptr, len] + lb.ins().div_imm_u32(4, SourceSpan::UNKNOWN); // [word_offset, i, sum, ptr, len] // Calculate the address for `array[i / 4]` - lb.ins().dup(3); // [ptr, word_offset, ..] - lb.ins().swap(1); - lb.ins().add_u32(Overflow::Checked); // [ptr + word_offset, i, sum, ptr, len] + lb.ins().dup(3, SourceSpan::UNKNOWN); // [ptr, word_offset, ..] + lb.ins().swap(1, SourceSpan::UNKNOWN); + lb.ins().add_u32(Overflow::Checked, SourceSpan::UNKNOWN); // [ptr + word_offset, i, sum, ptr, len] // Calculate the `i % 4` - lb.ins().dup(1); // [i, ptr + word_offset, i, sum, ptr, len] - lb.ins().mod_imm_u32(4); // [element_offset, ptr + word_offset, ..] + lb.ins().dup(1, SourceSpan::UNKNOWN); // [i, ptr + word_offset, i, sum, ptr, len] + lb.ins().mod_imm_u32(4, SourceSpan::UNKNOWN); // [element_offset, ptr + word_offset, ..] // Precalculate what elements of the word to drop, so that // we are only left with the specific element we wanted - lb.ins().push_u32(4); // [n, element_offset, ..] - let mut rb = lb.ins().repeat(3); - rb.ins().sub_imm_u32(1, Overflow::Checked); // [n = n - 1, element_offset] - rb.ins().dup(1); // [element_offset, n, element_offset, ..] - rb.ins().dup(1); // [n, element_offset, n, element_offset, ..] - rb.ins().lt_u32(); // [element_offset < n, n, element_offset, ..] - rb.ins().movdn(2); // [n, element_offset, element_offset < n] + lb.ins().push_u32(4, SourceSpan::UNKNOWN); // [n, element_offset, ..] + let mut rb = lb.ins().repeat(3, SourceSpan::UNKNOWN); + rb.ins().sub_imm_u32(1, Overflow::Checked, SourceSpan::UNKNOWN); // [n = n - 1, element_offset] + rb.ins().dup(1, SourceSpan::UNKNOWN); // [element_offset, n, element_offset, ..] + rb.ins().dup(1, SourceSpan::UNKNOWN); // [n, element_offset, n, element_offset, ..] + rb.ins().lt_u32(SourceSpan::UNKNOWN); // [element_offset < n, n, element_offset, ..] + rb.ins().movdn(2, SourceSpan::UNKNOWN); // [n, element_offset, element_offset < n] rb.build(); // [0, element_offset, element_offset < 1, element_offset < 2, ..] // Clean up the now unused operands we used to calculate which element we want - lb.ins().drop(); // [element_offset, ..] - lb.ins().drop(); // [element_offset < 1, ..] + lb.ins().drop(SourceSpan::UNKNOWN); // [element_offset, ..] + lb.ins().drop(SourceSpan::UNKNOWN); // [element_offset < 1, ..] // Load the word - lb.ins().movup(3); // [ptr + word_offset, element_offset < 1] - lb.ins().loadw(); // [word[0], word[1], word[2], word[3], element_offset < 1] + lb.ins().movup(3, SourceSpan::UNKNOWN); // [ptr + word_offset, element_offset < 1] + lb.ins().loadw(SourceSpan::UNKNOWN); // [word[0], word[1], word[2], word[3], element_offset < 1] // Select the element, `E`, that we want by conditionally dropping // elements on the operand stack with a carefully chosen sequence // of conditionals: E < N forall N in 0..=3 - lb.ins().movup(4); // [element_offset < 1, word[0], ..] - lb.ins().cdrop(); // [word[0 or 1], word[2], word[3], element_offset < 2] - lb.ins().movup(3); // [element_offset < 2, word[0 or 1], ..] - lb.ins().cdrop(); // [word[0 or 1 or 2], word[3], element_offset < 3] - lb.ins().movup(2); // [element_offset < 3, ..] - lb.ins().cdrop(); // [array[i], i, sum, ptr, len] - lb.ins().movup(2); // [sum, array[i], i, ptr, len] - lb.ins().add(); // [sum + array[i], i, ptr, len] - lb.ins().swap(1); // [i, sum + array[i], ptr, len] + lb.ins().movup(4, SourceSpan::UNKNOWN); // [element_offset < 1, word[0], ..] + lb.ins().cdrop(SourceSpan::UNKNOWN); // [word[0 or 1], word[2], word[3], element_offset < 2] + lb.ins().movup(3, SourceSpan::UNKNOWN); // [element_offset < 2, word[0 or 1], ..] + lb.ins().cdrop(SourceSpan::UNKNOWN); // [word[0 or 1 or 2], word[3], element_offset < 3] + lb.ins().movup(2, SourceSpan::UNKNOWN); // [element_offset < 3, ..] + lb.ins().cdrop(SourceSpan::UNKNOWN); // [array[i], i, sum, ptr, len] + lb.ins().movup(2, SourceSpan::UNKNOWN); // [sum, array[i], i, ptr, len] + lb.ins().add(SourceSpan::UNKNOWN); // [sum + array[i], i, ptr, len] + lb.ins().swap(1, SourceSpan::UNKNOWN); // [i, sum + array[i], ptr, len] // We've reached the end of the loop, but we need a copy of the // loop header here in order to use the expression `i < len` as // the condition for the loop - lb.ins().dup(0); // [i, i, sum + array[i], ptr, len] - lb.ins().dup(4); // [len, i, i, sum + array[i], ptr, len] - lb.ins().lt_u32(); // [i < len, i, sum + array[i], ptr, len] + lb.ins().dup(0, SourceSpan::UNKNOWN); // [i, i, sum + array[i], ptr, len] + lb.ins().dup(4, SourceSpan::UNKNOWN); // [len, i, i, sum + array[i], ptr, len] + lb.ins().lt_u32(SourceSpan::UNKNOWN); // [i < len, i, sum + array[i], ptr, len] // Finalize, it is at this point that validation will occur lb.build(); @@ -107,10 +107,10 @@ fn inline_asm_builders_test() { // Clean up the operand stack and return the sum // // The stack here is: [i, sum, ptr, len] - asm_builder.ins().swap(1); // [sum, i, ptr, len] - asm_builder.ins().movdn(3); // [i, ptr, len, sum] - let mut rb = asm_builder.ins().repeat(3); - rb.ins().drop(); + asm_builder.ins().swap(1, SourceSpan::UNKNOWN); // [sum, i, ptr, len] + asm_builder.ins().movdn(3, SourceSpan::UNKNOWN); // [i, ptr, len, sum] + let mut rb = asm_builder.ins().repeat(3, SourceSpan::UNKNOWN); + rb.ins().drop(SourceSpan::UNKNOWN); rb.build(); // [sum] // Finish the inline assembly block diff --git a/hir/src/value.rs b/hir/src/value.rs index eec14516..24ffa609 100644 --- a/hir/src/value.rs +++ b/hir/src/value.rs @@ -1,7 +1,6 @@ use cranelift_entity::{self as entity, entity_impl}; -use miden_diagnostics::SourceSpan; -use super::{Block, Inst, Type}; +use crate::{diagnostics::SourceSpan, Block, Inst, Type}; pub type ValueList = entity::EntityList; pub type ValueListPool = entity::ListPool; diff --git a/midenc-compile/Cargo.toml b/midenc-compile/Cargo.toml index a067ea23..6e166ab6 100644 --- a/midenc-compile/Cargo.toml +++ b/midenc-compile/Cargo.toml @@ -14,18 +14,18 @@ readme.workspace = true edition.workspace = true [dependencies] -anyhow.workspace = true clap.workspace = true +either.workspace = true log.workspace = true +intrusive-collections.workspace = true inventory.workspace = true -miden-assembly.workspace = true midenc-codegen-masm.workspace = true +miden-assembly = { workspace = true, features = ["std"] } miden-diagnostics.workspace = true midenc-frontend-wasm.workspace = true midenc-hir.workspace = true midenc-hir-analysis.workspace = true midenc-hir-transform.workspace = true midenc-session.workspace = true -rustc-hash.workspace = true thiserror.workspace = true wat.workspace = true diff --git a/midenc-compile/src/compiler.rs b/midenc-compile/src/compiler.rs index b701d28c..b50dfff1 100644 --- a/midenc-compile/src/compiler.rs +++ b/midenc-compile/src/compiler.rs @@ -1,162 +1,503 @@ -use std::{path::PathBuf, sync::Arc}; +use std::{ffi::OsString, path::PathBuf, sync::Arc}; -use clap::{Args, ColorChoice}; -use miden_diagnostics::{term::termcolor::ColorChoice as MDColorChoice, Emitter}; +use clap::{builder::ArgPredicate, ColorChoice, Parser}; use midenc_session::{ - InputFile, Options, OutputFile, OutputType, OutputTypeSpec, OutputTypes, ProjectType, Session, - TargetEnv, VerbosityFlag, Warnings, + diagnostics::{ColorChoice as MDColorChoice, DefaultSourceManager, Emitter}, + DebugInfo, InputFile, LinkLibrary, OptLevel, Options, OutputFile, OutputType, OutputTypeSpec, + OutputTypes, ProjectType, Session, TargetEnv, Verbosity, Warnings, }; /// Compile a program from WebAssembly or Miden IR, to Miden Assembly. -#[derive(Debug, Args)] +#[derive(Debug, Parser)] +#[command(name = "midenc")] pub struct Compiler { - /// The input file to compile + /// Write all intermediate compiler artifacts to `` + /// + /// Defaults to a directory named `target/midenc` in the current working directory + #[arg( + long, + value_name = "DIR", + env = "MIDENC_TARGET_DIR", + default_value = "target/midenc", + help_heading = "Output" + )] + pub target_dir: PathBuf, + /// The working directory for the compiler + /// + /// By default this will be the working directory the compiler is executed from + #[arg(long, value_name = "DIR", help_heading = "Output")] + pub working_dir: Option, + /// The path to the root directory of the Miden toolchain libraries /// - /// You may specify `-` to read from stdin, otherwise you must provide a path - #[arg(required(true), value_name = "FILE")] - input: InputFile, + /// By default this is assumed to be ~/.miden/toolchains/ + #[arg( + long, + value_name = "DIR", + env = "MIDENC_SYSROOT", + help_heading = "Compiler" + )] + pub sysroot: Option, + /// Write compiled output to compiler-chosen filename in `` + #[arg( + long, + short = 'O', + value_name = "DIR", + env = "MIDENC_OUT_DIR", + help_heading = "Output" + )] + pub output_dir: Option, + /// Write compiled output to `` + #[arg(long, short = 'o', value_name = "FILENAME", help_heading = "Output")] + pub output_file: Option, + /// Write output to stdout + #[arg(long, conflicts_with("output_file"), help_heading = "Output")] + pub stdout: bool, + /// Specify the name of the project being compiled + /// + /// The default is derived from the name of the first input file, or if reading from stdin, + /// the base name of the working directory. + #[arg( + long, + short = 'n', + value_name = "NAME", + default_value = None, + help_heading = "Diagnostics" + )] + pub name: Option, /// Specify what type and level of informational output to emit #[arg( long = "verbose", short = 'v', value_enum, value_name = "LEVEL", - next_line_help(true), - default_value_t = VerbosityFlag::Info, + default_value_t = Verbosity::Info, default_missing_value = "debug", + num_args(0..=1), help_heading = "Diagnostics" )] - verbosity: VerbosityFlag, + pub verbosity: Verbosity, /// Specify how warnings should be treated by the compiler. #[arg( long, short = 'W', value_enum, value_name = "LEVEL", - next_line_help(true), default_value_t = Warnings::All, default_missing_value = "all", + num_args(0..=1), help_heading = "Diagnostics" )] - warn: Warnings, + pub warn: Warnings, /// Whether, and how, to color terminal output - #[arg(long, value_enum, default_value_t = ColorChoice::Auto, default_missing_value = "auto", help_heading = "Diagnostics")] - color: ColorChoice, + #[arg( + long, + value_enum, + default_value_t = ColorChoice::Auto, + default_missing_value = "auto", + num_args(0..=1), + help_heading = "Diagnostics" + )] + pub color: ColorChoice, /// The target environment to compile for - #[arg(long, value_name = "TARGET", default_value_t = TargetEnv::Base, help_heading = "Compiler")] - target: TargetEnv, + #[arg( + long, + value_name = "TARGET", + default_value_t = TargetEnv::Base, + help_heading = "Compiler" + )] + pub target: TargetEnv, + /// Specify the function to call as the entrypoint for the program + #[arg(long, help_heading = "Compiler", hide(true))] + pub entrypoint: Option, /// Tells the compiler to produce an executable Miden program /// - /// When the target is `base` or `rollup`, this defaults to true + /// Implied by `--entrypoint`, defaults to true for non-rollup targets. #[arg( long = "exe", default_value_t = true, - default_value_if("target", "emu", Some("false")), - help_heading = "Compiler" + default_value_ifs([ + // When targeting the rollup, never build an executable + ("target", "rollup".into(), Some("false")), + // Setting the entrypoint implies building an executable in all other cases + ("entrypoint", ArgPredicate::IsPresent, Some("true")), + ]), + help_heading = "Linker" )] - is_program: bool, + pub is_program: bool, /// Tells the compiler to produce a Miden library /// - /// When the target is `emu`, this defaults to true + /// Implied by `--target rollup`, defaults to false. #[arg( long = "lib", conflicts_with("is_program"), + conflicts_with("entrypoint"), default_value_t = false, - default_value_if("target", "emu", Some("true")), - help_heading = "Compiler" + default_value_ifs([ + // When an entrypoint is specified, always set the default to false + ("entrypoint", ArgPredicate::IsPresent, Some("false")), + // When targeting the rollup, we always build as a library + ("target", "rollup".into(), Some("true")), + ]), + help_heading = "Linker" )] - is_library: bool, - /// Write all intermediate compiler artifacts to `` - /// - /// Defaults to a directory named `target` in the current working directory + pub is_library: bool, + /// Specify one or more search paths for link libraries requested via `-l` #[arg( - hide(true), - long, - value_name = "DIR", - env = "MIDENC_TARGET_DIR", - help_heading = "Output" + long = "search-path", + short = 'L', + value_name = "PATH", + help_heading = "Linker" )] - target_dir: Option, - /// The working directory for the compiler + pub search_path: Vec, + /// Link compiled projects to the specified library NAME. /// - /// By default this will be the working directory the compiler is executed from - #[arg(long, value_name = "DIR", help_heading = "Output")] - pub working_dir: Option, - /// Write output to compiler-chosen filename in `` + /// The optional KIND can be provided to indicate what type of library it is. + /// + /// NAME must either be an absolute path (with extension when applicable), or + /// a library namespace (no extension). The former will be used as the path + /// to load the library, without looking for it in the library search paths, + /// while the latter will be located in the search path based on its KIND. + /// + /// See below for valid KINDs: #[arg( - long, - value_name = "DIR", - env = "MIDENC_OUT_DIR", - help_heading = "Output" + long = "link-library", + short = 'l', + value_name = "[KIND=]NAME", + value_delimiter = ',', + default_value_ifs([ + ("target", "base", "std"), + ("target", "rollup", "std,base"), + ]), + next_line_help(true), + help_heading = "Linker" )] - output_dir: Option, - /// Write output to `` - #[arg(long, short = 'o', value_name = "FILENAME", help_heading = "Output")] - output_file: Option, - /// Write output to stdout - #[arg(long, conflicts_with("output_file"), help_heading = "Output")] - stdout: bool, + pub link_libraries: Vec, /// Specify one or more output types for the compiler to emit + /// + /// The format for SPEC is `KIND[=PATH]`. You can specify multiple items at + /// once by separating each SPEC with a comma, you can also pass this flag + /// multiple times. + /// + /// PATH must be a directory in which to place the outputs, or `-` for stdout. #[arg( long = "emit", value_name = "SPEC", value_delimiter = ',', + next_line_help(true), + help_heading = "Output" + )] + pub output_types: Vec, + /// Specify what level of debug information to emit in compilation artifacts + #[arg( + long, + value_enum, + value_name = "LEVEL", + next_line_help(true), + default_value_t = DebugInfo::Full, + default_missing_value = "full", + num_args(0..=1), help_heading = "Output" )] - output_types: Vec, + pub debug: DebugInfo, + /// Specify what type, and to what degree, of optimizations to apply to code during + /// compilation. + #[arg( + long = "optimize", + value_enum, + value_name = "LEVEL", + next_line_help(true), + default_value_t = OptLevel::None, + default_missing_value = "balanced", + num_args(0..=1), + help_heading = "Output" + )] + pub opt_level: OptLevel, + /// Set a codegen option + /// + /// Use `-C help` to print available options + #[arg( + long, + short = 'C', + value_name = "OPT[=VALUE]", + help_heading = "Compiler" + )] + pub codegen: Option, + /// Set an unstable compiler option + /// + /// Use `-Z help` to print available options + #[arg( + long, + short = 'Z', + value_name = "OPT[=VALUE]", + help_heading = "Compiler" + )] + pub unstable: Option, +} + +#[derive(Debug, Clone, Parser)] +#[command(name = "-C")] +pub struct CodegenOptions { + /// Tell the compiler to exit after it has parsed the inputs + #[arg( + long, + conflicts_with_all(["analyze_only", "link_only"]), + )] + pub parse_only: bool, + /// Tell the compiler to exit after it has performed semantic analysis on the inputs + #[arg( + long, + conflicts_with_all(["parse_only", "link_only"]), + )] + pub analyze_only: bool, + /// Tell the compiler to exit after linking the inputs, without generating Miden Assembly + #[arg( + long, + conflicts_with_all(["no_link"]), + )] + pub link_only: bool, + /// Tell the compiler to generate Miden Assembly from the inputs without linking them + #[arg(long)] + pub no_link: bool, +} + +#[derive(Debug, Clone, Parser)] +#[command(name = "-Z")] +pub struct UnstableOptions { /// Print the IR after each pass is applied #[arg(long, default_value_t = false, help_heading = "Passes")] - print_ir_after_all: bool, + pub print_ir_after_all: bool, /// Print the IR after running a specific pass - #[arg(long, value_name = "PASS", help_heading = "Passes")] - print_ir_after_pass: Option, + #[arg( + long, + value_name = "PASS", + value_delimiter = ',', + help_heading = "Passes" + )] + pub print_ir_after_pass: Vec, +} + +impl clap::builder::ValueParserFactory for CodegenOptions { + type Parser = CodegenOptionsParser; + + fn value_parser() -> Self::Parser { + CodegenOptionsParser + } } + +#[doc(hidden)] +#[derive(Clone)] +pub struct CodegenOptionsParser; +impl clap::builder::TypedValueParser for CodegenOptionsParser { + type Value = CodegenOptions; + + fn parse_ref( + &self, + _cmd: &clap::Command, + _arg: Option<&clap::Arg>, + value: &std::ffi::OsStr, + ) -> Result { + use clap::error::{Error, ErrorKind}; + + let command = ::command() + .no_binary_name(true) + .arg_required_else_help(true) + .help_template( + "\ +Available codegen options: + +Usage: midenc compile -C + +{all-args}{after-help} + +NOTE: When specifying these options, strip the leading '--'", + ); + + let option = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?; + let mut argv = match option.split_once('=') { + None => vec![option], + Some((opt, value)) => vec![opt, value], + }; + + if option == "help" || option == "h" { + argv.clear(); + argv.push("--help"); + } + + let mut matches = command.try_get_matches_from(argv).unwrap_or_else(|err| err.exit()); + let opts = ::from_arg_matches_mut(&mut matches) + .map_err(format_error::) + .unwrap_or_else(|err| err.exit()); + + Ok(opts) + } +} + +impl clap::builder::ValueParserFactory for UnstableOptions { + type Parser = UnstableOptionsParser; + + fn value_parser() -> Self::Parser { + UnstableOptionsParser + } +} + +#[doc(hidden)] +#[derive(Clone)] +pub struct UnstableOptionsParser; +impl clap::builder::TypedValueParser for UnstableOptionsParser { + type Value = UnstableOptions; + + fn parse_ref( + &self, + _cmd: &clap::Command, + _arg: Option<&clap::Arg>, + value: &std::ffi::OsStr, + ) -> Result { + use clap::error::{Error, ErrorKind}; + + let command = ::command() + .no_binary_name(true) + .arg_required_else_help(true) + .help_template( + "\ +Available unstable options: + +Usage: midenc compile -Z + +{all-args}{after-help} + +NOTE: When specifying these options, strip the leading '--'", + ); + + let option = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?; + let mut argv = match option.split_once('=') { + None => vec![option], + Some((opt, value)) => vec![opt, value], + }; + + if option == "help" || option == "h" { + argv.clear(); + argv.push("--help"); + } + + let mut matches = command.try_get_matches_from(argv).unwrap_or_else(|err| err.exit()); + let opts = ::from_arg_matches_mut(&mut matches) + .map_err(format_error::) + .unwrap_or_else(|err| err.exit()); + + Ok(opts) + } +} + impl Compiler { + /// Construct a [Compiler] programatically + pub fn new_session(inputs: I, emitter: Option>, argv: A) -> Session + where + I: IntoIterator, + A: IntoIterator, + S: Into + Clone, + { + let argv = [OsString::from("midenc")] + .into_iter() + .chain(argv.into_iter().map(|arg| arg.into())); + let command = ::command(); + let command = crate::register_flags(command); + let mut matches = command.try_get_matches_from(argv).unwrap_or_else(|err| err.exit()); + let compile_matches = matches.clone(); + + let opts = ::from_arg_matches_mut(&mut matches) + .map_err(format_error::) + .unwrap_or_else(|err| err.exit()); + + let inputs = inputs.into_iter().collect(); + opts.into_session(inputs, emitter).with_arg_matches(compile_matches) + } + /// Use this configuration to obtain a [Session] used for compilation - pub fn into_session(self, emitter: Option>) -> Session { + pub fn into_session( + self, + inputs: Vec, + emitter: Option>, + ) -> Session { let cwd = self .working_dir .unwrap_or_else(|| std::env::current_dir().expect("no working directory available")); - let tmp_dir = self.target_dir.unwrap_or_else(std::env::temp_dir); + // Map clap color choices to internal color choice let color = match self.color { ColorChoice::Auto => MDColorChoice::Auto, ColorChoice::Always => MDColorChoice::Always, ColorChoice::Never => MDColorChoice::Never, }; + // Determine if a specific output file has been requested + let output_file = match self.output_file { + Some(path) => Some(OutputFile::Real(path)), + None if self.stdout => Some(OutputFile::Stdout), + None => None, + }; + + // Initialize output types + let mut output_types = OutputTypes::new(self.output_types).unwrap_or_else(|err| err.exit()); + if output_types.is_empty() { + output_types.insert(OutputType::Mast, output_file.clone()); + } else if output_file.is_some() && output_types.get(&OutputType::Mast).is_some() { + // The -o flag overrides --emit + output_types.insert(OutputType::Mast, output_file.clone()); + } + + // Convert --exe or --lib to project type let project_type = if self.is_program { ProjectType::Program } else { ProjectType::Library }; - let mut output_types = OutputTypes::new(self.output_types); - if output_types.is_empty() { - output_types.insert(OutputType::Mast, None); - } - let mut options = Options::new(cwd) + + // Consolidate all compiler options + let mut options = Options::new(self.name, self.target, project_type, cwd, self.sysroot) .with_color(color) - .with_verbosity(self.verbosity.into()) + .with_verbosity(self.verbosity) .with_warnings(self.warn) + .with_debug_info(self.debug) + .with_optimization(self.opt_level) .with_output_types(output_types); - options.print_ir_after_all = self.print_ir_after_all; - options.print_ir_after_pass = self.print_ir_after_pass; + options.search_paths = self.search_path; + options.link_libraries = self.link_libraries; + options.entrypoint = self.entrypoint; + if let Some(unstable) = self.unstable { + options.print_ir_after_all = unstable.print_ir_after_all; + options.print_ir_after_pass = unstable.print_ir_after_pass; + } + if let Some(codegen) = self.codegen { + options.parse_only = codegen.parse_only; + options.analyze_only = codegen.analyze_only; + options.link_only = codegen.link_only; + options.no_link = codegen.no_link; + } - let output_file = match self.output_file { - Some(path) => Some(OutputFile::Real(path)), - None if self.stdout => Some(OutputFile::Stdout), - None => None, + // Establish --target-dir + let target_dir = if self.target_dir.is_absolute() { + self.target_dir + } else { + options.current_dir.join(&self.target_dir) }; + std::fs::create_dir_all(&target_dir).unwrap_or_else(|err| { + panic!("unable to create --target-dir '{}': {err}", target_dir.display()) + }); + let source_manager = Arc::new(DefaultSourceManager::default()); Session::new( - self.target, - self.input, + inputs, self.output_dir, output_file, - Some(tmp_dir), + target_dir, options, emitter, + source_manager, ) - .with_project_type(project_type) } } + +fn format_error(err: clap::Error) -> clap::Error { + let mut cmd = I::command(); + err.format(&mut cmd) +} diff --git a/midenc-compile/src/lib.rs b/midenc-compile/src/lib.rs index 7264fe41..43f450e5 100644 --- a/midenc-compile/src/lib.rs +++ b/midenc-compile/src/lib.rs @@ -2,71 +2,32 @@ mod compiler; mod stage; mod stages; -use std::sync::Arc; +use std::rc::Rc; -use midenc_codegen_masm as masm; -use midenc_hir::pass::AnalysisManager; -use midenc_session::{OutputType, Session}; +use either::Either::{self, Left, Right}; +use midenc_codegen_masm::{self as masm, MasmArtifact}; +use midenc_hir::{ + diagnostics::{miette, Diagnostic, IntoDiagnostic, Report, WrapErr}, + pass::AnalysisManager, +}; +use midenc_session::{OutputMode, Session}; -pub use self::{compiler::Compiler, stages::Compiled}; +pub use self::compiler::Compiler; use self::{stage::Stage, stages::*}; -pub type CompilerResult = Result; +pub type CompilerResult = Result; -#[derive(Debug, thiserror::Error)] -pub enum CompilerError { - /// An error was raised due to invalid command-line arguments or argument validation - #[error(transparent)] - Clap(#[from] clap::Error), - /// The compilation pipeline was stopped early - #[error("compilation was canceled by user")] - Stopped, - /// An invalid input was given to the compiler - #[error(transparent)] - InvalidInput(#[from] midenc_session::InvalidInputError), - /// An error occurred while parsing/translating a Wasm module from binary - #[error(transparent)] - WasmError(#[from] midenc_frontend_wasm::WasmError), - /// An error occurred while parsing/translating a Wasm module from text - #[error(transparent)] - WatError(#[from] wat::Error), - /// An error occurred while parsing an HIR module - #[error(transparent)] - Parsing(#[from] midenc_hir::parser::ParseError), - /// An error occurred while running an analysis - #[error(transparent)] - Analysis(#[from] midenc_hir::pass::AnalysisError), - /// An error occurred while rewriting an IR entity - #[error(transparent)] - Rewriting(#[from] midenc_hir::pass::RewriteError), - /// An error occurred while converting from one dialect to another - #[error(transparent)] - Conversion(#[from] midenc_hir::pass::ConversionError), - /// An error occurred while linking a program - #[error(transparent)] - Linker(#[from] midenc_hir::LinkerError), - /// An error occurred when reading a file - #[error(transparent)] - Io(#[from] std::io::Error), - /// An error occurred while compiling a program - #[error(transparent)] - Failed(#[from] anyhow::Error), - /// An error was emitted as a diagnostic, so we don't need to emit info to stdout - #[error("exited due to error: see diagnostics for details")] - Reported, -} -impl From for CompilerError { - fn from(err: midenc_hir::ModuleConflictError) -> CompilerError { - Self::Linker(midenc_hir::LinkerError::ModuleConflict(err.0)) - } -} +/// The compilation pipeline was stopped early +#[derive(Debug, thiserror::Error, Diagnostic)] +#[error("compilation was canceled by user")] +#[diagnostic()] +pub struct CompilerStopped; /// Register dynamic flags to be shown via `midenc help compile` pub fn register_flags(cmd: clap::Command) -> clap::Command { - use midenc_hir::RewritePassRegistration; use midenc_session::CompileFlag; - let cmd = inventory::iter::.into_iter().fold(cmd, |cmd, flag| { + inventory::iter::.into_iter().fold(cmd, |cmd, flag| { let arg = clap::Arg::new(flag.name) .long(flag.long.unwrap_or(flag.name)) .action(clap::ArgAction::from(flag.action)); @@ -100,93 +61,90 @@ pub fn register_flags(cmd: clap::Command) -> clap::Command { } else { arg }; + let arg = if let Some(value) = flag.hide { + arg.hide(value) + } else { + arg + }; cmd.arg(arg) - }); - - inventory::iter::>.into_iter().fold( - cmd, - |cmd, rewrite| { - let name = rewrite.name(); - let arg = clap::Arg::new(name) - .long(name) - .action(clap::ArgAction::SetTrue) - .help(rewrite.summary()) - .help_heading("Transformations"); - cmd.arg(arg) - }, - ) + }) } /// Run the compiler using the provided [Session] -pub fn compile(session: Arc) -> CompilerResult<()> { - let inputs = vec![session.input.clone()]; +pub fn compile(session: Rc) -> CompilerResult<()> { let mut analyses = AnalysisManager::new(); - match compile_inputs(inputs, &mut analyses, &session) { - Ok(Compiled::Program(ref program)) => { - if let Some(path) = session.emit_to(OutputType::Mast, None) { - log::warn!( - "skipping emission of MAST to {} as output type is not fully supported yet", - path.display() - ); - } - if session.should_emit(OutputType::Masm) { - for module in program.modules() { - session.emit(module)?; - } - } - } - Ok(Compiled::Modules(modules)) => { - let mut program = masm::Program::empty(); - for module in modules.into_iter() { - program.insert(module); - } - if let Some(path) = session.emit_to(OutputType::Mast, None) { - log::warn!( - "skipping emission of MAST to {} as output type is not fully supported yet", - path.display() - ); - } - if session.should_emit(OutputType::Masm) { - for module in program.modules() { - session.emit(module)?; - } - } - } - Err(CompilerError::Stopped) => return Ok(()), - Err(CompilerError::Reported) => return Err(CompilerError::Reported), - Err(err) => { - session.diagnostics.error(err); - session.diagnostics.abort_if_errors(); + match compile_inputs(session.inputs.clone(), &mut analyses, &session)? { + Artifact::Assembled(ref mast) => { + session + .emit(OutputMode::Text, mast) + .into_diagnostic() + .wrap_err("failed to pretty print 'mast' artifact")?; + session + .emit(OutputMode::Binary, mast) + .into_diagnostic() + .wrap_err("failed to serialize 'mast' artifact") } + Artifact::Linked(_) | Artifact::Lowered(_) => Ok(()), } - - Ok(()) } /// Same as `compile`, but return compiled artifacts to the caller -pub fn compile_to_memory(session: Arc) -> CompilerResult { - let inputs = vec![session.input.clone()]; +pub fn compile_to_memory(session: Rc) -> CompilerResult { let mut analyses = AnalysisManager::new(); - match compile_inputs(inputs, &mut analyses, &session) { - Ok(output) => Ok(output), - Err(err) => { - session.diagnostics.error(err.to_string()); - session.diagnostics.abort_if_errors(); - Err(CompilerError::Reported) + compile_inputs(session.inputs.clone(), &mut analyses, &session) +} + +/// Same as `compile_to_memory`, but allows registering a callback which will be used as an extra +/// compiler stage immediately after code generation and prior to assembly, if the linker was run. +pub fn compile_to_memory_with_pre_assembly_stage( + session: Rc, + stage: &mut F, +) -> CompilerResult +where + F: FnMut(MasmArtifact, &mut AnalysisManager, &Session) -> CompilerResult, +{ + type AssemblyInput = Either; + + let mut analyses = AnalysisManager::new(); + + let mut pre_assembly_stage = move |output: AssemblyInput, + analysis: &mut AnalysisManager, + session: &Session| { + match output { + Left(artifact) => stage(artifact, analysis, session).map(Left), + right @ Right(_) => Ok(right), } - } + }; + let mut stages = ParseStage + .next(SemanticAnalysisStage) + .next_optional(ApplyRewritesStage) + .collect(LinkerStage) + .next(CodegenStage) + .next( + &mut pre_assembly_stage + as &mut (dyn FnMut( + AssemblyInput, + &mut AnalysisManager, + &Session, + ) -> CompilerResult + + '_), + ) + .next(AssembleStage); + + stages.run(session.inputs.clone(), &mut analyses, &session) } fn compile_inputs( inputs: Vec, analyses: &mut AnalysisManager, session: &Session, -) -> CompilerResult { +) -> CompilerResult { let mut stages = ParseStage .next(SemanticAnalysisStage) .next_optional(ApplyRewritesStage) .collect(LinkerStage) - .next(CodegenStage); + .next(CodegenStage) + .next(AssembleStage); stages.run(inputs, analyses, session) } diff --git a/midenc-compile/src/stage.rs b/midenc-compile/src/stage.rs index ef3a16ed..5111377c 100644 --- a/midenc-compile/src/stage.rs +++ b/midenc-compile/src/stage.rs @@ -1,7 +1,7 @@ use midenc_hir::pass::AnalysisManager; use midenc_session::Session; -use crate::{CompilerError, CompilerResult}; +use crate::{CompilerResult, CompilerStopped}; /// This trait is implemented by a stage in the compiler pub trait Stage { @@ -47,6 +47,36 @@ pub trait Stage { } } +impl<'a, I, O> Stage for &'a mut dyn FnMut(I, &mut AnalysisManager, &Session) -> CompilerResult { + type Input = I; + type Output = O; + + #[inline] + fn run( + &mut self, + input: Self::Input, + analyses: &mut AnalysisManager, + session: &Session, + ) -> CompilerResult { + (*self)(input, analyses, session) + } +} + +impl Stage for Box CompilerResult> { + type Input = I; + type Output = O; + + #[inline] + fn run( + &mut self, + input: Self::Input, + analyses: &mut AnalysisManager, + session: &Session, + ) -> CompilerResult { + self(input, analyses, session) + } +} + /// This struct is used to chain multiple [Stage] together pub struct Chain { a: A, @@ -72,11 +102,11 @@ where session: &Session, ) -> CompilerResult { if !self.a.enabled(session) { - return Err(CompilerError::Stopped); + return Err(CompilerStopped.into()); } let output = self.a.run(input, analyses, session)?; if !self.b.enabled(session) { - return Err(CompilerError::Stopped); + return Err(CompilerStopped.into()); } self.b.run(output, analyses, session) } @@ -107,7 +137,7 @@ where session: &Session, ) -> CompilerResult { if !self.a.enabled(session) { - return Err(CompilerError::Stopped); + return Err(CompilerStopped.into()); } let output = self.a.run(input, analyses, session)?; if !self.b.enabled(session) { diff --git a/midenc-compile/src/stages/assemble.rs b/midenc-compile/src/stages/assemble.rs new file mode 100644 index 00000000..365b6875 --- /dev/null +++ b/midenc-compile/src/stages/assemble.rs @@ -0,0 +1,47 @@ +use super::*; + +/// The artifact produced by the full compiler pipeline. +/// +/// The type of artifact depends on what outputs were requested, and what options were specified. +pub enum Artifact { + /// The user requested MASM outputs, but + Lowered(masm::ModuleTree), + Linked(masm::MasmArtifact), + Assembled(masm::MastArtifact), +} +impl Artifact { + pub fn unwrap_mast(self) -> masm::MastArtifact { + match self { + Self::Assembled(mast) => mast, + Self::Linked(_) => { + panic!("expected 'mast' artifact, but got linked 'masm' artifact instead") + } + Self::Lowered(_) => { + panic!("expected 'mast' artifact, but got unlinked 'masm' artifact instead") + } + } + } +} + +/// Perform assembly of the generated Miden Assembly, producing MAST +pub struct AssembleStage; +impl Stage for AssembleStage { + type Input = Either; + type Output = Artifact; + + fn run( + &mut self, + input: Self::Input, + _analyses: &mut AnalysisManager, + session: &Session, + ) -> CompilerResult { + match input { + Left(masm_artifact) if session.should_assemble() => { + masm_artifact.assemble(session).map(Artifact::Assembled) + } + Left(masm_artifact) => Ok(Artifact::Linked(masm_artifact)), + Right(_masm_modules) if session.should_assemble() => todo!(), /* Ok(Artifact::Assembled(todo!())), */ + Right(masm_modules) => Ok(Artifact::Lowered(masm_modules)), + } + } +} diff --git a/midenc-compile/src/stages/codegen.rs b/midenc-compile/src/stages/codegen.rs index a3c8f170..719a66a2 100644 --- a/midenc-compile/src/stages/codegen.rs +++ b/midenc-compile/src/stages/codegen.rs @@ -1,19 +1,12 @@ -use midenc_codegen_masm::intrinsics; +use midenc_session::OutputType; use super::*; -/// The code generator may output either a single program, -/// ora collection of modules, depending on earlier stages. -pub enum Compiled { - Program(Box), - Modules(Vec>), -} - /// Perform code generation on the possibly-linked output of previous stages pub struct CodegenStage; impl Stage for CodegenStage { - type Input = MaybeLinked; - type Output = Compiled; + type Input = LinkerOutput; + type Output = Either; fn enabled(&self, session: &Session) -> bool { session.should_codegen() @@ -21,32 +14,50 @@ impl Stage for CodegenStage { fn run( &mut self, - input: Self::Input, + linker_output: Self::Input, analyses: &mut AnalysisManager, session: &Session, ) -> CompilerResult { - match input { - MaybeLinked::Linked(program) => { + let LinkerOutput { + linked, + masm: mut masm_modules, + } = linker_output; + match linked { + Left(program) => { let mut convert_to_masm = masm::ConvertHirToMasm::::default(); - let mut program = convert_to_masm.convert(program, analyses, session)?; + let mut artifact = convert_to_masm.convert(program, analyses, session)?; + + if session.should_emit(OutputType::Masm) { + for module in artifact.modules() { + session.emit(OutputMode::Text, module).into_diagnostic()?; + } + } + // Ensure intrinsics modules are linked for intrinsics_module in required_intrinsics_modules(session) { - program.insert(Box::new(intrinsics_module)); + artifact.insert(Box::new(intrinsics_module)); + } + // Link in any MASM inputs provided to the compiler + for module in masm_modules.into_iter() { + artifact.insert(module); } - Ok(Compiled::Program(program)) + + Ok(Left(artifact)) } - MaybeLinked::Unlinked(modules) => { + Right(ir) => { let mut convert_to_masm = masm::ConvertHirToMasm::::default(); - let mut masm_modules = Vec::with_capacity(modules.len()); - // Ensure intrinsics modules are linked - for intrinsics_module in required_intrinsics_modules(session) { - masm_modules.push(Box::new(intrinsics_module)); - } - for module in modules.into_iter() { + for module in ir.into_iter() { let masm_module = convert_to_masm.convert(module, analyses, session)?; - masm_modules.push(masm_module); + session + .emit(OutputMode::Text, masm_module.as_ref()) + .into_diagnostic() + .wrap_err_with(|| { + format!("failed to emit 'masm' output for '{}'", masm_module.id) + })?; + masm_modules.insert(masm_module); } - Ok(Compiled::Modules(masm_modules)) + + Ok(Right(masm_modules)) } } } @@ -54,8 +65,11 @@ impl Stage for CodegenStage { fn required_intrinsics_modules(session: &Session) -> Vec { vec![ - intrinsics::load("intrinsics::mem", &session.codemap).expect("undefined intrinsics module"), - intrinsics::load("intrinsics::i32", &session.codemap).expect("undefined intrinsics module"), - intrinsics::load("intrinsics::i64", &session.codemap).expect("undefined intrinsics module"), + masm::intrinsics::load("intrinsics::mem", &session.source_manager) + .expect("undefined intrinsics module"), + masm::intrinsics::load("intrinsics::i32", &session.source_manager) + .expect("undefined intrinsics module"), + masm::intrinsics::load("intrinsics::i64", &session.source_manager) + .expect("undefined intrinsics module"), ] } diff --git a/midenc-compile/src/stages/link.rs b/midenc-compile/src/stages/link.rs index 20fc4772..e5611684 100644 --- a/midenc-compile/src/stages/link.rs +++ b/midenc-compile/src/stages/link.rs @@ -1,44 +1,81 @@ -use midenc_session::ProjectType; - use super::*; -/// This type is used to represent the fact that depending on -/// flags provided to the compiler, we may or may not perform -/// the link, in which case we will just have a loose collection -/// of modules, not a [Program] -#[allow(clippy::vec_box)] -pub enum MaybeLinked { - Linked(Box), - Unlinked(Vec>), +pub enum LinkerInput { + Hir(Box), + Masm(Box), +} + +pub struct LinkerOutput { + /// The linked HIR program, or the unlinked HIR modules + pub linked: Either, hir::ModuleList>, + /// The set of MASM inputs to the linker + pub masm: masm::ModuleTree, } /// Link together one or more HIR modules into an HIR program pub struct LinkerStage; impl Stage for LinkerStage { - type Input = Vec>; - type Output = MaybeLinked; + type Input = Vec; + type Output = LinkerOutput; fn run( &mut self, - input: Self::Input, + inputs: Self::Input, _analyses: &mut AnalysisManager, session: &Session, ) -> CompilerResult { - // Temporary workaround for the issue that backend builds only Program for all - // OutputType::Masm output types. In case we need a library, we should not link the modules. - match session.project_type { - ProjectType::Program => { - if session.should_link() { - let mut builder = hir::ProgramBuilder::new(&session.diagnostics); - for module in input.into_iter() { - builder.add_module(module)?; - } - Ok(MaybeLinked::Linked(builder.link()?)) - } else { - Ok(MaybeLinked::Unlinked(input.into_iter().collect())) + let mut ir = hir::ModuleList::default(); + let mut masm = masm::ModuleTree::default(); + for input in inputs { + match input { + LinkerInput::Hir(module) => { + ir.push_back(module); + } + LinkerInput::Masm(module) => { + masm.insert(module); } } - ProjectType::Library => Ok(MaybeLinked::Unlinked(input.into_iter().collect())), + } + if session.should_link() { + // Construct a new [Program] builder + let mut builder = match session.options.entrypoint.as_deref() { + Some(entrypoint) => { + let entrypoint = entrypoint + .parse::() + .map_err(|err| Report::msg(format!("invalid --entrypoint: {err}")))?; + hir::ProgramBuilder::new(&session.diagnostics).with_entrypoint(entrypoint) + } + None => hir::ProgramBuilder::new(&session.diagnostics), + }; + + // Add our HIR modules + for module in ir.into_iter() { + builder.add_module(module)?; + } + + // Handle linking against ad-hoc MASM sources + for module in masm.iter() { + builder + .add_extern_module(module.id, module.functions().map(|f| f.name.function))?; + } + + // Load link libraries now + for link_lib in session.options.link_libraries.iter() { + builder.add_library(link_lib.load(session)?); + } + + let linked = Left(builder.link()?); + + if session.options.link_only { + Err(Report::from(CompilerStopped)) + } else { + Ok(LinkerOutput { linked, masm }) + } + } else { + Ok(LinkerOutput { + linked: Right(ir), + masm, + }) } } } diff --git a/midenc-compile/src/stages/mod.rs b/midenc-compile/src/stages/mod.rs index 22027d79..d60f86c5 100644 --- a/midenc-compile/src/stages/mod.rs +++ b/midenc-compile/src/stages/mod.rs @@ -1,3 +1,4 @@ +use either::Either::{self, *}; use midenc_codegen_masm as masm; use midenc_frontend_wasm as wasm; use midenc_hir::{ @@ -5,11 +6,15 @@ use midenc_hir::{ parser::ast, pass::{AnalysisManager, ConversionPass, RewritePass}, }; -use midenc_session::Session; +use midenc_session::{ + diagnostics::{IntoDiagnostic, Report, WrapErr}, + OutputMode, Session, +}; use super::Stage; -use crate::{CompilerError, CompilerResult}; +use crate::{CompilerResult, CompilerStopped}; +mod assemble; mod codegen; mod link; mod parse; @@ -17,8 +22,9 @@ mod rewrite; mod sema; pub use self::{ - codegen::{CodegenStage, Compiled}, - link::{LinkerStage, MaybeLinked}, + assemble::{Artifact, AssembleStage}, + codegen::CodegenStage, + link::{LinkerInput, LinkerOutput, LinkerStage}, parse::{ParseOutput, ParseStage}, rewrite::ApplyRewritesStage, sema::SemanticAnalysisStage, diff --git a/midenc-compile/src/stages/parse.rs b/midenc-compile/src/stages/parse.rs index 6cc64747..02c13429 100644 --- a/midenc-compile/src/stages/parse.rs +++ b/midenc-compile/src/stages/parse.rs @@ -1,6 +1,9 @@ use std::path::Path; -use midenc_session::InputFile; +use midenc_session::{ + diagnostics::{IntoDiagnostic, Spanned, WrapErr}, + InputFile, +}; use wasm::WasmTranslationConfig; use super::*; @@ -12,6 +15,8 @@ pub enum ParseOutput { Ast(Box), /// We parsed HIR from a Wasm module or other binary format Hir(Box), + /// We parsed MASM from a Miden Assembly module or other binary format + Masm(Box), } /// This stage of compilation is where we parse input files into the @@ -36,7 +41,11 @@ impl Stage for ParseStage { FileType::Hir => self.parse_ast_from_file(path.as_ref(), session), FileType::Wasm => self.parse_hir_from_wasm_file(path.as_ref(), session), FileType::Wat => self.parse_hir_from_wat_file(path.as_ref(), session), - unsupported => unreachable!("unsupported file type: {unsupported}"), + FileType::Masm => self.parse_masm_from_file(path.as_ref(), session), + FileType::Mast => Err(Report::msg( + "invalid input: mast libraries are not supported as inputs, did you mean to \ + use '-l'?", + )), }, InputType::Stdin { name, ref input } => match file_type { FileType::Hir => self.parse_ast_from_bytes(input, session), @@ -56,7 +65,13 @@ impl Stage for ParseStage { ..Default::default() }, ), - unsupported => unreachable!("unsupported file type: {unsupported}"), + FileType::Masm => { + self.parse_masm_from_bytes(name.as_str().unwrap(), input, session) + } + FileType::Mast => Err(Report::msg( + "invalid input: mast libraries are not supported as inputs, did you mean to \ + use '-l'?", + )), }, } } @@ -65,31 +80,20 @@ impl ParseStage { fn parse_ast_from_file(&self, path: &Path, session: &Session) -> CompilerResult { use std::io::Read; - let mut file = std::fs::File::open(path)?; + let mut file = std::fs::File::open(path).into_diagnostic()?; let mut bytes = Vec::with_capacity(1024); - file.read_to_end(&mut bytes)?; + file.read_to_end(&mut bytes).into_diagnostic()?; self.parse_ast_from_bytes(&bytes, session) } fn parse_ast_from_bytes(&self, bytes: &[u8], session: &Session) -> CompilerResult { - use std::io::{Error, ErrorKind}; - use midenc_hir::parser::Parser; - let source = core::str::from_utf8(bytes).map_err(|_| { - CompilerError::Io(Error::new(ErrorKind::InvalidInput, "input is not valid utf-8")) - })?; + let source = core::str::from_utf8(bytes) + .into_diagnostic() + .wrap_err("input is not valid utf-8")?; let parser = Parser::new(session); - match parser.parse_str(source).map(Box::new) { - Ok(ast) => { - session.emit(&ast)?; - Ok(ParseOutput::Ast(ast)) - } - Err(err) => { - session.diagnostics.emit(err); - Err(CompilerError::Reported) - } - } + parser.parse_str(source).map(Box::new).map(ParseOutput::Ast) } fn parse_hir_from_wasm_file( @@ -99,9 +103,11 @@ impl ParseStage { ) -> CompilerResult { use std::io::Read; - let mut file = std::fs::File::open(path)?; + let mut file = std::fs::File::open(path) + .into_diagnostic() + .wrap_err("could not open input for reading")?; let mut bytes = Vec::with_capacity(1024); - file.read_to_end(&mut bytes)?; + file.read_to_end(&mut bytes).into_diagnostic()?; let file_name = path.file_stem().unwrap().to_str().unwrap().to_owned(); let config = wasm::WasmTranslationConfig { source_name: file_name.into(), @@ -116,7 +122,7 @@ impl ParseStage { session: &Session, config: &WasmTranslationConfig, ) -> CompilerResult { - let module = wasm::translate(bytes, config, &session.diagnostics)?.unwrap_one_module(); + let module = wasm::translate(bytes, config, session)?.unwrap_one_module(); Ok(ParseOutput::Hir(module)) } @@ -131,8 +137,8 @@ impl ParseStage { source_name: file_name.into(), ..Default::default() }; - let wasm = wat::parse_file(path)?; - let module = wasm::translate(&wasm, &config, &session.diagnostics)?.unwrap_one_module(); + let wasm = wat::parse_file(path).into_diagnostic().wrap_err("failed to parse wat")?; + let module = wasm::translate(&wasm, &config, session)?.unwrap_one_module(); Ok(ParseOutput::Hir(module)) } @@ -143,9 +149,70 @@ impl ParseStage { session: &Session, config: &WasmTranslationConfig, ) -> CompilerResult { - let wasm = wat::parse_bytes(bytes)?; - let module = wasm::translate(&wasm, config, &session.diagnostics)?.unwrap_one_module(); + let wasm = wat::parse_bytes(bytes).into_diagnostic().wrap_err("failed to parse wat")?; + let module = wasm::translate(&wasm, config, session)?.unwrap_one_module(); Ok(ParseOutput::Hir(module)) } + + fn parse_masm_from_file(&self, path: &Path, session: &Session) -> CompilerResult { + use miden_assembly::{ + ast::{self, Ident, ModuleKind}, + LibraryNamespace, LibraryPath, + }; + use midenc_codegen_masm as masm; + + // Construct library path for MASM module + let module_name = Ident::new(path.file_stem().unwrap().to_str().unwrap()) + .into_diagnostic() + .wrap_err_with(|| { + format!( + "failed to construct valid module identifier from path '{}'", + path.display() + ) + })?; + let namespace = path + .parent() + .map(|dir| { + LibraryNamespace::User(dir.to_str().unwrap().to_string().into_boxed_str().into()) + }) + .unwrap_or(LibraryNamespace::Anon); + let name = LibraryPath::new_from_components(namespace, [module_name]); + + // Parse AST + let mut parser = ast::Module::parser(ModuleKind::Library); + let ast = parser.parse_file(name, path, &session.source_manager)?; + let span = ast.span(); + + // Convert to MASM IR representation + Ok(ParseOutput::Masm(Box::new(masm::Module::from_ast(&ast, span)))) + } + + fn parse_masm_from_bytes( + &self, + name: &str, + bytes: &[u8], + session: &Session, + ) -> CompilerResult { + use miden_assembly::{ + ast::{self, ModuleKind}, + LibraryPath, + }; + use midenc_codegen_masm as masm; + + let source = core::str::from_utf8(bytes) + .into_diagnostic() + .wrap_err_with(|| format!("input '{name}' contains invalid utf-8"))?; + + // Construct library path for MASM module + let name = LibraryPath::new(name).into_diagnostic()?; + + // Parse AST + let mut parser = ast::Module::parser(ModuleKind::Library); + let ast = parser.parse_str(name, source, &session.source_manager)?; + let span = ast.span(); + + // Convert to MASM IR representation + Ok(ParseOutput::Masm(Box::new(masm::Module::from_ast(&ast, span)))) + } } diff --git a/midenc-compile/src/stages/rewrite.rs b/midenc-compile/src/stages/rewrite.rs index 319e88dc..9dd92c9e 100644 --- a/midenc-compile/src/stages/rewrite.rs +++ b/midenc-compile/src/stages/rewrite.rs @@ -1,45 +1,55 @@ -use midenc_hir::{self as hir, RewritePassRegistration}; +use midenc_hir::RewritePassRegistration; use super::*; /// This stage applies all registered (and enabled) module-scoped rewrites to input HIR module(s) pub struct ApplyRewritesStage; impl Stage for ApplyRewritesStage { - type Input = Box; - type Output = Box; + type Input = LinkerInput; + type Output = LinkerInput; fn enabled(&self, session: &Session) -> bool { - !session.parse_only() + !session.analyze_only() } fn run( &mut self, - mut input: Self::Input, + input: Self::Input, analyses: &mut AnalysisManager, session: &Session, ) -> CompilerResult { - // Get all registered module rewrites and apply them in the order they appear - let mut registered = vec![]; - let matches = session.matches(); - for rewrite in inventory::iter::> { - let flag = rewrite.name(); - if matches.try_contains_id(flag).is_ok() { - if let Some(index) = matches.index_of(flag) { - let is_enabled = matches.get_flag(flag); - if is_enabled { - registered.push((index, rewrite.get())); + let output = match input { + input @ LinkerInput::Masm(_) => input, + LinkerInput::Hir(mut input) => { + // Get all registered module rewrites and apply them in the order they appear + let mut registered = vec![]; + let matches = session.matches(); + for rewrite in inventory::iter::> { + let flag = rewrite.name(); + if matches.try_contains_id(flag).is_ok() { + if let Some(index) = matches.index_of(flag) { + let is_enabled = matches.get_flag(flag); + if is_enabled { + registered.push((index, rewrite.get())); + } + } } } - } - } - registered.sort_unstable_by(|(a, _), (b, _)| a.cmp(b)); + registered.sort_unstable_by(|(a, _), (b, _)| a.cmp(b)); - // Populate the set of rewrite passes with default transformations, if there are no - // specific passes selected. - let mut rewrites = - midenc_codegen_masm::default_rewrites(registered.into_iter().map(|(_, r)| r), session); - rewrites.apply(&mut input, analyses, session)?; + // Populate the set of rewrite passes with default transformations, if there are no + // specific passes selected. + let mut rewrites = + masm::default_rewrites(registered.into_iter().map(|(_, r)| r), session); + rewrites.apply(&mut input, analyses, session)?; - Ok(input) + LinkerInput::Hir(input) + } + }; + if session.rewrite_only() { + Err(Report::from(CompilerStopped)) + } else { + Ok(output) + } } } diff --git a/midenc-compile/src/stages/sema.rs b/midenc-compile/src/stages/sema.rs index a6bdf298..1d4b78cd 100644 --- a/midenc-compile/src/stages/sema.rs +++ b/midenc-compile/src/stages/sema.rs @@ -7,11 +7,7 @@ use super::*; pub struct SemanticAnalysisStage; impl Stage for SemanticAnalysisStage { type Input = ParseOutput; - type Output = Box; - - fn enabled(&self, session: &Session) -> bool { - !session.parse_only() - } + type Output = LinkerInput; fn run( &mut self, @@ -19,17 +15,33 @@ impl Stage for SemanticAnalysisStage { analyses: &mut AnalysisManager, session: &Session, ) -> CompilerResult { - match input { + let parse_only = session.parse_only(); + let output = match input { + ParseOutput::Ast(ast) if parse_only => { + session.emit(OutputMode::Text, &ast).into_diagnostic()?; + return Err(CompilerStopped.into()); + } ParseOutput::Ast(ast) => { + session.emit(OutputMode::Text, &ast).into_diagnostic()?; let mut convert_to_hir = ast::ConvertAstToHir; let module = Box::new(convert_to_hir.convert(ast, analyses, session)?); - session.emit(&module)?; - Ok(module) + LinkerInput::Hir(module) + } + ParseOutput::Hir(module) if parse_only => { + session.emit(OutputMode::Text, &module).into_diagnostic()?; + return Err(CompilerStopped.into()); } - ParseOutput::Hir(module) => { - session.emit(&module)?; - Ok(module) + ParseOutput::Hir(module) => LinkerInput::Hir(module), + ParseOutput::Masm(masm) if parse_only => { + session.emit(OutputMode::Text, &masm).into_diagnostic()?; + return Err(CompilerStopped.into()); } + ParseOutput::Masm(masm) => LinkerInput::Masm(masm), + }; + if session.analyze_only() { + Err(CompilerStopped.into()) + } else { + Ok(output) } } } diff --git a/midenc-debug/Cargo.toml b/midenc-debug/Cargo.toml new file mode 100644 index 00000000..ee5095a2 --- /dev/null +++ b/midenc-debug/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "midenc-debug" +description = "An interactive debugger for Miden VM programs" +version = "0.0.1" +rust-version.workspace = true +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +categories.workspace = true +keywords.workspace = true +license.workspace = true +readme.workspace = true +edition.workspace = true + +[dependencies] +clap.workspace = true +log.workspace = true +glob = "0.3.1" +miden-assembly.workspace = true +miden-core.workspace = true +miden-processor.workspace = true +miden-stdlib.workspace = true +midenc-session.workspace = true +midenc-codegen-masm.workspace = true +midenc-hir.workspace = true +thiserror.workspace = true +proptest.workspace = true +ratatui = "0.28.0" +crossterm = { version = "0.28.1", features = ["event-stream"] } +tui-input = "0.10" +tokio = { version = "1.39.2", features = ["rt", "time", "macros"] } +tokio-util = "0.7.11" +futures = "0.3.30" +signal-hook = "0.3.17" +syntect = { version = "5.2.0", default-features = false, features = [ + "parsing", + "default-syntaxes", + "default-themes", + "yaml-load", + "regex-onig", +] } diff --git a/midenc-debug/README.md b/midenc-debug/README.md new file mode 100644 index 00000000..57ea888e --- /dev/null +++ b/midenc-debug/README.md @@ -0,0 +1,133 @@ +# Miden Debugger + +This crate implements a TUI-based interactive debugger for the Miden VM, designed to +interoperate with `midenc`. + +# Usage + +The easiest way to use the debugger, is via `midenc run`, and giving it a path to a +program compiled by `midenc compile`. + +Once started, you will be dropped into the main debugger UI, stopped at the first cycle of +the program. The UI is organized into pages and panes, with the main/home page being the +one you get dropped into when the debugger starts. The home page contains the following panes: + +* Source Code - displays source code for the current instruction, if available, with + the relevant line and span highlighted, with syntax highlighting (when available) +* Disassembly - displays the 5 most recently executed VM instructions, and the current + cycle count +* Stack Trace - displays a stack trace for the current instruction, if the program was + compiled with tracing enabled. If frames are unavailable, this pane may be empty. +* Operand Stack - displays the contents of the operand stack and its current depth +* Breakpoints - displays the set of current breakpoints, along with how many were hit + at the current instruction, when relevant + +On the home page, the following keyboard shortcuts are available: + +* `q` (quit) - exit the debugger +* `h`,`l` (pane movement) - cycle focus to the next pane (`h`) or previous pane (`l`) +* `s` (step) - advance the VM one cycle +* `n` (step next) - advance the VM to the next instruction (i.e. skip over all the cycles + of a multi-cycle instructions) +* `c` (continue) - advance the VM to the next breakpoint, or until execution terminates +* `d` (delete) - delete an item (where applicable, for example, the breakpoints pane) +* `:` (command prompt) - bring up the command prompt (described further below) + +When various panes have focus, additional keyboard shortcuts are available, in any pane +with a list of items, or multiple lines (e.g. source code), `j` and `k` (or the up and +down arrows) will select the next item up and down, respectively. As more features are +added, I will document their keyboard shortcuts below. + +## Commands + +From the home page, typing `:` will bring up the command prompt in the footer pane. + +You will know the prompt is active because the keyboard shortcuts normally shown there will +no longer appear, and instead you will see the prompt, starting with `:`. It supports any +of the following commands: + +* `q` or `quit` (quit) - exit the debugger +* `debug` (debug log) - display internal debug log for the debugger itself +* `reload` (reload current program) - reloads the program from disk, and resets the UI, with the + exception of breakpoints, which are retained across reloads +* `b` or `break` or `breakpoint` (breakpoints) - manage breakpoints (see [Breakpoints](#breakpoints)) +* `r` or `read` (read memory) - read values from linear memory (see [Reading Memory](#read-memory)) + +## Breakpoints + +One of the most common things you will want to do with the debugger is set and manage breakpoints. +Using the command prompt, you can create breakpoints by typing `b` (or `break` or `breakpoint`), +followed by a space, and then the desired breakpoint expression to do any of the following: + +* Break at an instruction which corresponds to a source file (or file and line) whose name/path + matches a pattern +* Break at the first instruction which causes a call frame to be pushed for a procedure whose name + matches a pattern +* Break any time a specific opcode is executed +* Break at the next instruction +* Break after N cycles +* Break at CYCLE + +The syntax for each of these can be found below, in the same order (shown using `b` as the command): + +* `b FILE[:LINE]` - where `FILE` is a glob pattern matched against the source file path. The `:LINE` + part is optional, as indicated by the brackets. If specified, only instructions with source + locations in `FILE` _and_ that occur on `LINE`, will cause a hit. +* `b in NAME` - where `NAME` is a glob pattern matched against the fully-qualified procedure name +* `b for OPCODE` - where `OPCODE` is the exact opcode you want to break on (including immediates) +* `b next` +* `b after N` +* `b at CYCLE` - if `CYCLE` is in the past, this breakpoint will have no effect + +When a breakpoint is hit, it will be highlighted, and the breakpoint window will display the number +of hit breakpoints in the lower right. + +After a breakpoint is hit, it expires if it is one of the following types: + +* Break after N +* Break at CYCLE +* Break next + +When a breakpoint expires, it is removed from the breakpoint list on the next cycle. + +## Read Memory + +Another useful diagnostic task is examining the contents of linear memory, to verify that expected +data has been written. You can do this via the command prompt, using `r` (or `read`), followed by +a space, and then the desired memory address and options: + +The format for read expressions is `:r ADDR [OPTIONS..]`, where `ADDR` is a memory address in +decimal or hexadecimal format (the latter requires the `0x` prefix). The `read` command supports +the following for `OPTIONS`: + +* `-m MODE` or `-mode MODE`, specify a memory addressing mode, either `words` or `bytes` (aliases + `w`/`b`, `word`/`byte`, or `miden`/`rust` are permitted). This determines whether `ADDR` is an + address in units of words or bytes. (default `words`) +* `-f FORMAT` or `-format FORMAT`, specify the format used to print integral values + (default `decimal`): + - `d`, `decimal`: print as decimal/base-10 + - `x`, `hex`, `hexadecimal`: print as hexadecimal/base-16 + - `b`, `bin`, `binary`, `bits`: print as binary/base-2 +* `-c N` or `-count N`, specify the number of units to read (default `1`) +* `-t TYPE` or `-type TYPE`, specify the type of value to read. In addition to modifying the default + for `-format`, and the unit size for `-count`, this will also attempt to interpret the memory as + a value of the specified type, and notify you if the value is invalid. The default type is `word`. + Available types are listed below: + - `iN` and `uN`: integer of `N` bits, with the `i` or `u` prefix determining its signedness. + `N` must be a power of two. + - `felt`: a field element + - `word`: a word, i.e. an array of four `felt` + - `ptr` or `pointer`: a 32-bit memory address (defaults `-format hex`) + - In the future, more types will be supported, namely structs/arrays + +Any invalid combination of options, or invalid syntax, will display an error in the status bar. + +# Roadmap + +The following are some features planned for the near future: + +* Watchpoints, i.e. cause execution to break when a memory store touches a specific address +* Conditional breakpoints, i.e. only trigger a breakpoint when an expression attached to it + evaluates to true +* More robust type support in the `read` command +* Display procedure locals and their contents in a dedicated pane diff --git a/midenc-debug/src/cli.rs b/midenc-debug/src/cli.rs new file mode 100644 index 00000000..8179dac2 --- /dev/null +++ b/midenc-debug/src/cli.rs @@ -0,0 +1,138 @@ +use std::{ffi::OsString, path::PathBuf, sync::Arc}; + +use clap::{ColorChoice, Parser}; +use midenc_session::{ + diagnostics::{ColorChoice as MDColorChoice, DefaultSourceManager, Emitter}, + InputFile, LinkLibrary, Options, ProjectType, Session, TargetEnv, +}; + +/// Run a compiled Miden program with the Miden VM +#[derive(Default, Debug, Parser)] +#[command(name = "debug")] +pub struct Debugger { + /// The working directory for the compiler + /// + /// By default this will be the working directory the compiler is executed from + #[arg(long, value_name = "DIR", help_heading = "Output")] + pub working_dir: Option, + /// The path to the root directory of the Miden toolchain libraries + /// + /// By default this is assumed to be ~/.miden/toolchains/ + #[arg( + long, + value_name = "DIR", + env = "MIDENC_SYSROOT", + help_heading = "Compiler" + )] + pub sysroot: Option, + /// Whether, and how, to color terminal output + #[arg( + long, + value_enum, + default_value_t = ColorChoice::Auto, + default_missing_value = "auto", + num_args(0..=1), + help_heading = "Diagnostics" + )] + pub color: ColorChoice, + /// The target environment to compile for + #[arg( + long, + value_name = "TARGET", + default_value_t = TargetEnv::Base, + help_heading = "Compiler" + )] + pub target: TargetEnv, + /// Specify the function to call as the entrypoint for the program + #[arg(long, help_heading = "Compiler", hide(true))] + pub entrypoint: Option, + /// Specify one or more search paths for link libraries requested via `-l` + #[arg( + long = "search-path", + short = 'L', + value_name = "PATH", + help_heading = "Linker" + )] + pub search_path: Vec, + /// Link compiled projects to the specified library NAME. + /// + /// The optional KIND can be provided to indicate what type of library it is. + /// + /// NAME must either be an absolute path (with extension when applicable), or + /// a library namespace (no extension). The former will be used as the path + /// to load the library, without looking for it in the library search paths, + /// while the latter will be located in the search path based on its KIND. + /// + /// See below for valid KINDs: + #[arg( + long = "link-library", + short = 'l', + value_name = "[KIND=]NAME", + value_delimiter = ',', + default_value_ifs([ + ("target", "base", "std"), + ("target", "rollup", "std,base"), + ]), + next_line_help(true), + help_heading = "Linker" + )] + pub link_libraries: Vec, +} + +impl Debugger { + /// Construct a [Compiler] programatically + pub fn new_session(inputs: I, emitter: Option>, argv: A) -> Session + where + I: IntoIterator, + A: IntoIterator, + S: Into + Clone, + { + let argv = [OsString::from("run")] + .into_iter() + .chain(argv.into_iter().map(|arg| arg.into())); + let mut matches = ::command() + .try_get_matches_from(argv) + .unwrap_or_else(|err| err.exit()); + + let opts = ::from_arg_matches_mut(&mut matches) + .map_err(format_error::) + .unwrap_or_else(|err| err.exit()); + + let inputs = inputs.into_iter().collect(); + opts.into_session(inputs, emitter) + } + + /// Use this configuration to obtain a [Session] used for compilation + pub fn into_session( + self, + inputs: Vec, + emitter: Option>, + ) -> Session { + let cwd = self + .working_dir + .unwrap_or_else(|| std::env::current_dir().expect("no working directory available")); + + // Map clap color choices to internal color choice + let color = match self.color { + ColorChoice::Auto => MDColorChoice::Auto, + ColorChoice::Always => MDColorChoice::Always, + ColorChoice::Never => MDColorChoice::Never, + }; + + // Consolidate all compiler options + let mut options = Options::new(None, self.target, ProjectType::Program, cwd, self.sysroot) + .with_color(color); + options.search_paths = self.search_path; + options.link_libraries = self.link_libraries; + options.entrypoint = self.entrypoint; + + let target_dir = std::env::temp_dir(); + let source_manager = Arc::new(DefaultSourceManager::default()); + Session::new(inputs, None, None, target_dir, options, emitter, source_manager) + } +} + +fn format_error(err: clap::Error) -> clap::Error { + let mut cmd = I::command(); + err.format(&mut cmd) +} diff --git a/midenc-debug/src/debug/breakpoint.rs b/midenc-debug/src/debug/breakpoint.rs new file mode 100644 index 00000000..1170909d --- /dev/null +++ b/midenc-debug/src/debug/breakpoint.rs @@ -0,0 +1,164 @@ +use std::{ops::Deref, str::FromStr}; + +use glob::Pattern; +use miden_processor::VmState; + +use super::ResolvedLocation; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Breakpoint { + pub id: u8, + pub creation_cycle: usize, + pub ty: BreakpointType, +} + +impl Default for Breakpoint { + fn default() -> Self { + Self { + id: 0, + creation_cycle: 0, + ty: BreakpointType::Step, + } + } +} + +impl Breakpoint { + /// Return the number of cycles this breakpoint indicates we should skip, or `None` if the + /// number of cycles is context-specific, or the breakpoint is triggered by something other + /// than cycle count. + pub fn cycles_to_skip(&self, current_cycle: usize) -> Option { + let cycles_passed = current_cycle - self.creation_cycle; + match &self.ty { + BreakpointType::Step => Some(1), + BreakpointType::StepN(n) => Some(n.saturating_sub(cycles_passed)), + BreakpointType::StepTo(to) if to >= ¤t_cycle => Some(to.abs_diff(current_cycle)), + _ => None, + } + } +} +impl Deref for Breakpoint { + type Target = BreakpointType; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.ty + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum BreakpointType { + /// Break at next cycle + Step, + /// Skip N cycles + StepN(usize), + /// Break at a given cycle + StepTo(usize), + /// Break at the first cycle of the next instruction + Next, + /// Break when any cycle corresponds to a source location whose file matches PATTERN + File(Pattern), + /// Break when any cycle corresponds to a source location whose file matches PATTERN and occurs + /// on LINE + Line { pattern: Pattern, line: u32 }, + /// Break anytime the given operation occurs + Opcode(miden_core::Operation), + /// Break when any cycle causes us to push a frame for PROCEDURE on the call stack + Called(Pattern), +} +impl BreakpointType { + /// Return true if this breakpoint indicates we should break for `current_op` + pub fn should_break_for(&self, current_op: &miden_core::Operation) -> bool { + match self { + Self::Opcode(op) => current_op == op, + _ => false, + } + } + + /// Return true if this breakpoint indicates we should break on entry to `procedure` + pub fn should_break_in(&self, procedure: &str) -> bool { + match self { + Self::Called(pattern) => pattern.matches(procedure), + _ => false, + } + } + + /// Return true if this breakpoint indicates we should break at `loc` + pub fn should_break_at(&self, loc: &ResolvedLocation) -> bool { + match self { + Self::File(pattern) => pattern.matches_path(loc.source_file.path()), + Self::Line { pattern, line } if line == &loc.line => { + pattern.matches_path(loc.source_file.path()) + } + _ => false, + } + } + + /// Returns true if this breakpoint is internal to the debugger (i.e. not creatable via :b) + pub fn is_internal(&self) -> bool { + matches!(self, BreakpointType::Next | BreakpointType::Step) + } + + /// Returns true if this breakpoint is removed upon being hit + pub fn is_one_shot(&self) -> bool { + matches!( + self, + BreakpointType::Next + | BreakpointType::Step + | BreakpointType::StepN(_) + | BreakpointType::StepTo(_) + ) + } +} + +impl FromStr for BreakpointType { + type Err = String; + + fn from_str(s: &str) -> Result { + let s = s.trim(); + + // b next + // b after {n} + // b for {opcode} + // b at {cycle} + // b in {procedure} + // b {file}[:{line}] + if s == "next" { + return Ok(BreakpointType::Next); + } + if let Some(n) = s.strip_prefix("after ") { + let n = n.trim().parse::().map_err(|err| { + format!("invalid breakpoint expression: could not parse cycle count: {err}") + })?; + return Ok(BreakpointType::StepN(n)); + } + if let Some(_opcode) = s.strip_prefix("for ") { + todo!() + } + if let Some(cycle) = s.strip_prefix("at ") { + let cycle = cycle.trim().parse::().map_err(|err| { + format!("invalid breakpoint expression: could not parse cycle value: {err}") + })?; + return Ok(BreakpointType::StepTo(cycle)); + } + if let Some(procedure) = s.strip_prefix("in ") { + let pattern = Pattern::new(procedure.trim()) + .map_err(|err| format!("invalid breakpoint expression: bad pattern: {err}"))?; + return Ok(BreakpointType::Called(pattern)); + } + match s.split_once(':') { + Some((file, line)) => { + let pattern = Pattern::new(file.trim()) + .map_err(|err| format!("invalid breakpoint expression: bad pattern: {err}"))?; + let line = line.trim().parse::().map_err(|err| { + format!("invalid breakpoint expression: could not parse line: {err}") + })?; + Ok(BreakpointType::Line { pattern, line }) + } + None => { + let pattern = Pattern::new(s.trim()) + .map_err(|err| format!("invalid breakpoint expression: bad pattern: {err}"))?; + Ok(BreakpointType::File(pattern)) + } + } + } +} diff --git a/midenc-debug/src/debug/memory.rs b/midenc-debug/src/debug/memory.rs new file mode 100644 index 00000000..ab52bb2e --- /dev/null +++ b/midenc-debug/src/debug/memory.rs @@ -0,0 +1,264 @@ +use std::{ + ffi::{OsStr, OsString}, + fmt, + str::FromStr, +}; + +use clap::{Parser, ValueEnum}; +use midenc_codegen_masm::NativePtr; +use midenc_hir::Type; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ReadMemoryExpr { + pub addr: NativePtr, + pub ty: Type, + pub count: u8, + pub mode: MemoryMode, + pub format: FormatType, +} +impl FromStr for ReadMemoryExpr { + type Err = String; + + fn from_str(s: &str) -> Result { + let argv = s.split_whitespace(); + let args = Read::parse(argv)?; + + let ty = args.ty.unwrap_or_else(|| Type::Array(Box::new(Type::Felt), 4)); + let addr = match args.mode { + MemoryMode::Word => NativePtr::new(args.addr, 0, 0), + MemoryMode::Byte => NativePtr::from_ptr(args.addr), + }; + Ok(Self { + addr, + ty, + count: args.count, + mode: args.mode, + format: args.format, + }) + } +} + +#[derive(Default, Debug, Parser)] +#[command(name = "read")] +pub struct Read { + /// The memory address to start reading from + #[arg(required(true), value_name = "ADDR", value_parser(parse_address))] + pub addr: u32, + /// The type of value to read from ADDR, defaults to 'word' + #[arg( + short = 't', + long = "type", + value_name = "TYPE", + value_parser(TypeParser) + )] + pub ty: Option, + /// The number of values to read + #[arg(short = 'c', long = "count", value_name = "N", default_value_t = 1)] + pub count: u8, + /// The addressing mode to use + #[arg( + short = 'm', + long = "mode", + value_name = "MODE", + default_value_t = MemoryMode::Word, + value_parser(MemoryModeParser) + )] + pub mode: MemoryMode, + /// The format to use when printing integral values + #[arg( + short = 'f', + long = "format", + value_name = "FORMAT", + default_value_t = FormatType::Decimal, + value_parser(FormatTypeParser) + )] + pub format: FormatType, +} +impl Read { + pub fn parse(argv: I) -> Result + where + I: IntoIterator, + S: Into + Clone, + { + let command = ::command() + .disable_help_flag(true) + .disable_version_flag(true) + .disable_colored_help(true) + .no_binary_name(true); + + let mut matches = command.try_get_matches_from(argv).map_err(|err| err.to_string())?; + ::from_arg_matches_mut(&mut matches) + .map_err(|err| err.to_string()) + } +} + +#[doc(hidden)] +#[derive(Clone)] +struct TypeParser; +impl clap::builder::TypedValueParser for TypeParser { + type Value = Type; + + fn parse_ref( + &self, + _cmd: &clap::Command, + _arg: Option<&clap::Arg>, + value: &OsStr, + ) -> Result { + use clap::error::{Error, ErrorKind}; + + let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?; + + Ok(match value { + "i1" => Type::I1, + "i8" => Type::I8, + "i16" => Type::I16, + "i32" => Type::I32, + "i64" => Type::I64, + "i128" => Type::I128, + "u8" => Type::U8, + "u16" => Type::U16, + "u32" => Type::U32, + "u64" => Type::U64, + "u128" => Type::U128, + "felt" => Type::Felt, + "word" => Type::Array(Box::new(Type::Felt), 4), + "ptr" | "pointer" => Type::Ptr(Box::new(Type::U32)), + _ => { + return Err(Error::raw( + ErrorKind::InvalidValue, + format!("invalid/unsupported type '{value}'"), + )) + } + }) + } +} + +fn parse_address(s: &str) -> Result { + if let Some(s) = s.strip_prefix("0x") { + u32::from_str_radix(s, 16).map_err(|err| format!("invalid memory address: {err}")) + } else if s.is_empty() { + Err(format!("expected memory address at '{s}'")) + } else { + s.parse::().map_err(|err| format!("invalid memory address: {err}")) + } +} + +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, ValueEnum)] +pub enum MemoryMode { + #[default] + Word, + Byte, +} +impl fmt::Display for MemoryMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Word => f.write_str("word"), + Self::Byte => f.write_str("byte"), + } + } +} +impl FromStr for MemoryMode { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "w" | "word" | "words" | "miden" => Ok(Self::Word), + "b" | "byte" | "bytes" | "rust" => Ok(Self::Byte), + _ => Err(format!("invalid memory mode '{s}'")), + } + } +} + +#[doc(hidden)] +#[derive(Clone)] +struct MemoryModeParser; +impl clap::builder::TypedValueParser for MemoryModeParser { + type Value = MemoryMode; + + fn possible_values( + &self, + ) -> Option + '_>> { + use clap::builder::PossibleValue; + Some(Box::new( + [ + PossibleValue::new("words").aliases(["w", "word", "miden"]), + PossibleValue::new("bytes").aliases(["b", "byte", "rust"]), + ] + .into_iter(), + )) + } + + fn parse_ref( + &self, + _cmd: &clap::Command, + _arg: Option<&clap::Arg>, + value: &OsStr, + ) -> Result { + use clap::error::{Error, ErrorKind}; + + let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?; + value.parse().map_err(|err| Error::raw(ErrorKind::InvalidValue, err)) + } +} + +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] +pub enum FormatType { + #[default] + Decimal, + Hex, + Binary, +} +impl fmt::Display for FormatType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Decimal => f.write_str("decimal"), + Self::Hex => f.write_str("hex"), + Self::Binary => f.write_str("binary"), + } + } +} +impl FromStr for FormatType { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "d" | "decimal" => Ok(Self::Decimal), + "x" | "hex" | "hexadecimal" => Ok(Self::Hex), + "b" | "bin" | "binary" | "bits" => Ok(Self::Binary), + _ => Err(format!("invalid format type '{s}'")), + } + } +} + +#[doc(hidden)] +#[derive(Clone)] +struct FormatTypeParser; +impl clap::builder::TypedValueParser for FormatTypeParser { + type Value = FormatType; + + fn possible_values( + &self, + ) -> Option + '_>> { + use clap::builder::PossibleValue; + Some(Box::new( + [ + PossibleValue::new("decimal").alias("d"), + PossibleValue::new("hex").aliases(["x", "hexadecimal"]), + PossibleValue::new("binary").aliases(["b", "bin", "bits"]), + ] + .into_iter(), + )) + } + + fn parse_ref( + &self, + _cmd: &clap::Command, + _arg: Option<&clap::Arg>, + value: &OsStr, + ) -> Result { + use clap::error::{Error, ErrorKind}; + + let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?; + value.parse().map_err(|err| Error::raw(ErrorKind::InvalidValue, err)) + } +} diff --git a/midenc-debug/src/debug/mod.rs b/midenc-debug/src/debug/mod.rs new file mode 100644 index 00000000..6272b98a --- /dev/null +++ b/midenc-debug/src/debug/mod.rs @@ -0,0 +1,9 @@ +mod breakpoint; +mod memory; +mod stacktrace; + +pub use self::{ + breakpoint::{Breakpoint, BreakpointType}, + memory::{FormatType, MemoryMode, ReadMemoryExpr}, + stacktrace::{CallFrame, CallStack, CurrentFrame, OpDetail, ResolvedLocation, StackTrace}, +}; diff --git a/midenc-debug/src/debug/stacktrace.rs b/midenc-debug/src/debug/stacktrace.rs new file mode 100644 index 00000000..1ac8cb6d --- /dev/null +++ b/midenc-debug/src/debug/stacktrace.rs @@ -0,0 +1,536 @@ +use std::{ + borrow::Cow, + cell::{OnceCell, RefCell}, + collections::{BTreeMap, BTreeSet, VecDeque}, + fmt, + path::Path, + rc::Rc, + sync::Arc, +}; + +use miden_core::{debuginfo::Location, AssemblyOp}; +use miden_processor::{Operation, RowIndex, VmState}; +use midenc_hir::demangle; +use midenc_session::{ + diagnostics::{SourceFile, SourceSpan}, + Session, +}; + +use crate::TraceEvent; + +#[derive(Debug, Clone)] +struct SpanContext { + frame_index: usize, + location: Option, +} + +pub struct CallStack { + trace_events: Rc>>, + contexts: BTreeSet>, + frames: Vec, + block_stack: Vec>, +} +impl CallStack { + pub fn new(trace_events: Rc>>) -> Self { + Self { + trace_events, + contexts: BTreeSet::default(), + frames: vec![], + block_stack: vec![], + } + } + + pub fn stacktrace<'a>( + &'a self, + recent: &'a VecDeque, + session: &'a Session, + ) -> StackTrace<'a> { + StackTrace::new(self, recent, session) + } + + pub fn current_frame(&self) -> Option<&CallFrame> { + self.frames.last() + } + + pub fn nth_frame(&self, n: usize) -> Option<&CallFrame> { + self.frames.iter().nth_back(n) + } + + pub fn frames(&self) -> &[CallFrame] { + self.frames.as_slice() + } + + pub fn next(&mut self, state: &VmState) { + if let Some(op) = state.op { + // Do not do anything if this cycle is a continuation of the last instruction + //let skip = state.asmop.as_ref().map(|op| op.cycle_idx() > 1).unwrap_or(false); + //if skip { + //return; + //} + + // Get the current procedure name context, if available + let procedure = + state.asmop.as_ref().map(|op| self.cache_procedure_name(op.context_name())); + /* + if procedure.is_none() { + dbg!(self.frames.last().map(|frame| frame.procedure.as_deref())); + dbg!(self.block_stack.last().map(|ctx| ctx.as_ref())); + } + */ + // Handle trace events for this cycle + let event = self.trace_events.borrow().get(&state.clk).copied(); + log::trace!("handling {op} at cycle {}: {:?}", state.clk, &event); + let is_frame_end = self.handle_trace_event(event, procedure.as_ref()); + + // These ops we do not record in call frame details + let ignore = matches!( + op, + Operation::Join + | Operation::Split + | Operation::Span + | Operation::Respan + | Operation::End + ); + + // Manage block stack + match op { + Operation::Span => { + if let Some(asmop) = state.asmop.as_ref() { + log::debug!("{asmop:#?}"); + self.block_stack.push(Some(SpanContext { + frame_index: self.frames.len().saturating_sub(1), + location: asmop.as_ref().location().cloned(), + })); + } else { + self.block_stack.push(None); + } + } + Operation::End => { + self.block_stack.pop(); + } + Operation::Join | Operation::Split => { + self.block_stack.push(None); + } + _ => (), + } + + if ignore || is_frame_end { + return; + } + + // Attempt to supply procedure context from the current span context, if needed + + // available + let (procedure, asmop) = match procedure { + proc @ Some(_) => { + (proc, state.asmop.as_ref().map(|info| info.as_ref()).map(Cow::Borrowed)) + } + None => match self.block_stack.last() { + Some(Some(span_ctx)) => { + let proc = + self.frames.get(span_ctx.frame_index).and_then(|f| f.procedure.clone()); + let info = state + .asmop + .as_ref() + .map(|info| info.as_ref()) + .map(Cow::Borrowed) + .or_else(|| { + let context_name = + proc.as_deref().unwrap_or("").to_string(); + let raw_asmop = miden_core::AssemblyOp::new( + span_ctx.location.clone(), + context_name, + 1, + op.to_string(), + false, + ); + Some(Cow::Owned(raw_asmop)) + }); + (proc, info) + } + _ => (None, state.asmop.as_ref().map(|info| info.as_ref()).map(Cow::Borrowed)), + }, + }; + + // Use the current frame's procedure context, if no other more precise context is + // available + let procedure = + procedure.or_else(|| self.frames.last().and_then(|f| f.procedure.clone())); + + // Do we have a frame? If not, create one + if self.frames.is_empty() { + self.frames.push(CallFrame::new(procedure.clone())); + } + + let current_frame = self.frames.last_mut().unwrap(); + + // Does the current frame have a procedure context/location? Use the one from this op if + // so + let procedure_context_updated = + current_frame.procedure.is_none() && procedure.is_some(); + if procedure_context_updated { + current_frame.procedure.clone_from(&procedure); + } + + // If this is the frame pointer prologue/epilogue drop the last op, which should be a + // push + if matches!(op, Operation::FmpUpdate) { + current_frame.context.pop_back(); + } + + // Push op into call frame if this is any op other than `nop` or frame setup + if !matches!(op, Operation::Noop | Operation::FmpUpdate) { + let cycle_idx = state.asmop.as_ref().map(|info| info.cycle_idx()).unwrap_or(1); + current_frame.push(op, cycle_idx, asmop.as_deref()); + } + + // Check if we should also update the caller frame's exec detail + let num_frames = self.frames.len(); + if procedure_context_updated && num_frames > 1 { + let caller_frame = &mut self.frames[num_frames - 2]; + if let Some(OpDetail::Exec { ref mut callee }) = caller_frame.context.back_mut() { + if callee.is_none() { + *callee = procedure; + } + } + } + } + } + + // Get or cache procedure name/context as `Rc` + fn cache_procedure_name(&mut self, context_name: &str) -> Rc { + match self.contexts.get(context_name) { + Some(name) => Rc::clone(name), + None => { + let name = Rc::from(context_name.to_string().into_boxed_str()); + self.contexts.insert(Rc::clone(&name)); + name + } + } + } + + fn handle_trace_event( + &mut self, + event: Option, + procedure: Option<&Rc>, + ) -> bool { + // Do we need to handle any frame events? + if let Some(event) = event { + match event { + TraceEvent::FrameStart => { + // Record the fact that we exec'd a new procedure in the op context + if let Some(current_frame) = self.frames.last_mut() { + current_frame.push_exec(procedure.cloned()); + } + // Push a new frame + self.frames.push(CallFrame::new(procedure.cloned())); + } + TraceEvent::Unknown(code) => log::debug!("unknown trace event: {code}"), + TraceEvent::FrameEnd => { + self.frames.pop(); + return true; + } + _ => (), + } + } + false + } +} + +pub struct CallFrame { + procedure: Option>, + context: VecDeque, + display_name: std::cell::OnceCell>, +} +impl CallFrame { + pub fn new(procedure: Option>) -> Self { + Self { + procedure, + context: Default::default(), + display_name: Default::default(), + } + } + + pub fn procedure(&self, strip_prefix: &str) -> Option> { + self.procedure.as_ref()?; + let name = self.display_name.get_or_init(|| { + let name = self.procedure.as_deref().unwrap(); + let name = match name.split_once("::") { + Some((module, rest)) if module == strip_prefix => demangle(rest), + _ => demangle(name), + }; + Rc::from(name.into_boxed_str()) + }); + Some(Rc::clone(name)) + } + + pub fn push_exec(&mut self, callee: Option>) { + if self.context.len() == 5 { + self.context.pop_front(); + } + + self.context.push_back(OpDetail::Exec { callee }); + } + + pub fn push(&mut self, opcode: Operation, cycle_idx: u8, op: Option<&AssemblyOp>) { + if cycle_idx > 1 { + // Should we ignore this op? + let skip = self.context.back().map(|detail| matches!(detail, OpDetail::Full { op, .. } | OpDetail::Basic { op } if op == &opcode)).unwrap_or(false); + if skip { + return; + } + } + + if self.context.len() == 5 { + self.context.pop_front(); + } + + match op { + Some(op) => { + let location = op.location().cloned(); + self.context.push_back(OpDetail::Full { + op: opcode, + location, + resolved: Default::default(), + }); + } + None => { + // If this instruction does not have a location, inherit the location + // of the previous op in the frame, if one is present + if let Some(loc) = self.context.back().map(|op| op.location().cloned()) { + self.context.push_back(OpDetail::Full { + op: opcode, + location: loc, + resolved: Default::default(), + }); + } else { + self.context.push_back(OpDetail::Basic { op: opcode }); + } + } + } + } + + pub fn last_location(&self) -> Option<&Location> { + match self.context.back() { + Some(OpDetail::Full { location, .. }) => { + let loc = location.as_ref(); + if loc.is_none() { + dbg!(&self.context); + } + loc + } + Some(OpDetail::Basic { .. }) => None, + Some(OpDetail::Exec { .. }) => { + let op = self.context.iter().rev().nth(1)?; + op.location() + } + None => None, + } + } + + pub fn last_resolved(&self, session: &Session) -> Option<&ResolvedLocation> { + self.context.back().and_then(|op| op.resolve(session)) + } + + pub fn recent(&self) -> &VecDeque { + &self.context + } +} + +#[derive(Debug, Clone)] +pub enum OpDetail { + Full { + op: Operation, + location: Option, + resolved: OnceCell>, + }, + Exec { + callee: Option>, + }, + Basic { + op: Operation, + }, +} +impl OpDetail { + pub fn callee(&self, strip_prefix: &str) -> Option> { + match self { + Self::Exec { callee: None } => Some(Box::from("")), + Self::Exec { + callee: Some(ref callee), + } => { + let name = match callee.split_once("::") { + Some((module, rest)) if module == strip_prefix => demangle(rest), + _ => demangle(callee), + }; + Some(name.into_boxed_str()) + } + _ => None, + } + } + + pub fn display(&self) -> String { + match self { + Self::Full { op, .. } | Self::Basic { op } => format!("{op}"), + Self::Exec { + callee: Some(callee), + } => format!("exec.{callee}"), + Self::Exec { callee: None } => "exec.".to_string(), + } + } + + pub fn opcode(&self) -> Operation { + match self { + Self::Full { op, .. } | Self::Basic { op } => *op, + Self::Exec { .. } => panic!("no opcode associated with execs"), + } + } + + pub fn location(&self) -> Option<&Location> { + match self { + Self::Full { ref location, .. } => location.as_ref(), + Self::Basic { .. } | Self::Exec { .. } => None, + } + } + + pub fn resolve(&self, session: &Session) -> Option<&ResolvedLocation> { + use midenc_session::diagnostics::SourceManagerExt; + + match self { + Self::Full { + location: Some(ref loc), + ref resolved, + .. + } => resolved + .get_or_init(|| { + let path = Path::new(loc.path.as_ref()); + let source_file = if path.exists() { + session.source_manager.load_file(path).ok()? + } else { + session.source_manager.get_by_path(loc.path.as_ref())? + }; + let span = SourceSpan::new(source_file.id(), loc.start..loc.end); + let file_line_col = source_file.location(span); + Some(ResolvedLocation { + source_file, + line: file_line_col.line, + col: file_line_col.column, + span, + }) + }) + .as_ref(), + _ => None, + } + } +} + +#[derive(Debug, Clone)] +pub struct ResolvedLocation { + pub source_file: Arc, + pub line: u32, + pub col: u32, + pub span: SourceSpan, +} +impl fmt::Display for ResolvedLocation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}:{}:{}", self.source_file.path().display(), self.line, self.col) + } +} + +pub struct CurrentFrame { + pub procedure: Option>, + pub location: Option, +} + +pub struct StackTrace<'a> { + callstack: &'a CallStack, + recent: &'a VecDeque, + session: &'a Session, + current_frame: Option, +} + +impl<'a> StackTrace<'a> { + pub fn new( + callstack: &'a CallStack, + recent: &'a VecDeque, + session: &'a Session, + ) -> Self { + let current_frame = callstack.current_frame().map(|frame| { + let location = frame.last_resolved(session).cloned(); + let procedure = frame.procedure(session.name()); + CurrentFrame { + procedure, + location, + } + }); + Self { + callstack, + recent, + session, + current_frame, + } + } + + pub fn current_frame(&self) -> Option<&CurrentFrame> { + self.current_frame.as_ref() + } +} + +impl<'a> fmt::Display for StackTrace<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use std::fmt::Write; + + let session_name = self.session.name(); + let num_frames = self.callstack.frames.len(); + + writeln!(f, "\nStack Trace:")?; + + for (i, frame) in self.callstack.frames.iter().enumerate() { + let is_top = i + 1 == num_frames; + let name = frame.procedure(session_name); + let name = name.as_deref().unwrap_or(""); + if is_top { + write!(f, " `-> {name}")?; + } else { + write!(f, " |-> {name}")?; + } + if let Some(resolved) = frame.last_resolved(self.session) { + write!(f, " in {resolved}")?; + } else { + write!(f, " in ")?; + } + if is_top { + // Print op context + let context_size = frame.context.len(); + writeln!(f, ":\n\nLast {context_size} Instructions (of current frame):")?; + for (i, op) in frame.context.iter().enumerate() { + let is_last = i + 1 == context_size; + if let Some(callee) = op.callee(session_name) { + write!(f, " | exec.{callee}")?; + } else { + write!(f, " | {}", &op.opcode())?; + } + if is_last { + writeln!(f, "\n `-> ")?; + } else { + f.write_char('\n')?; + } + } + + let context_size = self.recent.len(); + writeln!(f, "\n\nLast {context_size} Instructions (any frame):")?; + for (i, op) in self.recent.iter().enumerate() { + let is_last = i + 1 == context_size; + if is_last { + writeln!(f, " | {}", &op)?; + writeln!(f, " `-> ")?; + } else { + writeln!(f, " | {}", &op)?; + } + } + } else { + f.write_char('\n')?; + } + } + + Ok(()) + } +} diff --git a/midenc-debug/src/exec/executor.rs b/midenc-debug/src/exec/executor.rs new file mode 100644 index 00000000..1971d4c4 --- /dev/null +++ b/midenc-debug/src/exec/executor.rs @@ -0,0 +1,289 @@ +use std::{ + cell::RefCell, + collections::{BTreeMap, BTreeSet, VecDeque}, + rc::Rc, +}; + +use miden_assembly::Library as CompiledLibrary; +use miden_core::{Program, StackInputs, Word}; +use miden_processor::{ + AdviceInputs, ContextId, ExecutionError, Felt, MastForest, MemAdviceProvider, Process, + ProcessState, RowIndex, StackOutputs, VmState, VmStateIterator, +}; +use midenc_codegen_masm::NativePtr; +use midenc_hir::Type; +use midenc_session::Session; + +use super::{DebugExecutor, DebuggerHost, ExecutionTrace, TraceEvent}; +use crate::{debug::CallStack, felt::PopFromStack, TestFelt}; + +/// The [Executor] is responsible for executing a program with the Miden VM. +/// +/// It is used by either converting it into a [DebugExecutor], and using that to +/// manage execution step-by-step, such as is done by the debugger; or by running +/// the program to completion and obtaining an [ExecutionTrace], which can be used +/// to introspect the final program state. +pub struct Executor { + stack: StackInputs, + advice: AdviceInputs, + libraries: Vec, +} +impl Executor { + /// Construct an executor with the given arguments on the operand stack + pub fn new(args: Vec) -> Self { + Self { + stack: StackInputs::new(args).expect("invalid stack inputs"), + advice: AdviceInputs::default(), + libraries: Default::default(), + } + } + + /// Set the contents of memory for the shadow stack frame of the entrypoint + pub fn with_advice_inputs(&mut self, advice: AdviceInputs) -> &mut Self { + self.advice.extend(advice); + self + } + + /// Add a [CompiledLibrary] to the execution context + pub fn with_library(&mut self, lib: &CompiledLibrary) -> &mut Self { + self.libraries.push(lib.mast_forest().clone()); + self + } + + /// Convert this [Executor] into a [DebugExecutor], which captures much more information + /// about the program being executed, and must be stepped manually. + pub fn into_debug(mut self, program: &Program, session: &Session) -> DebugExecutor { + let advice_provider = MemAdviceProvider::from(self.advice); + let mut host = DebuggerHost::new(advice_provider); + for lib in core::mem::take(&mut self.libraries) { + host.load_mast_forest(lib); + } + + let trace_events: Rc>> = Rc::new(Default::default()); + let frame_start_events = Rc::clone(&trace_events); + host.register_trace_handler(TraceEvent::FrameStart, move |clk, event| { + frame_start_events.borrow_mut().insert(clk, event); + }); + let frame_end_events = Rc::clone(&trace_events); + host.register_trace_handler(TraceEvent::FrameEnd, move |clk, event| { + frame_end_events.borrow_mut().insert(clk, event); + }); + let assertion_events = Rc::clone(&trace_events); + host.register_assert_failed_tracer(move |clk, event| { + assertion_events.borrow_mut().insert(clk, event); + }); + + let mut process = Process::new_debug(program.kernel().clone(), self.stack, host); + let root_context = process.ctx(); + let result = process.execute(program); + let mut iter = VmStateIterator::new(process, result.clone()); + let mut callstack = CallStack::new(trace_events); + DebugExecutor { + iter, + result, + contexts: Default::default(), + root_context, + current_context: root_context, + callstack, + recent: VecDeque::with_capacity(5), + last: None, + cycle: 0, + stopped: false, + } + } + + /// Execute the given program until termination, producing a trace + pub fn capture_trace(mut self, program: &Program, session: &Session) -> ExecutionTrace { + let mut executor = self.into_debug(program, session); + while let Some(step) = executor.next() { + if step.is_err() { + return executor.into_execution_trace(); + } + } + executor.into_execution_trace() + } + + /// Execute the given program, producing a trace + #[track_caller] + pub fn execute(mut self, program: &Program, session: &Session) -> ExecutionTrace { + let mut executor = self.into_debug(program, session); + while let Some(step) = executor.next() { + if let Err(err) = step { + render_execution_error(err, &executor, session); + } + + /* + if let Some(op) = state.op { + match op { + miden_core::Operation::MLoad => { + let load_addr = last_state + .as_ref() + .map(|state| state.stack[0].as_int()) + .unwrap(); + let loaded = match state + .memory + .binary_search_by_key(&load_addr, |&(addr, _)| addr) + { + Ok(index) => state.memory[index].1[0].as_int(), + Err(_) => 0, + }; + //dbg!(load_addr, loaded, format!("{loaded:08x}")); + } + miden_core::Operation::MLoadW => { + let load_addr = last_state + .as_ref() + .map(|state| state.stack[0].as_int()) + .unwrap(); + let loaded = match state + .memory + .binary_search_by_key(&load_addr, |&(addr, _)| addr) + { + Ok(index) => { + let word = state.memory[index].1; + [ + word[0].as_int(), + word[1].as_int(), + word[2].as_int(), + word[3].as_int(), + ] + } + Err(_) => [0; 4], + }; + let loaded_bytes = { + let word = loaded; + let a = (word[0] as u32).to_be_bytes(); + let b = (word[1] as u32).to_be_bytes(); + let c = (word[2] as u32).to_be_bytes(); + let d = (word[3] as u32).to_be_bytes(); + let bytes = [ + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3], c[0], c[1], + c[2], c[3], d[0], d[1], d[2], d[3], + ]; + u128::from_be_bytes(bytes) + }; + //dbg!(load_addr, loaded, format!("{loaded_bytes:032x}")); + } + miden_core::Operation::MStore => { + let store_addr = last_state + .as_ref() + .map(|state| state.stack[0].as_int()) + .unwrap(); + let stored = match state + .memory + .binary_search_by_key(&store_addr, |&(addr, _)| addr) + { + Ok(index) => state.memory[index].1[0].as_int(), + Err(_) => 0, + }; + //dbg!(store_addr, stored, format!("{stored:08x}")); + } + miden_core::Operation::MStoreW => { + let store_addr = last_state + .as_ref() + .map(|state| state.stack[0].as_int()) + .unwrap(); + let stored = { + let memory = state + .memory + .iter() + .find_map(|(addr, word)| { + if addr == &store_addr { + Some(word) + } else { + None + } + }) + .unwrap(); + let a = memory[0].as_int(); + let b = memory[1].as_int(); + let c = memory[2].as_int(); + let d = memory[3].as_int(); + [a, b, c, d] + }; + let stored_bytes = { + let word = stored; + let a = (word[0] as u32).to_be_bytes(); + let b = (word[1] as u32).to_be_bytes(); + let c = (word[2] as u32).to_be_bytes(); + let d = (word[3] as u32).to_be_bytes(); + let bytes = [ + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3], c[0], c[1], + c[2], c[3], d[0], d[1], d[2], d[3], + ]; + u128::from_be_bytes(bytes) + }; + //dbg!(store_addr, stored, format!("{stored_bytes:032x}")); + } + _ => (), + } + } + */ + } + + executor.into_execution_trace() + } + + /// Execute a program, parsing the operand stack outputs as a value of type `T` + pub fn execute_into(self, program: &Program, session: &Session) -> T + where + T: PopFromStack + PartialEq, + { + let out = self.execute(program, session); + out.parse_result().expect("invalid result") + } +} + +#[track_caller] +fn render_execution_error( + err: ExecutionError, + execution_state: &DebugExecutor, + session: &Session, +) -> ! { + use midenc_hir::diagnostics::{miette::miette, reporting::PrintDiagnostic, LabeledSpan}; + + let stacktrace = execution_state.callstack.stacktrace(&execution_state.recent, session); + + eprintln!("{stacktrace}"); + + if let Some(last_state) = execution_state.last.as_ref() { + let stack = last_state.stack.iter().map(|elem| elem.as_int()); + let stack = midenc_hir::DisplayValues::new(stack); + let fmp = last_state.fmp.as_int(); + eprintln!( + "\nLast Known State (at most recent instruction which succeeded): + | Frame Pointer: {fmp} (starts at 2^30) + | Operand Stack: [{stack}] + " + ); + + let mut labels = vec![]; + if let Some(span) = stacktrace + .current_frame() + .and_then(|frame| frame.location.as_ref()) + .map(|loc| loc.span) + { + labels.push(LabeledSpan::new_with_span( + None, + span.start().to_usize()..span.end().to_usize(), + )); + } + let report = miette!( + labels = labels, + "program execution failed at step {step} (cycle {cycle}): {err}", + step = execution_state.cycle, + cycle = last_state.clk, + ); + let report = match stacktrace + .current_frame() + .and_then(|frame| frame.location.as_ref()) + .map(|loc| loc.source_file.clone()) + { + Some(source) => report.with_source_code(source), + None => report, + }; + + panic!("{}", PrintDiagnostic::new(report)); + } else { + panic!("program execution failed at step {step}: {err}", step = execution_state.cycle); + } +} diff --git a/midenc-debug/src/exec/host.rs b/midenc-debug/src/exec/host.rs new file mode 100644 index 00000000..576526e1 --- /dev/null +++ b/midenc-debug/src/exec/host.rs @@ -0,0 +1,113 @@ +use std::{collections::BTreeMap, sync::Arc}; + +use miden_core::crypto::hash::RpoDigest; +use miden_processor::{ + AdviceExtractor, AdviceInjector, AdviceProvider, ExecutionError, Host, HostResponse, + MastForest, MastForestStore, MemAdviceProvider, MemMastForestStore, ProcessState, RowIndex, +}; + +use super::{TraceEvent, TraceHandler}; + +/// This is an implementation of [Host] which is essentially [miden_processor::DefaultHost], +/// but extended with additional functionality for debugging, in particular it manages trace +/// events that record the entry or exit of a procedure call frame. +#[derive(Default)] +pub struct DebuggerHost { + adv_provider: MemAdviceProvider, + store: MemMastForestStore, + tracing_callbacks: BTreeMap>>, + on_assert_failed: Option>, +} +impl DebuggerHost { + /// Construct a new instance of [DebuggerHost] with the given advice provider. + pub fn new(adv_provider: MemAdviceProvider) -> Self { + Self { + adv_provider, + store: Default::default(), + tracing_callbacks: Default::default(), + on_assert_failed: None, + } + } + + /// Register a trace handler for `event` + pub fn register_trace_handler(&mut self, event: TraceEvent, callback: F) + where + F: FnMut(RowIndex, TraceEvent) + 'static, + { + let key = match event { + TraceEvent::AssertionFailed(None) => u32::MAX, + ev => ev.into(), + }; + self.tracing_callbacks.entry(key).or_default().push(Box::new(callback)); + } + + /// Register a handler to be called when an assertion in the VM fails + pub fn register_assert_failed_tracer(&mut self, callback: F) + where + F: FnMut(RowIndex, TraceEvent) + 'static, + { + self.on_assert_failed = Some(Box::new(callback)); + } + + /// Load `forest` into the MAST store for this host + pub fn load_mast_forest(&mut self, forest: MastForest) { + self.store.insert(forest); + } +} + +impl Host for DebuggerHost { + fn get_advice( + &mut self, + process: &P, + extractor: AdviceExtractor, + ) -> Result { + self.adv_provider.get_advice(process, &extractor) + } + + fn set_advice( + &mut self, + process: &P, + injector: AdviceInjector, + ) -> Result { + self.adv_provider.set_advice(process, &injector) + } + + fn get_mast_forest(&self, node_digest: &RpoDigest) -> Option> { + self.store.get(node_digest) + } + + fn on_trace( + &mut self, + process: &S, + trace_id: u32, + ) -> Result { + let event = TraceEvent::from(trace_id); + let clk = process.clk(); + if let Some(handlers) = self.tracing_callbacks.get_mut(&trace_id) { + for handler in handlers.iter_mut() { + handler(clk, event); + } + } + Ok(HostResponse::None) + } + + fn on_assert_failed(&mut self, process: &S, err_code: u32) -> ExecutionError { + let clk = process.clk(); + if let Some(handler) = self.on_assert_failed.as_mut() { + handler(clk, TraceEvent::AssertionFailed(core::num::NonZeroU32::new(err_code))); + } + let err_msg = match err_code { + midenc_hir::ASSERT_FAILED_ALIGNMENT => Some( + "failed alignment: use of memory address violates minimum alignment requirements \ + for that use" + .to_string(), + ), + _ => None, + }; + ExecutionError::FailedAssertion { + clk, + err_code, + err_msg, + } + } +} diff --git a/midenc-debug/src/exec/mod.rs b/midenc-debug/src/exec/mod.rs new file mode 100644 index 00000000..4e2d8b35 --- /dev/null +++ b/midenc-debug/src/exec/mod.rs @@ -0,0 +1,11 @@ +mod executor; +mod host; +mod state; +mod trace; + +pub use self::{ + executor::Executor, + host::DebuggerHost, + state::{Chiplets, DebugExecutor}, + trace::{ExecutionTrace, TraceEvent, TraceHandler}, +}; diff --git a/midenc-debug/src/exec/state.rs b/midenc-debug/src/exec/state.rs new file mode 100644 index 00000000..301015f3 --- /dev/null +++ b/midenc-debug/src/exec/state.rs @@ -0,0 +1,127 @@ +use std::collections::{BTreeSet, VecDeque}; + +use miden_core::Word; +use miden_processor::{ + ContextId, ExecutionError, Operation, RowIndex, StackOutputs, VmState, VmStateIterator, +}; + +use super::ExecutionTrace; +use crate::{CallStack, TestFelt}; + +/// A special version of [crate::Executor] which provides finer-grained control over execution, +/// and captures a ton of information about the program being executed, so as to make it possible +/// to introspect everything about the program and the state of the VM at a given cycle. +/// +/// This is used by the debugger to execute programs, and provide all of the functionality made +/// available by the TUI. +pub struct DebugExecutor { + /// The underlying [VmStateIterator] being driven + pub iter: VmStateIterator, + /// The final outcome of the program being executed + pub result: Result, + /// The set of contexts allocated during execution so far + pub contexts: BTreeSet, + /// The root context + pub root_context: ContextId, + /// The current context at `cycle` + pub current_context: ContextId, + /// The current call stack + pub callstack: CallStack, + /// A sliding window of the last 5 operations successfully executed by the VM + pub recent: VecDeque, + /// The most recent [VmState] produced by the [VmStateIterator] + pub last: Option, + /// The current clock cycle + pub cycle: usize, + /// Whether or not execution has terminated + pub stopped: bool, +} + +impl DebugExecutor { + /// Advance the program state by one cycle. + /// + /// If the program has already reached its termination state, it returns the same result + /// as the previous time it was called. + pub fn step(&mut self) -> Result<(), ExecutionError> { + if self.stopped { + return self.result.as_ref().map(|_| ()).map_err(|err| err.clone()); + } + match self.iter.next() { + Some(Ok(state)) => { + self.cycle += 1; + if self.current_context != state.ctx { + self.contexts.insert(state.ctx); + self.current_context = state.ctx; + } + + if let Some(op) = state.op { + if self.recent.len() == 5 { + self.recent.pop_front(); + } + self.recent.push_back(op); + } + + self.callstack.next(&state); + + self.last = Some(state); + + Ok(()) + } + Some(Err(err)) => { + self.stopped = true; + Err(err) + } + None => { + self.stopped = true; + Ok(()) + } + } + } + + /// Consume the [DebugExecutor], converting it into an [ExecutionTrace] at the current cycle. + pub fn into_execution_trace(self) -> ExecutionTrace { + let last_cycle = self.cycle; + let (_, _, _, chiplets, _) = self.iter.into_parts(); + let outputs = self + .result + .map(|res| res.stack().iter().copied().map(TestFelt).collect::>()) + .unwrap_or_default(); + ExecutionTrace { + root_context: self.root_context, + last_cycle: RowIndex::from(last_cycle), + chiplets: Chiplets::new(move |context, clk| chiplets.get_mem_state_at(context, clk)), + outputs, + } + } +} +impl core::iter::FusedIterator for DebugExecutor {} +impl Iterator for DebugExecutor { + type Item = Result; + + #[inline] + fn next(&mut self) -> Option { + if self.stopped { + return None; + } + match self.step() { + Ok(_) => self.last.clone().map(Ok), + Err(err) => Some(Err(err)), + } + } +} + +// Dirty, gross, horrible hack until miden_processor::chiplets::Chiplets is exported +#[allow(clippy::type_complexity)] +pub struct Chiplets(Box Vec<(u64, Word)>>); +impl Chiplets { + pub fn new(callback: F) -> Self + where + F: Fn(ContextId, RowIndex) -> Vec<(u64, Word)> + 'static, + { + Self(Box::new(callback)) + } + + pub fn get_mem_state_at(&self, context: ContextId, clk: RowIndex) -> Vec<(u64, Word)> { + (self.0)(context, clk) + } +} diff --git a/midenc-debug/src/exec/trace.rs b/midenc-debug/src/exec/trace.rs new file mode 100644 index 00000000..fe707c94 --- /dev/null +++ b/midenc-debug/src/exec/trace.rs @@ -0,0 +1,270 @@ +use std::{ + cell::RefCell, + collections::{BTreeMap, BTreeSet, VecDeque}, + rc::Rc, +}; + +use miden_assembly::Library as CompiledLibrary; +use miden_core::{Program, StackInputs, Word}; +use miden_processor::{ + AdviceInputs, ContextId, ExecutionError, Felt, MastForest, MemAdviceProvider, Process, + ProcessState, RowIndex, StackOutputs, VmState, VmStateIterator, +}; +use midenc_codegen_masm::NativePtr; +pub use midenc_hir::TraceEvent; +use midenc_hir::Type; +use midenc_session::Session; + +use super::Chiplets; +use crate::{debug::CallStack, felt::PopFromStack, DebuggerHost, TestFelt}; + +/// A callback to be executed when a [TraceEvent] occurs at a given clock cycle +pub type TraceHandler = dyn FnMut(RowIndex, TraceEvent); + +/// Occurs when an attempt to read memory of the VM fails +#[derive(Debug, thiserror::Error)] +pub enum MemoryReadError { + #[error("attempted to read beyond end of linear memory")] + OutOfBounds, + #[error("unaligned reads are not supported yet")] + UnalignedRead, +} + +/// An [ExecutionTrace] represents a final state of a program that was executed. +/// +/// It can be used to examine the program results, and the memory of the program at +/// any cycle up to the last cycle. It is typically used for those purposes once +/// execution of a program terminates. +pub struct ExecutionTrace { + pub(super) root_context: ContextId, + pub(super) last_cycle: RowIndex, + pub(super) chiplets: Chiplets, + pub(super) outputs: VecDeque, +} + +impl ExecutionTrace { + /// Parse the program outputs on the operand stack as a value of type `T` + pub fn parse_result(&self) -> Option + where + T: PopFromStack, + { + let mut stack = self.outputs.clone(); + T::try_pop(&mut stack) + } + + /// Consume the [ExecutionTrace], extracting just the outputs on the operand stack + #[inline] + pub fn into_outputs(self) -> VecDeque { + self.outputs + } + + /// Read the word at the given Miden memory address + pub fn read_memory_word(&self, addr: u32) -> Option { + self.read_memory_word_in_context(addr, self.root_context, self.last_cycle) + } + + /// Read the word at the given Miden memory address, under `ctx`, at cycle `clk` + pub fn read_memory_word_in_context( + &self, + addr: u32, + ctx: ContextId, + clk: RowIndex, + ) -> Option { + use miden_core::FieldElement; + + let words = self.chiplets.get_mem_state_at(ctx, clk); + let addr = addr as u64; + match words.binary_search_by_key(&addr, |item| item.0) { + Ok(index) => Some(words[index].1), + Err(_) => Some([Felt::ZERO; 4]), + } + } + + /// Read the word at the given Miden memory address and element offset + #[track_caller] + pub fn read_memory_element(&self, addr: u32, index: u8) -> Option { + self.read_memory_element_in_context(addr, index, self.root_context, self.last_cycle) + } + + /// Read the word at the given Miden memory address and element offset, under `ctx`, at cycle + /// `clk` + #[track_caller] + pub fn read_memory_element_in_context( + &self, + addr: u32, + index: u8, + ctx: ContextId, + clk: RowIndex, + ) -> Option { + assert!(index < 4, "invalid element index"); + self.read_memory_word_in_context(addr, ctx, clk) + .map(|word| word[index as usize]) + } + + /// Read a raw byte vector from `addr`, under `ctx`, at cycle `clk`, sufficient to hold a value + /// of type `ty` + pub fn read_bytes_for_type( + &self, + addr: NativePtr, + ty: &Type, + ctx: ContextId, + clk: RowIndex, + ) -> Result, MemoryReadError> { + const U32_MASK: u64 = u32::MAX as u64; + let size = ty.size_in_bytes(); + let mut buf = Vec::with_capacity(size); + + let size_in_words = ty.size_in_words(); + let mut elems = Vec::with_capacity(size_in_words); + + if addr.is_word_aligned() { + for i in 0..size_in_words { + let addr = addr.waddr.checked_add(i as u32).ok_or(MemoryReadError::OutOfBounds)?; + elems.extend(self.read_memory_word_in_context(addr, ctx, clk).unwrap_or_default()); + } + } else if addr.is_element_aligned() { + let leading = + self.read_memory_word_in_context(addr.waddr, ctx, clk).unwrap_or_default(); + for item in leading.into_iter().skip(addr.index as usize) { + elems.push(item); + } + for i in 1..size_in_words { + let addr = addr.waddr.checked_add(i as u32).ok_or(MemoryReadError::OutOfBounds)?; + elems.extend(self.read_memory_word_in_context(addr, ctx, clk).unwrap_or_default()); + } + let trailing_addr = addr + .waddr + .checked_add(size_in_words as u32) + .ok_or(MemoryReadError::OutOfBounds)?; + let trailing = + self.read_memory_word_in_context(trailing_addr, ctx, clk).unwrap_or_default(); + for item in trailing.into_iter().take(4 - addr.index as usize) { + elems.push(item); + } + } else { + return Err(MemoryReadError::UnalignedRead); + } + + let mut needed = size - buf.len(); + for elem in elems { + let bytes = ((elem.as_int() & U32_MASK) as u32).to_be_bytes(); + let take = core::cmp::min(needed, 4); + buf.extend(&bytes[0..take]); + needed -= take; + } + + Ok(buf) + } + + /// Read a value of the given type, given an address in Rust's address space + #[track_caller] + pub fn read_from_rust_memory(&self, addr: u32) -> Option + where + T: core::any::Any + PopFromStack, + { + self.read_from_rust_memory_in_context(addr, self.root_context, self.last_cycle) + } + + /// Read a value of the given type, given an address in Rust's address space, under `ctx`, at + /// cycle `clk` + #[track_caller] + pub fn read_from_rust_memory_in_context( + &self, + addr: u32, + ctx: ContextId, + clk: RowIndex, + ) -> Option + where + T: core::any::Any + PopFromStack, + { + use core::any::TypeId; + + let ptr = NativePtr::from_ptr(addr); + if TypeId::of::() == TypeId::of::() { + assert_eq!(ptr.offset, 0, "cannot read values of type Felt from unaligned addresses"); + let elem = self.read_memory_element_in_context(ptr.waddr, ptr.index, ctx, clk)?; + let mut stack = VecDeque::from([TestFelt(elem)]); + return Some(T::try_pop(&mut stack).unwrap_or_else(|| { + panic!( + "could not decode a value of type {} from {}", + core::any::type_name::(), + addr + ) + })); + } + match core::mem::size_of::() { + n if n < 4 => { + if (4 - ptr.offset as usize) < n { + todo!("unaligned, split read") + } + let elem = self.read_memory_element_in_context(ptr.waddr, ptr.index, ctx, clk)?; + let elem = if ptr.offset > 0 { + let mask = 2u64.pow(32 - (ptr.offset as u32 * 8)) - 1; + let elem = elem.as_int() & mask; + Felt::new(elem << (ptr.offset as u64 * 8)) + } else { + elem + }; + let mut stack = VecDeque::from([TestFelt(elem)]); + Some(T::try_pop(&mut stack).unwrap_or_else(|| { + panic!( + "could not decode a value of type {} from {}", + core::any::type_name::(), + addr + ) + })) + } + 4 if ptr.offset > 0 => { + todo!("unaligned, split read") + } + 4 => { + let elem = self.read_memory_element_in_context(ptr.waddr, ptr.index, ctx, clk)?; + let mut stack = VecDeque::from([TestFelt(elem)]); + Some(T::try_pop(&mut stack).unwrap_or_else(|| { + panic!( + "could not decode a value of type {} from {}", + core::any::type_name::(), + addr + ) + })) + } + n if n <= 16 && ptr.offset > 0 => { + todo!("unaligned, split read") + } + n if n <= 16 => { + let word = self.read_memory_word_in_context(ptr.waddr, ctx, clk)?; + let mut stack = VecDeque::from_iter(word.into_iter().map(TestFelt)); + Some(T::try_pop(&mut stack).unwrap_or_else(|| { + panic!( + "could not decode a value of type {} from {}", + core::any::type_name::(), + addr + ) + })) + } + n => { + let mut buf = VecDeque::default(); + let chunks_needed = n / 4; + if ptr.offset > 0 { + todo!() + } else if ptr.index > 0 { + todo!() + } else { + for i in 0..chunks_needed { + let word = self + .read_memory_word_in_context(ptr.waddr + i as u32, ctx, clk) + .expect("invalid memory access"); + buf.extend(word.into_iter().map(TestFelt)); + } + } + Some(T::try_pop(&mut buf).unwrap_or_else(|| { + panic!( + "could not decode a value of type {} from {}", + core::any::type_name::(), + addr + ) + })) + } + } + } +} diff --git a/midenc-debug/src/felt.rs b/midenc-debug/src/felt.rs new file mode 100644 index 00000000..7591a6ef --- /dev/null +++ b/midenc-debug/src/felt.rs @@ -0,0 +1,423 @@ +use std::collections::VecDeque; + +use miden_processor::Felt as RawFelt; +use proptest::{ + arbitrary::Arbitrary, + strategy::{BoxedStrategy, Strategy}, +}; + +pub trait PushToStack: Sized { + fn try_push(&self, stack: &mut Vec) { + let mut ptr = self as *const Self as *const u8; + let mut num_bytes = core::mem::size_of::(); + let mut buf = Vec::with_capacity(num_bytes / core::mem::size_of::()); + while num_bytes > 0 { + let mut next = [0u8; 4]; + let consume = core::cmp::min(4, num_bytes); + unsafe { + ptr.copy_to_nonoverlapping(next.as_mut_ptr(), consume); + ptr = ptr.byte_add(consume); + } + num_bytes -= consume; + buf.push(RawFelt::new(u32::from_be_bytes(next) as u64)); + } + + for item in buf.into_iter().rev() { + stack.push(item); + } + } +} + +pub trait PopFromStack: Sized { + fn try_pop(stack: &mut VecDeque) -> Option { + use core::mem::MaybeUninit; + + let mut num_bytes = core::mem::size_of::(); + let mut result = MaybeUninit::::uninit(); + let mut ptr = result.as_mut_ptr() as *mut u8; + while num_bytes > 0 { + let next = stack.pop_front().expect("expected more operand stack elements"); + let next_bytes = (next.0.as_int() as u32).to_be_bytes(); + let consume = core::cmp::min(4, num_bytes); + unsafe { + next_bytes.as_ptr().copy_to_nonoverlapping(ptr, consume); + ptr = ptr.byte_add(consume); + } + num_bytes -= consume; + } + Some(unsafe { result.assume_init() }) + } +} + +impl PushToStack for bool { + fn try_push(&self, stack: &mut Vec) { + stack.push(RawFelt::new(*self as u64)) + } +} +impl PopFromStack for bool { + fn try_pop(stack: &mut VecDeque) -> Option { + Some(stack.pop_front().unwrap().0.as_int() != 0) + } +} + +impl PushToStack for u8 { + fn try_push(&self, stack: &mut Vec) { + stack.push(RawFelt::new(*self as u64)) + } +} +impl PopFromStack for u8 { + fn try_pop(stack: &mut VecDeque) -> Option { + Some(stack.pop_front().unwrap().0.as_int() as u8) + } +} + +impl PushToStack for i8 { + fn try_push(&self, stack: &mut Vec) { + stack.push(RawFelt::new(*self as u8 as u64)) + } +} +impl PopFromStack for i8 { + fn try_pop(stack: &mut VecDeque) -> Option { + Some(stack.pop_front().unwrap().0.as_int() as i8) + } +} + +impl PushToStack for u16 { + fn try_push(&self, stack: &mut Vec) { + stack.push(RawFelt::new(*self as u64)) + } +} +impl PopFromStack for u16 { + fn try_pop(stack: &mut VecDeque) -> Option { + Some(stack.pop_front().unwrap().0.as_int() as u16) + } +} + +impl PushToStack for i16 { + fn try_push(&self, stack: &mut Vec) { + stack.push(RawFelt::new(*self as u16 as u64)) + } +} +impl PopFromStack for i16 { + fn try_pop(stack: &mut VecDeque) -> Option { + Some(stack.pop_front().unwrap().0.as_int() as i16) + } +} + +impl PushToStack for u32 { + fn try_push(&self, stack: &mut Vec) { + stack.push(RawFelt::new(*self as u64)) + } +} +impl PopFromStack for u32 { + fn try_pop(stack: &mut VecDeque) -> Option { + Some(stack.pop_front().unwrap().0.as_int() as u32) + } +} + +impl PushToStack for i32 { + fn try_push(&self, stack: &mut Vec) { + stack.push(RawFelt::new(*self as u32 as u64)) + } +} +impl PopFromStack for i32 { + fn try_pop(stack: &mut VecDeque) -> Option { + Some(stack.pop_front().unwrap().0.as_int() as i32) + } +} + +impl PushToStack for u64 { + fn try_push(&self, stack: &mut Vec) { + let lo = self.rem_euclid(2u64.pow(32)); + let hi = self.div_euclid(2u64.pow(32)); + stack.push(RawFelt::new(lo)); + stack.push(RawFelt::new(hi)); + } +} +impl PopFromStack for u64 { + fn try_pop(stack: &mut VecDeque) -> Option { + let hi = stack.pop_front().unwrap().0.as_int() * 2u64.pow(32); + let lo = stack.pop_front().unwrap().0.as_int(); + Some(hi + lo) + } +} + +impl PushToStack for i64 { + fn try_push(&self, stack: &mut Vec) { + (*self as u64).try_push(stack) + } +} +impl PopFromStack for i64 { + fn try_pop(stack: &mut VecDeque) -> Option { + u64::try_pop(stack).map(|value| value as i64) + } +} + +impl PushToStack for u128 { + fn try_push(&self, stack: &mut Vec) { + let lo = self.rem_euclid(2u128.pow(64)); + let hi = self.div_euclid(2u128.pow(64)); + (lo as u64).try_push(stack); + (hi as u64).try_push(stack); + } +} +impl PopFromStack for u128 { + fn try_pop(stack: &mut VecDeque) -> Option { + let hi = (u64::try_pop(stack).unwrap() as u128) * 2u128.pow(64); + let lo = u64::try_pop(stack).unwrap() as u128; + Some(hi + lo) + } +} + +impl PushToStack for i128 { + fn try_push(&self, stack: &mut Vec) { + (*self as u128).try_push(stack) + } +} +impl PopFromStack for i128 { + fn try_pop(stack: &mut VecDeque) -> Option { + u128::try_pop(stack).map(|value| value as i128) + } +} + +impl PushToStack for RawFelt { + #[inline(always)] + fn try_push(&self, stack: &mut Vec) { + stack.push(*self); + } +} +impl PopFromStack for RawFelt { + #[inline(always)] + fn try_pop(stack: &mut VecDeque) -> Option { + Some(stack.pop_front()?.0) + } +} + +impl PushToStack for Felt { + #[inline(always)] + fn try_push(&self, stack: &mut Vec) { + stack.push(self.0); + } +} +impl PopFromStack for Felt { + #[inline(always)] + fn try_pop(stack: &mut VecDeque) -> Option { + stack.pop_front() + } +} + +impl PushToStack for [u8; N] { + fn try_push(&self, stack: &mut Vec) { + let mut iter = self.iter().array_chunks::<4>(); + let buf_size = (self.len() / 4) + (self.len() % 4 == 0) as usize; + let mut buf = vec![0u32; buf_size]; + let mut i = 0; + for chunk in iter.by_ref() { + let n = u32::from_be_bytes([*chunk[0], *chunk[1], *chunk[2], *chunk[3]]); + buf[i] = n; + i += 1; + } + if let Some(rest) = iter.into_remainder() { + let mut n_buf = [0u8; 4]; + for (i, byte) in rest.into_iter().enumerate() { + n_buf[i] = *byte; + } + buf[i] = u32::from_be_bytes(n_buf); + } + for chunk in buf.into_iter().rev() { + PushToStack::try_push(&chunk, stack); + } + } +} + +impl PopFromStack for [u8; N] { + fn try_pop(stack: &mut VecDeque) -> Option { + let mut out = [0u8; N]; + + let byte_size = out.len(); + let mut i = 0; + while i < byte_size { + let chunk: u32 = PopFromStack::try_pop(stack).expect("invalid u32"); + let bytes = chunk.to_be_bytes(); + if i + 4 > byte_size { + for byte in bytes[..(byte_size - i)].iter().copied() { + out[i] = byte; + i += 1; + } + break; + } else { + for byte in bytes.iter().copied() { + out[i] = byte; + i += 1; + } + } + } + + Some(out) + } +} + +/// Wrapper around `miden_processor::Felt` that implements useful traits that are not implemented +/// for that type. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct Felt(pub RawFelt); + +impl clap::builder::ValueParserFactory for Felt { + type Parser = FeltParser; + + fn value_parser() -> Self::Parser { + FeltParser + } +} + +#[doc(hidden)] +#[derive(Clone)] +pub struct FeltParser; +impl clap::builder::TypedValueParser for FeltParser { + type Value = Felt; + + fn parse_ref( + &self, + _cmd: &clap::Command, + _arg: Option<&clap::Arg>, + value: &std::ffi::OsStr, + ) -> Result { + use clap::error::{Error, ErrorKind}; + + let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?; + + let value = value.parse::().map_err(|err| { + Error::raw(ErrorKind::InvalidValue, format!("invalid field element value: {err}")) + })?; + + RawFelt::try_from(value) + .map(Felt) + .map_err(|err| Error::raw(ErrorKind::InvalidValue, err)) + } +} + +impl From for miden_processor::Felt { + fn from(f: Felt) -> Self { + f.0 + } +} + +impl From for Felt { + fn from(b: bool) -> Self { + Self(RawFelt::from(b as u32)) + } +} + +impl From for Felt { + fn from(t: u8) -> Self { + Self(t.into()) + } +} + +impl From for Felt { + fn from(t: i8) -> Self { + Self((t as u8).into()) + } +} + +impl From for Felt { + fn from(t: i16) -> Self { + Self((t as u16).into()) + } +} + +impl From for Felt { + fn from(t: u16) -> Self { + Self(t.into()) + } +} + +impl From for Felt { + fn from(t: i32) -> Self { + Self((t as u32).into()) + } +} + +impl From for Felt { + fn from(t: u32) -> Self { + Self(t.into()) + } +} + +impl From for Felt { + fn from(t: u64) -> Self { + Self(RawFelt::new(t)) + } +} + +impl From for Felt { + fn from(t: i64) -> Self { + Self(RawFelt::new(t as u64)) + } +} + +// Reverse Felt to Rust types conversion + +impl From for bool { + fn from(f: Felt) -> Self { + f.0.as_int() != 0 + } +} + +impl From for u8 { + fn from(f: Felt) -> Self { + f.0.as_int() as u8 + } +} + +impl From for i8 { + fn from(f: Felt) -> Self { + f.0.as_int() as i8 + } +} + +impl From for u16 { + fn from(f: Felt) -> Self { + f.0.as_int() as u16 + } +} + +impl From for i16 { + fn from(f: Felt) -> Self { + f.0.as_int() as i16 + } +} + +impl From for u32 { + fn from(f: Felt) -> Self { + f.0.as_int() as u32 + } +} + +impl From for i32 { + fn from(f: Felt) -> Self { + f.0.as_int() as i32 + } +} + +impl From for u64 { + fn from(f: Felt) -> Self { + f.0.as_int() + } +} + +impl From for i64 { + fn from(f: Felt) -> Self { + f.0.as_int() as i64 + } +} + +impl Arbitrary for Felt { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + use miden_core::StarkField; + (0u64..RawFelt::MODULUS).prop_map(|v| Felt(RawFelt::new(v))).boxed() + } +} diff --git a/midenc-debug/src/inputs.rs b/midenc-debug/src/inputs.rs new file mode 100644 index 00000000..64b9c153 --- /dev/null +++ b/midenc-debug/src/inputs.rs @@ -0,0 +1,44 @@ +use std::{ffi::OsStr, path::Path}; + +use miden_processor::{AdviceInputs, ExecutionOptions, StackInputs}; + +#[derive(Debug, Clone, Default)] +pub struct ProgramInputs { + pub inputs: StackInputs, + pub advice_inputs: AdviceInputs, + pub options: ExecutionOptions, +} + +impl clap::builder::ValueParserFactory for ProgramInputs { + type Parser = ProgramInputsParser; + + fn value_parser() -> Self::Parser { + ProgramInputsParser + } +} + +#[doc(hidden)] +#[derive(Clone)] +pub struct ProgramInputsParser; +impl clap::builder::TypedValueParser for ProgramInputsParser { + type Value = ProgramInputs; + + fn parse_ref( + &self, + _cmd: &clap::Command, + _arg: Option<&clap::Arg>, + value: &OsStr, + ) -> Result { + use clap::error::{Error, ErrorKind}; + + let inputs_path = Path::new(value); + if !inputs_path.is_file() { + return Err(Error::raw( + ErrorKind::InvalidValue, + format!("invalid inputs file: '{}' is not a file", inputs_path.display()), + )); + } + + todo!() + } +} diff --git a/midenc-debug/src/lib.rs b/midenc-debug/src/lib.rs new file mode 100644 index 00000000..ff6a8cd7 --- /dev/null +++ b/midenc-debug/src/lib.rs @@ -0,0 +1,70 @@ +#![feature(iter_array_chunks)] +#![feature(lazy_cell)] +#![allow(unused)] + +mod cli; +mod debug; +mod exec; +mod felt; +mod inputs; +mod logger; +mod ui; + +use std::rc::Rc; + +use midenc_session::{ + diagnostics::{IntoDiagnostic, Report}, + Session, +}; + +pub use self::{ + cli::Debugger, + debug::*, + exec::*, + felt::{Felt, Felt as TestFelt, PopFromStack, PushToStack}, + inputs::ProgramInputs, +}; + +pub type ExecutionResult = Result; + +pub fn run( + inputs: Option, + args: Vec, + session: Rc, + logger: Box, +) -> ExecutionResult<()> { + let mut builder = tokio::runtime::Builder::new_current_thread(); + let rt = builder.enable_all().build().into_diagnostic()?; + rt.block_on(async move { start_ui(inputs, args, session, logger).await }) +} + +pub fn trace( + _options: Option, + _args: Vec, + _session: Rc, +) -> ExecutionResult { + todo!() +} + +pub async fn start_ui( + inputs: Option, + args: Vec, + session: Rc, + logger: Box, +) -> Result<(), Report> { + use ratatui::crossterm as term; + + logger::DebugLogger::install(logger); + + let original_hook = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |panic_info| { + let _ = term::terminal::disable_raw_mode(); + let _ = term::execute!(std::io::stdout(), term::terminal::LeaveAlternateScreen); + original_hook(panic_info); + })); + + let mut app = ui::App::new(inputs, args, session).await?; + app.run().await?; + + Ok(()) +} diff --git a/midenc-debug/src/logger.rs b/midenc-debug/src/logger.rs new file mode 100644 index 00000000..8e3e1bfe --- /dev/null +++ b/midenc-debug/src/logger.rs @@ -0,0 +1,76 @@ +use std::{ + borrow::Cow, + collections::VecDeque, + sync::{Arc, LazyLock, Mutex}, +}; + +use log::{Level, Log}; + +static LOGGER: LazyLock = LazyLock::new(DebugLogger::default); + +#[derive(Default)] +struct DebugLoggerImpl { + inner: Option>, + captured: VecDeque, +} + +pub struct LogEntry { + pub level: Level, + pub file: Option>, + pub line: Option, + pub message: String, +} + +#[derive(Default, Clone)] +pub struct DebugLogger(Arc>); +impl Log for DebugLogger { + fn enabled(&self, _metadata: &log::Metadata) -> bool { + true + } + + fn log(&self, record: &log::Record) { + let file = record + .file_static() + .map(Cow::Borrowed) + .or_else(|| record.file().map(|f| f.to_string()).map(Cow::Owned)); + let entry = LogEntry { + level: record.level(), + file, + line: record.line(), + message: format!("{}", record.args()), + }; + let mut guard = self.0.lock().unwrap(); + guard.captured.push_back(entry); + if guard.captured.len() > 100 { + guard.captured.pop_front(); + } + if let Some(inner) = guard.inner.as_ref() { + if inner.enabled(record.metadata()) { + inner.log(record); + } + } + } + + fn flush(&self) {} +} +impl DebugLogger { + pub fn install(inner: Box) { + let logger = &*LOGGER; + logger.set_inner(inner); + log::set_logger(logger).unwrap_or_else(|err| panic!("failed to install logger: {err}")); + log::set_max_level(log::LevelFilter::Trace); + } + + pub fn get() -> &'static Self { + &LOGGER + } + + pub fn take_captured(&self) -> VecDeque { + let mut guard = self.0.lock().unwrap(); + core::mem::take(&mut guard.captured) + } + + fn set_inner(&self, logger: Box) { + drop(self.0.lock().unwrap().inner.replace(logger)); + } +} diff --git a/midenc-debug/src/ui/action.rs b/midenc-debug/src/ui/action.rs new file mode 100644 index 00000000..83ebe30a --- /dev/null +++ b/midenc-debug/src/ui/action.rs @@ -0,0 +1,39 @@ +type Command = String; +type Args = Option; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Action { + Tick, + Render, + Resize(u16, u16), + Suspend, + Resume, + Quit, + Refresh, + Error(String), + Help, + FocusNext, + FocusPrev, + Focus, + UnFocus, + Up, + Down, + Submit, + Update, + Tab(u32), + TabNext, + TabPrev, + Go, + Back, + ToggleFullScreen, + StatusLine(String), + TimedStatusLine(String, u64), + FocusFooter(Command, Args), + FooterResult(Command, Args), + Noop, + ClosePopup, + ShowDebug, + Continue, + Delete, + Reload, +} diff --git a/midenc-debug/src/ui/app.rs b/midenc-debug/src/ui/app.rs new file mode 100644 index 00000000..3ba306b2 --- /dev/null +++ b/midenc-debug/src/ui/app.rs @@ -0,0 +1,282 @@ +use std::{collections::HashMap, rc::Rc}; + +use midenc_session::{ + diagnostics::{IntoDiagnostic, Report}, + Session, +}; +use ratatui::{ + crossterm::event::KeyEvent, + layout::{Constraint, Layout}, + prelude::Rect, +}; +use tokio::sync::mpsc; + +use super::{ + pages::{home::Home, Page}, + panes::{debug::DebugPane, footer::FooterPane, header::HeaderPane, Pane}, + state::{InputMode, State}, + tui, Action, +}; + +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Mode { + #[default] + Home, +} + +pub struct App { + pub pages: Vec>, + pub keybindings: KeyBindings, + pub active_page: usize, + pub footer: FooterPane, + pub header: HeaderPane, + pub popup: Option>, + pub last_tick_key_events: Vec, + pub mode: Mode, + pub state: State, + pub should_quit: bool, + pub should_suspend: bool, +} + +pub type KeyBindings = HashMap, Action>>; + +impl App { + pub async fn new( + inputs: Option, + args: Vec, + session: Rc, + ) -> Result { + let state = State::from_inputs(inputs, args, session)?; + let home = Home::new()?; + Ok(Self { + pages: vec![Box::new(home)], + keybindings: Default::default(), + active_page: 0, + footer: FooterPane::new(), + header: HeaderPane::new(), + popup: None, + last_tick_key_events: vec![], + mode: Mode::Home, + state, + should_quit: false, + should_suspend: false, + }) + } + + pub async fn run(&mut self) -> Result<(), Report> { + let (action_tx, mut action_rx) = mpsc::unbounded_channel::(); + + let mut tui = tui::Tui::new()? + .tick_rate(4.0) // 4 ticks per second + .frame_rate(30.0); // 30 frames per second + + // Starts event handler, enters raw mode, enters alternate screen + tui.enter()?; + + for page in self.pages.iter_mut() { + page.register_action_handler(action_tx.clone())?; + } + + for page in self.pages.iter_mut() { + page.init(&self.state)?; + page.focus()?; + } + + self.header.init(&self.state)?; + self.footer.init(&self.state)?; + + loop { + if let Some(evt) = tui.next().await { + let mut stop_event_propagation = self + .popup + .as_mut() + .and_then(|pane| pane.handle_events(evt.clone(), &mut self.state).ok()) + .map(|response| match response { + Some(tui::EventResponse::Continue(action)) => { + action_tx.send(action).ok(); + false + } + Some(tui::EventResponse::Stop(action)) => { + action_tx.send(action).ok(); + true + } + _ => false, + }) + .unwrap_or(false); + stop_event_propagation = stop_event_propagation + || self + .pages + .get_mut(self.active_page) + .and_then(|page| page.handle_events(evt.clone(), &mut self.state).ok()) + .map(|response| match response { + Some(tui::EventResponse::Continue(action)) => { + action_tx.send(action).ok(); + false + } + Some(tui::EventResponse::Stop(action)) => { + action_tx.send(action).ok(); + true + } + _ => false, + }) + .unwrap_or(false); + stop_event_propagation = stop_event_propagation + || self + .footer + .handle_events(evt.clone(), &mut self.state) + .map(|response| match response { + Some(tui::EventResponse::Continue(action)) => { + action_tx.send(action).ok(); + false + } + Some(tui::EventResponse::Stop(action)) => { + action_tx.send(action).ok(); + true + } + _ => false, + }) + .unwrap_or(false); + + if !stop_event_propagation { + match evt { + tui::Event::Quit if self.state.input_mode == InputMode::Normal => { + action_tx.send(Action::Quit).into_diagnostic()? + } + tui::Event::Tick => action_tx.send(Action::Tick).into_diagnostic()?, + tui::Event::Render => action_tx.send(Action::Render).into_diagnostic()?, + tui::Event::Resize(x, y) => { + action_tx.send(Action::Resize(x, y)).into_diagnostic()? + } + tui::Event::Key(key) => { + if let Some(keymap) = self.keybindings.get(&self.mode) { + if let Some(action) = keymap.get(&vec![key]) { + action_tx.send(action.clone()).into_diagnostic()?; + } else { + // If the key was not handled as a single key action, + // then consider it for multi-key combinations. + self.last_tick_key_events.push(key); + + if let Some(action) = keymap.get(&self.last_tick_key_events) { + action_tx.send(action.clone()).into_diagnostic()?; + } + } + } + } + _ => (), + } + } + } + + while let Ok(action) = action_rx.try_recv() { + if action != Action::Tick && action != Action::Render { + log::debug!("{action:?}"); + } + match action { + Action::Tick => { + self.last_tick_key_events.clear(); + } + Action::Quit if self.state.input_mode == InputMode::Normal => { + self.should_quit = true + } + Action::Suspend => self.should_suspend = true, + Action::Resume => self.should_suspend = false, + Action::Resize(w, h) => { + tui.resize(Rect::new(0, 0, w, h)).into_diagnostic()?; + tui.draw(|f| { + self.draw(f).unwrap_or_else(|err| { + action_tx + .send(Action::Error(format!("Failed to draw: {err:?}"))) + .unwrap(); + }) + }) + .into_diagnostic()?; + } + Action::Render => { + tui.draw(|f| { + self.draw(f).unwrap_or_else(|err| { + action_tx + .send(Action::Error(format!("Failed to draw {err:?}"))) + .unwrap() + }) + }) + .into_diagnostic()?; + } + Action::ShowDebug => { + let debug_popup = DebugPane::default(); + self.popup = Some(Box::new(debug_popup)); + } + Action::ClosePopup => { + if self.popup.is_some() { + self.popup = None; + } + } + _ => (), + } + + if let Some(popup) = self.popup.as_mut() { + if let Some(action) = popup.update(action.clone(), &mut self.state)? { + action_tx.send(action).into_diagnostic()?; + } + } else if let Some(page) = self.pages.get_mut(self.active_page) { + if let Some(action) = page.update(action.clone(), &mut self.state)? { + action_tx.send(action).into_diagnostic()?; + } + } + + if let Some(action) = self.header.update(action.clone(), &mut self.state)? { + action_tx.send(action).into_diagnostic()?; + } + + if let Some(action) = self.footer.update(action.clone(), &mut self.state)? { + action_tx.send(action).into_diagnostic()?; + } + } + + if self.should_suspend { + tui.suspend()?; + action_tx.send(Action::Resume).into_diagnostic()?; + tui = tui::Tui::new()?; + tui.enter()?; + } else if self.should_quit { + tui.stop()?; + break; + } + } + + // stops event handler, exits raw mode, exits alternate screen + tui.exit()?; + + Ok(()) + } + + fn draw(&mut self, frame: &mut tui::Frame<'_>) -> Result<(), Report> { + let vertical_layout = + Layout::vertical(vec![Constraint::Max(1), Constraint::Fill(1), Constraint::Max(1)]) + .split(frame.area()); + + self.header.draw(frame, vertical_layout[0], &self.state)?; + + if let Some(page) = self.pages.get_mut(self.active_page) { + page.draw(frame, vertical_layout[1], &self.state)?; + } + + if let Some(popup) = self.popup.as_mut() { + let popup_vertical_layout = Layout::vertical(vec![ + Constraint::Fill(1), + popup.height_constraint(), + Constraint::Fill(1), + ]) + .split(frame.area()); + let popup_layout = Layout::horizontal(vec![ + Constraint::Fill(1), + Constraint::Percentage(80), + Constraint::Fill(1), + ]) + .split(popup_vertical_layout[1]); + popup.draw(frame, popup_layout[1], &self.state)?; + } + + self.footer.draw(frame, vertical_layout[2], &self.state)?; + Ok(()) + } +} diff --git a/midenc-debug/src/ui/mod.rs b/midenc-debug/src/ui/mod.rs new file mode 100644 index 00000000..aa266bcd --- /dev/null +++ b/midenc-debug/src/ui/mod.rs @@ -0,0 +1,9 @@ +mod action; +mod app; +mod pages; +mod panes; +mod state; +mod syntax_highlighting; +mod tui; + +pub use self::{action::Action, app::App}; diff --git a/midenc-debug/src/ui/pages/home.rs b/midenc-debug/src/ui/pages/home.rs new file mode 100644 index 00000000..e28dff8f --- /dev/null +++ b/midenc-debug/src/ui/pages/home.rs @@ -0,0 +1,422 @@ +use midenc_session::diagnostics::{IntoDiagnostic, Report}; +use ratatui::{ + crossterm::{ + self, + event::{KeyCode, KeyEvent}, + }, + prelude::*, +}; +use tokio::sync::mpsc::UnboundedSender; + +use crate::{ + ui::{ + action::Action, + pages::Page, + panes::{ + breakpoints::BreakpointsPane, disasm::DisassemblyPane, source_code::SourceCodePane, + stack::OperandStackPane, stacktrace::StackTracePane, Pane, + }, + state::{InputMode, State}, + tui::EventResponse, + }, + Breakpoint, BreakpointType, ReadMemoryExpr, +}; + +#[derive(Default)] +pub struct Home { + command_tx: Option>, + panes: Vec>, + focused_pane_index: usize, + fullscreen_pane_index: Option, +} + +impl Home { + pub fn new() -> Result { + let focused_border_style = Style::default().fg(Color::LightGreen); + + Ok(Self { + command_tx: None, + panes: vec![ + Box::new(SourceCodePane::new(true, focused_border_style)), + Box::new(DisassemblyPane::new(false, focused_border_style)), + Box::new(StackTracePane::new(false, focused_border_style)), + Box::new(OperandStackPane::new(false, focused_border_style)), + Box::new(BreakpointsPane::new(false, focused_border_style)), + ], + + focused_pane_index: 0, + fullscreen_pane_index: None, + }) + } +} + +impl Page for Home { + fn init(&mut self, state: &State) -> Result<(), Report> { + for pane in self.panes.iter_mut() { + pane.init(state)?; + } + Ok(()) + } + + fn focus(&mut self) -> Result<(), Report> { + if let Some(command_tx) = &self.command_tx { + const ARROW: &str = symbols::scrollbar::HORIZONTAL.end; + let status_line = + format!("[l,h {ARROW} pane movement] [: {ARROW} commands] [q {ARROW} quit]"); + command_tx.send(Action::StatusLine(status_line)).into_diagnostic()?; + } + Ok(()) + } + + fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<(), Report> { + self.command_tx = Some(tx); + Ok(()) + } + + fn update(&mut self, action: Action, state: &mut State) -> Result, Report> { + let mut actions: Vec> = vec![]; + match action { + Action::Tick => {} + Action::FocusNext => { + let next_index = self.focused_pane_index.saturating_add(1) % self.panes.len(); + if let Some(pane) = self.panes.get_mut(self.focused_pane_index) { + actions.push(pane.update(Action::UnFocus, state)?); + } + self.focused_pane_index = next_index; + if let Some(pane) = self.panes.get_mut(self.focused_pane_index) { + actions.push(pane.update(Action::Focus, state)?); + } + } + Action::FocusPrev => { + let prev_index = + self.focused_pane_index.saturating_add(self.panes.len() - 1) % self.panes.len(); + if let Some(pane) = self.panes.get_mut(self.focused_pane_index) { + actions.push(pane.update(Action::UnFocus, state)?); + } + self.focused_pane_index = prev_index; + if let Some(pane) = self.panes.get_mut(self.focused_pane_index) { + actions.push(pane.update(Action::Focus, state)?); + } + } + Action::Update => { + for pane in self.panes.iter_mut() { + actions.push(pane.update(action.clone(), state)?); + } + } + Action::ToggleFullScreen => { + self.fullscreen_pane_index = + self.fullscreen_pane_index.map_or(Some(self.focused_pane_index), |_| None); + } + Action::FocusFooter(..) => { + if let Some(pane) = self.panes.get_mut(self.focused_pane_index) { + actions.push(pane.update(Action::UnFocus, state)?); + } + } + Action::FooterResult(cmd, Some(args)) if cmd.eq(":") => { + if let Some(pane) = self.panes.get_mut(self.focused_pane_index) { + pane.update(Action::Focus, state)?; + } + // Dispatch commands of the form: CMD [ARGS..] + match args.split_once(' ') { + Some((cmd, rest)) => match cmd.trim() { + "b" | "break" | "breakpoint" => match rest.parse::() { + Ok(ty) => { + state.create_breakpoint(ty); + actions.push(Some(Action::TimedStatusLine( + "breakpoint created".to_string(), + 1, + ))); + } + Err(err) => { + actions.push(Some(Action::TimedStatusLine(err, 5))); + } + }, + "r" | "read" => match rest.parse::() { + Ok(expr) => match state.read_memory(&expr) { + Ok(result) => actions.push(Some(Action::StatusLine(result))), + Err(err) => actions.push(Some(Action::TimedStatusLine(err, 5))), + }, + Err(err) => actions.push(Some(Action::TimedStatusLine(err, 5))), + }, + _ => { + log::debug!("unknown command with arguments: '{cmd} {args}'"); + actions.push(Some(Action::TimedStatusLine("unknown command".into(), 1))) + } + }, + None => match args.trim() { + "q" | "quit" => actions.push(Some(Action::Quit)), + "reload" => { + actions.push(Some(Action::Reload)); + } + "debug" => { + actions.push(Some(Action::ShowDebug)); + } + invalid => { + log::debug!("unknown command: '{invalid}'"); + actions.push(Some(Action::TimedStatusLine("unknown command".into(), 1))) + } + }, + } + } + Action::FooterResult(_cmd, None) => { + if let Some(pane) = self.panes.get_mut(self.focused_pane_index) { + actions.push(pane.update(Action::Focus, state)?); + } + } + Action::Continue => { + let start_cycle = state.executor.cycle; + let mut breakpoints = core::mem::take(&mut state.breakpoints); + state.stopped = false; + let stopped = loop { + // If stepping the program results in the program terminating succesfully, stop + if state.executor.stopped { + break true; + } + + if let Err(err) = state.executor.step() { + // Execution terminated with an error + state.execution_failed = Some(err); + break true; + } + + if breakpoints.is_empty() { + // No breakpoint management needed, keep executing + continue; + } + + let (op, is_op_boundary, proc, loc) = match state.executor.last.as_ref() { + Some(last_state) => { + let op = last_state.op; + let is_boundary = last_state + .asmop + .as_ref() + .map(|info| info.cycle_idx() == 1) + .unwrap_or(false); + let (proc, loc) = match state.executor.callstack.current_frame() { + Some(frame) => { + let loc = frame + .recent() + .back() + .and_then(|detail| detail.resolve(&state.session)) + .cloned(); + (frame.procedure(state.session.name()), loc) + } + None => (None, None), + }; + (op, is_boundary, proc, loc) + } + None => (None, false, None, None), + }; + + // Remove all breakpoints triggered at this cycle + let current_cycle = state.executor.cycle; + let cycles_stepped = current_cycle - start_cycle; + breakpoints.retain_mut(|bp| { + if let Some(n) = bp.cycles_to_skip(current_cycle) { + if cycles_stepped >= n { + let retained = !bp.is_one_shot(); + if retained { + state.breakpoints_hit.push(bp.clone()); + } else { + state.breakpoints_hit.push(core::mem::take(bp)); + } + return retained; + } else { + return true; + } + } + + if cycles_stepped > 0 + && is_op_boundary + && matches!(&bp.ty, BreakpointType::Next) + { + state.breakpoints_hit.push(core::mem::take(bp)); + return false; + } + + if let Some(loc) = loc.as_ref() { + if bp.should_break_at(loc) { + let retained = !bp.is_one_shot(); + if retained { + state.breakpoints_hit.push(bp.clone()); + } else { + state.breakpoints_hit.push(core::mem::take(bp)); + } + return retained; + } + } + + if let Some(proc) = proc.as_deref() { + if bp.should_break_in(proc) { + let retained = !bp.is_one_shot(); + if retained { + state.breakpoints_hit.push(bp.clone()); + } else { + state.breakpoints_hit.push(core::mem::take(bp)); + } + return retained; + } + } + + true + }); + + if !state.breakpoints_hit.is_empty() { + break true; + } + }; + + // Restore the breakpoints state + state.breakpoints = breakpoints; + + // Ensure that if we yield to the runtime, that we resume executing when + // resumed, unless we specifically stopped for a breakpoint or other condition + state.stopped = stopped; + + // Report program termination to the user + if stopped && state.executor.stopped { + if let Some(err) = state.execution_failed.as_ref() { + actions.push(Some(Action::StatusLine(err.to_string()))); + } else { + actions.push(Some(Action::StatusLine( + "program terminated successfully".to_string(), + ))); + } + } + + // Update the UI with latest state + for pane in self.panes.iter_mut() { + actions.push(pane.update(Action::Update, state)?); + } + } + Action::Reload => match state.reload() { + Ok(_) => { + for pane in self.panes.iter_mut() { + actions.push(pane.update(Action::Reload, state)?); + } + } + Err(err) => { + actions.push(Some(Action::TimedStatusLine(err.to_string(), 5))); + } + }, + _ => { + if let Some(pane) = self.panes.get_mut(self.focused_pane_index) { + actions.push(pane.update(action, state)?); + } + } + } + + if let Some(tx) = &mut self.command_tx { + actions.into_iter().flatten().for_each(|action| { + tx.send(action).ok(); + }); + } + Ok(None) + } + + fn handle_key_events( + &mut self, + key: KeyEvent, + state: &mut State, + ) -> Result>, Report> { + match state.input_mode { + InputMode::Normal => { + let response = match key.code { + KeyCode::Right | KeyCode::Char('l') | KeyCode::Char('L') => { + EventResponse::Stop(Action::FocusNext) + } + KeyCode::Left | KeyCode::Char('h') | KeyCode::Char('H') => { + EventResponse::Stop(Action::FocusPrev) + } + KeyCode::Down | KeyCode::Char('j') | KeyCode::Char('J') => { + EventResponse::Stop(Action::Down) + } + KeyCode::Up | KeyCode::Char('k') | KeyCode::Char('K') => { + EventResponse::Stop(Action::Up) + } + KeyCode::Char('g') | KeyCode::Char('G') => EventResponse::Stop(Action::Go), + KeyCode::Backspace | KeyCode::Char('b') | KeyCode::Char('B') => { + EventResponse::Stop(Action::Back) + } + KeyCode::Char('f') | KeyCode::Char('F') => { + EventResponse::Stop(Action::ToggleFullScreen) + } + KeyCode::Char(c) if ('1'..='9').contains(&c) => { + EventResponse::Stop(Action::Tab(c.to_digit(10).unwrap_or(0) - 1)) + } + KeyCode::Char(']') => EventResponse::Stop(Action::TabNext), + KeyCode::Char('[') => EventResponse::Stop(Action::TabPrev), + KeyCode::Char(':') => { + EventResponse::Stop(Action::FocusFooter(":".into(), None)) + } + KeyCode::Char('q') => EventResponse::Stop(Action::Quit), + // Only step if we're stopped, and execution has not terminated + KeyCode::Char('s') if state.stopped && !state.executor.stopped => { + state.create_breakpoint(BreakpointType::Step); + state.stopped = false; + EventResponse::Stop(Action::Continue) + } + // Only step-next if we're stopped, and execution has not terminated + KeyCode::Char('n') if state.stopped && !state.executor.stopped => { + state.create_breakpoint(BreakpointType::Next); + state.stopped = false; + EventResponse::Stop(Action::Continue) + } + // Only resume execution if we're stopped, and execution has not terminated + KeyCode::Char('c') if state.stopped && !state.executor.stopped => { + state.stopped = false; + EventResponse::Stop(Action::Continue) + } + // Do not try to continue if execution has terminated, but warn user + KeyCode::Char('c' | 's' | 'n') if state.stopped && state.executor.stopped => { + EventResponse::Stop(Action::TimedStatusLine( + "program has terminated, cannot continue".to_string(), + 3, + )) + } + KeyCode::Char('d') => EventResponse::Stop(Action::Delete), + _ => { + return Ok(None); + } + }; + Ok(Some(response)) + } + InputMode::Insert => Ok(None), + InputMode::Command => Ok(None), + } + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report> { + if let Some(fullscreen_pane_index) = self.fullscreen_pane_index { + self.panes[fullscreen_pane_index].draw(frame, area, state)?; + } else { + let outer_layout = Layout::default() + .direction(Direction::Horizontal) + .constraints(vec![Constraint::Fill(3), Constraint::Fill(1)]) + .split(area); + + let left_panes = Layout::default() + .direction(Direction::Vertical) + .constraints(vec![ + self.panes[0].height_constraint(), + self.panes[1].height_constraint(), + self.panes[2].height_constraint(), + ]) + .split(outer_layout[0]); + + let right_panes = Layout::default() + .direction(Direction::Vertical) + .constraints(vec![ + self.panes[3].height_constraint(), + self.panes[4].height_constraint(), + ]) + .split(outer_layout[1]); + self.panes[0].draw(frame, left_panes[0], state)?; + self.panes[1].draw(frame, left_panes[1], state)?; + self.panes[2].draw(frame, left_panes[2], state)?; + self.panes[3].draw(frame, right_panes[0], state)?; + self.panes[4].draw(frame, right_panes[1], state)?; + } + Ok(()) + } +} diff --git a/midenc-debug/src/ui/pages/mod.rs b/midenc-debug/src/ui/pages/mod.rs new file mode 100644 index 00000000..dc6288ad --- /dev/null +++ b/midenc-debug/src/ui/pages/mod.rs @@ -0,0 +1,65 @@ +use crossterm::event::{KeyEvent, MouseEvent}; +use midenc_session::diagnostics::Report; +use ratatui::layout::Rect; +use tokio::sync::mpsc::UnboundedSender; + +use crate::ui::{ + action::Action, + state::State, + tui::{Event, EventResponse, Frame}, +}; + +pub mod home; + +pub trait Page { + fn register_action_handler(&mut self, _tx: UnboundedSender) -> Result<(), Report> { + Ok(()) + } + + fn init(&mut self, _state: &State) -> Result<(), Report> { + Ok(()) + } + + fn focus(&mut self) -> Result<(), Report> { + Ok(()) + } + + fn unfocus(&mut self) -> Result<(), Report> { + Ok(()) + } + + fn handle_events( + &mut self, + event: Event, + state: &mut State, + ) -> Result>, Report> { + let r = match event { + Event::Key(key_event) => self.handle_key_events(key_event, state)?, + Event::Mouse(mouse_event) => self.handle_mouse_events(mouse_event, state)?, + _ => None, + }; + Ok(r) + } + + fn handle_key_events( + &mut self, + _key: KeyEvent, + _state: &mut State, + ) -> Result>, Report> { + Ok(None) + } + + fn handle_mouse_events( + &mut self, + _mouse: MouseEvent, + _state: &mut State, + ) -> Result>, Report> { + Ok(None) + } + + fn update(&mut self, _action: Action, _state: &mut State) -> Result, Report> { + Ok(None) + } + + fn draw(&mut self, f: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report>; +} diff --git a/midenc-debug/src/ui/panes/breakpoints.rs b/midenc-debug/src/ui/panes/breakpoints.rs new file mode 100644 index 00000000..b5e4ee57 --- /dev/null +++ b/midenc-debug/src/ui/panes/breakpoints.rs @@ -0,0 +1,248 @@ +use midenc_session::diagnostics::{Report, SourceId, SourceSpan}; +use ratatui::{ + prelude::*, + widgets::{block::*, *}, +}; + +use crate::{ + ui::{action::Action, panes::Pane, state::State, tui::Frame}, + Breakpoint, BreakpointType, ResolvedLocation, +}; + +pub struct BreakpointsPane { + focused: bool, + focused_border_style: Style, + breakpoint_selected: Option, + breakpoints_hit: Vec, + breakpoint_cycle: usize, +} + +impl BreakpointsPane { + pub fn new(focused: bool, focused_border_style: Style) -> Self { + Self { + focused, + focused_border_style, + breakpoint_selected: None, + breakpoints_hit: vec![], + breakpoint_cycle: 0, + } + } + + fn border_style(&self) -> Style { + match self.focused { + true => self.focused_border_style, + false => Style::default(), + } + } + + fn border_type(&self) -> BorderType { + match self.focused { + true => BorderType::Thick, + false => BorderType::Plain, + } + } +} + +impl Pane for BreakpointsPane { + fn height_constraint(&self) -> Constraint { + match self.focused { + true => Constraint::Fill(5), + false => Constraint::Fill(5), + } + } + + fn init(&mut self, state: &State) -> Result<(), Report> { + self.breakpoint_cycle = state.executor.cycle; + self.breakpoints_hit.clear(); + self.breakpoint_selected = None; + Ok(()) + } + + fn update(&mut self, action: Action, state: &mut State) -> Result, Report> { + match action { + Action::Focus => { + self.focused = true; + } + Action::UnFocus => { + self.focused = false; + } + Action::Down => { + if let Some(prev) = self.breakpoint_selected.take() { + self.breakpoint_selected = state + .breakpoints + .iter() + .find_map(|bp| if bp.id > prev { Some(bp.id) } else { None }) + .or_else(|| state.breakpoints.first().map(|bp| bp.id)); + } else { + self.breakpoint_selected = state.breakpoints.first().map(|bp| bp.id); + } + return Ok(Some(Action::Update)); + } + Action::Up => { + if let Some(prev) = self.breakpoint_selected.take() { + self.breakpoint_selected = state + .breakpoints + .iter() + .rev() + .find_map(|bp| if bp.id < prev { Some(bp.id) } else { None }) + .or_else(|| state.breakpoints.last().map(|bp| bp.id)); + } else { + self.breakpoint_selected = state.breakpoints.last().map(|bp| bp.id); + } + return Ok(Some(Action::Update)); + } + Action::Delete => { + if let Some(prev) = self.breakpoint_selected.take() { + state.breakpoints.retain(|bp| bp.id != prev); + let select_next = state + .breakpoints + .iter() + .find_map(|bp| if bp.id > prev { Some(bp.id) } else { None }) + .or_else(|| state.breakpoints.first().map(|bp| bp.id)); + self.breakpoint_selected = select_next; + } + } + Action::Reload => { + self.init(state)?; + } + Action::Update => { + if self.breakpoint_cycle < state.executor.cycle { + self.breakpoints_hit.clear(); + self.breakpoints_hit.append(&mut state.breakpoints_hit); + if let Some(prev) = self.breakpoint_selected { + if self.breakpoints_hit.iter().any(|bp| bp.id == prev && bp.is_one_shot()) { + self.breakpoint_selected = None; + } + } + } + self.breakpoint_cycle = state.executor.cycle; + } + _ => {} + } + + Ok(None) + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report> { + use crate::Breakpoint; + + let mut breakpoints = self + .breakpoints_hit + .iter() + .map(|bp| (true, bp)) + .chain(state.breakpoints.iter().filter_map(|bp| { + if self.breakpoints_hit.iter().any(|hit| hit.id == bp.id) { + None + } else { + Some((false, bp)) + } + })) + .filter(|(_, bp)| !bp.is_internal()) + .collect::>(); + breakpoints.sort_by_key(|(_, bp)| bp.id); + let user_created_breakpoints = breakpoints.len(); + let user_breakpoints_hit = + self.breakpoints_hit.iter().filter(|bp| !bp.is_internal()).count(); + + let fg = Color::White; + let bg = Color::Black; + let yellow = Color::Yellow; + let gray = Color::Gray; + let fg_hit = Color::Red; + let bg_hit = Color::Black; + let yellow_hit = Color::LightRed; + let gray_hit = Color::DarkGray; + let selected_index = if let Some(id) = self.breakpoint_selected { + breakpoints.iter().position(|(_, bp)| bp.id == id) + } else { + None + }; + let lines = breakpoints + .into_iter() + .map(|(is_hit, bp)| { + let (fg, bg, gray, yellow) = if is_hit { + (fg_hit, bg_hit, gray_hit, yellow_hit) + } else { + (fg, bg, gray, yellow) + }; + let yellow = Style::default().fg(yellow).bg(bg); + let gray = Style::default().fg(gray).bg(bg); + let gutter = if is_hit { + Span::styled("! ", Color::Red) + } else { + Span::styled("", Style::default()) + }; + let line = match &bp.ty { + BreakpointType::Next | BreakpointType::Step => unreachable!(), + BreakpointType::StepN(n) => Line::from(vec![ + gutter, + Span::styled("cycle:", yellow), + Span::styled(format!("{}", bp.creation_cycle + *n), gray), + ]), + BreakpointType::StepTo(cycle) => Line::from(vec![ + gutter, + Span::styled("cycle:", yellow), + Span::styled(format!("{cycle}"), gray), + ]), + BreakpointType::File(ref pattern) => Line::from(vec![ + gutter, + Span::styled("file:", yellow), + Span::styled(pattern.as_str(), gray), + ]), + BreakpointType::Line { ref pattern, line } => Line::from(vec![ + gutter, + Span::styled("file:", yellow), + Span::styled(pattern.as_str(), gray), + Span::styled(format!(":{line}"), yellow), + ]), + BreakpointType::Called(ref pattern) => Line::from(vec![ + gutter, + Span::styled("proc:", yellow), + Span::styled(pattern.as_str(), gray), + ]), + BreakpointType::Opcode(ref op) => Line::from(vec![ + gutter, + Span::styled("opcode:", yellow), + Span::styled(format!("{op}"), gray), + ]), + }; + if is_hit { + line.patch_style(Style::default().add_modifier(Modifier::BOLD)) + } else { + line + } + }) + .collect::>(); + + let list = List::new(lines) + .block(Block::default().borders(Borders::ALL)) + .highlight_symbol(symbols::scrollbar::HORIZONTAL.end) + .highlight_spacing(HighlightSpacing::Always) + .highlight_style(Style::default().add_modifier(Modifier::BOLD)); + let mut list_state = ListState::default().with_selected(selected_index); + + let pane = Block::default() + .title("Breakpoints") + .borders(Borders::ALL) + .border_style(self.border_style()) + .border_type(self.border_type()); + let pane = if user_breakpoints_hit > 0 { + pane.title_bottom( + Line::styled( + format!( + " {} of {} hit this cycle", + user_breakpoints_hit, user_created_breakpoints, + ), + Style::default().add_modifier(Modifier::ITALIC), + ) + .right_aligned(), + ) + } else { + pane + }; + + frame.render_stateful_widget(list, area, &mut list_state); + frame.render_widget(pane, area); + Ok(()) + } +} diff --git a/midenc-debug/src/ui/panes/debug.rs b/midenc-debug/src/ui/panes/debug.rs new file mode 100644 index 00000000..417fc2c3 --- /dev/null +++ b/midenc-debug/src/ui/panes/debug.rs @@ -0,0 +1,134 @@ +use std::collections::VecDeque; + +use crossterm::event::KeyCode; +use midenc_session::diagnostics::Report; +use ratatui::{ + prelude::*, + widgets::{block::*, *}, +}; + +use crate::{ + logger::{DebugLogger, LogEntry}, + ui::{ + action::Action, + panes::Pane, + state::{InputMode, State}, + tui::{EventResponse, Frame}, + }, +}; + +pub struct DebugPane { + logger: &'static DebugLogger, + entries: VecDeque, + selected_entry: Option, +} +impl Default for DebugPane { + fn default() -> Self { + Self { + logger: DebugLogger::get(), + entries: Default::default(), + selected_entry: None, + } + } +} + +impl DebugPane { + fn level_color(level: log::Level) -> Color { + use log::Level; + match level { + Level::Trace => Color::LightCyan, + Level::Debug => Color::LightMagenta, + Level::Info => Color::LightGreen, + Level::Warn => Color::LightYellow, + Level::Error => Color::LightRed, + } + } +} + +impl Pane for DebugPane { + fn height_constraint(&self) -> Constraint { + Constraint::Fill(3) + } + + fn handle_key_events( + &mut self, + key: crossterm::event::KeyEvent, + state: &mut State, + ) -> Result>, Report> { + match state.input_mode { + InputMode::Normal => { + let response = match key.code { + KeyCode::Down | KeyCode::Char('j') | KeyCode::Char('J') => { + EventResponse::Stop(Action::Down) + } + KeyCode::Up | KeyCode::Char('k') | KeyCode::Char('K') => { + EventResponse::Stop(Action::Up) + } + KeyCode::Esc => EventResponse::Stop(Action::ClosePopup), + _ => { + return Ok(Some(EventResponse::Stop(Action::Noop))); + } + }; + Ok(Some(response)) + } + InputMode::Insert => Ok(Some(EventResponse::Stop(Action::Noop))), + InputMode::Command => Ok(Some(EventResponse::Stop(Action::Noop))), + } + } + + fn update(&mut self, action: Action, _state: &mut State) -> Result, Report> { + let added = self.logger.take_captured(); + self.entries.extend(added); + match action { + Action::Down => { + let selected_entry = self + .selected_entry + .map(|s| s.saturating_add(1) % self.entries.len()) + .unwrap_or(self.entries.len().saturating_sub(1)); + self.selected_entry = Some(selected_entry); + return Ok(Some(Action::Update)); + } + Action::Up => { + let selected_entry = self + .selected_entry + .map(|s| s.wrapping_sub(1) % self.entries.len()) + .unwrap_or(self.entries.len().saturating_sub(1)); + self.selected_entry = Some(selected_entry); + return Ok(Some(Action::Update)); + } + _ => {} + } + Ok(None) + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, _state: &State) -> Result<(), Report> { + frame.render_widget(Clear, area); + let items = self.entries.iter().map(|entry| { + Line::from(vec![ + Span::styled(format!(" {:6} | ", entry.level), Self::level_color(entry.level)), + Span::styled(entry.message.as_str(), Self::level_color(entry.level)), + ]) + }); + let selected = if self.entries.is_empty() { + None + } else { + Some(self.selected_entry.unwrap_or(self.entries.len().saturating_sub(1))) + }; + let list = List::new(items) + .block(Block::default().borders(Borders::ALL)) + .highlight_symbol(symbols::scrollbar::HORIZONTAL.end) + .highlight_spacing(HighlightSpacing::Always) + .highlight_style(Style::default().add_modifier(Modifier::BOLD)); + let mut list_state = ListState::default().with_selected(selected); + + frame.render_stateful_widget(list, area, &mut list_state); + frame.render_widget( + Block::default() + .borders(Borders::ALL) + .title("Debug Log") + .style(Style::default()), + area, + ); + Ok(()) + } +} diff --git a/midenc-debug/src/ui/panes/disasm.rs b/midenc-debug/src/ui/panes/disasm.rs new file mode 100644 index 00000000..c3ae525f --- /dev/null +++ b/midenc-debug/src/ui/panes/disasm.rs @@ -0,0 +1,127 @@ +use midenc_session::diagnostics::{Report, SourceId, SourceSpan}; +use ratatui::{ + prelude::*, + widgets::{block::*, *}, +}; + +use crate::{ + ui::{action::Action, panes::Pane, state::State, tui::Frame}, + ResolvedLocation, +}; + +pub struct DisassemblyPane { + focused: bool, + focused_border_style: Style, +} + +impl DisassemblyPane { + pub fn new(focused: bool, focused_border_style: Style) -> Self { + Self { + focused, + focused_border_style, + } + } + + fn border_style(&self) -> Style { + match self.focused { + true => self.focused_border_style, + false => Style::default(), + } + } + + fn border_type(&self) -> BorderType { + match self.focused { + true => BorderType::Thick, + false => BorderType::Plain, + } + } +} + +impl Pane for DisassemblyPane { + fn height_constraint(&self) -> Constraint { + match self.focused { + true => Constraint::Max(7), + false => Constraint::Max(7), + } + } + + fn update(&mut self, action: Action, _state: &mut State) -> Result, Report> { + match action { + Action::Focus => { + self.focused = true; + } + Action::UnFocus => { + self.focused = false; + } + _ => {} + } + + Ok(None) + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report> { + let (current_proc, lines) = match state.executor.callstack.current_frame() { + None => { + let proc = Line::from("in ").right_aligned(); + ( + proc, + state + .executor + .recent + .iter() + .map(|op| { + Line::from(vec![Span::styled(format!(" | {}", op), Color::White)]) + }) + .collect::>(), + ) + } + Some(frame) => { + let proc = frame + .procedure(state.session.name()) + .map(|proc| Line::from(format!("in {proc}"))) + .unwrap_or_else(|| Line::from("in ")) + .right_aligned(); + ( + proc, + frame + .recent() + .iter() + .map(|op| { + Line::from(vec![Span::styled( + format!(" | {}", &op.display()), + Color::White, + )]) + }) + .collect::>(), + ) + } + }; + let selected_line = lines.len().saturating_sub(1); + + let list = List::new(lines) + .block(Block::default().borders(Borders::ALL)) + .highlight_symbol(symbols::scrollbar::HORIZONTAL.end) + .highlight_spacing(HighlightSpacing::Always) + .highlight_style(Style::default().add_modifier(Modifier::BOLD)); + let mut list_state = ListState::default().with_selected(Some(selected_line)); + + frame.render_stateful_widget(list, area, &mut list_state); + frame.render_widget( + Block::default() + .title("Disassembly") + .borders(Borders::ALL) + .border_style(self.border_style()) + .border_type(self.border_type()) + .title_bottom(current_proc) + .title( + Line::styled( + format!(" at cycle {}", state.executor.cycle), + Style::default().add_modifier(Modifier::ITALIC), + ) + .right_aligned(), + ), + area, + ); + Ok(()) + } +} diff --git a/midenc-debug/src/ui/panes/footer.rs b/midenc-debug/src/ui/panes/footer.rs new file mode 100644 index 00000000..8e43b138 --- /dev/null +++ b/midenc-debug/src/ui/panes/footer.rs @@ -0,0 +1,205 @@ +use std::{collections::VecDeque, time::Instant}; + +use midenc_session::diagnostics::Report; +use ratatui::{ + crossterm::{ + self, + event::{Event, KeyCode, KeyEvent}, + }, + prelude::*, + widgets::Paragraph, +}; +use tui_input::{backend::crossterm::EventHandler, Input}; + +use crate::ui::{ + action::Action, + panes::Pane, + state::{InputMode, State}, + tui::{EventResponse, Frame}, +}; + +struct TimedStatusLine { + created: Instant, + show_time: u64, + status_line: String, +} + +struct Config { + max_command_history: usize, +} + +static CONFIG: Config = Config { + max_command_history: 20, +}; + +#[derive(Default)] +pub struct FooterPane { + focused: bool, + input: Input, + command: String, + status_line: String, + timed_status_line: Option, + command_history: VecDeque, + command_history_index: Option, +} + +impl FooterPane { + pub fn new() -> Self { + Self { + focused: false, + ..Default::default() + } + } + + fn get_status_line(&mut self) -> &String { + if self + .timed_status_line + .as_ref() + .is_some_and(|tsl| tsl.created.elapsed().as_secs() < tsl.show_time) + { + return &self.timed_status_line.as_ref().unwrap().status_line; + } + self.timed_status_line = None; + &self.status_line + } +} + +impl Pane for FooterPane { + fn height_constraint(&self) -> Constraint { + Constraint::Max(1) + } + + fn handle_key_events( + &mut self, + key: KeyEvent, + state: &mut State, + ) -> Result>, Report> { + match state.input_mode { + InputMode::Command => { + self.input.handle_event(&Event::Key(key)); + let response = match key.code { + KeyCode::Enter => { + let command = self.input.to_string(); + if !command.is_empty() { + self.command_history.push_front(self.input.to_string()); + self.command_history.truncate(CONFIG.max_command_history); + self.command_history_index = None; + } + Some(EventResponse::Stop(Action::FooterResult( + self.command.clone(), + Some(command), + ))) + } + KeyCode::Esc => { + self.command_history_index = None; + Some(EventResponse::Stop(Action::FooterResult(self.command.clone(), None))) + } + KeyCode::Up if !self.command_history.is_empty() => { + let history_index = self + .command_history_index + .map(|idx| idx.saturating_add(1) % self.command_history.len()) + .unwrap_or(0); + self.input = self + .input + .clone() + .with_value(self.command_history[history_index].clone()); + self.command_history_index = Some(history_index); + None + } + KeyCode::Down if !self.command_history.is_empty() => { + let history_index = self + .command_history_index + .map(|idx| { + idx.saturating_add(self.command_history.len() - 1) + % self.command_history.len() + }) + .unwrap_or(self.command_history.len() - 1); + self.input = self + .input + .clone() + .with_value(self.command_history[history_index].clone()); + self.command_history_index = Some(history_index); + None + } + _ => None, + }; + Ok(response) + } + _ => Ok(None), + } + } + + fn update(&mut self, action: Action, state: &mut State) -> Result, Report> { + match action { + Action::FocusFooter(cmd, args) => { + self.focused = true; + state.input_mode = InputMode::Command; + if let Some(args) = args { + self.input = self.input.clone().with_value(args); + } else { + self.input = self.input.clone().with_value("".into()); + } + self.command = cmd; + Ok(Some(Action::Update)) + } + Action::FooterResult(..) => { + state.input_mode = InputMode::Normal; + self.focused = false; + Ok(Some(Action::Update)) + } + Action::StatusLine(status_line) => { + self.status_line = status_line; + Ok(None) + } + Action::TimedStatusLine(status_line, show_time) => { + self.timed_status_line = Some(TimedStatusLine { + status_line, + show_time, + created: Instant::now(), + }); + Ok(None) + } + _ => Ok(None), + } + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report> { + if self.focused { + let mut area = area; + area.width = area.width.saturating_sub(4); + + let width = area.width.max(3); + let scroll = self.input.visual_scroll(width as usize - self.command.len()); + let input = Paragraph::new(Line::from(vec![ + Span::styled(&self.command, Style::default().fg(Color::LightBlue)), + Span::styled(self.input.value(), Style::default()), + ])) + .scroll((0, scroll as u16)); + frame.render_widget(input, area); + + frame.set_cursor_position(Position::new( + area.x + + ((self.input.visual_cursor()).max(scroll) - scroll) as u16 + + self.command.len() as u16, + area.y + 1, + )); + } else { + frame.render_widget( + Line::from(vec![Span::styled(self.get_status_line(), Style::default())]) + .style(Style::default().fg(Color::DarkGray)), + area, + ); + } + frame.render_widget( + Line::from(vec![match state.input_mode { + InputMode::Normal => Span::from("[N]"), + InputMode::Insert => Span::from("[I]"), + InputMode::Command => Span::from("[C]"), + }]) + .right_aligned(), + area, + ); + + Ok(()) + } +} diff --git a/midenc-debug/src/ui/panes/header.rs b/midenc-debug/src/ui/panes/header.rs new file mode 100644 index 00000000..14f39617 --- /dev/null +++ b/midenc-debug/src/ui/panes/header.rs @@ -0,0 +1,36 @@ +use midenc_session::diagnostics::Report; +use ratatui::prelude::*; + +use crate::ui::{panes::Pane, state::State, tui::Frame}; + +#[derive(Default)] +pub struct HeaderPane; + +impl HeaderPane { + pub const fn new() -> Self { + Self + } +} + +impl Pane for HeaderPane { + fn height_constraint(&self) -> Constraint { + Constraint::Max(1) + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report> { + frame.render_widget( + Line::from(vec![ + Span::styled( + format!("[ Miden Debugger {} ", symbols::DOT), + Style::default().fg(Color::Blue), + ), + Span::styled("0.1.0", Style::default().fg(Color::LightCyan)), + Span::styled("]", Style::default().fg(Color::Blue)), + ]) + .right_aligned(), + area, + ); + + Ok(()) + } +} diff --git a/midenc-debug/src/ui/panes/mod.rs b/midenc-debug/src/ui/panes/mod.rs new file mode 100644 index 00000000..6038fdf7 --- /dev/null +++ b/midenc-debug/src/ui/panes/mod.rs @@ -0,0 +1,63 @@ +use midenc_session::diagnostics::Report; +use ratatui::{ + crossterm::event::{self, KeyEvent, MouseEvent}, + layout::{Constraint, Rect}, +}; + +use super::{ + action::Action, + state::State, + tui::{Event, EventResponse, Frame}, +}; + +pub mod breakpoints; +pub mod debug; +pub mod disasm; +pub mod footer; +pub mod header; +pub mod source_code; +pub mod stack; +pub mod stacktrace; + +pub trait Pane { + fn init(&mut self, _state: &State) -> Result<(), Report> { + Ok(()) + } + + fn height_constraint(&self) -> Constraint; + + fn handle_events( + &mut self, + event: Event, + state: &mut State, + ) -> Result>, Report> { + let r = match event { + Event::Key(key_event) => self.handle_key_events(key_event, state)?, + Event::Mouse(mouse_event) => self.handle_mouse_events(mouse_event, state)?, + _ => None, + }; + Ok(r) + } + + fn handle_key_events( + &mut self, + _key: KeyEvent, + _state: &mut State, + ) -> Result>, Report> { + Ok(None) + } + + fn handle_mouse_events( + &mut self, + _mouse: MouseEvent, + _state: &mut State, + ) -> Result>, Report> { + Ok(None) + } + + fn update(&mut self, _action: Action, _state: &mut State) -> Result, Report> { + Ok(None) + } + + fn draw(&mut self, f: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report>; +} diff --git a/midenc-debug/src/ui/panes/source_code.rs b/midenc-debug/src/ui/panes/source_code.rs new file mode 100644 index 00000000..a0acac44 --- /dev/null +++ b/midenc-debug/src/ui/panes/source_code.rs @@ -0,0 +1,512 @@ +use std::{collections::BTreeMap, sync::Arc}; + +use miden_assembly::diagnostics::SourceCode; +use midenc_session::diagnostics::{LineIndex, Report, SourceFile, SourceId, SourceSpan}; +use ratatui::{ + prelude::*, + widgets::{block::*, *}, +}; + +use crate::{ + ui::{ + action::Action, + panes::Pane, + state::State, + syntax_highlighting::{Highlighter, HighlighterState, NoopHighlighter, SyntectHighlighter}, + tui::Frame, + }, + ResolvedLocation, +}; + +pub struct SourceCodePane { + focused: bool, + current_source_id: SourceId, + current_span: SourceSpan, + current_line: u32, + current_col: u32, + num_lines: u32, + selected_line: u32, + syntax_highlighter: Box, + syntax_highlighting_states: BTreeMap>, + current_file: Option, + theme: Theme, +} + +struct HighlightedFile { + source_file: Arc, + /// The syntax highlighted lines of `source_file`, cached so that patching + /// them with the current selected line can be done efficiently + lines: Vec>>, + selected_line: u32, + selected_span: SourceSpan, + gutter_width: u8, +} + +impl SourceCodePane { + fn highlight_file(&mut self, resolved: &ResolvedLocation) -> HighlightedFile { + let highlighter_state = self + .syntax_highlighting_states + .entry(resolved.source_file.id()) + .or_insert_with(|| { + let span_contents = resolved + .source_file + .read_span(&resolved.source_file.source_span().into(), 0, 0) + .expect("failed to read span of file"); + self.syntax_highlighter.start_highlighter_state(span_contents.as_ref()) + }); + let resolved_span = resolved.span.into_slice_index(); + let content = resolved.source_file.content(); + let last_line = content.last_line_index(); + let max_line_no = last_line.number().get() as usize; + let gutter_width = max_line_no.ilog10() as u8; + let lines = (0..(max_line_no - 1)) + .map(|line_index| { + let line_index = miden_core::debuginfo::LineIndex::from(line_index as u32); + let line_no = line_index.number().get(); + let span = content.line_range(line_index).expect("invalid line index"); + let span = span.start.to_usize()..span.end.to_usize(); + + let line_content = strip_newline(&content.as_bytes()[span.start..span.end]); + + // Only highlight a portion of the line if the full span fits on that line + let is_highlighted = span.contains(&resolved_span.start) + && span.contains(&resolved_span.end) + && span != resolved_span; + + let line_content = + strip_newline(&content.as_bytes()[span.start..span.end]).into_owned(); + let highlighted = if is_highlighted { + let selection = if resolved.span.is_empty() { + // Select the closest character to the span + //let start = core::cmp::max(span.start, resolved_span.start); + //let end = core::cmp::min(span.end, resolved_span.end.saturating_add(1)); + //(start - span.start)..(end - span.start) + 0..(span.end - span.start) + } else { + (resolved_span.start - span.start)..(resolved_span.end - span.start) + }; + highlighter_state.highlight_line_with_selection( + line_content.into(), + selection, + self.theme.current_span, + ) + } else { + highlighter_state.highlight_line(line_content.into()) + }; + + highlighted + }) + .collect::>(); + + HighlightedFile { + source_file: resolved.source_file.clone(), + lines, + selected_line: resolved.line, + selected_span: resolved.span, + gutter_width, + } + } + + /// Get the cached lines of the source file, or compute them for the first time + /// if the file has changed. + /// + /// Each line consists of a vector of styled [Span]s, so that we can modify the + /// styles based on the relevant source span. + fn current_source_lines(&mut self, resolved: &ResolvedLocation) -> Vec>> { + let file_changed = self + .current_file + .as_ref() + .map(|file| file.source_file.id() != resolved.source_file.id()) + .unwrap_or(true); + + // NOTE: We could cache all of the files we highlight, but that could get memory-dense + if file_changed { + let file = self.highlight_file(resolved); + let lines = file.lines.clone(); + self.current_file = Some(file); + lines + } else { + self.current_file.as_ref().unwrap().lines.clone() + } + } + + /// Get the [ResolvedLocation] for the current state + fn current_location(&self, state: &State) -> Option { + match state.executor.callstack.current_frame() { + Some(frame) => { + let resolved = frame.last_resolved(&state.session); + resolved.cloned() + } + None if !self.current_source_id.is_unknown() => { + let source_file = state.session.source_manager.get(self.current_source_id).ok(); + source_file.map(|src| ResolvedLocation { + source_file: src, + line: self.current_line, + col: self.current_col, + span: self.current_span, + }) + } + None => { + // Render empty source pane + None + } + } + } +} + +struct Theme { + focused_border_style: Style, + current_line: Style, + current_span: Style, + line_number: Style, + gutter_border: Style, +} +impl Default for Theme { + fn default() -> Self { + Self { + focused_border_style: Style::default(), + current_line: Style::default() + .bg(Color::Black) + .fg(Color::White) + .add_modifier(Modifier::BOLD), + current_span: Style::default() + .fg(Color::White) + .bg(Color::DarkGray) + .add_modifier(Modifier::BOLD), + line_number: Style::default(), + gutter_border: Style::default(), + } + } +} +impl Theme { + pub fn patch_from_syntect(&mut self, theme: &syntect::highlighting::Theme) { + use crate::ui::syntax_highlighting::convert_color; + if let Some(bg) = theme.settings.line_highlight.map(convert_color) { + self.current_line.bg = Some(bg); + } + if let Some(bg) = theme.settings.selection.map(convert_color) { + self.current_span.bg = Some(bg); + } + if let Some(fg) = theme.settings.selection_foreground.map(convert_color) { + self.current_span.fg = Some(fg); + } + if let Some(bg) = theme.settings.gutter.map(convert_color) { + self.line_number.bg = Some(bg); + self.gutter_border.bg = Some(bg); + } + if let Some(fg) = theme.settings.gutter_foreground.map(convert_color) { + self.line_number.fg = Some(fg); + self.gutter_border.fg = Some(fg); + } + } +} + +impl SourceCodePane { + pub fn new(focused: bool, focused_border_style: Style) -> Self { + let theme = Theme { + focused_border_style, + ..Default::default() + }; + Self { + focused, + current_source_id: SourceId::UNKNOWN, + num_lines: 0, + selected_line: 0, + current_line: 0, + current_col: 0, + current_span: SourceSpan::default(), + syntax_highlighter: Box::new(NoopHighlighter), + syntax_highlighting_states: Default::default(), + current_file: None, + theme, + } + } + + fn reload(&mut self, state: &State) { + self.current_source_id = SourceId::UNKNOWN; + self.current_span = SourceSpan::default(); + self.current_line = 0; + self.current_col = 0; + self.num_lines = 0; + self.selected_line = 0; + self.current_file = None; + + if let Some(frame) = state.executor.callstack.current_frame() { + if let Some(loc) = frame.last_resolved(&state.session) { + self.current_source_id = loc.source_file.id(); + self.current_span = loc.span; + self.current_line = loc.line; + self.current_col = loc.col; + self.num_lines = loc.source_file.line_count() as u32; + self.selected_line = loc.line; + } + } + } + + fn border_style(&self) -> Style { + match self.focused { + true => self.theme.focused_border_style, + false => Style::default(), + } + } + + fn border_type(&self) -> BorderType { + match self.focused { + true => BorderType::Thick, + false => BorderType::Plain, + } + } + + fn enable_syntax_highlighting(&mut self, state: &State) { + use std::io::IsTerminal; + + use midenc_session::diagnostics::ColorChoice; + + let nocolor = match state.session.options.color { + ColorChoice::Always | ColorChoice::AlwaysAnsi => false, + ColorChoice::Never => true, + ColorChoice::Auto => match std::env::var("NO_COLOR") { + _ if !std::io::stdout().is_terminal() => true, + Ok(value) => !matches!(value.as_str(), "0" | "false"), + _ => false, + }, + }; + + if nocolor { + return; + } + + let syntax_set = syntect::parsing::SyntaxSet::load_defaults_nonewlines(); + let theme_set = syntect::highlighting::ThemeSet::load_defaults(); + let theme = theme_set.themes["base16-eighties.dark"].clone(); + self.theme.patch_from_syntect(&theme); + self.syntax_highlighter = Box::new(SyntectHighlighter::new(syntax_set, theme, false)); + } +} + +impl Pane for SourceCodePane { + fn init(&mut self, state: &State) -> Result<(), Report> { + self.enable_syntax_highlighting(state); + + if let Some(frame) = state.executor.callstack.current_frame() { + if let Some(loc) = frame.last_resolved(&state.session) { + self.current_source_id = loc.source_file.id(); + self.current_span = loc.span; + self.current_line = loc.line; + self.current_col = loc.col; + self.num_lines = loc.source_file.line_count() as u32; + self.selected_line = loc.line; + } + } + + Ok(()) + } + + fn height_constraint(&self) -> Constraint { + match self.focused { + true => Constraint::Fill(3), + false => Constraint::Fill(3), + } + } + + fn update(&mut self, action: Action, state: &mut State) -> Result, Report> { + match action { + Action::Down => { + if self.num_lines > 0 { + self.selected_line = self.selected_line.saturating_add(1) % self.num_lines; + } + return Ok(Some(Action::Update)); + } + Action::Up => { + if self.num_lines > 0 { + self.selected_line = + self.selected_line.saturating_add(self.num_lines.saturating_sub(1)) + % self.num_lines; + } + return Ok(Some(Action::Update)); + } + Action::Focus => { + self.focused = true; + static STATUS_LINE: &str = "[j,k → movement]"; + return Ok(Some(Action::TimedStatusLine(STATUS_LINE.into(), 3))); + } + Action::UnFocus => { + self.focused = false; + } + Action::Submit => {} + Action::Update | Action::Reload => { + if action == Action::Reload { + self.reload(state); + } + + if let Some(frame) = state.executor.callstack.current_frame() { + if let Some(loc) = frame.last_resolved(&state.session) { + let source_id = loc.source_file.id(); + if source_id != self.current_source_id { + self.current_source_id = source_id; + self.num_lines = loc.source_file.line_count() as u32; + self.selected_line = loc.line; + } else if self.selected_line != loc.line { + self.selected_line = loc.line; + } + self.current_span = loc.span; + self.current_line = loc.line; + self.current_col = loc.col; + } + } + } + _ => {} + } + + Ok(None) + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report> { + let resolved = self.current_location(state); + if resolved.is_none() { + frame.render_widget( + Block::default() + .title("Source Code") + .borders(Borders::ALL) + .border_style(self.border_style()) + .border_type(self.border_type()) + .title_bottom( + Line::from("no source code available for current instruction") + .right_aligned(), + ) + .title( + Line::styled("nofile", Style::default().add_modifier(Modifier::ITALIC)) + .right_aligned(), + ), + area, + ); + return Ok(()); + } + + let resolved = unsafe { resolved.unwrap_unchecked() }; + + // Get the cached (highlighted) lines for the current source file + let mut lines = self.current_source_lines(&resolved); + let selected_line = resolved.line.saturating_sub(1) as usize; + // Extract the current selected line as a vector of raw syntect parts + let selected_line_deconstructed = lines[selected_line] + .iter() + .map(|span| { + ( + crate::ui::syntax_highlighting::convert_to_syntect_style(span.style, false), + span.content.as_ref(), + ) + }) + .collect::>(); + + // Modify the selected line's highlighting style to reflect the selection + let syntect_style = syntect::highlighting::StyleModifier { + foreground: self + .theme + .current_span + .fg + .map(crate::ui::syntax_highlighting::convert_to_syntect_color), + background: self + .theme + .current_span + .bg + .map(crate::ui::syntax_highlighting::convert_to_syntect_color), + font_style: if self.theme.current_span.add_modifier.is_empty() { + None + } else { + Some(crate::ui::syntax_highlighting::convert_to_font_style( + self.theme.current_span.add_modifier, + )) + }, + }; + let span = resolved + .source_file + .content() + .line_range((selected_line as u32).into()) + .unwrap(); + let resolved_span = resolved.span.into_slice_index(); + let selected = if resolved.span.is_empty() { + // Select the closest character to the span + 0..(span.end.to_usize() - span.start.to_usize()) + } else { + (resolved_span.start - span.start.to_usize()) + ..(resolved_span.end - span.start.to_usize()) + }; + let highlighter_state = + self.syntax_highlighting_states.get_mut(&resolved.source_file.id()).unwrap(); + let mut parts = syntect::util::modify_range( + selected_line_deconstructed.as_slice(), + selected, + syntect_style, + ) + .into_iter() + .map(|(style, str)| { + Span::styled( + str.to_string(), + crate::ui::syntax_highlighting::convert_style(style, true), + ) + }) + .collect(); + lines[selected_line].clear(); + lines[selected_line].append(&mut parts); + + let gutter_width = self.current_file.as_ref().unwrap().gutter_width as usize; + let lines = lines.into_iter().enumerate().map(|(line_index, highlighted_parts)| { + let line_number_style = if line_index == selected_line { + self.theme.current_line + } else { + self.theme.line_number + }; + Line::from_iter( + [ + Span::styled( + format!("{line_no:gutter_width$}", line_no = line_index + 1), + line_number_style, + ), + Span::styled(" | ", line_number_style), + ] + .into_iter() + .chain(highlighted_parts), + ) + }); + + // Render the syntax-highlighted lines + let selected_line = self.selected_line.saturating_sub(1); + let list = List::new(lines) + .block(Block::default().borders(Borders::ALL)) + .highlight_symbol(symbols::scrollbar::HORIZONTAL.end) + .highlight_spacing(HighlightSpacing::Always) + .scroll_padding(15); + let mut list_state = ListState::default().with_selected(Some(selected_line as usize)); + + frame.render_stateful_widget(list, area, &mut list_state); + frame.render_widget( + Block::default() + .title("Source Code") + .borders(Borders::ALL) + .border_style(self.border_style()) + .border_type(self.border_type()) + .title_bottom( + Line::from(format!("{} of {}", self.selected_line, self.num_lines,)) + .right_aligned(), + ) + .title( + Line::styled( + resolved.source_file.path().to_string_lossy(), + Style::default().add_modifier(Modifier::ITALIC), + ) + .right_aligned(), + ), + area, + ); + Ok(()) + } +} + +fn strip_newline(s: &[u8]) -> std::borrow::Cow<'_, str> { + if let Some(sans_newline) = s.strip_suffix(b"\n") { + String::from_utf8_lossy(sans_newline) + } else { + String::from_utf8_lossy(s) + } +} diff --git a/midenc-debug/src/ui/panes/stack.rs b/midenc-debug/src/ui/panes/stack.rs new file mode 100644 index 00000000..cbfc5629 --- /dev/null +++ b/midenc-debug/src/ui/panes/stack.rs @@ -0,0 +1,100 @@ +use midenc_session::diagnostics::{Report, SourceId, SourceSpan}; +use ratatui::{ + prelude::*, + widgets::{block::*, *}, +}; + +use crate::{ + ui::{action::Action, panes::Pane, state::State, tui::Frame}, + ResolvedLocation, +}; + +pub struct OperandStackPane { + focused: bool, + focused_border_style: Style, +} + +impl OperandStackPane { + pub fn new(focused: bool, focused_border_style: Style) -> Self { + Self { + focused, + focused_border_style, + } + } + + fn border_style(&self) -> Style { + match self.focused { + true => self.focused_border_style, + false => Style::default(), + } + } + + fn border_type(&self) -> BorderType { + match self.focused { + true => BorderType::Thick, + false => BorderType::Plain, + } + } +} + +impl Pane for OperandStackPane { + fn height_constraint(&self) -> Constraint { + match self.focused { + true => Constraint::Max(30), + false => Constraint::Max(30), + } + } + + fn update(&mut self, action: Action, _state: &mut State) -> Result, Report> { + match action { + Action::Focus => { + self.focused = true; + } + Action::UnFocus => { + self.focused = false; + } + _ => {} + } + + Ok(None) + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report> { + let lines = match state.executor.last.as_ref() { + None => vec![], + Some(state) => state + .stack + .iter() + .rev() + .map(|item| Line::from(Span::styled(format!(" {}", item.as_int()), Color::White))) + .collect(), + }; + + let depth = lines.len(); + let selected_line = depth.saturating_sub(1); + let list = List::new(lines) + .block(Block::default().borders(Borders::ALL)) + .highlight_symbol(symbols::scrollbar::HORIZONTAL.end) + .highlight_spacing(HighlightSpacing::Always) + .highlight_style(Style::default().add_modifier(Modifier::BOLD)); + let mut list_state = ListState::default().with_selected(Some(selected_line)); + + frame.render_stateful_widget(list, area, &mut list_state); + frame.render_widget( + Block::default() + .title("Operand Stack") + .borders(Borders::ALL) + .border_style(self.border_style()) + .border_type(self.border_type()) + .title_bottom( + Line::styled( + format!("depth is {depth}"), + Style::default().add_modifier(Modifier::ITALIC), + ) + .right_aligned(), + ), + area, + ); + Ok(()) + } +} diff --git a/midenc-debug/src/ui/panes/stacktrace.rs b/midenc-debug/src/ui/panes/stacktrace.rs new file mode 100644 index 00000000..f6f630b1 --- /dev/null +++ b/midenc-debug/src/ui/panes/stacktrace.rs @@ -0,0 +1,154 @@ +use midenc_session::diagnostics::{Report, SourceId, SourceSpan}; +use ratatui::{ + prelude::*, + widgets::{block::*, *}, +}; + +use crate::{ + ui::{action::Action, panes::Pane, state::State, tui::Frame}, + ResolvedLocation, +}; + +pub struct StackTracePane { + focused: bool, + focused_border_style: Style, +} + +impl StackTracePane { + pub fn new(focused: bool, focused_border_style: Style) -> Self { + Self { + focused, + focused_border_style, + } + } + + fn border_style(&self) -> Style { + match self.focused { + true => self.focused_border_style, + false => Style::default(), + } + } + + fn border_type(&self) -> BorderType { + match self.focused { + true => BorderType::Thick, + false => BorderType::Plain, + } + } +} + +impl Pane for StackTracePane { + fn height_constraint(&self) -> Constraint { + match self.focused { + true => Constraint::Max(15), + false => Constraint::Max(15), + } + } + + fn update(&mut self, action: Action, _state: &mut State) -> Result, Report> { + match action { + Action::Focus => { + self.focused = true; + } + Action::UnFocus => { + self.focused = false; + } + _ => {} + } + + Ok(None) + } + + fn draw(&mut self, frame: &mut Frame<'_>, area: Rect, state: &State) -> Result<(), Report> { + let mut lines = Vec::default(); + let num_frames = state.executor.callstack.frames().len(); + for (i, frame) in state.executor.callstack.frames().iter().enumerate() { + let is_top = i + 1 == num_frames; + let mut parts = vec![]; + /* + let gutter = if is_top { + Span::styled(" `-> ", Color::Magenta) + } else { + Span::styled(" |-> ", Color::Gray) + }; + */ + let gutter = Span::styled(" ", Color::White); + parts.push(gutter); + let name = frame.procedure(state.session.name()); + let name = name.as_deref().unwrap_or("").to_string(); + let name = if is_top { + Span::styled(name, Color::Gray) + } else { + Span::styled( + name, + Style::default().fg(Color::White).bg(Color::Black).add_modifier(Modifier::BOLD), + ) + }; + parts.push(name); + if let Some(resolved) = frame.last_resolved(&state.session) { + parts.push(Span::styled(" in ", Color::DarkGray)); + let path = resolved.source_file.path(); + let path = path + .strip_prefix(state.session.options.current_dir.as_path()) + .ok() + .unwrap_or(path); + let path_str = path.to_string_lossy(); + let max_width = (area.as_size().width as usize).saturating_sub(4); + let path_width = path_str.chars().count(); + if path_width >= max_width { + let trim_min = path_width - max_width; + let mut taken = 0; + let mut components = path.components(); + while taken < trim_min { + match components.next() { + Some(std::path::Component::CurDir) => break, + Some( + std::path::Component::ParentDir + | std::path::Component::Prefix(_) + | std::path::Component::RootDir, + ) => continue, + Some(std::path::Component::Normal(c)) => { + let c = c.to_string_lossy(); + taken += c.chars().count(); + } + None => break, + } + } + parts.push(Span::styled( + format!("{}", components.as_path().display()), + Color::Cyan, + )); + } else { + parts.push(Span::styled(path_str, Color::Cyan)); + } + parts.push(Span::styled( + format!(" {}:{}", resolved.line, resolved.col), + Color::Green, + )); + } else { + parts.push(Span::styled(" in ", Color::DarkGray)); + } + lines.push(Line::from(parts)); + } + + let selected_line = lines.len().saturating_sub(1); + + let list = List::new(lines) + .block(Block::default().borders(Borders::ALL)) + .highlight_symbol(symbols::scrollbar::HORIZONTAL.end) + .highlight_spacing(HighlightSpacing::Always) + .highlight_style(Style::default().add_modifier(Modifier::BOLD)); + let mut list_state = ListState::default().with_selected(Some(selected_line)); + + frame.render_stateful_widget(list, area, &mut list_state); + frame.render_widget( + Block::default() + .title("Stack Trace") + .borders(Borders::ALL) + .border_style(self.border_style()) + .border_type(self.border_type()), + area, + ); + Ok(()) + } +} diff --git a/midenc-debug/src/ui/state.rs b/midenc-debug/src/ui/state.rs new file mode 100644 index 00000000..f54282f8 --- /dev/null +++ b/midenc-debug/src/ui/state.rs @@ -0,0 +1,320 @@ +use std::{rc::Rc, sync::Arc}; + +use miden_assembly::Library; +use miden_core::{utils::Deserializable, FieldElement}; +use miden_processor::{Felt, Program, StackInputs}; +use midenc_session::{ + diagnostics::{IntoDiagnostic, Report, SourceSpan, Span, WrapErr}, + InputType, Session, +}; + +use crate::{ + Breakpoint, BreakpointType, DebugExecutor, ExecutionTrace, ProgramInputs, ReadMemoryExpr, +}; + +pub struct State { + pub program: Arc, + pub inputs: ProgramInputs, + pub executor: DebugExecutor, + pub execution_trace: ExecutionTrace, + pub execution_failed: Option, + pub session: Rc, + pub input_mode: InputMode, + pub breakpoints: Vec, + pub breakpoints_hit: Vec, + pub next_breakpoint_id: u8, + pub stopped: bool, +} + +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] +pub enum InputMode { + #[default] + Normal, + Insert, + Command, +} + +impl State { + pub fn from_inputs( + inputs: Option, + mut args: Vec, + session: Rc, + ) -> Result { + let mut inputs = inputs.unwrap_or_default(); + if !args.is_empty() { + args.reverse(); + inputs.inputs = StackInputs::new(args).into_diagnostic()?; + } + let args = inputs.inputs.values().iter().copied().rev().collect::>(); + let program = load_program(&session)?; + + let mut executor = crate::Executor::new(args.clone()); + executor.with_advice_inputs(inputs.advice_inputs.clone()); + for link_library in session.options.link_libraries.iter() { + let lib = link_library.load(&session)?; + executor.with_library(&lib); + } + + let executor = executor.into_debug(&program, &session); + + // Execute the program until it terminates to capture a full trace for use during debugging + let mut trace_executor = crate::Executor::new(args); + trace_executor.with_advice_inputs(inputs.advice_inputs.clone()); + for link_library in session.options.link_libraries.iter() { + let lib = link_library.load(&session)?; + trace_executor.with_library(&lib); + } + + let execution_trace = trace_executor.capture_trace(&program, &session); + + Ok(Self { + program, + inputs, + executor, + execution_trace, + execution_failed: None, + session, + input_mode: InputMode::Normal, + breakpoints: vec![], + breakpoints_hit: vec![], + next_breakpoint_id: 0, + stopped: true, + }) + } + + pub fn reload(&mut self) -> Result<(), Report> { + log::debug!("reloading program"); + let program = load_program(&self.session)?; + let args = self.inputs.inputs.values().iter().copied().rev().collect::>(); + + let mut executor = crate::Executor::new(args.clone()); + executor.with_advice_inputs(self.inputs.advice_inputs.clone()); + for link_library in self.session.options.link_libraries.iter() { + let lib = link_library.load(&self.session)?; + executor.with_library(&lib); + } + let executor = executor.into_debug(&self.program, &self.session); + + // Execute the program until it terminates to capture a full trace for use during debugging + let mut trace_executor = crate::Executor::new(args); + trace_executor.with_advice_inputs(self.inputs.advice_inputs.clone()); + for link_library in self.session.options.link_libraries.iter() { + let lib = link_library.load(&self.session)?; + trace_executor.with_library(&lib); + } + let execution_trace = trace_executor.capture_trace(&program, &self.session); + + self.program = program; + self.executor = executor; + self.execution_trace = execution_trace; + self.execution_failed = None; + self.breakpoints_hit.clear(); + let breakpoints = core::mem::take(&mut self.breakpoints); + self.breakpoints.reserve(breakpoints.len()); + self.next_breakpoint_id = 0; + self.stopped = true; + for bp in breakpoints { + self.create_breakpoint(bp.ty); + } + Ok(()) + } + + pub fn create_breakpoint(&mut self, ty: BreakpointType) { + let id = self.next_breakpoint_id(); + let creation_cycle = self.executor.cycle; + log::trace!("created breakpoint with id {id} at cycle {creation_cycle}"); + self.breakpoints.push(Breakpoint { + id, + creation_cycle, + ty, + }); + } + + fn next_breakpoint_id(&mut self) -> u8 { + let mut candidate = self.next_breakpoint_id; + let mut initial = candidate; + let mut next = candidate.wrapping_add(1); + loop { + assert_ne!(initial, next, "unable to allocate a breakpoint id: too many breakpoints"); + if self + .breakpoints + .iter() + .chain(self.breakpoints_hit.iter()) + .any(|bp| bp.id == candidate) + { + candidate = next; + continue; + } + self.next_breakpoint_id = next; + break candidate; + } + } +} + +macro_rules! write_with_format_type { + ($out:ident, $read_expr:ident, $value:expr) => { + match $read_expr.format { + crate::FormatType::Decimal => write!(&mut $out, "{}", $value).unwrap(), + crate::FormatType::Hex => write!(&mut $out, "{:0x}", $value).unwrap(), + crate::FormatType::Binary => write!(&mut $out, "{:0b}", $value).unwrap(), + } + }; +} + +impl State { + pub fn read_memory(&self, expr: &ReadMemoryExpr) -> Result { + use core::fmt::Write; + + use midenc_hir::Type; + + let cycle = miden_processor::RowIndex::from(self.executor.cycle); + let context = self.executor.current_context; + let mut output = String::new(); + if expr.count > 1 { + return Err("-count with value > 1 is not yet implemented".into()); + } else if matches!(expr.ty, Type::Felt) { + if !expr.addr.is_element_aligned() { + return Err( + "read failed: type 'felt' must be aligned to an element boundary".into() + ); + } + let felt = self + .execution_trace + .read_memory_element_in_context(expr.addr.waddr, expr.addr.index, context, cycle) + .unwrap_or(Felt::ZERO); + write_with_format_type!(output, expr, felt.as_int()); + } else if matches!(expr.ty, Type::Array(ref elem_ty, 4) if elem_ty.as_ref() == &Type::Felt) + { + if !expr.addr.is_word_aligned() { + return Err("read failed: type 'word' must be aligned to a word boundary".into()); + } + let word = self.execution_trace.read_memory_word(expr.addr.waddr).unwrap_or_default(); + output.push('['); + for (i, elem) in word.iter().enumerate() { + if i > 0 { + output.push_str(", "); + } + write_with_format_type!(output, expr, elem.as_int()); + } + output.push(']'); + } else { + let bytes = self + .execution_trace + .read_bytes_for_type(expr.addr, &expr.ty, context, cycle) + .map_err(|err| format!("invalid read: {err}"))?; + match &expr.ty { + Type::I1 => match expr.format { + crate::FormatType::Decimal => write!(&mut output, "{}", bytes[0] != 0).unwrap(), + crate::FormatType::Hex => { + write!(&mut output, "{:#0x}", (bytes[0] != 0) as u8).unwrap() + } + crate::FormatType::Binary => { + write!(&mut output, "{:#0b}", (bytes[0] != 0) as u8).unwrap() + } + }, + Type::I8 => write_with_format_type!(output, expr, bytes[0] as i8), + Type::U8 => write_with_format_type!(output, expr, bytes[0]), + Type::I16 => { + write_with_format_type!(output, expr, i16::from_be_bytes([bytes[0], bytes[1]])) + } + Type::U16 => { + write_with_format_type!(output, expr, u16::from_be_bytes([bytes[0], bytes[1]])) + } + Type::I32 => write_with_format_type!( + output, + expr, + i32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) + ), + Type::U32 => write_with_format_type!( + output, + expr, + u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) + ), + ty @ (Type::I64 | Type::U64) => { + let mut hi = + u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as u64; + let mut lo = + u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]) as u64; + let val = (hi * 2u64.pow(32)) + lo; + if matches!(ty, Type::I64) { + write_with_format_type!(output, expr, val as i64) + } else { + write_with_format_type!(output, expr, val) + } + } + ty => { + return Err(format!("support for reads of type '{ty}' are not implemented yet")) + } + } + } + + Ok(output) + } +} + +fn load_program(session: &Session) -> Result, Report> { + if let Some(entry) = session.options.entrypoint.as_ref() { + // Input must be a library, not a program + let id = entry + .parse::() + .map_err(|_| Report::msg(format!("invalid function identifier: '{entry}'")))?; + let library = match session.inputs[0].file { + InputType::Real(ref path) => read_library(path)?, + InputType::Stdin { ref input, .. } => Library::read_from_bytes(input) + .map_err(|err| Report::msg(format!("failed to read library from stdin: {err}")))?, + }; + let module = library + .module_infos() + .find(|info| info.path().path() == id.module.as_str()) + .ok_or_else(|| { + Report::msg(format!( + "invalid entrypoint: library does not contain a module named '{}'", + id.module.as_str() + )) + })?; + let name = miden_assembly::ast::ProcedureName::new_unchecked( + miden_assembly::ast::Ident::new_unchecked(Span::new( + SourceSpan::UNKNOWN, + Arc::from(id.function.as_str()), + )), + ); + if let Some(digest) = module.get_procedure_digest_by_name(&name) { + let node_id = library.mast_forest().find_procedure_root(digest).ok_or_else(|| { + Report::msg( + "invalid entrypoint: malformed library - procedure exported, but digest has \ + no node in the forest", + ) + })?; + Ok(Arc::new(Program::new(library.mast_forest().clone(), node_id))) + } else { + Err(Report::msg(format!( + "invalid entrypoint: library does not export '{}'", + id.display() + ))) + } + } else { + match session.inputs[0].file { + InputType::Real(ref path) => read_program(path), + InputType::Stdin { ref input, .. } => Program::read_from_bytes(input) + .map(Arc::new) + .map_err(|err| Report::msg(format!("failed to read program from stdin: {err}",))), + } + } +} + +fn read_program(path: &std::path::Path) -> Result, Report> { + use miden_core::utils::ReadAdapter; + let bytes = std::fs::read(path) + .into_diagnostic() + .wrap_err_with(|| format!("failed to open program file '{}'", path.display()))?; + let mut reader = miden_core::utils::SliceReader::new(bytes.as_slice()); + Program::read_from(&mut reader).map(Arc::new).map_err(|err| { + Report::msg(format!("failed to read program from '{}': {err}", path.display())) + }) +} + +fn read_library(path: &std::path::Path) -> Result { + Library::deserialize_from_file(path).map_err(|err| { + Report::msg(format!("failed to read library from '{}': {err}", path.display())) + }) +} diff --git a/midenc-debug/src/ui/syntax_highlighting.rs b/midenc-debug/src/ui/syntax_highlighting.rs new file mode 100644 index 00000000..cd495a45 --- /dev/null +++ b/midenc-debug/src/ui/syntax_highlighting.rs @@ -0,0 +1,459 @@ +use std::{borrow::Cow, ops::Range, path::Path, rc::Rc}; + +mod syntax { + pub(super) use syntect::{ + highlighting::{ + Color, FontStyle, HighlightIterator, HighlightState, Highlighter, Style, StyleModifier, + Theme, ThemeSet, + }, + parsing::{ParseState, ScopeStack, SyntaxReference, SyntaxSet}, + }; +} + +use midenc_session::diagnostics::miette::SpanContents; +use ratatui::{ + style::{Color, Modifier, Style}, + text::{Line, Span}, +}; + +pub trait Highlighter { + /// Creates a new [HighlighterState] to begin parsing and highlighting + /// a [SpanContents]. + /// + /// The [GraphicalReportHandler](crate::GraphicalReportHandler) will call + /// this method at the start of rendering a [SpanContents]. + /// + /// The [SpanContents] is provided as input only so that the [Highlighter] + /// can detect language syntax and make other initialization decisions prior + /// to highlighting, but it is not intended that the Highlighter begin + /// highlighting at this point. The returned [HighlighterState] is + /// responsible for the actual rendering. + fn start_highlighter_state(&self, source: &dyn SpanContents<'_>) -> Box; +} + +/// A stateful highlighter that incrementally highlights lines of a particular +/// source code. +/// +/// The [GraphicalReportHandler](crate::GraphicalReportHandler) +/// will create a highlighter state by calling +/// [start_highlighter_state](Highlighter::start_highlighter_state) at the +/// start of rendering, then it will iteratively call +/// [highlight_line](HighlighterState::highlight_line) to render individual +/// highlighted lines. This allows [Highlighter] implementations to maintain +/// mutable parsing and highlighting state. +pub trait HighlighterState { + /// Highlight an individual line from the source code by returning a vector of [Styled] + /// regions. + fn highlight_line<'a>(&mut self, line: Cow<'a, str>) -> Vec>; + fn highlight_line_with_selection<'a>( + &mut self, + line: Cow<'a, str>, + selected: Range, + style: Style, + ) -> Vec>; +} + +/// The fallback syntax highlighter. +/// +/// This simply returns a line without any styling at all +#[derive(Debug, Clone)] +pub struct NoopHighlighter; + +impl Highlighter for NoopHighlighter { + fn start_highlighter_state(&self, _source: &dyn SpanContents<'_>) -> Box { + Box::new(NoopHighlighterState) + } +} + +impl Default for NoopHighlighter { + fn default() -> Self { + NoopHighlighter + } +} + +/// The fallback highlighter state. +#[derive(Debug, Clone)] +pub struct NoopHighlighterState; + +impl HighlighterState for NoopHighlighterState { + fn highlight_line<'a>(&mut self, line: Cow<'a, str>) -> Vec> { + vec![Span::raw(line)] + } + + fn highlight_line_with_selection<'a>( + &mut self, + line: Cow<'a, str>, + selected: Range, + style: Style, + ) -> Vec> { + default_line_with_selection(line, selected, style) + } +} + +fn default_line_with_selection( + line: Cow<'_, str>, + selected: Range, + style: Style, +) -> Vec> { + let prefix_content = + core::str::from_utf8(&line.as_bytes()[..selected.start]).expect("invalid selection"); + let selected_content = + core::str::from_utf8(&line.as_bytes()[selected.clone()]).expect("invalid selection"); + let suffix_content = + core::str::from_utf8(&line.as_bytes()[selected.end..]).expect("invalid selection"); + let (selected_content, suffix_content) = if suffix_content.is_empty() { + (selected_content.strip_suffix('\n').unwrap_or(selected_content), suffix_content) + } else { + (selected_content, suffix_content.strip_suffix('\n').unwrap_or(suffix_content)) + }; + vec![ + Span::raw(prefix_content.to_string()), + Span::styled(selected_content.to_string(), style), + Span::raw(suffix_content.to_string()), + ] +} + +/// Syntax highlighting provided by [syntect](https://docs.rs/syntect/latest/syntect/). +/// +/// Currently only 24-bit truecolor output is supported due to syntect themes +/// representing color as RGBA. +#[derive(Debug, Clone)] +pub struct SyntectHighlighter { + theme: &'static syntax::Theme, + syntax_set: Rc, + use_bg_color: bool, +} + +impl Default for SyntectHighlighter { + fn default() -> Self { + let theme_set = syntax::ThemeSet::load_defaults(); + let theme = theme_set.themes["base16-ocean.dark"].clone(); + Self::new_themed(theme, false) + } +} + +impl Highlighter for SyntectHighlighter { + fn start_highlighter_state(&self, source: &dyn SpanContents<'_>) -> Box { + if let Some(syntax) = self.detect_syntax(source) { + let highlighter = syntax::Highlighter::new(self.theme); + let parse_state = syntax::ParseState::new(syntax); + let highlight_state = + syntax::HighlightState::new(&highlighter, syntax::ScopeStack::new()); + Box::new(SyntectHighlighterState { + syntax_set: Rc::clone(&self.syntax_set), + highlighter, + parse_state, + highlight_state, + use_bg_color: self.use_bg_color, + }) + } else { + Box::new(NoopHighlighterState) + } + } +} + +impl SyntectHighlighter { + /// Create a syntect highlighter with the given theme and syntax set. + pub fn new(syntax_set: syntax::SyntaxSet, theme: syntax::Theme, use_bg_color: bool) -> Self { + // This simplifies a lot of things API-wise, we only ever really have one of these anyway + let theme = Box::leak(Box::new(theme)); + Self { + theme, + syntax_set: Rc::new(syntax_set), + use_bg_color, + } + } + + /// Create a syntect highlighter with the given theme and the default syntax set. + pub fn new_themed(theme: syntax::Theme, use_bg_color: bool) -> Self { + Self::new(syntax::SyntaxSet::load_defaults_nonewlines(), theme, use_bg_color) + } + + /// Determine syntect SyntaxReference to use for given SourceCode + fn detect_syntax(&self, contents: &dyn SpanContents<'_>) -> Option<&syntax::SyntaxReference> { + // use language if given + if let Some(language) = contents.language() { + return self.syntax_set.find_syntax_by_name(language); + } + // otherwise try to use any file extension provided in the name + if let Some(name) = contents.name() { + if let Some(ext) = Path::new(name).extension() { + return self.syntax_set.find_syntax_by_extension(ext.to_string_lossy().as_ref()); + } + } + // finally, attempt to guess syntax based on first line + return self.syntax_set.find_syntax_by_first_line( + core::str::from_utf8(contents.data()).ok()?.split('\n').next()?, + ); + } +} + +/// Stateful highlighting iterator for [SyntectHighlighter] +#[derive(Debug)] +pub(crate) struct SyntectHighlighterState<'h> { + syntax_set: Rc, + highlighter: syntax::Highlighter<'h>, + parse_state: syntax::ParseState, + highlight_state: syntax::HighlightState, + use_bg_color: bool, +} + +impl<'h> HighlighterState for SyntectHighlighterState<'h> { + fn highlight_line<'a>(&mut self, line: Cow<'a, str>) -> Vec> { + if let Ok(ops) = self.parse_state.parse_line(&line, &self.syntax_set) { + let use_bg_color = self.use_bg_color; + syntax::HighlightIterator::new( + &mut self.highlight_state, + &ops, + &line, + &self.highlighter, + ) + .map(|(style, str)| Span::styled(str.to_string(), convert_style(style, use_bg_color))) + .collect() + } else { + vec![Span::raw(line)] + } + } + + fn highlight_line_with_selection<'a>( + &mut self, + line: Cow<'a, str>, + selected: Range, + style: Style, + ) -> Vec> { + if let Ok(ops) = self.parse_state.parse_line(&line, &self.syntax_set) { + let use_bg_color = self.use_bg_color; + let parts = syntax::HighlightIterator::new( + &mut self.highlight_state, + &ops, + &line, + &self.highlighter, + ) + .collect::>(); + let syntect_style = syntax::StyleModifier { + foreground: style.fg.map(convert_to_syntect_color), + background: style.bg.map(convert_to_syntect_color), + font_style: if style.add_modifier.is_empty() { + None + } else { + Some(convert_to_font_style(style.add_modifier)) + }, + }; + syntect::util::modify_range(&parts, selected, syntect_style) + .into_iter() + .map(|(style, str)| { + Span::styled(str.to_string(), convert_style(style, use_bg_color)) + }) + .collect() + } else { + default_line_with_selection(line, selected, style) + } + } +} + +/// Convert syntect [syntax::Style] into ratatui [Style] */ +#[inline] +pub fn convert_style(syntect_style: syntax::Style, use_bg_color: bool) -> Style { + let style = if use_bg_color { + let fg = blend_fg_color(syntect_style); + let bg = convert_color(syntect_style.background); + Style::new().fg(fg).bg(bg) + } else { + let fg = convert_color(syntect_style.foreground); + Style::new().fg(fg) + }; + let mods = convert_font_style(syntect_style.font_style); + style.add_modifier(mods) +} + +pub fn convert_to_syntect_style(style: Style, use_bg_color: bool) -> syntax::Style { + let fg = style.fg.map(convert_to_syntect_color); + let bg = style.bg.map(convert_to_syntect_color); + let fs = convert_to_font_style(style.add_modifier); + syntax::Style { + foreground: fg.unwrap_or(convert_to_syntect_color(Color::White)), + background: bg.unwrap_or(convert_to_syntect_color(Color::Black)), + font_style: fs, + } +} + +/// Blend foreground RGB into background RGB according to alpha channel +#[inline] +fn blend_fg_color(syntect_style: syntax::Style) -> Color { + let fg = syntect_style.foreground; + if fg.a == 0xff { + return convert_color(fg); + } + let bg = syntect_style.background; + let ratio = fg.a as u32; + let r = (fg.r as u32 * ratio + bg.r as u32 * (255 - ratio)) / 255; + let g = (fg.g as u32 * ratio + bg.g as u32 * (255 - ratio)) / 255; + let b = (fg.b as u32 * ratio + bg.b as u32 * (255 - ratio)) / 255; + Color::from_u32(u32::from_be_bytes([0, r as u8, g as u8, b as u8])) +} + +/// Convert syntect color into ratatui color +/// +/// Note: ignores alpha channel. use [`blend_fg_color`] if you need that +#[inline] +pub fn convert_color(color: syntax::Color) -> Color { + Color::from_u32(u32::from_be_bytes([color.a, color.r, color.g, color.b])) +} + +/// Convert syntect font style into ratatui modifiers +#[inline] +fn convert_font_style(font_style: syntax::FontStyle) -> Modifier { + use syntax::FontStyle; + + let mut mods = Modifier::default(); + if font_style.contains(FontStyle::BOLD) { + mods.insert(Modifier::BOLD); + } + if font_style.contains(FontStyle::ITALIC) { + mods.insert(Modifier::ITALIC); + } + if font_style.contains(FontStyle::UNDERLINE) { + mods.insert(Modifier::UNDERLINED); + } + mods +} + +pub fn convert_to_font_style(mods: Modifier) -> syntax::FontStyle { + use syntax::FontStyle; + + let mut style = FontStyle::default(); + if mods.contains(Modifier::BOLD) { + style.insert(FontStyle::BOLD); + } + if mods.contains(Modifier::ITALIC) { + style.insert(FontStyle::ITALIC); + } + if mods.contains(Modifier::UNDERLINED) { + style.insert(FontStyle::UNDERLINE); + } + style +} + +pub fn convert_to_syntect_color(color: Color) -> syntax::Color { + match color { + Color::Rgb(r, g, b) => syntax::Color { r, g, b, a: 0 }, + Color::Indexed(code) => convert_to_syntect_color(match code { + 0 => Color::Black, + 1 => Color::Red, + 2 => Color::Green, + 3 => Color::Yellow, + 4 => Color::Blue, + 5 => Color::Magenta, + 6 => Color::Cyan, + 7 => Color::Gray, + 8 => Color::DarkGray, + 9 => Color::LightRed, + 10 => Color::LightGreen, + 11 => Color::LightYellow, + 12 => Color::LightBlue, + 13 => Color::LightMagenta, + 14 => Color::LightCyan, + 15 => Color::White, + code => panic!("unrecognized ansi color index: {code}"), + }), + Color::Black => syntax::Color { + r: 0, + g: 0, + b: 0, + a: u8::MAX, + }, + Color::Green => syntax::Color { + r: 0, + g: 128, + b: 0, + a: u8::MAX, + }, + Color::LightGreen => syntax::Color { + r: 0, + g: 255, + b: 0, + a: u8::MAX, + }, + Color::Red => syntax::Color { + r: 128, + g: 0, + b: 0, + a: u8::MAX, + }, + Color::LightRed => syntax::Color { + r: 255, + g: 0, + b: 0, + a: u8::MAX, + }, + Color::Yellow => syntax::Color { + r: 128, + g: 128, + b: 0, + a: u8::MAX, + }, + Color::LightYellow => syntax::Color { + r: 255, + g: 255, + b: 0, + a: u8::MAX, + }, + Color::Blue => syntax::Color { + r: 0, + g: 0, + b: 128, + a: u8::MAX, + }, + Color::LightBlue => syntax::Color { + r: 0, + g: 0, + b: 255, + a: u8::MAX, + }, + Color::DarkGray => syntax::Color { + r: 128, + g: 128, + b: 128, + a: u8::MAX, + }, + Color::Gray => syntax::Color { + r: 192, + g: 192, + b: 192, + a: u8::MAX, + }, + Color::White => syntax::Color { + r: 255, + g: 255, + b: 255, + a: u8::MAX, + }, + Color::Magenta => syntax::Color { + r: 128, + g: 0, + b: 128, + a: u8::MAX, + }, + Color::LightMagenta => syntax::Color { + r: 255, + g: 0, + b: 255, + a: u8::MAX, + }, + Color::Cyan => syntax::Color { + r: 0, + g: 128, + b: 128, + a: u8::MAX, + }, + Color::LightCyan => syntax::Color { + r: 0, + g: 255, + b: 255, + a: u8::MAX, + }, + Color::Reset => { + panic!("invalid syntax color: reset cannot be used for syntax highlighting") + } + } +} diff --git a/midenc-debug/src/ui/tui.rs b/midenc-debug/src/ui/tui.rs new file mode 100644 index 00000000..b663ce1a --- /dev/null +++ b/midenc-debug/src/ui/tui.rs @@ -0,0 +1,253 @@ +use std::{ + ops::{Deref, DerefMut}, + time::Duration, +}; + +use futures::{FutureExt, StreamExt}; +use midenc_session::diagnostics::{IntoDiagnostic, Report, WrapErr}; +use ratatui::{ + backend::CrosstermBackend as Backend, + crossterm::{ + self, cursor, + event::{ + DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture, + Event as CrosstermEvent, KeyEvent, KeyEventKind, MouseEvent, + }, + terminal::{EnterAlternateScreen, LeaveAlternateScreen}, + }, +}; +use tokio::{ + sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, + task::JoinHandle, +}; +use tokio_util::sync::CancellationToken; + +pub type Frame<'a> = ratatui::Frame<'a>; + +#[derive(Clone, Debug)] +pub enum Event { + Init, + Quit, + Error, + Closed, + Tick, + Render, + FocusGained, + FocusLost, + Paste(String), + Key(KeyEvent), + Mouse(MouseEvent), + Resize(u16, u16), +} + +pub enum EventResponse { + Continue(T), + Stop(T), +} + +pub struct Tui { + pub terminal: ratatui::Terminal>, + pub task: JoinHandle<()>, + pub cancellation_token: CancellationToken, + pub event_rx: UnboundedReceiver, + pub event_tx: UnboundedSender, + pub frame_rate: f64, + pub tick_rate: f64, + pub mouse: bool, + pub paste: bool, +} + +impl Tui { + pub fn new() -> Result { + let tick_rate = 4.0; + let frame_rate = 60.0; + let terminal = ratatui::Terminal::new(Backend::new(std::io::stdout())).into_diagnostic()?; + let (event_tx, event_rx) = mpsc::unbounded_channel(); + let cancellation_token = CancellationToken::new(); + let task = tokio::spawn(async {}); + let mouse = false; + let paste = false; + Ok(Self { + terminal, + task, + cancellation_token, + event_rx, + event_tx, + frame_rate, + tick_rate, + mouse, + paste, + }) + } + + pub fn tick_rate(mut self, tick_rate: f64) -> Self { + self.tick_rate = tick_rate; + self + } + + pub fn frame_rate(mut self, frame_rate: f64) -> Self { + self.frame_rate = frame_rate; + self + } + + pub fn mouse(mut self, mouse: bool) -> Self { + self.mouse = mouse; + self + } + + pub fn paste(mut self, paste: bool) -> Self { + self.paste = paste; + self + } + + pub fn start(&mut self) { + let tick_delay = std::time::Duration::from_secs_f64(1.0 / self.tick_rate); + let render_delay = std::time::Duration::from_secs_f64(1.0 / self.frame_rate); + self.cancel(); + self.cancellation_token = CancellationToken::new(); + let _cancellation_token = self.cancellation_token.clone(); + let _event_tx = self.event_tx.clone(); + self.task = tokio::spawn(async move { + let mut reader = ::crossterm::event::EventStream::new(); + let mut tick_interval = tokio::time::interval(tick_delay); + let mut render_interval = tokio::time::interval(render_delay); + _event_tx.send(Event::Init).unwrap(); + loop { + let tick_delay = tick_interval.tick(); + let render_delay = render_interval.tick(); + let crossterm_event = reader.next().fuse(); + tokio::select! { + _ = _cancellation_token.cancelled() => { + break; + } + maybe_event = crossterm_event => { + match maybe_event { + Some(Ok(evt)) => { + match evt { + CrosstermEvent::Key(key) => { + if key.kind == KeyEventKind::Press { + _event_tx.send(Event::Key(key)).unwrap(); + } + }, + CrosstermEvent::Mouse(mouse) => { + _event_tx.send(Event::Mouse(mouse)).unwrap(); + }, + CrosstermEvent::Resize(x, y) => { + _event_tx.send(Event::Resize(x, y)).unwrap(); + }, + CrosstermEvent::FocusLost => { + _event_tx.send(Event::FocusLost).unwrap(); + }, + CrosstermEvent::FocusGained => { + _event_tx.send(Event::FocusGained).unwrap(); + }, + CrosstermEvent::Paste(s) => { + _event_tx.send(Event::Paste(s)).unwrap(); + }, + } + } + Some(Err(_)) => { + _event_tx.send(Event::Error).unwrap(); + } + None => {}, + } + }, + _ = tick_delay => { + _event_tx.send(Event::Tick).unwrap(); + }, + _ = render_delay => { + _event_tx.send(Event::Render).unwrap(); + }, + } + } + }); + } + + pub fn stop(&self) -> Result<(), Report> { + self.cancel(); + let mut counter = 0; + while !self.task.is_finished() { + std::thread::sleep(Duration::from_millis(1)); + counter += 1; + if counter > 50 { + self.task.abort(); + } + if counter > 100 { + log::error!("Failed to abort task in 100 milliseconds for unknown reason"); + break; + } + } + Ok(()) + } + + pub fn enter(&mut self) -> Result<(), Report> { + crossterm::terminal::enable_raw_mode().into_diagnostic()?; + crossterm::execute!(std::io::stderr(), EnterAlternateScreen, cursor::Hide) + .into_diagnostic()?; + if self.mouse { + crossterm::execute!(std::io::stderr(), EnableMouseCapture).into_diagnostic()?; + } + if self.paste { + crossterm::execute!(std::io::stderr(), EnableBracketedPaste).into_diagnostic()?; + } + self.start(); + Ok(()) + } + + pub fn exit(&mut self) -> Result<(), Report> { + self.stop()?; + if crossterm::terminal::is_raw_mode_enabled().into_diagnostic()? { + self.flush().into_diagnostic()?; + if self.paste { + crossterm::execute!(std::io::stderr(), DisableBracketedPaste).into_diagnostic()?; + } + if self.mouse { + crossterm::execute!(std::io::stderr(), DisableMouseCapture).into_diagnostic()?; + } + crossterm::execute!(std::io::stderr(), LeaveAlternateScreen, cursor::Show) + .into_diagnostic()?; + crossterm::terminal::disable_raw_mode().into_diagnostic()?; + } + Ok(()) + } + + pub fn cancel(&self) { + self.cancellation_token.cancel(); + } + + pub fn suspend(&mut self) -> Result<(), Report> { + self.exit()?; + #[cfg(not(windows))] + signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).into_diagnostic()?; + Ok(()) + } + + pub fn resume(&mut self) -> Result<(), Report> { + self.enter()?; + Ok(()) + } + + pub async fn next(&mut self) -> Option { + self.event_rx.recv().await + } +} + +impl Deref for Tui { + type Target = ratatui::Terminal>; + + fn deref(&self) -> &Self::Target { + &self.terminal + } +} + +impl DerefMut for Tui { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.terminal + } +} + +impl Drop for Tui { + fn drop(&mut self) { + self.exit().unwrap(); + } +} diff --git a/midenc-driver/Cargo.toml b/midenc-driver/Cargo.toml index 826a8e1a..09382776 100644 --- a/midenc-driver/Cargo.toml +++ b/midenc-driver/Cargo.toml @@ -14,10 +14,10 @@ readme.workspace = true edition.workspace = true [dependencies] -anyhow.workspace = true clap.workspace = true +log.workspace = true midenc-hir.workspace = true -miden-diagnostics.workspace = true midenc-session.workspace = true midenc-compile.workspace = true +midenc-debug.workspace = true thiserror.workspace = true diff --git a/midenc-driver/src/lib.rs b/midenc-driver/src/lib.rs index 74dbcd86..ac78228d 100644 --- a/midenc-driver/src/lib.rs +++ b/midenc-driver/src/lib.rs @@ -1,38 +1,51 @@ mod midenc; +pub use clap::Error as ClapError; +use log::Log; +pub use midenc_session::diagnostics; +use midenc_session::diagnostics::{miette, Diagnostic, Report}; + pub use self::midenc::Midenc; -/// A convenience alias for `Result` -pub type DriverResult = Result; - -/// This error type is produced by the `midenc` driver -#[derive(Debug, thiserror::Error)] -pub enum DriverError { - /// An error was raised due to invalid command-line arguments or argument validation - #[error(transparent)] - Clap(#[from] clap::Error), - /// Compilation failed - #[error(transparent)] - Compile(#[from] midenc_compile::CompilerError), - /// An error occurred when reading a file - #[error(transparent)] - Io(#[from] std::io::Error), - /// An unexpected error occurred - #[error(transparent)] - Failed(#[from] anyhow::Error), - /// An error was emitted as a diagnostic, so we don't need to emit info to stdout - #[error("exited due to error: see diagnostics for details")] - Reported, +/// A convenience alias for `Result` +pub type DriverResult = Result; + +#[derive(Debug, thiserror::Error, Diagnostic)] +#[error(transparent)] +#[diagnostic()] +pub struct ClapDiagnostic { + #[from] + err: ClapError, +} +impl ClapDiagnostic { + pub fn exit(self) -> ! { + self.err.exit() + } } /// Run the driver as if it was invoked from the command-line -pub fn run(cwd: P, args: A) -> Result<(), DriverError> +pub fn run(cwd: P, args: A, logger: Box) -> Result<(), Report> where P: Into, A: IntoIterator, { - match Midenc::run(cwd, args) { - Err(DriverError::Compile(midenc_compile::CompilerError::Stopped)) => Ok(()), + setup_diagnostics(); + + match Midenc::run(cwd, args, logger) { + Err(report) => match report.downcast::() { + Ok(_) => Ok(()), + Err(report) => Err(report), + }, result => result, } } + +fn setup_diagnostics() { + use diagnostics::ReportHandlerOpts; + + let result = + diagnostics::reporting::set_hook(Box::new(|_| Box::new(ReportHandlerOpts::new().build()))); + if result.is_ok() { + diagnostics::reporting::set_panic_hook(); + } +} diff --git a/midenc-driver/src/midenc.rs b/midenc-driver/src/midenc.rs index d6643890..8399ed1c 100644 --- a/midenc-driver/src/midenc.rs +++ b/midenc-driver/src/midenc.rs @@ -1,12 +1,16 @@ -use std::{ffi::OsString, path::PathBuf, sync::Arc}; +use std::{ffi::OsString, path::PathBuf, rc::Rc, sync::Arc}; use clap::{ColorChoice, Parser, Subcommand}; -use miden_diagnostics::Emitter; +use log::Log; use midenc_compile as compile; +use midenc_debug as debugger; use midenc_hir::FunctionIdent; -use midenc_session::{InputFile, TargetEnv, VerbosityFlag, Warnings}; +use midenc_session::{ + diagnostics::{Emitter, Report}, + InputFile, Verbosity, Warnings, +}; -use super::DriverError; +use crate::ClapDiagnostic; /// This struct provides the command-line interface used by `midenc` #[derive(Debug, Parser)] @@ -19,7 +23,15 @@ pub struct Midenc { #[derive(Debug, Subcommand)] enum Commands { - Compile(compile::Compiler), + Compile { + /// The input file to compile + /// + /// You may specify `-` to read from stdin, otherwise you must provide a path + #[arg(required(true), value_name = "FILE")] + input: InputFile, + #[command(flatten)] + options: compile::Compiler, + }, /// Execute a compiled function using the Miden VM emulator. /// /// The emulator is more restrictive, but is faster than the Miden VM, and @@ -46,11 +58,11 @@ enum Commands { short = 'v', value_name = "LEVEL", value_enum, - default_value_t = VerbosityFlag::Info, + default_value_t = Verbosity::Info, default_missing_value = "debug", help_heading = "Diagnostics", )] - verbosity: VerbosityFlag, + verbosity: Verbosity, /// Specify how warnings should be treated by the compiler. #[arg( long, @@ -81,17 +93,24 @@ enum Commands { #[arg(long, short = 'e', value_name = "NAME")] entrypoint: Option, }, - /// Compile and run a program with the Miden VM + /// Run a program under the interactive Miden VM debugger /// - /// The program will be compiled to Miden Assembly and then run with the Miden VM. - /// - /// The inputs given must constitute a valid executable program. - Run { - /// Specify one or more input files to compile as part of the program to execute + /// This command starts a TUI-based interactive debugger with the given program loaded. + Debug { + /// Specify the path to a Miden program file to execute. + /// + /// Miden Assembly programs are emitted by the compiler with a `.masl` extension. /// /// You may use `-` as a file name to read a file from stdin. #[arg(required(true), value_name = "FILE")] input: InputFile, + /// Specify the path to a file containing program inputs. + /// + /// Program inputs are stack and advice provider values which the program can + /// access during execution. The inputs file is a JSON file which describes + /// what the inputs are, or where to source them from. + #[arg(long, value_name = "FILE")] + inputs: Option, /// Arguments to place on the operand stack before calling the program entrypoint. /// /// Arguments will be pushed on the operand stack in the order of appearance, @@ -99,68 +118,30 @@ enum Commands { /// Example: `-- a b` will push `a` on the stack, then `b`. /// /// These arguments must be valid field element values expressed in decimal format. - #[arg(last(true), value_name = "ARGV")] - args: Vec, - /// Specify what type and level of informational output to emit - #[arg( - long = "verbose", - short = 'v', - value_name = "LEVEL", - value_enum, - default_value_t = VerbosityFlag::Info, - default_missing_value = "debug", - help_heading = "Diagnostics", - )] - verbosity: VerbosityFlag, - /// Specify how warnings should be treated by the compiler. - #[arg( - long, - short = 'W', - value_name = "LEVEL", - value_enum, - default_value_t = Warnings::All, - help_heading = "Diagnostics", - )] - warn: Warnings, - /// Whether, and how, to color terminal output - #[arg(long, value_enum, default_value_t = ColorChoice::Auto, default_missing_value = "auto", help_heading = "Diagnostics")] - color: ColorChoice, - /// Write all intermediate compiler artifacts to `` - /// - /// Defaults to a directory named `target` in the current working directory - #[arg( - long, - value_name = "DIR", - hide(true), - env = "MIDENC_TARGET_DIR", - help_heading = "Output" - )] - target_dir: Option, - /// The target environment to compile for - #[arg(long, value_name = "TARGET", hide(true), default_value_t = TargetEnv::Base)] - target: TargetEnv, - /// Specify the fully-qualified name of the function to invoke as the program entrypoint /// - /// For example, `foo::bar` - #[arg(long, short = 'e', value_name = "NAME")] - entrypoint: Option, + /// NOTE: These arguments will override any stack values provided via --inputs + #[arg(last(true), value_name = "ARGV")] + args: Vec, + #[command(flatten)] + options: debugger::Debugger, }, } impl Midenc { - pub fn run(cwd: P, args: A) -> Result<(), DriverError> + pub fn run(cwd: P, args: A, logger: Box) -> Result<(), Report> where P: Into, A: IntoIterator, { - Self::run_with_emitter(cwd, args, None) + Self::run_with_emitter(cwd, args, None, logger) } pub fn run_with_emitter( cwd: P, args: A, emitter: Option>, - ) -> Result<(), DriverError> + logger: Box, + ) -> Result<(), Report> where P: Into, A: IntoIterator, @@ -168,31 +149,44 @@ impl Midenc { let command = ::command(); let command = command.mut_subcommand("compile", compile::register_flags); - let mut matches = command.try_get_matches_from(args)?; + let mut matches = command.try_get_matches_from(args).map_err(ClapDiagnostic::from)?; let compile_matches = matches.subcommand_matches("compile").cloned().unwrap_or_default(); let cli = ::from_arg_matches_mut(&mut matches) - .map_err(format_error::)?; + .map_err(format_error::) + .map_err(ClapDiagnostic::from)?; - cli.invoke(cwd.into(), emitter, compile_matches) + cli.invoke(cwd.into(), emitter, logger, compile_matches) } fn invoke( self, cwd: PathBuf, emitter: Option>, + logger: Box, matches: clap::ArgMatches, - ) -> Result<(), DriverError> { + ) -> Result<(), Report> { match self.command { - Commands::Compile(mut config) => { - if config.working_dir.is_none() { - config.working_dir = Some(cwd); + Commands::Compile { input, mut options } => { + log::set_boxed_logger(logger) + .unwrap_or_else(|err| panic!("failed to install logger: {err}")); + if options.working_dir.is_none() { + options.working_dir = Some(cwd); } - let session = config.into_session(emitter).with_arg_matches(matches); - match compile::compile(Arc::new(session)) { - Ok(_) => Ok(()), - Err(compile::CompilerError::Reported) => Err(DriverError::Reported), - Err(err) => Err(DriverError::Compile(err)), + let session = options.into_session(vec![input], emitter).with_arg_matches(matches); + compile::compile(Rc::new(session)) + } + Commands::Debug { + input, + inputs, + args, + mut options, + } => { + if options.working_dir.is_none() { + options.working_dir = Some(cwd); } + let session = options.into_session(vec![input], emitter); + let args = args.into_iter().map(|felt| felt.0).collect(); + debugger::run(inputs, args, Rc::new(session), logger) } _ => unimplemented!(), } diff --git a/midenc-session/Cargo.toml b/midenc-session/Cargo.toml index a39fb730..03eb744f 100644 --- a/midenc-session/Cargo.toml +++ b/midenc-session/Cargo.toml @@ -17,7 +17,11 @@ edition.workspace = true atty = "0.2" clap.workspace = true inventory.workspace = true +miden-assembly.workspace = true +miden-core.workspace = true +miden-stdlib.workspace = true miden-diagnostics.workspace = true midenc-hir-symbol.workspace = true -rustc-hash.workspace = true +midenc-hir-macros.workspace = true +miden-base-sys = { version = "0.0.0", path = "../sdk/base-sys", features = ["masl-lib"] } thiserror.workspace = true diff --git a/midenc-session/build.rs b/midenc-session/build.rs new file mode 100644 index 00000000..2062cd65 --- /dev/null +++ b/midenc-session/build.rs @@ -0,0 +1,37 @@ +use std::{env, str}; + +fn main() { + println!("cargo::rerun-if-env-changed=MIDENC_BUILD_VERSION"); + println!("cargo::rerun-if-env-changed=MIDENC_BUILD_REV"); + println!("cargo::rerun-if-env-changed=CARGO_PKG_VERSION"); + println!("cargo::rerun-if-env-changed=PROFILE"); + + if let Some(sha) = git_describe() { + println!("cargo::rustc-env=MIDENC_BUILD_REV={sha}"); + } else { + println!("cargo::rustc-env=MIDENC_BUILD_REV=unknown"); + } + + if let Ok(version) = env::var("MIDENC_BUILD_VERSION") { + println!("cargo::rustc-env=MIDENC_BUILD_VERSION={}", &version); + return; + } + + let version = env::var("CARGO_PKG_VERSION").unwrap(); + let profile = env::var("PROFILE").unwrap(); + if profile == "debug" { + println!("cargo::rustc-env=MIDENC_BUILD_VERSION=nightly-{version}"); + } else { + println!("cargo::rustc-env=MIDENC_BUILD_VERSION={version}"); + } +} + +fn git_describe() -> Option { + use std::process::Command; + + Command::new("git") + .args(["describe", "--tags", "--always"]) + .output() + .ok() + .and_then(|out| str::from_utf8(&out.stdout[..]).map(str::trim).map(str::to_owned).ok()) +} diff --git a/midenc-session/src/diagnostics.rs b/midenc-session/src/diagnostics.rs new file mode 100644 index 00000000..a21b2841 --- /dev/null +++ b/midenc-session/src/diagnostics.rs @@ -0,0 +1,392 @@ +use std::{ + collections::BTreeMap, + fmt::{self, Display}, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, +}; + +pub use miden_assembly::diagnostics::{ + miette, + miette::MietteDiagnostic as AdHocDiagnostic, + reporting, + reporting::{PrintDiagnostic, ReportHandlerOpts}, + Diagnostic, IntoDiagnostic, Label, LabeledSpan, RelatedError, RelatedLabel, Report, Severity, + WrapErr, +}; +pub use miden_core::debuginfo::*; +pub use miden_diagnostics::{ + term::termcolor::{Buffer as EmitterBuffer, ColorChoice}, + CaptureEmitter, DefaultEmitter, Emitter, FatalError, NullEmitter, +}; +pub use midenc_hir_macros::Spanned; + +use crate::{Verbosity, Warnings}; + +#[derive(Default, Debug, Copy, Clone)] +pub struct DiagnosticsConfig { + pub verbosity: Verbosity, + pub warnings: Warnings, +} + +pub struct DiagnosticsHandler { + emitter: Arc, + source_manager: Arc, + err_count: AtomicUsize, + verbosity: Verbosity, + warnings: Warnings, + silent: bool, +} + +impl Default for DiagnosticsHandler { + fn default() -> Self { + let emitter = Arc::new(DefaultEmitter::new(ColorChoice::Auto)); + let source_manager = Arc::new(DefaultSourceManager::default()); + Self::new(Default::default(), source_manager, emitter) + } +} + +// We can safely implement these traits for DiagnosticsHandler, +// as the only two non-atomic fields are read-only after creation +unsafe impl Send for DiagnosticsHandler {} +unsafe impl Sync for DiagnosticsHandler {} + +impl DiagnosticsHandler { + /// Create a new [DiagnosticsHandler] from the given [DiagnosticsConfig], + /// [CodeMap], and [Emitter] implementation. + pub fn new( + config: DiagnosticsConfig, + source_manager: Arc, + emitter: Arc, + ) -> Self { + let warnings = match config.warnings { + Warnings::Error => Warnings::Error, + _ if config.verbosity > Verbosity::Warning => Warnings::None, + warnings => warnings, + }; + Self { + emitter, + source_manager, + err_count: AtomicUsize::new(0), + verbosity: config.verbosity, + warnings, + silent: config.verbosity == Verbosity::Silent, + } + } + + #[inline] + pub fn source_manager(&self) -> Arc { + self.source_manager.clone() + } + + #[inline] + pub fn source_manager_ref(&self) -> &dyn SourceManager { + self.source_manager.as_ref() + } + + /// Returns true if the [DiagnosticsHandler] has emitted any error diagnostics + pub fn has_errors(&self) -> bool { + self.err_count.load(Ordering::Relaxed) > 0 + } + + /// Triggers a panic if the [DiagnosticsHandler] has emitted any error diagnostics + #[track_caller] + pub fn abort_if_errors(&self) { + if self.has_errors() { + FatalError.raise(); + } + } + + /// Emits an error message and produces a FatalError object + /// which can be used to terminate execution immediately + pub fn fatal(&self, err: impl ToString) -> FatalError { + self.error(err); + FatalError + } + + /// Emit a diagnostic [Report] + pub fn report(&self, report: impl Into) { + self.emit(report.into()) + } + + /// Report an error diagnostic + pub fn error(&self, error: impl ToString) { + self.emit(Report::msg(error.to_string())); + } + + /// Report a warning diagnostic + /// + /// If `warnings_as_errors` is set, it produces an error diagnostic instead. + pub fn warn(&self, warning: impl ToString) { + if matches!(self.warnings, Warnings::Error) { + return self.error(warning); + } + let diagnostic = AdHocDiagnostic::new(warning.to_string()).with_severity(Severity::Warning); + self.emit(diagnostic); + } + + /// Emits an informational diagnostic + pub fn info(&self, message: impl ToString) { + if self.verbosity > Verbosity::Info { + return; + } + let diagnostic = AdHocDiagnostic::new(message.to_string()).with_severity(Severity::Advice); + self.emit(diagnostic); + } + + /// Starts building an [InFlightDiagnostic] for rich compiler diagnostics. + /// + /// The caller is responsible for dropping/emitting the diagnostic using the + /// [InFlightDiagnostic] API. + pub fn diagnostic(&self, severity: Severity) -> InFlightDiagnosticBuilder<'_> { + InFlightDiagnosticBuilder::new(self, severity) + } + + /// Emits the given diagnostic + #[inline(always)] + pub fn emit(&self, diagnostic: impl Into) { + use std::io::Write; + + let diagnostic: Report = diagnostic.into(); + let diagnostic = match diagnostic.severity() { + Some(Severity::Advice) if self.verbosity > Verbosity::Info => return, + Some(Severity::Warning) => match self.warnings { + Warnings::None => return, + Warnings::All => diagnostic, + Warnings::Error => { + self.err_count.fetch_add(1, Ordering::Relaxed); + Report::from(WarningAsError::from(diagnostic)) + } + }, + Some(Severity::Error) => { + self.err_count.fetch_add(1, Ordering::Relaxed); + diagnostic + } + _ => diagnostic, + }; + + if self.silent { + return; + } + + let mut buffer = self.emitter.buffer(); + let printer = PrintDiagnostic::new(diagnostic); + write!(&mut buffer, "{printer}").expect("failed to write diagnostic to buffer"); + self.emitter.print(buffer).unwrap(); + } +} + +#[derive(thiserror::Error, Diagnostic, Debug)] +#[error("{}", .report)] +#[diagnostic( + severity(Error), + help("this warning was promoted to an error via --warnings-as-errors") +)] +struct WarningAsError { + #[diagnostic_source] + report: Report, +} +impl From for WarningAsError { + fn from(report: Report) -> Self { + Self { report } + } +} + +/// Constructs an in-flight diagnostic using the builder pattern +pub struct InFlightDiagnosticBuilder<'h> { + handler: &'h DiagnosticsHandler, + diagnostic: InFlightDiagnostic, + /// The source id of the primary diagnostic being constructed, if known + primary_source_id: Option, + /// The set of secondary labels which reference code in other source files than the primary + references: BTreeMap, +} +impl<'h> InFlightDiagnosticBuilder<'h> { + pub(crate) fn new(handler: &'h DiagnosticsHandler, severity: Severity) -> Self { + Self { + handler, + diagnostic: InFlightDiagnostic::new(severity), + primary_source_id: None, + references: BTreeMap::default(), + } + } + + /// Sets the primary diagnostic message to `message` + pub fn with_message(mut self, message: impl ToString) -> Self { + self.diagnostic.message = message.to_string(); + self + } + + /// Sets the error code for this diagnostic + pub fn with_code(mut self, code: impl ToString) -> Self { + self.diagnostic.code = Some(code.to_string()); + self + } + + /// Sets the error url for this diagnostic + pub fn with_url(mut self, url: impl ToString) -> Self { + self.diagnostic.url = Some(url.to_string()); + self + } + + /// Adds a primary label for `span` to this diagnostic, with no label message. + pub fn with_primary_span(mut self, span: SourceSpan) -> Self { + use miden_assembly::diagnostics::LabeledSpan; + + assert!(self.diagnostic.labels.is_empty(), "cannot set the primary span more than once"); + let source_id = span.source_id(); + let source_file = self.handler.source_manager.get(source_id).ok(); + self.primary_source_id = Some(source_id); + self.diagnostic.source_code = source_file; + self.diagnostic.labels.push(LabeledSpan::new_primary_with_span(None, span)); + self + } + + /// Adds a primary label for `span` to this diagnostic, with the given message + /// + /// A primary label is one which should be rendered as the relevant source code + /// at which a diagnostic originates. Secondary labels are used for related items + /// involved in the diagnostic. + pub fn with_primary_label(mut self, span: SourceSpan, message: impl ToString) -> Self { + use miden_assembly::diagnostics::LabeledSpan; + + assert!(self.diagnostic.labels.is_empty(), "cannot set the primary span more than once"); + let source_id = span.source_id(); + let source_file = self.handler.source_manager.get(source_id).ok(); + self.primary_source_id = Some(source_id); + self.diagnostic.source_code = source_file; + self.diagnostic + .labels + .push(LabeledSpan::new_primary_with_span(Some(message.to_string()), span)); + self + } + + /// Adds a secondary label for `span` to this diagnostic, with the given message + /// + /// A secondary label is used to point out related items in the source code which + /// are relevant to the diagnostic, but which are not themselves the point at which + /// the diagnostic originates. + pub fn with_secondary_label(mut self, span: SourceSpan, message: impl ToString) -> Self { + use miden_assembly::diagnostics::LabeledSpan; + + assert!( + !self.diagnostic.labels.is_empty(), + "must set a primary label before any secondary labels" + ); + let source_id = span.source_id(); + if source_id != self.primary_source_id.unwrap_or_default() { + let related = self.references.entry(source_id).or_insert_with(|| { + let source_file = self.handler.source_manager.get(source_id).ok(); + RelatedLabel::advice("see diagnostics for more information") + .with_source_file(source_file) + }); + related.labels.push(Label::new(span, message.to_string())); + } else { + self.diagnostic + .labels + .push(LabeledSpan::new_with_span(Some(message.to_string()), span)); + } + self + } + + /// Adds a note to the diagnostic + /// + /// Notes are used for explaining general concepts or suggestions + /// related to a diagnostic, and are not associated with any particular + /// source location. They are always rendered after the other diagnostic + /// content. + pub fn with_help(mut self, note: impl ToString) -> Self { + self.diagnostic.help = Some(note.to_string()); + self + } + + /// Consume this [InFlightDiagnostic] and create a [Report] + pub fn into_report(mut self) -> Report { + if self.diagnostic.message.is_empty() { + self.diagnostic.message = "reported".into(); + } + self.diagnostic.related.extend(self.references.into_values()); + Report::from(self.diagnostic) + } + + /// Emit the underlying [Diagnostic] via the [DiagnosticHandler] + pub fn emit(self) { + let handler = self.handler; + handler.emit(self.into_report()); + } +} + +#[derive(Default)] +struct InFlightDiagnostic { + source_code: Option>, + severity: Option, + message: String, + code: Option, + help: Option, + url: Option, + labels: Vec, + related: Vec, +} + +impl InFlightDiagnostic { + fn new(severity: Severity) -> Self { + Self { + severity: Some(severity), + ..Default::default() + } + } +} + +impl fmt::Display for InFlightDiagnostic { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", &self.message) + } +} + +impl fmt::Debug for InFlightDiagnostic { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", &self.message) + } +} + +impl std::error::Error for InFlightDiagnostic {} + +impl Diagnostic for InFlightDiagnostic { + fn code<'a>(&'a self) -> Option> { + self.code.as_ref().map(Box::new).map(|c| c as Box) + } + + fn severity(&self) -> Option { + self.severity + } + + fn help<'a>(&'a self) -> Option> { + self.help.as_ref().map(Box::new).map(|c| c as Box) + } + + fn url<'a>(&'a self) -> Option> { + self.url.as_ref().map(Box::new).map(|c| c as Box) + } + + fn labels(&self) -> Option + '_>> { + if self.labels.is_empty() { + return None; + } + let iter = self.labels.iter().cloned(); + Some(Box::new(iter) as Box>) + } + + fn related(&self) -> Option + '_>> { + if self.related.is_empty() { + return None; + } + + let iter = self.related.iter().map(|r| r as &dyn Diagnostic); + Some(Box::new(iter) as Box>) + } + + fn diagnostic_source(&self) -> Option<&(dyn Diagnostic + '_)> { + None + } +} diff --git a/midenc-session/src/duration.rs b/midenc-session/src/duration.rs index 88681479..34aae7d9 100644 --- a/midenc-session/src/duration.rs +++ b/midenc-session/src/duration.rs @@ -20,6 +20,11 @@ impl From for HumanDuration { Self(d) } } +impl fmt::Debug for HumanDuration { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} impl fmt::Display for HumanDuration { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let t = self.0.as_secs(); diff --git a/midenc-session/src/emit.rs b/midenc-session/src/emit.rs index 1804aab3..281c25e5 100644 --- a/midenc-session/src/emit.rs +++ b/midenc-session/src/emit.rs @@ -1,29 +1,47 @@ -use std::{fs::File, io::Write, path::Path}; +use std::{fmt, fs::File, io::Write, path::Path, sync::Arc}; +use miden_core::{prettier::PrettyPrint, utils::Serializable}; use midenc_hir_symbol::Symbol; -use crate::OutputType; +use crate::{OutputMode, OutputType, Session}; pub trait Emit { /// The name of this item, if applicable fn name(&self) -> Option; - /// The output type associated with this item - fn output_type(&self) -> OutputType; - /// Write this item to standard output - fn write_to_stdout(&self) -> std::io::Result<()> { + /// The output type associated with this item and the given `mode` + fn output_type(&self, mode: OutputMode) -> OutputType; + /// Write this item to standard output, inferring the best [OutputMode] based on whether or not + /// stdout is a tty or not + fn write_to_stdout(&self, session: &Session) -> std::io::Result<()> { let stdout = std::io::stdout().lock(); - self.write_to(stdout) + let mode = if atty::is(atty::Stream::Stdout) { + OutputMode::Text + } else { + OutputMode::Binary + }; + self.write_to(stdout, mode, session) } - /// Write this item to the given file path - fn write_to_file(&self, path: &Path) -> std::io::Result<()> { + /// Write this item to the given file path, using `mode` to determine the output type + fn write_to_file( + &self, + path: &Path, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()> { if let Some(dir) = path.parent() { std::fs::create_dir_all(dir)?; } let file = File::create(path)?; - self.write_to(file) + self.write_to(file, mode, session) } - /// Write this item to the given [std::io::Write] handle - fn write_to(&self, writer: W) -> std::io::Result<()>; + /// Write this item to the given [std::io::Write] handle, using `mode` to determine the output + /// type + fn write_to( + &self, + writer: W, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()>; } impl Emit for Box { @@ -33,22 +51,247 @@ impl Emit for Box { } #[inline] - fn output_type(&self) -> OutputType { - (**self).output_type() + fn output_type(&self, mode: OutputMode) -> OutputType { + (**self).output_type(mode) } #[inline] - fn write_to_stdout(&self) -> std::io::Result<()> { - (**self).write_to_stdout() + fn write_to_stdout(&self, session: &Session) -> std::io::Result<()> { + (**self).write_to_stdout(session) } #[inline] - fn write_to_file(&self, path: &Path) -> std::io::Result<()> { - (**self).write_to_file(path) + fn write_to_file( + &self, + path: &Path, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()> { + (**self).write_to_file(path, mode, session) } #[inline] - fn write_to(&self, writer: W) -> std::io::Result<()> { - (**self).write_to(writer) + fn write_to( + &self, + writer: W, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()> { + (**self).write_to(writer, mode, session) + } +} + +impl Emit for Arc { + #[inline] + fn name(&self) -> Option { + (**self).name() + } + + #[inline] + fn output_type(&self, mode: OutputMode) -> OutputType { + (**self).output_type(mode) + } + + #[inline] + fn write_to_stdout(&self, session: &Session) -> std::io::Result<()> { + (**self).write_to_stdout(session) + } + + #[inline] + fn write_to_file( + &self, + path: &Path, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()> { + (**self).write_to_file(path, mode, session) + } + + #[inline] + fn write_to( + &self, + writer: W, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()> { + (**self).write_to(writer, mode, session) + } +} + +impl Emit for miden_assembly::ast::Module { + fn name(&self) -> Option { + Some(Symbol::intern(self.path().to_string())) + } + + fn output_type(&self, _mode: OutputMode) -> OutputType { + OutputType::Masm + } + + fn write_to( + &self, + mut writer: W, + mode: OutputMode, + _session: &Session, + ) -> std::io::Result<()> { + assert_eq!(mode, OutputMode::Text, "masm syntax trees do not support binary mode"); + writer.write_fmt(format_args!("{}\n", self)) + } +} + +macro_rules! serialize_into { + ($serializable:ident, $writer:ident) => { + // NOTE: We're protecting against unwinds here due to i/o errors that will get turned into + // panics if writing to the underlying file fails. This is because ByteWriter does not have + // fallible APIs, thus WriteAdapter has to panic if writes fail. This could be fixed, but + // that has to happen upstream in winterfell + std::panic::catch_unwind(move || { + let mut writer = $writer; + $serializable.write_into(&mut writer) + }) + .map_err(|p| { + match p.downcast::() { + // SAFETY: It is guaranteed to be safe to read Box + Ok(err) => unsafe { core::ptr::read(&*err) }, + // Propagate unknown panics + Err(err) => std::panic::resume_unwind(err), + } + }) + }; +} + +impl Emit for miden_assembly::Library { + fn name(&self) -> Option { + None + } + + fn output_type(&self, mode: OutputMode) -> OutputType { + match mode { + OutputMode::Text => OutputType::Mast, + OutputMode::Binary => OutputType::Masl, + } + } + + fn write_to( + &self, + mut writer: W, + mode: OutputMode, + _session: &Session, + ) -> std::io::Result<()> { + struct LibraryTextFormatter<'a>(&'a miden_assembly::Library); + impl<'a> miden_core::prettier::PrettyPrint for LibraryTextFormatter<'a> { + fn render(&self) -> miden_core::prettier::Document { + use miden_core::prettier::*; + + let mast_forest = self.0.mast_forest(); + let mut library_doc = Document::Empty; + for module_info in self.0.module_infos() { + let mut fragments = vec![]; + for (_, info) in module_info.procedures() { + if let Some(proc_node_id) = mast_forest.find_procedure_root(info.digest) { + let proc = mast_forest + .get_node_by_id(proc_node_id) + .expect("malformed mast forest") + .to_pretty_print(mast_forest) + .render(); + fragments.push(indent( + 4, + display(format!("procedure {} ({})", &info.name, &info.digest)) + + nl() + + proc + + nl() + + const_text("end"), + )); + } + } + let module_doc = indent( + 4, + display(format!("module {}", module_info.path())) + + nl() + + fragments + .into_iter() + .reduce(|l, r| l + nl() + nl() + r) + .unwrap_or_default() + + const_text("end"), + ); + if matches!(library_doc, Document::Empty) { + library_doc = module_doc; + } else { + library_doc += nl() + nl() + module_doc; + } + } + library_doc + } + } + impl<'a> fmt::Display for LibraryTextFormatter<'a> { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.pretty_print(f) + } + } + + match mode { + OutputMode::Text => writer.write_fmt(format_args!("{}", LibraryTextFormatter(self))), + OutputMode::Binary => { + self.write_into(&mut writer); + Ok(()) + } + } + } +} + +impl Emit for miden_core::Program { + fn name(&self) -> Option { + None + } + + fn output_type(&self, mode: OutputMode) -> OutputType { + match mode { + OutputMode::Text => OutputType::Mast, + OutputMode::Binary => OutputType::Masl, + } + } + + fn write_to_file( + &self, + path: &Path, + mode: OutputMode, + session: &Session, + ) -> std::io::Result<()> { + if let Some(dir) = path.parent() { + std::fs::create_dir_all(dir)?; + } + let mut file = std::fs::File::create(path)?; + match mode { + OutputMode::Text => self.write_to(&mut file, mode, session), + OutputMode::Binary => serialize_into!(self, file), + } + } + + fn write_to_stdout(&self, session: &Session) -> std::io::Result<()> { + let mut stdout = std::io::stdout().lock(); + let mode = if atty::is(atty::Stream::Stdout) { + OutputMode::Text + } else { + OutputMode::Binary + }; + match mode { + OutputMode::Text => self.write_to(&mut stdout, mode, session), + OutputMode::Binary => serialize_into!(self, stdout), + } + } + + fn write_to( + &self, + mut writer: W, + mode: OutputMode, + _session: &Session, + ) -> std::io::Result<()> { + match mode { + OutputMode::Text => writer.write_fmt(format_args!("{}", self)), + OutputMode::Binary => { + self.write_into(&mut writer); + Ok(()) + } + } } } diff --git a/midenc-session/src/flags.rs b/midenc-session/src/flags.rs index 8d36c499..44f61c0b 100644 --- a/midenc-session/src/flags.rs +++ b/midenc-session/src/flags.rs @@ -1,3 +1,4 @@ +#[derive(Debug)] pub struct CompileFlag { pub name: &'static str, pub short: Option, @@ -8,6 +9,7 @@ pub struct CompileFlag { pub action: FlagAction, pub default_missing_value: Option<&'static str>, pub default_value: Option<&'static str>, + pub hide: Option, } impl CompileFlag { pub const fn new(name: &'static str) -> Self { @@ -21,6 +23,7 @@ impl CompileFlag { action: FlagAction::Set, default_missing_value: None, default_value: None, + hide: None, } } @@ -63,6 +66,11 @@ impl CompileFlag { self.default_missing_value = Some(value); self } + + pub const fn hide(mut self, yes: bool) -> Self { + self.hide = Some(yes); + self + } } #[derive(Debug, Copy, Clone)] diff --git a/midenc-session/src/inputs.rs b/midenc-session/src/inputs.rs index 67ea945c..7135c7b2 100644 --- a/midenc-session/src/inputs.rs +++ b/midenc-session/src/inputs.rs @@ -33,6 +33,24 @@ pub struct InputFile { file_type: FileType, } impl InputFile { + pub fn new(ty: FileType, file: InputType) -> Self { + Self { + file, + file_type: ty, + } + } + + /// Returns an [InputFile] representing an empty WebAssembly module binary + pub fn empty() -> Self { + Self { + file: InputType::Stdin { + name: FileName::Virtual("empty".into()), + input: vec![], + }, + file_type: FileType::Wasm, + } + } + /// Get an [InputFile] representing the contents of `path`. /// /// This function returns an error if the contents are not a valid supported file type. @@ -58,20 +76,23 @@ impl InputFile { pub fn from_bytes(bytes: Vec, name: FileName) -> Result { let file_type = FileType::detect(&bytes)?; - match file_type { - FileType::Hir | FileType::Wasm | FileType::Wat => Ok(Self { - file: InputType::Stdin { name, input: bytes }, - file_type, - }), - // We do not yet have frontends for these file types - FileType::Masm => Err(InvalidInputError::UnsupportedFileType(PathBuf::from("stdin"))), - } + Ok(Self { + file: InputType::Stdin { name, input: bytes }, + file_type, + }) } pub fn file_type(&self) -> FileType { self.file_type } + pub fn file_name(&self) -> FileName { + match &self.file { + InputType::Real(ref path) => FileName::Real(path.clone()), + InputType::Stdin { name, .. } => name.clone(), + } + } + pub fn as_path(&self) -> Option<&Path> { match &self.file { InputType::Real(ref path) => Some(path), @@ -155,6 +176,7 @@ impl clap::builder::TypedValueParser for InputFileParser { pub enum FileType { Hir, Masm, + Mast, Wasm, Wat, } @@ -163,6 +185,7 @@ impl fmt::Display for FileType { match self { Self::Hir => f.write_str("hir"), Self::Masm => f.write_str("masm"), + Self::Mast => f.write_str("mast"), Self::Wasm => f.write_str("wasm"), Self::Wat => f.write_str("wat"), } @@ -174,6 +197,10 @@ impl FileType { return Ok(FileType::Wasm); } + if bytes.starts_with(b"MAST\0") { + return Ok(FileType::Mast); + } + fn is_masm_top_level_item(line: &str) -> bool { line.starts_with("const.") || line.starts_with("export.") || line.starts_with("proc.") } @@ -206,6 +233,7 @@ impl TryFrom<&Path> for FileType { match path.extension().and_then(|ext| ext.to_str()) { Some("hir") => Ok(FileType::Hir), Some("masm") => Ok(FileType::Masm), + Some("masl") | Some("mast") => Ok(FileType::Mast), Some("wasm") => Ok(FileType::Wasm), Some("wat") => Ok(FileType::Wat), _ => Err(InvalidInputError::UnsupportedFileType(path.to_path_buf())), diff --git a/midenc-session/src/lib.rs b/midenc-session/src/lib.rs index 021f4605..e3966e62 100644 --- a/midenc-session/src/lib.rs +++ b/midenc-session/src/lib.rs @@ -1,7 +1,12 @@ +#![feature(debug_closure_helpers)] +extern crate alloc; + +pub mod diagnostics; mod duration; mod emit; mod flags; mod inputs; +mod libs; mod options; mod outputs; mod statistics; @@ -12,17 +17,24 @@ use std::{ sync::Arc, }; +/// The version associated with the current compiler toolchain +pub const MIDENC_BUILD_VERSION: &str = env!("MIDENC_BUILD_VERSION"); + +/// The git revision associated with the current compiler toolchain +pub const MIDENC_BUILD_REV: &str = env!("MIDENC_BUILD_REV"); + use clap::ValueEnum; -use miden_diagnostics::{CodeMap, DiagnosticsHandler, Emitter}; use midenc_hir_symbol::Symbol; pub use self::{ + diagnostics::{DiagnosticsHandler, Emitter, SourceManager}, duration::HumanDuration, emit::Emit, flags::{CompileFlag, FlagAction}, inputs::{FileType, InputFile, InputType, InvalidInputError}, + libs::{LibraryKind, LinkLibrary}, options::*, - outputs::{OutputFile, OutputFiles, OutputType, OutputTypeSpec, OutputTypes}, + outputs::{OutputFile, OutputFiles, OutputMode, OutputType, OutputTypeSpec, OutputTypes}, statistics::Statistics, }; @@ -52,171 +64,205 @@ impl ProjectType { /// This struct provides access to all of the metadata and configuration /// needed during a single compilation session. pub struct Session { - /// The type of project we're compiling this session - pub project_type: ProjectType, - /// The current target environment for this session - pub target: TargetEnv, + /// The name of this session + pub name: String, /// Configuration for the current compiler session pub options: Options, - /// The current source map - pub codemap: Arc, + /// The current source manager + pub source_manager: Arc, /// The current diagnostics handler pub diagnostics: Arc, - /// The location of all libraries shipped with the compiler - pub sysroot: PathBuf, - /// The input being compiled - pub input: InputFile, + /// The inputs being compiled + pub inputs: Vec, /// The outputs to be produced by the compiler during compilation pub output_files: OutputFiles, /// Statistics gathered from the current compiler session pub statistics: Statistics, - /// We store any leftover argument matches in the session for use - /// by any downstream crates that register custom flags - arg_matches: clap::ArgMatches, } + +impl fmt::Debug for Session { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let inputs = self.inputs.iter().map(|input| input.file_name()).collect::>(); + f.debug_struct("Session") + .field("name", &self.name) + .field("options", &self.options) + .field("inputs", &inputs) + .field("output_files", &self.output_files) + .field("statistics", &self.statistics) + .finish_non_exhaustive() + } +} + impl Session { - pub fn new( - target: TargetEnv, - input: InputFile, + pub fn new( + inputs: I, output_dir: Option, output_file: Option, - tmp_dir: Option, + target_dir: PathBuf, options: Options, emitter: Option>, - ) -> Self { - // TODO: Make sure we pin this down when we need to ship stuff with compiler - let sysroot = match &options.sysroot { - Some(sysroot) => sysroot.clone(), - None => std::env::current_dir().unwrap(), - }; - let codemap = Arc::new(CodeMap::new()); + source_manager: Arc, + ) -> Self + where + I: IntoIterator, + { + let inputs = inputs.into_iter().collect::>(); + Self::make(inputs, output_dir, output_file, target_dir, options, emitter, source_manager) + } + + fn make( + inputs: Vec, + output_dir: Option, + output_file: Option, + target_dir: PathBuf, + options: Options, + emitter: Option>, + source_manager: Arc, + ) -> Self { let diagnostics = Arc::new(DiagnosticsHandler::new( - options.diagnostics.clone(), - codemap.clone(), + options.diagnostics, + source_manager.clone(), emitter.unwrap_or_else(|| options.default_emitter()), )); - let output_files = match output_file { - None => { - let output_dir = output_dir.unwrap_or_default(); - let stem = options.name.clone().unwrap_or_else(|| input.filestem().to_owned()); + let output_dir = output_dir + .as_deref() + .or_else(|| output_file.as_ref().and_then(|of| of.parent())) + .map(|path| path.to_path_buf()); + + let name = options + .name + .clone() + .or_else(|| { + output_file + .as_ref() + .and_then(|of| of.filestem().map(|stem| stem.to_string_lossy().into_owned())) + }) + .unwrap_or_else(|| match inputs.first() { + Some(InputFile { + file: InputType::Real(ref path), + .. + }) => path + .file_stem() + .and_then(|stem| stem.to_str()) + .or_else(|| path.extension().and_then(|stem| stem.to_str())) + .unwrap_or_else(|| { + panic!( + "invalid input path: '{}' has no file stem or extension", + path.display() + ) + }) + .to_string(), + Some( + input @ InputFile { + file: InputType::Stdin { ref name, .. }, + .. + }, + ) => { + let name = name.as_str(); + if matches!(name, Some("empty") | Some("stdin")) { + options + .current_dir + .file_stem() + .and_then(|stem| stem.to_str()) + .unwrap_or(name.unwrap()) + .to_string() + } else { + input.filestem().to_owned() + } + } + None => "out".to_owned(), + }); + + let output_files = OutputFiles::new( + name.clone(), + options.current_dir.clone(), + output_dir.unwrap_or_else(|| options.current_dir.clone()), + output_file, + target_dir, + options.output_types.clone(), + ); - OutputFiles::new(stem, output_dir, None, tmp_dir, options.output_types.clone()) - } - Some(out_file) => OutputFiles::new( - out_file.filestem().unwrap_or_default().to_str().unwrap().to_string(), - output_dir.unwrap_or_default(), - Some(out_file), - tmp_dir, - options.output_types.clone(), - ), - }; - - let project_type = ProjectType::default_for_target(target); Self { - project_type, - target, + name, options, - codemap, + source_manager, diagnostics, - sysroot, - input, + inputs, output_files, statistics: Default::default(), - arg_matches: Default::default(), } } pub fn with_project_type(mut self, ty: ProjectType) -> Self { - self.project_type = ty; + self.options.project_type = ty; self } #[doc(hidden)] pub fn with_arg_matches(mut self, matches: clap::ArgMatches) -> Self { - self.arg_matches = matches; + self.options.set_arg_matches(matches); + self + } + + #[doc(hidden)] + pub fn with_output_type(mut self, ty: OutputType, path: Option) -> Self { + self.output_files.outputs.insert(ty, path.clone()); + self.options.output_types.insert(ty, path.clone()); self } /// Get the value of a custom flag with action `FlagAction::SetTrue` or `FlagAction::SetFalse` + #[inline] pub fn get_flag(&self, name: &str) -> bool { - self.arg_matches.get_flag(name) + self.options.get_flag(name) } /// Get the count of a specific custom flag with action `FlagAction::Count` + #[inline] pub fn get_flag_count(&self, name: &str) -> usize { - self.arg_matches.get_count(name) as usize + self.options.get_flag_count(name) } /// Get the value of a specific custom flag + #[inline] pub fn get_flag_value(&self, name: &str) -> Option<&T> where T: core::any::Any + Clone + Send + Sync + 'static, { - self.arg_matches.get_one(name) + self.options.get_flag_value(name) } /// Iterate over values of a specific custom flag + #[inline] pub fn get_flag_values(&self, name: &str) -> Option> where T: core::any::Any + Clone + Send + Sync + 'static, { - self.arg_matches.get_many(name) + self.options.get_flag_values(name) } /// Get the remaining [clap::ArgMatches] left after parsing the base session configuration + #[inline] pub fn matches(&self) -> &clap::ArgMatches { - &self.arg_matches + self.options.matches() } /// The name of this session (used as the name of the project, output file, etc.) - pub fn name(&self) -> String { - self.options - .name - .clone() - .or_else(|| { - if self.input.is_real() { - Some(self.input.filestem().to_string()) - } else { - None - } - }) - .unwrap_or_else(|| { - self.options.current_dir.file_name().unwrap().to_string_lossy().into_owned() - }) + pub fn name(&self) -> &str { + &self.name } - pub fn out_filename(&self, outputs: &OutputFiles, progname: Symbol) -> OutputFile { - let default_filename = self.filename_for_input(outputs, progname); - let out_filename = outputs - .outputs - .get(&OutputType::Mast) - .and_then(|s| s.to_owned()) - .or_else(|| outputs.out_file.clone()) - .unwrap_or(default_filename); + /// Get the [OutputFile] to write the assembled MAST output to + pub fn out_file(&self) -> OutputFile { + let out_file = self.output_files.output_file(OutputType::Masl, None); - if let OutputFile::Real(ref path) = out_filename { + if let OutputFile::Real(ref path) = out_file { self.check_file_is_writeable(path); } - out_filename - } - - pub fn filename_for_input(&self, outputs: &OutputFiles, progname: Symbol) -> OutputFile { - match self.project_type { - ProjectType::Program => { - let out_filename = outputs.path(OutputType::Mast); - if let OutputFile::Real(ref path) = out_filename { - OutputFile::Real(path.with_extension(OutputType::Mast.extension())) - } else { - out_filename - } - } - ProjectType::Library => OutputFile::Real( - outputs.out_dir.join(format!("{progname}.{}", OutputType::Mast.extension())), - ), - } + out_file } fn check_file_is_writeable(&self, file: &Path) { @@ -229,29 +275,61 @@ impl Session { } } + /// Returns true if the compiler should exit after parsing the input pub fn parse_only(&self) -> bool { - self.options.output_types.parse_only() + self.options.parse_only } - pub fn should_codegen(&self) -> bool { - self.options.output_types.should_codegen() + /// Returns true if the compiler should exit after performing semantic analysis + pub fn analyze_only(&self) -> bool { + self.options.analyze_only } + /// Returns true if the compiler should exit after applying rewrites to the IR + pub fn rewrite_only(&self) -> bool { + let link_or_masm_requested = self.should_link() || self.should_codegen(); + !self.options.parse_only && !self.options.analyze_only && !link_or_masm_requested + } + + /// Returns true if an [OutputType] that requires linking + assembly was requested pub fn should_link(&self) -> bool { - self.options.output_types.should_link() + self.options.output_types.should_link() && !self.options.no_link + } + + /// Returns true if an [OutputType] that requires generating Miden Assembly was requested + pub fn should_codegen(&self) -> bool { + self.options.output_types.should_codegen() && !self.options.link_only + } + + /// Returns true if an [OutputType] that requires assembling MAST was requested + pub fn should_assemble(&self) -> bool { + self.options.output_types.should_assemble() && !self.options.link_only } + /// Returns true if the given [OutputType] should be emitted as an output pub fn should_emit(&self, ty: OutputType) -> bool { self.options.output_types.contains_key(&ty) } + /// Returns true if IR should be printed to stdout, after executing a pass named `pass` + pub fn should_print_ir(&self, pass: &str) -> bool { + self.options.print_ir_after_all + || self.options.print_ir_after_pass.iter().any(|p| p == pass) + } + + /// Print the given emittable IR to stdout, as produced by a pass with name `pass` + pub fn print(&self, ir: impl Emit, pass: &str) -> std::io::Result<()> { + if self.should_print_ir(pass) { + ir.write_to_stdout(self)?; + } + Ok(()) + } + /// Get the path to emit the given [OutputType] to pub fn emit_to(&self, ty: OutputType, name: Option) -> Option { if self.should_emit(ty) { - match self.output_files.path(ty) { - OutputFile::Real(path) => name - .map(|name| path.with_file_name(name.as_str()).with_extension(ty.extension())) - .or(Some(path)), + match self.output_files.output_file(ty, name.map(|n| n.as_str())) { + OutputFile::Real(path) => Some(path), OutputFile::Stdout => None, } } else { @@ -260,22 +338,17 @@ impl Session { } /// Emit an item to stdout/file system depending on the current configuration - pub fn emit(&self, item: &E) -> std::io::Result<()> { - let output_type = item.output_type(); + pub fn emit(&self, mode: OutputMode, item: &E) -> std::io::Result<()> { + let output_type = item.output_type(mode); if self.should_emit(output_type) { - match self.output_files.path(output_type) { + let name = item.name().map(|n| n.as_str()); + match self.output_files.output_file(output_type, name) { OutputFile::Real(path) => { - let file_path = if path.is_dir() { - let item_name = - item.name().map(|s| s.to_string()).unwrap_or("noname".to_string()); - path.join(item_name.as_str()).with_extension(output_type.extension()) - } else { - path - }; - item.write_to_file(&file_path)?; + item.write_to_file(&path, mode, self)?; } OutputFile::Stdout => { - item.write_to_stdout()?; + let stdout = std::io::stdout().lock(); + item.write_to(stdout, mode, self)?; } } } diff --git a/midenc-session/src/libs.rs b/midenc-session/src/libs.rs new file mode 100644 index 00000000..4cc59092 --- /dev/null +++ b/midenc-session/src/libs.rs @@ -0,0 +1,274 @@ +use std::{ + borrow::Cow, + ffi::OsStr, + path::{Path, PathBuf}, + str::FromStr, +}; + +use miden_assembly::{Library as CompiledLibrary, LibraryNamespace}; +use miden_base_sys::masl::tx::MidenTxKernelLibrary; +use miden_stdlib::StdLibrary; + +use crate::{ + diagnostics::{IntoDiagnostic, Report, WrapErr}, + Session, +}; + +/// The types of libraries that can be linked against during compilation +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum LibraryKind { + /// A compiled MAST library + #[default] + Mast, + /// A source-form MASM library, using the standard project layout + Masm, +} + +impl FromStr for LibraryKind { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "mast" | "masl" => Ok(Self::Mast), + "masm" => Ok(Self::Masm), + _ => Err(()), + } + } +} + +/// A library requested by the user to be linked against during compilation +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct LinkLibrary { + /// The name of the library. + /// + /// If requested by name, e.g. `-l std`, the name is used as given. + /// + /// If requested by path, e.g. `-l ./target/libs/miden-base.masl`, then the name of the library + /// will be the basename of the file specified in the path. + pub name: Cow<'static, str>, + /// If specified, the path from which this library should be loaded + pub path: Option, + /// The kind of library to load. + /// + /// By default this is assumed to be a `.masl` library, but the kind will be detected based on + /// how it is requested by the user. It may also be specified explicitly by the user. + pub kind: LibraryKind, +} +impl LinkLibrary { + pub fn load(&self, session: &Session) -> Result { + if let Some(path) = self.path.as_deref() { + return self.load_from_path(path, session); + } + + // Handle libraries shipped with the compiler, or via Miden crates + match self.name.as_ref() { + "std" => return Ok(StdLibrary::default().into()), + "base" => return Ok(MidenTxKernelLibrary::default().into()), + _ => (), + } + + // Search for library among specified search paths + let path = self.find(session)?; + + self.load_from_path(&path, session) + } + + fn load_from_path(&self, path: &Path, session: &Session) -> Result { + match self.kind { + LibraryKind::Masm => { + let ns = LibraryNamespace::new(&self.name) + .into_diagnostic() + .wrap_err_with(|| format!("invalid library namespace '{}'", &self.name))?; + let assembler = miden_assembly::Assembler::new(session.source_manager.clone()) + .with_debug_mode(true); + CompiledLibrary::from_dir(path, ns, assembler) + } + LibraryKind::Mast => CompiledLibrary::deserialize_from_file(path).map_err(|err| { + Report::msg(format!( + "failed to deserialize library from '{}': {err}", + path.display() + )) + }), + } + } + + fn find(&self, session: &Session) -> Result { + use std::fs; + + for search_path in session.options.search_paths.iter() { + let reader = fs::read_dir(search_path).map_err(|err| { + Report::msg(format!( + "invalid library search path '{}': {err}", + search_path.display() + )) + })?; + for entry in reader { + let Ok(entry) = entry else { + continue; + }; + let path = entry.path(); + let Some(stem) = path.file_stem().and_then(|stem| stem.to_str()) else { + continue; + }; + if stem != self.name.as_ref() { + continue; + } + + match self.kind { + LibraryKind::Mast => { + if !path.is_file() { + return Err(Report::msg(format!( + "unable to load MAST library from '{}': not a file", + path.display() + ))); + } + } + LibraryKind::Masm => { + if !path.is_dir() { + return Err(Report::msg(format!( + "unable to load Miden Assembly library from '{}': not a directory", + path.display() + ))); + } + } + } + return Ok(path); + } + } + + Err(Report::msg(format!( + "unable to locate library '{}' using any of the provided search paths", + &self.name + ))) + } +} + +impl clap::builder::ValueParserFactory for LinkLibrary { + type Parser = LinkLibraryParser; + + fn value_parser() -> Self::Parser { + LinkLibraryParser + } +} + +#[doc(hidden)] +#[derive(Clone)] +pub struct LinkLibraryParser; +impl clap::builder::TypedValueParser for LinkLibraryParser { + type Value = LinkLibrary; + + fn possible_values( + &self, + ) -> Option + '_>> { + use clap::builder::PossibleValue; + + Some(Box::new( + [ + PossibleValue::new("masm").help("A Miden Assembly project directory"), + PossibleValue::new("masl").help("A compiled MAST library file"), + ] + .into_iter(), + )) + } + + /// Parses the `-l` flag using the following format: + /// + /// `-l[KIND=]NAME` + /// + /// * `KIND` is one of: `masl`, `masm`; defaults to `masl` + /// * `NAME` is either an absolute path, or a name (without extension) + fn parse_ref( + &self, + _cmd: &clap::Command, + _arg: Option<&clap::Arg>, + value: &OsStr, + ) -> Result { + use clap::error::{Error, ErrorKind}; + + let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?; + let (kind, name) = value + .split_once('=') + .map(|(kind, name)| (Some(kind), name)) + .unwrap_or((None, value)); + + if name.is_empty() { + return Err(Error::raw( + ErrorKind::ValueValidation, + "invalid link library: must specify a name or path", + )); + } + + let maybe_path = Path::new(name); + let extension = maybe_path.extension().map(|ext| ext.to_str().unwrap()); + let kind = match kind { + Some(kind) if !kind.is_empty() => kind.parse::().map_err(|_| { + Error::raw(ErrorKind::InvalidValue, format!("'{kind}' is not a valid library kind")) + })?, + Some(_) | None => match extension { + Some(kind) => kind.parse::().map_err(|_| { + Error::raw( + ErrorKind::InvalidValue, + format!("'{kind}' is not a valid library kind"), + ) + })?, + None => LibraryKind::default(), + }, + }; + + if maybe_path.is_absolute() { + let meta = maybe_path.metadata().map_err(|err| { + Error::raw( + ErrorKind::ValueValidation, + format!( + "invalid link library: unable to load '{}': {err}", + maybe_path.display() + ), + ) + })?; + + match kind { + LibraryKind::Mast if !meta.is_file() => { + return Err(Error::raw( + ErrorKind::ValueValidation, + format!("invalid link library: '{}' is not a file", maybe_path.display()), + )); + } + LibraryKind::Masm if !meta.is_dir() => { + return Err(Error::raw( + ErrorKind::ValueValidation, + format!( + "invalid link library: kind 'masm' was specified, but '{}' is not a \ + directory", + maybe_path.display() + ), + )); + } + _ => (), + } + + let name = maybe_path.file_stem().unwrap().to_str().unwrap().to_string(); + + Ok(LinkLibrary { + name: name.into(), + path: Some(maybe_path.to_path_buf()), + kind, + }) + } else if extension.is_some() { + let name = name.strip_suffix(unsafe { extension.unwrap_unchecked() }).unwrap(); + let mut name = name.to_string(); + name.pop(); + + Ok(LinkLibrary { + name: name.into(), + path: None, + kind, + }) + } else { + Ok(LinkLibrary { + name: name.to_string().into(), + path: None, + kind, + }) + } + } +} diff --git a/midenc-session/src/options/mod.rs b/midenc-session/src/options/mod.rs index 52acdab2..bcae76bd 100644 --- a/midenc-session/src/options/mod.rs +++ b/midenc-session/src/options/mod.rs @@ -1,21 +1,37 @@ -use std::{fmt, path::PathBuf, str::FromStr, sync::Arc}; +use std::{ + fmt, + path::{Path, PathBuf}, + str::FromStr, + sync::Arc, +}; use clap::ValueEnum; -use miden_diagnostics::{term::termcolor::ColorChoice, DiagnosticsConfig, Emitter, Verbosity}; -use crate::OutputTypes; +use crate::{ + diagnostics::{ColorChoice, DiagnosticsConfig, Emitter}, + LinkLibrary, OutputTypes, ProjectType, TargetEnv, +}; /// This struct contains all of the configuration options for the compiler -#[derive(Debug)] pub struct Options { /// The name of the program being compiled pub name: Option, + /// The type of project we're compiling this session + pub project_type: ProjectType, + /// The name of the function to call as the entrypoint + pub entrypoint: Option, + /// The current target environment for this session + pub target: TargetEnv, /// The optimization level for the current program pub optimize: OptLevel, + /// The level of debugging info for the current program + pub debug: DebugInfo, /// The type of outputs to emit pub output_types: OutputTypes, /// The paths in which to search for Miden Assembly libraries to link against pub search_paths: Vec, + /// The set of Miden libraries to link against + pub link_libraries: Vec, /// The location of the libraries which are shipped with the compiler pub sysroot: Option, /// Whether, and how, to color terminal output @@ -24,75 +40,236 @@ pub struct Options { pub diagnostics: DiagnosticsConfig, /// The current working directory of the compiler pub current_dir: PathBuf, + /// Only parse inputs + pub parse_only: bool, + /// Only perform semantic analysis on the input + pub analyze_only: bool, + /// Run the linker on the inputs, but do not generate Miden Assembly + pub link_only: bool, + /// Generate Miden Assembly from the inputs without the linker + pub no_link: bool, /// Print IR to stdout after each pass pub print_ir_after_all: bool, - /// Print IR to stdout each time the named pass is applied - pub print_ir_after_pass: Option, + /// Print IR to stdout each time the named passes are applied + pub print_ir_after_pass: Vec, + /// Save intermediate artifacts in memory during compilation + pub save_temps: bool, + /// We store any leftover argument matches in the session options for use + /// by any downstream crates that register custom flags + arg_matches: clap::ArgMatches, } + +impl fmt::Debug for Options { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Options") + .field("name", &self.name) + .field("project_type", &self.project_type) + .field("entrypoint", &self.entrypoint) + .field("target", &self.target) + .field("optimize", &self.optimize) + .field("debug", &self.debug) + .field("output_types", &self.output_types) + .field("search_paths", &self.search_paths) + .field("link_libraries", &self.link_libraries) + .field("sysroot", &self.sysroot) + .field("color", &self.color) + .field("diagnostics", &self.diagnostics) + .field("current_dir", &self.current_dir) + .field("parse_only", &self.parse_only) + .field("analyze_only", &self.analyze_only) + .field("link_only", &self.link_only) + .field("no_link", &self.no_link) + .field("save_temps", &self.save_temps) + .field("print_ir_after_all", &self.print_ir_after_all) + .field("print_ir_after_pass", &self.print_ir_after_pass) + .field_with("extra_arguments", |f| { + let mut map = f.debug_map(); + for id in self.arg_matches.ids() { + use clap::parser::ValueSource; + // Don't print CompilerOptions arg group + if id.as_str() == "CompilerOptions" { + continue; + } + // Don't print default values + if matches!( + self.arg_matches.value_source(id.as_str()), + Some(ValueSource::DefaultValue) + ) { + continue; + } + map.key(&id.as_str()).value_with(|f| { + let mut list = f.debug_list(); + if let Some(occurs) = self + .arg_matches + .try_get_raw_occurrences(id.as_str()) + .expect("expected flag") + { + list.entries(occurs.flatten()); + } + list.finish() + }); + } + map.finish() + }) + .finish() + } +} + impl Default for Options { fn default() -> Self { let current_dir = std::env::current_dir().expect("could not get working directory"); - Self::new(current_dir) + let target = TargetEnv::default(); + let project_type = ProjectType::default_for_target(target); + Self::new(None, target, project_type, current_dir, None) } } + impl Options { - pub fn new(current_dir: PathBuf) -> Self { + pub fn new( + name: Option, + target: TargetEnv, + project_type: ProjectType, + current_dir: PathBuf, + sysroot: Option, + ) -> Self { + let sysroot = sysroot.or_else(|| { + std::env::var("HOME").ok().map(|home| { + Path::new(&home) + .join(".miden") + .join("toolchains") + .join(crate::MIDENC_BUILD_VERSION) + }) + }); + Self { - name: None, + name, + target, + project_type, + entrypoint: None, optimize: OptLevel::None, + debug: DebugInfo::None, output_types: Default::default(), search_paths: vec![], - sysroot: None, + link_libraries: vec![], + sysroot, color: Default::default(), diagnostics: Default::default(), current_dir, + parse_only: false, + analyze_only: false, + link_only: false, + no_link: false, + save_temps: false, print_ir_after_all: false, - print_ir_after_pass: None, + print_ir_after_pass: vec![], + arg_matches: Default::default(), } } + #[inline(always)] pub fn with_color(mut self, color: ColorChoice) -> Self { self.color = color; self } + #[inline(always)] pub fn with_verbosity(mut self, verbosity: Verbosity) -> Self { self.diagnostics.verbosity = verbosity; self } + #[inline(always)] + pub fn with_debug_info(mut self, debug: DebugInfo) -> Self { + self.debug = debug; + self + } + + #[inline(always)] + pub fn with_optimization(mut self, level: OptLevel) -> Self { + self.optimize = level; + self + } + pub fn with_warnings(mut self, warnings: Warnings) -> Self { - match warnings { - Warnings::None => { - self.diagnostics.warnings_as_errors = false; - self.diagnostics.no_warn = true; - } - Warnings::All => { - self.diagnostics.warnings_as_errors = false; - self.diagnostics.no_warn = false; - } - Warnings::Error => { - self.diagnostics.warnings_as_errors = true; - self.diagnostics.no_warn = false; - } - } + self.diagnostics.warnings = warnings; self } + #[inline(always)] pub fn with_output_types(mut self, output_types: OutputTypes) -> Self { self.output_types = output_types; self } - /// Get a new [miden_diagnostics::Emitter] based on the current options. + #[doc(hidden)] + pub fn with_arg_matches(mut self, matches: clap::ArgMatches) -> Self { + self.arg_matches = matches; + self + } + + #[doc(hidden)] + pub fn set_arg_matches(&mut self, matches: clap::ArgMatches) { + self.arg_matches = matches; + } + + /// Get a new [Emitter] based on the current options. pub fn default_emitter(&self) -> Arc { - use miden_diagnostics::{DefaultEmitter, NullEmitter}; + use crate::diagnostics::{DefaultEmitter, NullEmitter}; match self.diagnostics.verbosity { Verbosity::Silent => Arc::new(NullEmitter::new(self.color)), _ => Arc::new(DefaultEmitter::new(self.color)), } } + + /// Returns true if source location information should be emitted by the compiler + #[inline(always)] + pub fn emit_source_locations(&self) -> bool { + matches!(self.debug, DebugInfo::Line | DebugInfo::Full) + } + + /// Returns true if rich debugging information should be emitted by the compiler + #[inline(always)] + pub fn emit_debug_decorators(&self) -> bool { + matches!(self.debug, DebugInfo::Full) + } + + /// Returns true if debug assertions are enabled + #[inline(always)] + pub fn emit_debug_assertions(&self) -> bool { + self.debug != DebugInfo::None && matches!(self.optimize, OptLevel::None | OptLevel::Basic) + } + + /// Get the value of a custom flag with action `FlagAction::SetTrue` or `FlagAction::SetFalse` + pub fn get_flag(&self, name: &str) -> bool { + self.arg_matches.get_flag(name) + } + + /// Get the count of a specific custom flag with action `FlagAction::Count` + pub fn get_flag_count(&self, name: &str) -> usize { + self.arg_matches.get_count(name) as usize + } + + /// Get the value of a specific custom flag + pub fn get_flag_value(&self, name: &str) -> Option<&T> + where + T: core::any::Any + Clone + Send + Sync + 'static, + { + self.arg_matches.get_one(name) + } + + /// Iterate over values of a specific custom flag + pub fn get_flag_values(&self, name: &str) -> Option> + where + T: core::any::Any + Clone + Send + Sync + 'static, + { + self.arg_matches.get_many(name) + } + + /// Get the remaining [clap::ArgMatches] left after parsing the base session configuration + pub fn matches(&self) -> &clap::ArgMatches { + &self.arg_matches + } } /// This enum describes the degree to which compiled programs will be optimized @@ -113,8 +290,20 @@ pub enum OptLevel { SizeMin, } +/// This enum describes what type of debugging information to emit in compiled programs +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, ValueEnum)] +pub enum DebugInfo { + /// Do not emit debug info in the final output + None, + /// Emit source location information in the final output + #[default] + Line, + /// Emit all available debug information in the final output + Full, +} + /// This enum represents the behavior of the compiler with regard to warnings -#[derive(Debug, Copy, Clone, Default, ValueEnum)] +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, ValueEnum)] pub enum Warnings { /// Disable all warnings None, @@ -147,8 +336,8 @@ impl FromStr for Warnings { } /// This enum represents the type of messages produced by the compiler during execution -#[derive(Debug, Copy, Clone, Default, ValueEnum)] -pub enum VerbosityFlag { +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum Verbosity { /// Emit additional debug/trace information during compilation Debug, /// Emit the standard informational, warning, and error messages @@ -161,25 +350,3 @@ pub enum VerbosityFlag { /// Do not emit anything to stdout/stderr Silent, } -impl From for VerbosityFlag { - fn from(v: Verbosity) -> Self { - match v { - Verbosity::Debug => Self::Debug, - Verbosity::Info => Self::Info, - Verbosity::Warning => Self::Warning, - Verbosity::Error => Self::Error, - Verbosity::Silent => Self::Silent, - } - } -} -impl From for Verbosity { - fn from(flag: VerbosityFlag) -> Self { - match flag { - VerbosityFlag::Debug => Self::Debug, - VerbosityFlag::Info => Self::Info, - VerbosityFlag::Warning => Self::Warning, - VerbosityFlag::Error => Self::Error, - VerbosityFlag::Silent => Self::Silent, - } - } -} diff --git a/midenc-session/src/outputs.rs b/midenc-session/src/outputs.rs index 5e6b6269..9723ecb8 100644 --- a/midenc-session/src/outputs.rs +++ b/midenc-session/src/outputs.rs @@ -8,6 +8,15 @@ use std::{ use clap::ValueEnum; +/// The type of output to produce for a given [OutputType], when multiple options are available +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum OutputMode { + /// Pretty-print the textual form of the current [OutputType] + Text, + /// Encode the current [OutputType] in its canonical binary format + Binary, +} + /// This enum represents the type of outputs the compiler can produce #[derive(Debug, Copy, Clone, Default, Hash, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] pub enum OutputType { @@ -15,24 +24,49 @@ pub enum OutputType { Ast, /// The compiler will emit Miden IR Hir, - /// The compiler will emit Miden Assembly + /// The compiler will emit Miden Assembly text Masm, - /// The compiler will emit binary MAST (Miden Abstract Syntax Tree) - #[default] + /// The compiler will emit a Merkalized Abstract Syntax Tree in text form Mast, + /// The compiler will emit a MAST library in binary form + #[default] + Masl, } impl OutputType { + /// Returns true if this output type is an intermediate artifact produced during compilation + pub fn is_intermediate(&self) -> bool { + !matches!(self, Self::Mast | Self::Masl) + } + pub fn extension(&self) -> &'static str { match self { Self::Ast => "ast", Self::Hir => "hir", Self::Masm => "masm", Self::Mast => "mast", + Self::Masl => "mast", } } pub fn shorthand_display() -> String { - format!("`{}`, `{}`, `{}`, `{}`", Self::Ast, Self::Hir, Self::Masm, Self::Mast,) + format!( + "`{}`, `{}`, `{}`, `{}`, `{}`", + Self::Ast, + Self::Hir, + Self::Masm, + Self::Mast, + Self::Masl + ) + } + + pub fn all() -> [OutputType; 5] { + [ + OutputType::Ast, + OutputType::Hir, + OutputType::Masm, + OutputType::Mast, + OutputType::Masl, + ] } } impl fmt::Display for OutputType { @@ -42,6 +76,7 @@ impl fmt::Display for OutputType { Self::Hir => f.write_str("hir"), Self::Masm => f.write_str("masm"), Self::Mast => f.write_str("mast"), + Self::Masl => f.write_str("masl"), } } } @@ -54,6 +89,7 @@ impl FromStr for OutputType { "hir" => Ok(Self::Hir), "masm" => Ok(Self::Masm), "mast" => Ok(Self::Mast), + "masl" => Ok(Self::Masl), _ => Err(()), } } @@ -75,7 +111,7 @@ impl OutputFile { pub fn filestem(&self) -> Option<&OsStr> { match self { Self::Real(ref path) => path.file_stem(), - Self::Stdout => Some(OsStr::new("stdout")), + Self::Stdout => None, } } @@ -90,10 +126,10 @@ impl OutputFile { } } - pub fn as_path(&self) -> &Path { + pub fn as_path(&self) -> Option<&Path> { match self { - Self::Real(ref path) => path.as_ref(), - Self::Stdout => Path::new("stdout"), + Self::Real(ref path) => Some(path.as_ref()), + Self::Stdout => None, } } @@ -109,100 +145,192 @@ impl OutputFile { } } } +impl fmt::Display for OutputFile { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Real(ref path) => write!(f, "{}", path.display()), + Self::Stdout => write!(f, "stdout"), + } + } +} #[derive(Debug)] pub struct OutputFiles { stem: String, + /// The compiler working directory + pub cwd: PathBuf, + /// The directory in which to place temporaries or intermediate artifacts + pub tmp_dir: PathBuf, + /// The directory in which to place objects produced by the current compiler operation + /// + /// This directory is intended for non-intermediate artifacts, though it may be used + /// to derive `tmp_dir` elsewhere. You should prefer to use `tmp_dir` for files which + /// are internal details of the compiler. pub out_dir: PathBuf, + /// If specified, the specific path at which to write the compiler output. + /// + /// This _only_ applies to the final output, i.e. the `.masl` library or executable. pub out_file: Option, - pub tmp_dir: Option, + /// The raw output types requested by the user on the command line pub outputs: OutputTypes, } impl OutputFiles { pub fn new( stem: String, + cwd: PathBuf, out_dir: PathBuf, out_file: Option, - tmp_dir: Option, + tmp_dir: PathBuf, outputs: OutputTypes, ) -> Self { Self { stem, + cwd, + tmp_dir, out_dir, out_file, - tmp_dir, outputs, } } - pub fn path(&self, ty: OutputType) -> OutputFile { + /// Return the [OutputFile] representing where an output of `ty` type should be written, + /// with an optional `name`, which overrides the file stem of the resulting path. + pub fn output_file(&self, ty: OutputType, name: Option<&str>) -> OutputFile { + let default_name = name.unwrap_or(self.stem.as_str()); self.outputs .get(&ty) .and_then(|p| p.to_owned()) - .or_else(|| self.out_file.clone()) - .unwrap_or_else(|| OutputFile::Real(self.output_path(ty))) + .map(|of| match of { + OutputFile::Real(path) => OutputFile::Real({ + let path = if path.is_absolute() { + path + } else { + self.cwd.join(path) + }; + if path.is_dir() { + path.join(default_name).with_extension(ty.extension()) + } else if let Some(name) = name { + path.with_stem_and_extension(name, ty.extension()) + } else { + path + } + }), + out @ OutputFile::Stdout => out, + }) + .unwrap_or_else(|| { + let out = if ty.is_intermediate() { + self.with_directory_and_extension(&self.tmp_dir, ty.extension()) + } else if let Some(output_file) = self.out_file.as_ref() { + return output_file.clone(); + } else { + self.with_directory_and_extension(&self.out_dir, ty.extension()) + }; + OutputFile::Real(if let Some(name) = name { + out.with_stem(name) + } else { + out + }) + }) } + /// Return the most appropriate file path for an output of `ty` type. + /// + /// The returned path _may_ be precise, if a specific file path was chosen by the user for + /// the given output type, but in general the returned path will be derived from the current + /// `self.stem`, and is thus an appropriate default path for the given output. pub fn output_path(&self, ty: OutputType) -> PathBuf { - let extension = ty.extension(); - if let Some(output_file) = self.outputs.get(&ty) { - match output_file { - Some(OutputFile::Real(ref path)) if path.is_absolute() => { - path.with_extension(extension) - } - Some(OutputFile::Real(ref path)) => { - self.out_dir.join(path).with_extension(extension) - } - Some(OutputFile::Stdout) | None => { - self.with_directory_and_extension(&self.out_dir, extension) + match self.output_file(ty, None) { + OutputFile::Real(path) => path, + OutputFile::Stdout => { + if ty.is_intermediate() { + self.with_directory_and_extension(&self.tmp_dir, ty.extension()) + } else if let Some(output_file) = self.out_file.as_ref().and_then(|of| of.as_path()) + { + output_file.to_path_buf() + } else { + self.with_directory_and_extension(&self.out_dir, ty.extension()) } } - } else { - self.with_directory_and_extension(&self.out_dir, extension) } } + /// Constructs a file path for a temporary file of the given output type, with an optional name, + /// falling back to `self.stem` if no name is provided. + /// + /// The file path is always a child of `self.tmp_dir` pub fn temp_path(&self, ty: OutputType, name: Option<&str>) -> PathBuf { - let extension = ty.extension(); - self.temp_path_ext(extension, name) + self.tmp_dir + .join(name.unwrap_or(self.stem.as_str())) + .with_extension(ty.extension()) } - fn temp_path_ext(&self, ext: &str, name: Option<&str>) -> PathBuf { - let mut extension = String::new(); - - if let Some(name) = name { - extension.push_str(name); - } - - if !ext.is_empty() { - if !extension.is_empty() { - extension.push('.'); + /// Build a file path which is either: + /// + /// * If `self.out_file` is set to a real path, returns it with extension set to `extension` + /// * Otherwise, calls [with_directory_and_extension] with `self.out_dir` and `extension` + pub fn with_extension(&self, extension: &str) -> PathBuf { + match self.out_file.as_ref() { + Some(OutputFile::Real(ref path)) => path.with_extension(extension), + Some(OutputFile::Stdout) | None => { + self.with_directory_and_extension(&self.out_dir, extension) } - extension.push_str(ext); } - - let tmp_dir = self.tmp_dir.as_ref().unwrap_or(&self.out_dir); - self.with_directory_and_extension(tmp_dir, &extension) - } - - pub fn with_extension(&self, extension: &str) -> PathBuf { - self.with_directory_and_extension(&self.out_dir, extension) } + /// Build a file path whose parent is `directory`, file stem is `self.stem`, and extension is + /// `extension` + #[inline] fn with_directory_and_extension(&self, directory: &Path, extension: &str) -> PathBuf { - let mut path = directory.join(&self.stem); - path.set_extension(extension); - path + directory.join(&self.stem).with_extension(extension) } } #[derive(Debug, Clone, Default)] pub struct OutputTypes(BTreeMap>); impl OutputTypes { - pub fn new>(entries: I) -> Self { - Self(BTreeMap::from_iter( - entries.into_iter().map(|spec| (spec.output_type, spec.path)), - )) + pub fn new>(entries: I) -> Result { + let entries = entries.into_iter(); + let mut map = BTreeMap::default(); + for spec in entries { + match spec { + OutputTypeSpec::All { path } => { + if !map.is_empty() { + return Err(clap::Error::raw( + clap::error::ErrorKind::ValueValidation, + "--emit=all cannot be combined with other --emit types", + )); + } + if let Some(OutputFile::Real(ref path)) = &path { + if path.extension().is_some() { + return Err(clap::Error::raw( + clap::error::ErrorKind::ValueValidation, + "invalid path for --emit=all: must be a directory", + )); + } + } + for ty in OutputType::all() { + map.insert(ty, path.clone()); + } + } + OutputTypeSpec::Typed { output_type, path } => { + if path.is_some() { + if matches!(map.get(&output_type), Some(Some(OutputFile::Real(_)))) { + return Err(clap::Error::raw( + clap::error::ErrorKind::ValueValidation, + format!( + "conflicting --emit options given for output type \ + '{output_type}'" + ), + )); + } + } else if matches!(map.get(&output_type), Some(Some(_))) { + continue; + } + map.insert(output_type, path); + } + } + } + Ok(Self(map)) } pub fn get(&self, key: &OutputType) -> Option<&Option> { @@ -213,6 +341,10 @@ impl OutputTypes { self.0.insert(key, value); } + pub fn clear(&mut self) { + self.0.clear(); + } + pub fn contains_key(&self, key: &OutputType) -> bool { self.0.contains_key(key) } @@ -231,6 +363,7 @@ impl OutputTypes { self.0.values() } + #[inline(always)] pub fn is_empty(&self) -> bool { self.0.is_empty() } @@ -240,23 +373,48 @@ impl OutputTypes { } pub fn parse_only(&self) -> bool { - !self.0.keys().any(|k| !matches!(k, OutputType::Ast)) + self.0.keys().all(|k| matches!(k, OutputType::Ast)) } - pub fn should_codegen(&self) -> bool { - self.0.keys().any(|k| matches!(k, OutputType::Masm | OutputType::Mast)) + pub fn should_analyze(&self) -> bool { + self.0.keys().any(|k| { + matches!(k, OutputType::Hir | OutputType::Masm | OutputType::Mast | OutputType::Masl) + }) + } + + pub fn should_rewrite(&self) -> bool { + self.0.keys().any(|k| { + matches!(k, OutputType::Hir | OutputType::Masm | OutputType::Mast | OutputType::Masl) + }) } pub fn should_link(&self) -> bool { - self.0.keys().any(|k| matches!(k, OutputType::Masm | OutputType::Mast)) + self.0.keys().any(|k| { + matches!(k, OutputType::Hir | OutputType::Masm | OutputType::Mast | OutputType::Masl) + }) + } + + pub fn should_codegen(&self) -> bool { + self.0 + .keys() + .any(|k| matches!(k, OutputType::Masm | OutputType::Mast | OutputType::Masl)) + } + + pub fn should_assemble(&self) -> bool { + self.0.keys().any(|k| matches!(k, OutputType::Mast | OutputType::Masl)) } } /// This type describes an output type with optional path specification #[derive(Debug, Clone)] -pub struct OutputTypeSpec { - pub output_type: OutputType, - pub path: Option, +pub enum OutputTypeSpec { + All { + path: Option, + }, + Typed { + output_type: OutputType, + path: Option, + }, } impl clap::builder::ValueParserFactory for OutputTypeSpec { type Parser = OutputTypeParser; @@ -272,6 +430,23 @@ pub struct OutputTypeParser; impl clap::builder::TypedValueParser for OutputTypeParser { type Value = OutputTypeSpec; + fn possible_values( + &self, + ) -> Option + '_>> { + use clap::builder::PossibleValue; + Some(Box::new( + [ + PossibleValue::new("ast").help("Abstract Syntax Tree (text)"), + PossibleValue::new("hir").help("High-level Intermediate Representation (text)"), + PossibleValue::new("masm").help("Miden Assembly (text)"), + PossibleValue::new("mast").help("Merkelized Abstract Syntax Tree (text)"), + PossibleValue::new("masl").help("Merkelized Abstract Syntax Tree (binary)"), + PossibleValue::new("all").help("All of the above"), + ] + .into_iter(), + )) + } + fn parse_ref( &self, _cmd: &clap::Command, @@ -287,6 +462,9 @@ impl clap::builder::TypedValueParser for OutputTypeParser { Some((shorthand, "-")) => (shorthand, Some(OutputFile::Stdout)), Some((shorthand, path)) => (shorthand, Some(OutputFile::Real(PathBuf::from(path)))), }; + if shorthand == "all" { + return Ok(OutputTypeSpec::All { path }); + } let output_type = shorthand.parse::().map_err(|_| { Error::raw( ErrorKind::InvalidValue, @@ -296,6 +474,47 @@ impl clap::builder::TypedValueParser for OutputTypeParser { ), ) })?; - Ok(OutputTypeSpec { output_type, path }) + Ok(OutputTypeSpec::Typed { output_type, path }) + } +} + +trait PathMut { + fn with_stem(self, stem: impl AsRef) -> PathBuf; + fn with_stem_and_extension(self, stem: impl AsRef, ext: impl AsRef) -> PathBuf; +} +impl PathMut for &Path { + fn with_stem(self, stem: impl AsRef) -> PathBuf { + let mut path = self.with_file_name(stem); + if let Some(ext) = self.extension() { + path.set_extension(ext); + } + path + } + + fn with_stem_and_extension(self, stem: impl AsRef, ext: impl AsRef) -> PathBuf { + let mut path = self.with_file_name(stem); + path.set_extension(ext); + path + } +} +impl PathMut for PathBuf { + fn with_stem(mut self, stem: impl AsRef) -> PathBuf { + if let Some(ext) = self.extension() { + let ext = ext.to_string_lossy().into_owned(); + self.with_stem_and_extension(stem, ext) + } else { + self.set_file_name(stem); + self + } + } + + fn with_stem_and_extension( + mut self, + stem: impl AsRef, + ext: impl AsRef, + ) -> PathBuf { + self.set_file_name(stem); + self.set_extension(ext); + self } } diff --git a/midenc-session/src/statistics.rs b/midenc-session/src/statistics.rs index 32c94be8..6528f22a 100644 --- a/midenc-session/src/statistics.rs +++ b/midenc-session/src/statistics.rs @@ -1,4 +1,5 @@ use std::{ + fmt, sync::atomic::{AtomicU64, Ordering}, time::{Duration, Instant}, }; @@ -23,6 +24,16 @@ pub struct Statistics { /// The elapsed time at which codegen started codegen_time: AtomicU64, } +impl fmt::Debug for Statistics { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Statistics") + .field("elapsed", &self.elapsed()) + .field("parsing", &self.parse_time()) + .field("optimization", &self.opt_time()) + .field("codegen", &self.codegen_time()) + .finish() + } +} impl Default for Statistics { fn default() -> Statistics { Self::new(Instant::now()) diff --git a/midenc/Cargo.toml b/midenc/Cargo.toml index 6a9116b0..8e44c2c2 100644 --- a/midenc/Cargo.toml +++ b/midenc/Cargo.toml @@ -14,7 +14,6 @@ readme.workspace = true edition.workspace = true [dependencies] -anyhow.workspace = true env_logger.workspace = true human-panic = "2.0" midenc-driver.workspace = true diff --git a/midenc/src/main.rs b/midenc/src/main.rs index b1bd3bcf..75630543 100644 --- a/midenc/src/main.rs +++ b/midenc/src/main.rs @@ -1,14 +1,17 @@ use std::env; -use anyhow::anyhow; -use midenc_driver::{self as driver, DriverError}; +use midenc_driver::{ + self as driver, + diagnostics::{IntoDiagnostic, Report, WrapErr}, + ClapDiagnostic, +}; -pub fn main() -> Result<(), DriverError> { +pub fn main() -> Result<(), Report> { if cfg!(not(debug_assertions)) && env::var_os("MIDENC_TRACE").is_none() { human_panic::setup_panic!(); } - // Initialize logger + // Initialize logger, but do not install it, leave that up to the command handler let mut builder = env_logger::Builder::from_env("MIDENC_TRACE"); builder.format_indent(Some(2)); if let Ok(precision) = env::var("MIDENC_TRACE_TIMING") { @@ -18,23 +21,33 @@ pub fn main() -> Result<(), DriverError> { "us" => builder.format_timestamp_micros(), "ns" => builder.format_timestamp_nanos(), other => { - return Err(DriverError::Failed(anyhow!( + return Err(Report::msg(format!( "invalid MIDENC_TRACE_TIMING precision, expected one of [s, ms, us, ns], got \ '{}'", other - ))) + ))); } }; } else { builder.format_timestamp(None); } - builder.init(); + let logger = Box::new(builder.build()); // Get current working directory - let cwd = env::current_dir()?; + let cwd = env::current_dir() + .into_diagnostic() + .wrap_err("could not read current working directory")?; - match driver::run(cwd, env::args_os()) { - Err(DriverError::Clap(err)) => err.exit(), + match driver::run(cwd, env::args_os(), logger) { + Err(report) => match report.downcast::() { + Ok(err) => { + // Remove the miette panic hook, so that clap errors can be reported without + // the diagnostic-style formatting + //drop(std::panic::take_hook()); + err.exit() + } + Err(report) => Err(report), + }, result => result, } } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 7b699598..e6723a7b 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "nightly-2024-03-10" -components = ["rustfmt", "rust-src"] -targets = ["wasm32-unknown-unknown"] +channel = "nightly-2024-05-07" +components = ["rustfmt", "rust-src", "clippy"] +targets = ["wasm32-unknown-unknown", "wasm32-wasip1"] profile = "minimal" diff --git a/sdk/.cargo/config.toml b/sdk/.cargo/config.toml index bc255e30..dc0be732 100644 --- a/sdk/.cargo/config.toml +++ b/sdk/.cargo/config.toml @@ -1,2 +1,2 @@ [build] -target = "wasm32-wasi" \ No newline at end of file +target = "wasm32-wasip1" \ No newline at end of file diff --git a/sdk/Cargo.lock b/sdk/Cargo.lock deleted file mode 100644 index bc8d3b5c..00000000 --- a/sdk/Cargo.lock +++ /dev/null @@ -1,22 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "miden-sdk" -version = "0.0.1" -dependencies = [ - "miden-stdlib-sys", - "miden-tx-kernel-sys", -] - -[[package]] -name = "miden-stdlib-sys" -version = "0.0.1" - -[[package]] -name = "miden-tx-kernel-sys" -version = "0.0.1" -dependencies = [ - "miden-stdlib-sys", -] diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml deleted file mode 100644 index 1eaee8a4..00000000 --- a/sdk/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[workspace] -resolver = "2" -members = [ - "stdlib-sys", - "tx-kernel-sys", - "sdk", -] - -[workspace.package] - -version = "0.0.0" -rust-version = "1.71" -authors = ["Miden contributors"] -repository = "https://github.com/0xPolygonMiden/compiler" -homepage = "https://github.com/0xPolygonMiden/compiler" -documentation = "https://github.com/0xPolygonMiden/compiler" -categories = ["Compilers"] -keywords = ["compiler", "miden"] -license = "MIT" -readme = "README.md" -edition = "2021" - - -[profile.release] -panic = "abort" -# optimize for size -opt-level = "z" diff --git a/sdk/base-sys/Cargo.toml b/sdk/base-sys/Cargo.toml new file mode 100644 index 00000000..51594b44 --- /dev/null +++ b/sdk/base-sys/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "miden-base-sys" +description = "Miden rollup Rust bingings and MASM library" +version = "0.0.0" +rust-version.workspace = true +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +categories.workspace = true +keywords.workspace = true +license.workspace = true +readme.workspace = true +edition.workspace = true + +[dependencies] +miden-assembly.workspace = true +miden-stdlib-sys = { version = "0.0.1", path = "../stdlib-sys", optional = true } + +[build-dependencies] +miden-assembly.workspace = true + +[features] +default = [] + +# User facing Rust bindings +"bindings" = ["miden-stdlib-sys"] +# MASL library for Miden rollup (tx kernel, etc.) used by the compiler in the link phase +"masl-lib" = [] \ No newline at end of file diff --git a/sdk/base-sys/build.rs b/sdk/base-sys/build.rs new file mode 100644 index 00000000..8f9dcaad --- /dev/null +++ b/sdk/base-sys/build.rs @@ -0,0 +1,30 @@ +use std::{env, path::Path, sync::Arc}; + +use miden_assembly::{ + diagnostics::{IntoDiagnostic, Result}, + Assembler, Library as CompiledLibrary, LibraryNamespace, +}; + +/// Read and parse the contents from `./masm/*` and compile it to MASL. +fn main() -> Result<()> { + // re-build the `[OUT_DIR]/assets/` file iff something in the `./masm` directory + // or its builder changed: + println!("cargo:rerun-if-changed=masm"); + + let build_dir = env::var("OUT_DIR").unwrap(); + let build_dir = Path::new(&build_dir); + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + let source_manager = Arc::new(miden_assembly::DefaultSourceManager::default()); + let namespace = "miden".parse::().expect("invalid base namespace"); + + let tx_asm_dir = Path::new(manifest_dir).join("masm").join("tx"); + let asm = Assembler::new(source_manager); + let txlib = CompiledLibrary::from_dir(tx_asm_dir, namespace, asm)?; + let tx_masl_path = build_dir + .join("assets") + .join("tx") + .with_extension(CompiledLibrary::LIBRARY_EXTENSION); + txlib.write_to_file(tx_masl_path).into_diagnostic()?; + + Ok(()) +} diff --git a/sdk/base-sys/masm/tx/account.masm b/sdk/base-sys/masm/tx/account.masm new file mode 100644 index 00000000..47229ce0 --- /dev/null +++ b/sdk/base-sys/masm/tx/account.masm @@ -0,0 +1,11 @@ +# Stubs for miden::account tx kernel module + +export.remove_asset + push.1 + assertz +end + +export.add_asset + push.1 + assertz +end \ No newline at end of file diff --git a/sdk/base-sys/masm/tx/tx.masm b/sdk/base-sys/masm/tx/tx.masm new file mode 100644 index 00000000..310d6912 --- /dev/null +++ b/sdk/base-sys/masm/tx/tx.masm @@ -0,0 +1,6 @@ +# Stubs for miden::tx tx kernel module + +export.create_note + push.1 + assertz +end \ No newline at end of file diff --git a/sdk/base-sys/src/bindings/mod.rs b/sdk/base-sys/src/bindings/mod.rs new file mode 100644 index 00000000..d7c32947 --- /dev/null +++ b/sdk/base-sys/src/bindings/mod.rs @@ -0,0 +1 @@ +pub mod tx; diff --git a/sdk/tx-kernel-sys/src/externs.rs b/sdk/base-sys/src/bindings/tx/externs.rs similarity index 94% rename from sdk/tx-kernel-sys/src/externs.rs rename to sdk/base-sys/src/bindings/tx/externs.rs index 412e6d7f..85ee9c9c 100644 --- a/sdk/tx-kernel-sys/src/externs.rs +++ b/sdk/base-sys/src/bindings/tx/externs.rs @@ -1,6 +1,6 @@ use miden_stdlib_sys::Felt; -use crate::{AccountId, CoreAsset, NoteId, NoteType, Tag}; +use crate::bindings::tx::{AccountId, CoreAsset, NoteId, NoteType, Tag}; #[link(wasm_import_module = "miden::account")] extern "C" { diff --git a/sdk/tx-kernel-sys/src/lib.rs b/sdk/base-sys/src/bindings/tx/mod.rs similarity index 99% rename from sdk/tx-kernel-sys/src/lib.rs rename to sdk/base-sys/src/bindings/tx/mod.rs index b4134653..f70691ef 100644 --- a/sdk/tx-kernel-sys/src/lib.rs +++ b/sdk/base-sys/src/bindings/tx/mod.rs @@ -1,5 +1,3 @@ -#![no_std] - mod externs; use externs::*; diff --git a/sdk/tx-kernel-sys/src/types.rs b/sdk/base-sys/src/bindings/tx/types.rs similarity index 100% rename from sdk/tx-kernel-sys/src/types.rs rename to sdk/base-sys/src/bindings/tx/types.rs diff --git a/sdk/base-sys/src/lib.rs b/sdk/base-sys/src/lib.rs new file mode 100644 index 00000000..f088d34d --- /dev/null +++ b/sdk/base-sys/src/lib.rs @@ -0,0 +1,7 @@ +// Enable no_std for the bindings module +#![cfg_attr(feature = "bindings", no_std)] + +#[cfg(feature = "bindings")] +pub mod bindings; +#[cfg(feature = "masl-lib")] +pub mod masl; diff --git a/sdk/base-sys/src/masl/mod.rs b/sdk/base-sys/src/masl/mod.rs new file mode 100644 index 00000000..d7c32947 --- /dev/null +++ b/sdk/base-sys/src/masl/mod.rs @@ -0,0 +1 @@ +pub mod tx; diff --git a/sdk/base-sys/src/masl/tx.rs b/sdk/base-sys/src/masl/tx.rs new file mode 100644 index 00000000..080087da --- /dev/null +++ b/sdk/base-sys/src/masl/tx.rs @@ -0,0 +1,24 @@ +use miden_assembly::{utils::Deserializable, Library as CompiledLibrary}; + +/// Stubs for the Miden rollup tx kernel +pub struct MidenTxKernelLibrary(CompiledLibrary); + +impl AsRef for MidenTxKernelLibrary { + fn as_ref(&self) -> &CompiledLibrary { + &self.0 + } +} + +impl From for CompiledLibrary { + fn from(lib: MidenTxKernelLibrary) -> Self { + lib.0 + } +} + +impl Default for MidenTxKernelLibrary { + fn default() -> Self { + let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/tx.masl")); + let contents = CompiledLibrary::read_from_bytes(bytes).expect("failed to read std masl!"); + Self(contents) + } +} diff --git a/sdk/sdk/Cargo.toml b/sdk/sdk/Cargo.toml index 69f0564c..5e17e29a 100644 --- a/sdk/sdk/Cargo.toml +++ b/sdk/sdk/Cargo.toml @@ -16,4 +16,4 @@ crate-type = ["rlib"] [dependencies] miden-stdlib-sys = { path = "../stdlib-sys" } -miden-tx-kernel-sys = { path = "../tx-kernel-sys" } +miden-base-sys = { path = "../base-sys", features = ["bindings"] } diff --git a/sdk/sdk/src/lib.rs b/sdk/sdk/src/lib.rs index aa1d0dbf..5905591f 100644 --- a/sdk/sdk/src/lib.rs +++ b/sdk/sdk/src/lib.rs @@ -1,4 +1,4 @@ #![no_std] +pub use miden_base_sys::bindings::tx::*; pub use miden_stdlib_sys::*; -pub use miden_tx_kernel_sys::*; diff --git a/sdk/stdlib-sys/src/intrinsics/felt.rs b/sdk/stdlib-sys/src/intrinsics/felt.rs index ebad89b7..632eec14 100644 --- a/sdk/stdlib-sys/src/intrinsics/felt.rs +++ b/sdk/stdlib-sys/src/intrinsics/felt.rs @@ -1,3 +1,5 @@ +#![allow(clippy::transmute_int_to_float)] + use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; #[link(wasm_import_module = "miden:stdlib/intrinsics_felt")] @@ -139,19 +141,19 @@ impl From for u64 { impl From for Felt { fn from(value: u32) -> Self { - Self(unsafe { core::mem::transmute(value) }) + Self(unsafe { core::mem::transmute::(value) }) } } impl From for Felt { fn from(value: u16) -> Self { - Self(unsafe { core::mem::transmute(value as u32) }) + Self(unsafe { core::mem::transmute::(value as u32) }) } } impl From for Felt { fn from(value: u8) -> Self { - Self(unsafe { core::mem::transmute(value as u32) }) + Self(unsafe { core::mem::transmute::(value as u32) }) } } @@ -308,12 +310,12 @@ pub fn assert_eq(a: Felt, b: Felt) { } } -#[cfg(test)] -mod tests { - use super::*; +// #[cfg(test)] +// mod tests { +// use super::*; - #[test] - fn felt_macro_smoke_test() { - let _ = felt!(1); - } -} +// #[test] +// fn felt_macro_smoke_test() { +// let _ = felt!(1); +// } +// } diff --git a/sdk/stdlib-sys/src/stdlib/crypto/dsa.rs b/sdk/stdlib-sys/src/stdlib/crypto/dsa.rs index 3e21a3e6..dab29c09 100644 --- a/sdk/stdlib-sys/src/stdlib/crypto/dsa.rs +++ b/sdk/stdlib-sys/src/stdlib/crypto/dsa.rs @@ -1,6 +1,6 @@ use crate::{Felt, Word}; -#[link(wasm_import_module = "miden:stdlib/std_crypto_dsa")] +#[link(wasm_import_module = "std::crypto::dsa::rpo_falcon512")] extern "C" { #[link_name = "rpo_falcon512_verify<0x0000000000000000000000000000000000000000000000000000000000000000>"] fn extern_rpo_falcon512_verify( diff --git a/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs b/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs index 67a37654..e223a62c 100644 --- a/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs +++ b/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs @@ -1,26 +1,25 @@ //! Contains procedures for computing hashes using BLAKE3 and SHA256 hash //! functions. The input and output elements are assumed to contain one 32-bit //! value per element. -use crate::Felt; -#[link(wasm_import_module = "std::crypto_hashes")] +#[link(wasm_import_module = "std::crypto::hashes::blake3")] extern "C" { /// Computes BLAKE3 1-to-1 hash. /// /// Input: 32-bytes stored in the first 8 elements of the stack (32 bits per element). /// Output: A 32-byte digest stored in the first 8 elements of stack (32 bits per element). /// The output is passed back to the caller via a pointer. - #[link_name = "blake3_hash_1to1<0x0000000000000000000000000000000000000000000000000000000000000000>"] + #[link_name = "hash_1to1<0x0000000000000000000000000000000000000000000000000000000000000000>"] fn extern_blake3_hash_1to1( - e1: Felt, - e2: Felt, - e3: Felt, - e4: Felt, - e5: Felt, - e6: Felt, - e7: Felt, - e8: Felt, - ptr: *mut Felt, + e1: u32, + e2: u32, + e3: u32, + e4: u32, + e5: u32, + e6: u32, + e7: u32, + e8: u32, + ptr: *mut u8, ); /// Computes BLAKE3 2-to-1 hash. @@ -28,27 +27,30 @@ extern "C" { /// Input: 64-bytes stored in the first 16 elements of the stack (32 bits per element). /// Output: A 32-byte digest stored in the first 8 elements of stack (32 bits per element) /// The output is passed back to the caller via a pointer. - #[link_name = "blake3_hash_2to1<0x0000000000000000000000000000000000000000000000000000000000000000>"] + #[link_name = "hash_2to1<0x0000000000000000000000000000000000000000000000000000000000000000>"] fn extern_blake3_hash_2to1( - e1: Felt, - e2: Felt, - e3: Felt, - e4: Felt, - e5: Felt, - e6: Felt, - e7: Felt, - e8: Felt, - e9: Felt, - e10: Felt, - e11: Felt, - e12: Felt, - e13: Felt, - e14: Felt, - e15: Felt, - e16: Felt, - ptr: *mut Felt, + e1: u32, + e2: u32, + e3: u32, + e4: u32, + e5: u32, + e6: u32, + e7: u32, + e8: u32, + e9: u32, + e10: u32, + e11: u32, + e12: u32, + e13: u32, + e14: u32, + e15: u32, + e16: u32, + ptr: *mut u8, ); +} +#[link(wasm_import_module = "std::crypto::hashes::sha256")] +extern "C" { /// Computes SHA256 1-to-1 hash. /// /// Input: 32-bytes stored in the first 8 elements of the stack (32 bits per element). @@ -56,15 +58,15 @@ extern "C" { /// The output is passed back to the caller via a pointer. #[link_name = "sha256_hash_1to1<0x0000000000000000000000000000000000000000000000000000000000000000>"] fn extern_sha256_hash_1to1( - e1: Felt, - e2: Felt, - e3: Felt, - e4: Felt, - e5: Felt, - e6: Felt, - e7: Felt, - e8: Felt, - ptr: *mut Felt, + e1: u32, + e2: u32, + e3: u32, + e4: u32, + e5: u32, + e6: u32, + e7: u32, + e8: u32, + ptr: *mut u8, ); /// Computes SHA256 2-to-1 hash. @@ -74,23 +76,23 @@ extern "C" { /// The output is passed back to the caller via a pointer. #[link_name = "sha256_hash_2to1<0x0000000000000000000000000000000000000000000000000000000000000000>"] fn extern_sha256_hash_2to1( - e1: Felt, - e2: Felt, - e3: Felt, - e4: Felt, - e5: Felt, - e6: Felt, - e7: Felt, - e8: Felt, - e9: Felt, - e10: Felt, - e11: Felt, - e12: Felt, - e13: Felt, - e14: Felt, - e15: Felt, - e16: Felt, - ptr: *mut Felt, + e1: u32, + e2: u32, + e3: u32, + e4: u32, + e5: u32, + e6: u32, + e7: u32, + e8: u32, + e9: u32, + e10: u32, + e11: u32, + e12: u32, + e13: u32, + e14: u32, + e15: u32, + e16: u32, + ptr: *mut u8, ); } @@ -98,139 +100,76 @@ extern "C" { #[inline(always)] fn hash_1to1( input: [u8; 32], - extern_hash_1to1: unsafe extern "C" fn( - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - *mut Felt, - ), + extern_hash_1to1: unsafe extern "C" fn(u32, u32, u32, u32, u32, u32, u32, u32, *mut u8), ) -> [u8; 32] { - let mut felts_input = [Felt::from_u64_unchecked(0); 8]; - for i in 0..8 { - felts_input[i] = Felt::from_u64_unchecked(u32::from_le_bytes( - input[i * 4..(i + 1) * 4].try_into().unwrap(), - ) as u64); - } + let input = unsafe { core::mem::transmute::<[u8; 32], [u32; 8]>(input) }; unsafe { - let mut ret_area = ::core::mem::MaybeUninit::<[Felt; 8]>::uninit(); - let ptr = ret_area.as_mut_ptr() as *mut Felt; + let mut ret_area = ::core::mem::MaybeUninit::<[u8; 32]>::uninit(); + let ptr = ret_area.as_mut_ptr() as *mut u8; extern_hash_1to1( - felts_input[0], - felts_input[1], - felts_input[2], - felts_input[3], - felts_input[4], - felts_input[5], - felts_input[6], - felts_input[7], - ptr, + input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7], ptr, ); - let felts_out = ret_area.assume_init(); - let mut result = [0u8; 32]; - for i in 0..8 { - let bytes = felts_out[i].as_u64().to_le_bytes(); - // Copy only 4 bytes since output felt values contain u32 value per felt - result[i * 4..(i + 1) * 4].copy_from_slice(&bytes[0..4]); - } - result + ret_area.assume_init() } } /// Hashes a 64-byte input to a 32-byte output using the given hash function. #[inline(always)] fn hash_2to1( - input1: [u8; 32], - input2: [u8; 32], + input: [u8; 64], extern_hash_2to1: unsafe extern "C" fn( - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - Felt, - *mut Felt, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + u32, + *mut u8, ), ) -> [u8; 32] { - let mut felts_input1 = [Felt::from_u64_unchecked(0); 8]; - for i in 0..8 { - felts_input1[i] = Felt::from_u64_unchecked(u32::from_le_bytes( - input1[i * 4..(i + 1) * 4].try_into().unwrap(), - ) as u64); - } - let mut felts_input2 = [Felt::from_u64_unchecked(0); 8]; - for i in 0..8 { - felts_input2[i] = Felt::from_u64_unchecked(u32::from_le_bytes( - input2[i * 4..(i + 1) * 4].try_into().unwrap(), - ) as u64); - } + let input = unsafe { core::mem::transmute::<[u8; 64], [u32; 16]>(input) }; unsafe { - let mut ret_area = ::core::mem::MaybeUninit::<[Felt; 16]>::uninit(); - let ptr = ret_area.as_mut_ptr() as *mut Felt; + let mut ret_area = ::core::mem::MaybeUninit::<[u8; 32]>::uninit(); + let ptr = ret_area.as_mut_ptr() as *mut u8; extern_hash_2to1( - felts_input1[0], - felts_input1[1], - felts_input1[2], - felts_input1[3], - felts_input1[4], - felts_input1[5], - felts_input1[6], - felts_input1[7], - felts_input2[0], - felts_input2[1], - felts_input2[2], - felts_input2[3], - felts_input2[4], - felts_input2[5], - felts_input2[6], - felts_input2[7], + input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7], + input[8], input[9], input[10], input[11], input[12], input[13], input[14], input[15], ptr, ); - let felts_out = ret_area.assume_init(); - let mut result = [0u8; 32]; - for i in 0..8 { - let bytes = felts_out[i].as_u64().to_le_bytes(); - // Copy only 4 bytes since output felt values contain u32 value per felt - result[i * 4..(i + 1) * 4].copy_from_slice(&bytes[0..4]); - } - result + ret_area.assume_init() } } /// Hashes a 32-byte input to a 32-byte output using the BLAKE3 hash function. -#[inline(always)] +#[inline] pub fn blake3_hash_1to1(input: [u8; 32]) -> [u8; 32] { hash_1to1(input, extern_blake3_hash_1to1) } -/// Hashes a 64-byte input (two 32-byte arrays) to a 32-byte output using the BLAKE3 hash function. -#[inline(always)] -pub fn blake3_hash_2to1(input1: [u8; 32], input2: [u8; 32]) -> [u8; 32] { - hash_2to1(input1, input2, extern_blake3_hash_2to1) +/// Hashes a 64-byte input to a 32-byte output using the BLAKE3 hash function. +#[inline] +pub fn blake3_hash_2to1(input: [u8; 64]) -> [u8; 32] { + hash_2to1(input, extern_blake3_hash_2to1) } /// Hashes a 32-byte input to a 32-byte output using the SHA256 hash function. -#[inline(always)] +#[inline] pub fn sha256_hash_1to1(input: [u8; 32]) -> [u8; 32] { hash_1to1(input, extern_sha256_hash_1to1) } -/// Hashes a 64-byte input(two 32-byte arrays) to a 32-byte output using the SHA256 hash function. -#[inline(always)] -pub fn sha256_hash_2to1(input1: [u8; 32], input2: [u8; 32]) -> [u8; 32] { - hash_2to1(input1, input2, extern_sha256_hash_2to1) +/// Hashes a 64-byte input to a 32-byte output using the SHA256 hash function. +#[inline] +pub fn sha256_hash_2to1(input: [u8; 64]) -> [u8; 32] { + hash_2to1(input, extern_sha256_hash_2to1) } diff --git a/sdk/stdlib-sys/src/stdlib/mem.rs b/sdk/stdlib-sys/src/stdlib/mem.rs index f827c357..aedb437b 100644 --- a/sdk/stdlib-sys/src/stdlib/mem.rs +++ b/sdk/stdlib-sys/src/stdlib/mem.rs @@ -5,7 +5,7 @@ use alloc::vec::Vec; use crate::{Felt, Word}; -#[link(wasm_import_module = "miden:stdlib/std_mem")] +#[link(wasm_import_module = "std::mem")] extern "C" { /// Moves an arbitrary number of words from the advice stack to memory. @@ -91,7 +91,7 @@ pub fn pipe_double_words_to_memory(num_words: Felt) -> (Word, Vec) { } let num_words_in_felts = num_words.as_u64() as usize * 4; - let mut buf: Vec = Vec::with_capacity(num_words_in_felts as usize); + let mut buf: Vec = Vec::with_capacity(num_words_in_felts); let write_ptr = buf.as_mut_ptr(); let end_ptr = unsafe { write_ptr.add(num_words_in_felts) }; // Place for returned C, B, A, write_ptr diff --git a/sdk/tx-kernel-sys/CHANGELOG.md b/sdk/tx-kernel-sys/CHANGELOG.md deleted file mode 100644 index de21c861..00000000 --- a/sdk/tx-kernel-sys/CHANGELOG.md +++ /dev/null @@ -1,15 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.0.1](https://github.com/0xPolygonMiden/compiler/compare/miden-tx-kernel-sys-v0.0.0...miden-tx-kernel-sys-v0.0.1) - 2024-07-18 - -### Other -- set crates versions to 0.0.0, and `publish = false` for tests -- rename `miden-sdk-tx-kernel` to `miden-tx-kernel-sys` -- rename `miden-prelude` to `miden-stdlib-sys` in SDK -- start guides for developing in rust in the book, diff --git a/sdk/tx-kernel-sys/Cargo.toml b/sdk/tx-kernel-sys/Cargo.toml deleted file mode 100644 index 3792587d..00000000 --- a/sdk/tx-kernel-sys/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "miden-tx-kernel-sys" -description = "Miden SDK transaction kernel" -version = "0.0.1" -rust-version.workspace = true -authors.workspace = true -repository.workspace = true -categories.workspace = true -keywords.workspace = true -license.workspace = true -readme.workspace = true -edition.workspace = true - -[lib] -crate-type = ["rlib"] - -[dependencies] -miden-stdlib-sys = { path = "../stdlib-sys" } diff --git a/tests/integration/Cargo.toml b/tests/integration/Cargo.toml index c59d3d65..4e0f7f17 100644 --- a/tests/integration/Cargo.toml +++ b/tests/integration/Cargo.toml @@ -12,34 +12,34 @@ edition.workspace = true publish = false [dependencies] -midenc-frontend-wasm.workspace = true -midenc-hir.workspace = true -midenc-hir-transform.workspace = true -midenc-codegen-masm.workspace = true +anyhow.workspace = true +cargo_metadata = "0.18" +cargo-util = "0.2" +derive_more.workspace = true +expect-test.workspace = true +filetime = "0.2.23" +glob = "0.3.1" +log.workspace = true miden-assembly.workspace = true miden-core.workspace = true miden-processor.workspace = true miden-stdlib.workspace = true -miden-diagnostics.workspace = true +midenc-frontend-wasm.workspace = true +midenc-hir.workspace = true +midenc-hir-transform.workspace = true +midenc-codegen-masm.workspace = true midenc-session.workspace = true midenc-compile.workspace = true -expect-test = "1.4.1" +midenc-driver.workspace = true +midenc-debug.workspace = true miden-integration-tests-rust-fib = { path = "../rust-apps/fib" } -wasmprinter = "0.2.63" +wasmprinter = "0.2.80" +proptest.workspace = true sha2 = "0.10" -rustc-demangle = { version = "0.1.19", features = ["std"] } -cargo_metadata = "0.18" -derive_more.workspace = true -anyhow.workspace = true -cargo-util = "0.2" -filetime = "0.2.23" -glob = "0.3.1" walkdir = "2.5.0" -proptest.workspace = true [dev-dependencies] -miden-core.workspace = true -concat-idents = "1.1" blake3.workspace = true -log.workspace = true +concat-idents = "1.1" env_logger.workspace = true +miden-core.workspace = true diff --git a/tests/integration/expected/abi_transform_stdlib_blake3_hash.hir b/tests/integration/expected/abi_transform_stdlib_blake3_hash.hir index 0e61ff76..e1a2d5df 100644 --- a/tests/integration/expected/abi_transform_stdlib_blake3_hash.hir +++ b/tests/integration/expected/abi_transform_stdlib_blake3_hash.hir @@ -1,9 +1,6 @@ (component ;; Modules (module #abi_transform_stdlib_blake3_hash - ;; Data Segments - (data (mut) (offset 1048576) 0x7e2f73646b2f7072656c7564652f7372632f7374646c69622f63727970746f2f6861736865732e72730000000000100029000000d100000028000000) - ;; Constants (const (id 0) 0x00100000) @@ -11,409 +8,119 @@ (global (export #__stack_pointer) (id 0) (type i32) (const 0)) ;; Functions - (func (export #entrypoint) (param i32) (param i32) (param i32) - (block 0 (param v0 i32) (param v1 i32) (param v2 i32) - (let (v3 i32) (const.i32 0)) - (let (v4 felt) (const.felt 0)) - (let (v5 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v6 i32) (const.i32 432)) - (let (v7 i32) (sub.wrapping v5 v6)) - (let (v8 (ptr i32)) (global.symbol #__stack_pointer)) - (store v8 v7) - (let (v9 i32) (const.i32 0)) - (let (v10 i64) (const.i64 0)) - (let (v11 felt) (cast v10)) - (br (block 2 v9 v7 v2 v0 v1 v11))) - - (block 1) - - (block 2 - (param v12 i32) - (param v275 i32) - (param v276 i32) - (param v277 i32) - (param v278 i32) - (param v282 felt) - (let (v13 i32) (const.i32 64)) - (let (v14 i1) (neq v12 v13)) - (let (v15 i32) (cast v14)) - (let (v16 i1) (neq v15 0)) - (condbr v16 (block 4) (block 5))) - - (block 3) - - (block 4 - (let (v279 i32) (const.i32 8)) - (let (v280 i32) (add.wrapping v275 v279)) - (let (v281 i32) (add.wrapping v280 v12)) - (let (v283 u32) (cast v281)) - (let (v284 (ptr felt)) (inttoptr v283)) - (store v284 v282) - (let (v285 i32) (const.i32 8)) - (let (v286 i32) (add.wrapping v12 v285)) - (br (block 2 v286 v275 v276 v277 v278 v282))) - - (block 5 - (let (v17 i32) (const.i32 0)) - (br (block 6 v17 v275 v276 v277 v278))) - - (block 6 - (param v18 i32) - (param v257 i32) - (param v258 i32) - (param v259 i32) - (param v263 i32) - (let (v19 i32) (const.i32 64)) - (let (v20 i1) (neq v18 v19)) - (let (v21 i32) (cast v20)) - (let (v22 i1) (neq v21 0)) - (condbr v22 (block 8) (block 9))) - - (block 7) - - (block 8 - (let (v260 i32) (const.i32 8)) - (let (v261 i32) (add.wrapping v257 v260)) - (let (v262 i32) (add.wrapping v261 v18)) - (let (v264 u32) (cast v263)) - (let (v265 (ptr u32)) (inttoptr v264)) - (let (v266 u32) (load v265)) - (let (v267 i64) (zext v266)) - (let (v268 felt) (cast v267)) - (let (v269 u32) (cast v262)) - (let (v270 (ptr felt)) (inttoptr v269)) - (store v270 v268) - (let (v271 i32) (const.i32 8)) - (let (v272 i32) (add.wrapping v18 v271)) - (let (v273 i32) (const.i32 4)) - (let (v274 i32) (add.wrapping v263 v273)) - (br (block 6 v272 v257 v258 v259 v274))) - - (block 9 - (let (v23 i32) (const.i32 0)) - (let (v24 i64) (const.i64 0)) - (let (v25 felt) (cast v24)) - (br (block 10 v23 v257 v258 v259 v25))) - - (block 10 - (param v26 i32) - (param v202 i32) - (param v203 i32) - (param v206 i32) - (param v252 felt) - (let (v27 i32) (const.i32 64)) - (let (v28 i1) (neq v26 v27)) - (let (v29 i32) (cast v28)) - (let (v30 i1) (neq v29 0)) - (condbr v30 (block 12) (block 13))) - - (block 11) - - (block 12 - (let (v249 i32) (const.i32 72)) - (let (v250 i32) (add.wrapping v202 v249)) - (let (v251 i32) (add.wrapping v250 v26)) - (let (v253 u32) (cast v251)) - (let (v254 (ptr felt)) (inttoptr v253)) - (store v254 v252) - (let (v255 i32) (const.i32 8)) - (let (v256 i32) (add.wrapping v26 v255)) - (br (block 10 v256 v202 v203 v206 v252))) - - (block 13 - (let (v31 i32) (const.i32 0)) - (br (block 15 v31 v202 v203 v206))) - - (block 14 - (let (v207 u32) (cast v166)) - (let (v208 u32) (add.checked v207 392)) - (let (v209 (ptr i64)) (inttoptr v208)) - (let (v210 i64) (load v209)) - (let (v211 u32) (cast v204)) - (let (v212 (ptr i64)) (inttoptr v211)) - (store v212 v210) - (let (v213 i32) (const.i32 24)) - (let (v214 i32) (add.wrapping v204 v213)) - (let (v215 i32) (const.i32 392)) - (let (v216 i32) (add.wrapping v166 v215)) - (let (v217 i32) (const.i32 24)) - (let (v218 i32) (add.wrapping v216 v217)) - (let (v219 u32) (cast v218)) - (let (v220 (ptr i64)) (inttoptr v219)) - (let (v221 i64) (load v220)) - (let (v222 u32) (cast v214)) - (let (v223 (ptr i64)) (inttoptr v222)) - (store v223 v221) - (let (v224 i32) (const.i32 16)) - (let (v225 i32) (add.wrapping v204 v224)) - (let (v226 i32) (const.i32 392)) - (let (v227 i32) (add.wrapping v166 v226)) - (let (v228 i32) (const.i32 16)) - (let (v229 i32) (add.wrapping v227 v228)) - (let (v230 u32) (cast v229)) - (let (v231 (ptr i64)) (inttoptr v230)) - (let (v232 i64) (load v231)) - (let (v233 u32) (cast v225)) - (let (v234 (ptr i64)) (inttoptr v233)) - (store v234 v232) - (let (v235 i32) (const.i32 8)) - (let (v236 i32) (add.wrapping v204 v235)) - (let (v237 i32) (const.i32 392)) - (let (v238 i32) (add.wrapping v166 v237)) - (let (v239 i32) (const.i32 8)) - (let (v240 i32) (add.wrapping v238 v239)) - (let (v241 u32) (cast v240)) - (let (v242 (ptr i64)) (inttoptr v241)) - (let (v243 i64) (load v242)) - (let (v244 u32) (cast v236)) - (let (v245 (ptr i64)) (inttoptr v244)) - (store v245 v243) - (let (v246 i32) (const.i32 432)) - (let (v247 i32) (add.wrapping v166 v246)) - (let (v248 (ptr i32)) (global.symbol #__stack_pointer)) - (store v248 v247) - (ret)) - - (block 15 - (param v32 i32) - (param v37 i32) - (param v190 i32) - (param v205 i32) - (let (v33 i32) (const.i32 64)) - (let (v34 i1) (neq v32 v33)) - (let (v35 i32) (cast v34)) - (let (v36 i1) (neq v35 0)) - (condbr v36 (block 17) (block 18))) - - (block 16) - - (block 17 - (let (v187 i32) (const.i32 72)) - (let (v188 i32) (add.wrapping v37 v187)) - (let (v189 i32) (add.wrapping v188 v32)) - (let (v191 u32) (cast v190)) - (let (v192 (ptr u32)) (inttoptr v191)) - (let (v193 u32) (load v192)) - (let (v194 i64) (zext v193)) - (let (v195 felt) (cast v194)) - (let (v196 u32) (cast v189)) - (let (v197 (ptr felt)) (inttoptr v196)) - (store v197 v195) - (let (v198 i32) (const.i32 8)) - (let (v199 i32) (add.wrapping v32 v198)) - (let (v200 i32) (const.i32 4)) - (let (v201 i32) (add.wrapping v190 v200)) - (br (block 15 v199 v37 v201 v205))) - - (block 18 - (let (v38 u32) (cast v37)) - (let (v39 u32) (add.checked v38 8)) - (let (v40 (ptr felt)) (inttoptr v39)) - (let (v41 felt) (load v40)) - (let (v42 u32) (cast v37)) - (let (v43 u32) (add.checked v42 16)) - (let (v44 (ptr felt)) (inttoptr v43)) - (let (v45 felt) (load v44)) - (let (v46 u32) (cast v37)) - (let (v47 u32) (add.checked v46 24)) - (let (v48 (ptr felt)) (inttoptr v47)) - (let (v49 felt) (load v48)) - (let (v50 u32) (cast v37)) - (let (v51 u32) (add.checked v50 32)) - (let (v52 (ptr felt)) (inttoptr v51)) - (let (v53 felt) (load v52)) - (let (v54 u32) (cast v37)) - (let (v55 u32) (add.checked v54 40)) - (let (v56 (ptr felt)) (inttoptr v55)) - (let (v57 felt) (load v56)) - (let (v58 u32) (cast v37)) - (let (v59 u32) (add.checked v58 48)) - (let (v60 (ptr felt)) (inttoptr v59)) - (let (v61 felt) (load v60)) - (let (v62 u32) (cast v37)) - (let (v63 u32) (add.checked v62 56)) - (let (v64 (ptr felt)) (inttoptr v63)) - (let (v65 felt) (load v64)) - (let (v66 u32) (cast v37)) - (let (v67 u32) (add.checked v66 64)) - (let (v68 (ptr felt)) (inttoptr v67)) - (let (v69 felt) (load v68)) - (let (v70 u32) (cast v37)) - (let (v71 u32) (add.checked v70 72)) - (let (v72 (ptr felt)) (inttoptr v71)) - (let (v73 felt) (load v72)) - (let (v74 u32) (cast v37)) - (let (v75 u32) (add.checked v74 80)) - (let (v76 (ptr felt)) (inttoptr v75)) - (let (v77 felt) (load v76)) - (let (v78 u32) (cast v37)) - (let (v79 u32) (add.checked v78 88)) - (let (v80 (ptr felt)) (inttoptr v79)) - (let (v81 felt) (load v80)) - (let (v82 u32) (cast v37)) - (let (v83 u32) (add.checked v82 96)) - (let (v84 (ptr felt)) (inttoptr v83)) - (let (v85 felt) (load v84)) - (let (v86 u32) (cast v37)) - (let (v87 u32) (add.checked v86 104)) - (let (v88 (ptr felt)) (inttoptr v87)) - (let (v89 felt) (load v88)) - (let (v90 u32) (cast v37)) - (let (v91 u32) (add.checked v90 112)) - (let (v92 (ptr felt)) (inttoptr v91)) - (let (v93 felt) (load v92)) - (let (v94 u32) (cast v37)) - (let (v95 u32) (add.checked v94 120)) - (let (v96 (ptr felt)) (inttoptr v95)) - (let (v97 felt) (load v96)) - (let (v98 u32) (cast v37)) - (let (v99 u32) (add.checked v98 128)) - (let (v100 (ptr felt)) (inttoptr v99)) - (let (v101 felt) (load v100)) - (let (v102 i32) (const.i32 136)) - (let (v103 i32) (add.wrapping v37 v102)) - (let [(v104 felt) (v105 felt) (v106 felt) (v107 felt) (v108 felt) (v109 felt) (v110 felt) (v111 felt)] (call (#std::crypto_hashes #blake3_hash_2to1) v41 v45 v49 v53 v57 v61 v65 v69 v73 v77 v81 v85 v89 v93 v97 v101)) - (let (v112 u32) (cast v103)) - (let (v113 (ptr felt)) (inttoptr v112)) - (store v113 v104) - (let (v114 u32) (add.checked v112 8)) - (let (v115 (ptr felt)) (inttoptr v114)) - (store v115 v105) - (let (v116 u32) (add.checked v112 16)) - (let (v117 (ptr felt)) (inttoptr v116)) - (store v117 v106) - (let (v118 u32) (add.checked v112 24)) - (let (v119 (ptr felt)) (inttoptr v118)) - (store v119 v107) - (let (v120 u32) (add.checked v112 32)) - (let (v121 (ptr felt)) (inttoptr v120)) - (store v121 v108) - (let (v122 u32) (add.checked v112 40)) - (let (v123 (ptr felt)) (inttoptr v122)) - (store v123 v109) - (let (v124 u32) (add.checked v112 48)) - (let (v125 (ptr felt)) (inttoptr v124)) - (store v125 v110) - (let (v126 u32) (add.checked v112 56)) - (let (v127 (ptr felt)) (inttoptr v126)) - (store v127 v111) - (let (v128 i32) (const.i32 264)) - (let (v129 i32) (add.wrapping v37 v128)) - (let (v130 i32) (const.i32 136)) - (let (v131 i32) (add.wrapping v37 v130)) - (let (v132 i32) (const.i32 128)) - (let (v133 u32) (cast v129)) - (let (v134 (ptr u8)) (inttoptr v133)) - (let (v135 u32) (cast v131)) - (let (v136 (ptr u8)) (inttoptr v135)) - (memcpy v136 v134 v132) - (let (v137 i32) (const.i32 416)) - (let (v138 i32) (add.wrapping v37 v137)) - (let (v139 i64) (const.i64 0)) - (let (v140 u32) (cast v138)) - (let (v141 (ptr i64)) (inttoptr v140)) - (store v141 v139) - (let (v142 i32) (const.i32 408)) - (let (v143 i32) (add.wrapping v37 v142)) - (let (v144 i64) (const.i64 0)) - (let (v145 u32) (cast v143)) - (let (v146 (ptr i64)) (inttoptr v145)) - (store v146 v144) - (let (v147 i32) (const.i32 392)) - (let (v148 i32) (add.wrapping v37 v147)) - (let (v149 i32) (const.i32 8)) - (let (v150 i32) (add.wrapping v148 v149)) - (let (v151 i64) (const.i64 0)) - (let (v152 u32) (cast v150)) - (let (v153 (ptr i64)) (inttoptr v152)) - (store v153 v151) - (let (v154 i64) (const.i64 0)) - (let (v155 u32) (cast v37)) - (let (v156 u32) (add.checked v155 392)) - (let (v157 (ptr i64)) (inttoptr v156)) - (store v157 v154) - (let (v158 i32) (const.i32 264)) - (let (v159 i32) (add.wrapping v37 v158)) - (let (v160 i32) (const.i32 0)) - (br (block 19 v160 v37 v159 v205))) - - (block 19 - (param v161 i32) - (param v166 i32) - (param v167 i32) - (param v204 i32) - (let (v162 i32) (const.i32 32)) - (let (v163 i1) (eq v161 v162)) - (let (v164 i32) (cast v163)) - (let (v165 i1) (neq v164 0)) - (condbr v165 (block 14) (block 21))) - - (block 20) - - (block 21 - (let (v168 u32) (cast v167)) - (let (v169 (ptr felt)) (inttoptr v168)) - (let (v170 felt) (load v169)) - (let (v171 i64) (cast v170)) - (let (v172 u32) (cast v166)) - (let (v173 u32) (add.checked v172 424)) - (let (v174 (ptr i64)) (inttoptr v173)) - (store v174 v171) - (let (v175 i32) (const.i32 392)) - (let (v176 i32) (add.wrapping v166 v175)) - (let (v177 i32) (add.wrapping v176 v161)) - (let (v178 i32) (const.i32 4)) - (let (v179 i32) (const.i32 424)) - (let (v180 i32) (add.wrapping v166 v179)) - (let (v181 i32) (const.i32 4)) - (let (v182 i32) (const.i32 1048620)) - (call #core::slice::::copy_from_slice v177 v178 v180 v181 v182) - (let (v183 i32) (const.i32 4)) - (let (v184 i32) (add.wrapping v161 v183)) - (let (v185 i32) (const.i32 8)) - (let (v186 i32) (add.wrapping v167 v185)) - (br (block 19 v184 v166 v186 v204))) - ) - - (func (export #core::slice::::copy_from_slice::len_mismatch_fail) - (param i32) (param i32) (param i32) - (block 0 (param v0 i32) (param v1 i32) (param v2 i32) - (unreachable)) - - (block 1) - ) - - (func (export #core::slice::::copy_from_slice) - (param i32) (param i32) (param i32) (param i32) (param i32) - (block 0 - (param v0 i32) - (param v1 i32) - (param v2 i32) - (param v3 i32) - (param v4 i32) - (let (v5 i1) (neq v1 v3)) - (let (v6 i32) (cast v5)) - (let (v7 i1) (neq v6 0)) - (condbr v7 (block 2) (block 3))) - - (block 1) - - (block 2 - (call #core::slice::::copy_from_slice::len_mismatch_fail v1 v1 v1) - (unreachable)) - - (block 3 - (let (v8 u32) (cast v0)) - (let (v9 (ptr u8)) (inttoptr v8)) - (let (v10 u32) (cast v2)) - (let (v11 (ptr u8)) (inttoptr v10)) - (memcpy v11 v9 v1) + (func (export #entrypoint) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v2 i32) (const.i32 0)) + (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v4 i32) (const.i32 32)) + (let (v5 i32) (sub.wrapping v3 v4)) + (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) + (store v6 v5) + (let (v7 u32) (cast v1)) + (let (v8 (ptr i32)) (inttoptr v7)) + (let (v9 i32) (load v8)) + (let (v10 u32) (cast v1)) + (let (v11 u32) (add.checked v10 4)) + (let (v12 (ptr i32)) (inttoptr v11)) + (let (v13 i32) (load v12)) + (let (v14 u32) (cast v1)) + (let (v15 u32) (add.checked v14 8)) + (let (v16 (ptr i32)) (inttoptr v15)) + (let (v17 i32) (load v16)) + (let (v18 u32) (cast v1)) + (let (v19 u32) (add.checked v18 12)) + (let (v20 (ptr i32)) (inttoptr v19)) + (let (v21 i32) (load v20)) + (let (v22 u32) (cast v1)) + (let (v23 u32) (add.checked v22 16)) + (let (v24 (ptr i32)) (inttoptr v23)) + (let (v25 i32) (load v24)) + (let (v26 u32) (cast v1)) + (let (v27 u32) (add.checked v26 20)) + (let (v28 (ptr i32)) (inttoptr v27)) + (let (v29 i32) (load v28)) + (let (v30 u32) (cast v1)) + (let (v31 u32) (add.checked v30 24)) + (let (v32 (ptr i32)) (inttoptr v31)) + (let (v33 i32) (load v32)) + (let (v34 u32) (cast v1)) + (let (v35 u32) (add.checked v34 28)) + (let (v36 (ptr i32)) (inttoptr v35)) + (let (v37 i32) (load v36)) + (let [(v38 i32) (v39 i32) (v40 i32) (v41 i32) (v42 i32) (v43 i32) (v44 i32) (v45 i32)] (call (#std::crypto::hashes::blake3 #hash_1to1) v9 v13 v17 v21 v25 v29 v33 v37)) + (let (v46 u32) (cast v5)) + (let (v47 (ptr i32)) (inttoptr v46)) + (store v47 v38) + (let (v48 u32) (add.checked v46 8)) + (let (v49 (ptr i32)) (inttoptr v48)) + (store v49 v39) + (let (v50 u32) (add.checked v46 16)) + (let (v51 (ptr i32)) (inttoptr v50)) + (store v51 v40) + (let (v52 u32) (add.checked v46 24)) + (let (v53 (ptr i32)) (inttoptr v52)) + (store v53 v41) + (let (v54 u32) (add.checked v46 32)) + (let (v55 (ptr i32)) (inttoptr v54)) + (store v55 v42) + (let (v56 u32) (add.checked v46 40)) + (let (v57 (ptr i32)) (inttoptr v56)) + (store v57 v43) + (let (v58 u32) (add.checked v46 48)) + (let (v59 (ptr i32)) (inttoptr v58)) + (store v59 v44) + (let (v60 u32) (add.checked v46 56)) + (let (v61 (ptr i32)) (inttoptr v60)) + (store v61 v45) + (let (v62 i32) (const.i32 24)) + (let (v63 i32) (add.wrapping v0 v62)) + (let (v64 i32) (const.i32 24)) + (let (v65 i32) (add.wrapping v5 v64)) + (let (v66 u32) (cast v65)) + (let (v67 (ptr i64)) (inttoptr v66)) + (let (v68 i64) (load v67)) + (let (v69 u32) (cast v63)) + (let (v70 (ptr i64)) (inttoptr v69)) + (store v70 v68) + (let (v71 i32) (const.i32 16)) + (let (v72 i32) (add.wrapping v0 v71)) + (let (v73 i32) (const.i32 16)) + (let (v74 i32) (add.wrapping v5 v73)) + (let (v75 u32) (cast v74)) + (let (v76 (ptr i64)) (inttoptr v75)) + (let (v77 i64) (load v76)) + (let (v78 u32) (cast v72)) + (let (v79 (ptr i64)) (inttoptr v78)) + (store v79 v77) + (let (v80 i32) (const.i32 8)) + (let (v81 i32) (add.wrapping v0 v80)) + (let (v82 i32) (const.i32 8)) + (let (v83 i32) (add.wrapping v5 v82)) + (let (v84 u32) (cast v83)) + (let (v85 (ptr i64)) (inttoptr v84)) + (let (v86 i64) (load v85)) + (let (v87 u32) (cast v81)) + (let (v88 (ptr i64)) (inttoptr v87)) + (store v88 v86) + (let (v89 u32) (cast v5)) + (let (v90 (ptr i64)) (inttoptr v89)) + (let (v91 i64) (load v90)) + (let (v92 u32) (cast v0)) + (let (v93 (ptr i64)) (inttoptr v92)) + (store v93 v91) + (let (v94 i32) (const.i32 32)) + (let (v95 i32) (add.wrapping v5 v94)) + (let (v96 (ptr i32)) (global.symbol #__stack_pointer)) + (store v96 v95) + (br (block 1))) + + (block 1 (ret)) ) ;; Imports - (func (import #std::crypto_hashes #blake3_hash_2to1) - (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (result felt felt felt felt felt felt felt felt)) + (func (import #std::crypto::hashes::blake3 #hash_1to1) + (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32 i32 i32 i32 i32 i32 i32 i32)) ) ) diff --git a/tests/integration/expected/abi_transform_stdlib_blake3_hash.masm b/tests/integration/expected/abi_transform_stdlib_blake3_hash.masm new file mode 100644 index 00000000..2c0281d8 --- /dev/null +++ b/tests/integration/expected/abi_transform_stdlib_blake3_hash.masm @@ -0,0 +1,403 @@ +# mod abi_transform_stdlib_blake3_hash + +use.std::crypto::hashes::blake3 + +export.entrypoint + mem_load.0x00001000 + push.32 + u32wrapping_sub + dup.1 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.0 + dup.0 + push.2147483648 + u32lte + assert + dup.3 + dup.0 + push.2147483648 + u32lte + assert + add.28 + u32assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + dup.4 + dup.0 + push.2147483648 + u32lte + assert + add.24 + u32assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + dup.5 + dup.0 + push.2147483648 + u32lte + assert + add.20 + u32assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + dup.6 + dup.0 + push.2147483648 + u32lte + assert + add.16 + u32assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + dup.7 + dup.0 + push.2147483648 + u32lte + assert + add.12 + u32assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + dup.8 + dup.0 + push.2147483648 + u32lte + assert + add.8 + u32assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + dup.9 + dup.0 + push.2147483648 + u32lte + assert + add.4 + u32assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + movup.10 + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + exec.::std::crypto::hashes::blake3::hash_1to1 + dup.8 + movup.8 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.7 + add.8 + u32assert + movup.7 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.6 + add.16 + u32assert + movup.6 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.5 + add.24 + u32assert + movup.5 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.4 + add.32 + u32assert + movup.4 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.3 + add.40 + u32assert + movup.3 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.2 + add.48 + u32assert + movup.2 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + swap.1 + add.56 + u32assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.24 + dup.1 + swap.1 + u32wrapping_add + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_dw + push.24 + dup.4 + swap.1 + u32wrapping_add + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_dw + push.16 + dup.1 + swap.1 + u32wrapping_add + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_dw + push.16 + dup.4 + swap.1 + u32wrapping_add + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_dw + push.8 + dup.1 + swap.1 + u32wrapping_add + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_dw + push.8 + dup.4 + swap.1 + u32wrapping_add + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_dw + dup.0 + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_dw + movup.3 + dup.0 + push.2147483648 + u32lte + assert + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_dw + push.32 + u32wrapping_add + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw +end + + diff --git a/tests/integration/expected/abi_transform_stdlib_blake3_hash.wat b/tests/integration/expected/abi_transform_stdlib_blake3_hash.wat index 4427e544..651e0277 100644 --- a/tests/integration/expected/abi_transform_stdlib_blake3_hash.wat +++ b/tests/integration/expected/abi_transform_stdlib_blake3_hash.wat @@ -1,295 +1,68 @@ (module $abi_transform_stdlib_blake3_hash.wasm - (type (;0;) (func (param i64) (result f64))) - (type (;1;) (func (param f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i32))) - (type (;2;) (func (param f64) (result i64))) - (type (;3;) (func (param i32 i32 i32))) - (type (;4;) (func (param i32 i32 i32 i32 i32))) - (import "miden:prelude/intrinsics_felt" "from_u64_unchecked" (func $miden_prelude::intrinsics::felt::extern_from_u64_unchecked (;0;) (type 0))) - (import "std::crypto_hashes" "blake3_hash_2to1<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_prelude::stdlib::crypto::hashes::extern_blake3_hash_2to1 (;1;) (type 1))) - (import "miden:prelude/intrinsics_felt" "as_u64" (func $miden_prelude::intrinsics::felt::extern_as_u64 (;2;) (type 2))) - (func $entrypoint (;3;) (type 3) (param i32 i32 i32) - (local i32 i32 f64) + (type (;0;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32))) + (type (;1;) (func (param i32 i32))) + (import "std::crypto::hashes::blake3" "hash_1to1<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 (;0;) (type 0))) + (func $entrypoint (;1;) (type 1) (param i32 i32) + (local i32) global.get $__stack_pointer - i32.const 432 + i32.const 32 i32.sub - local.tee 3 + local.tee 2 global.set $__stack_pointer - i32.const 0 - local.set 4 - i64.const 0 - call $miden_prelude::intrinsics::felt::extern_from_u64_unchecked - local.set 5 - loop ;; label = @1 - block ;; label = @2 - local.get 4 - i32.const 64 - i32.ne - br_if 0 (;@2;) - i32.const 0 - local.set 4 - loop ;; label = @3 - block ;; label = @4 - local.get 4 - i32.const 64 - i32.ne - br_if 0 (;@4;) - i32.const 0 - local.set 4 - i64.const 0 - call $miden_prelude::intrinsics::felt::extern_from_u64_unchecked - local.set 5 - loop ;; label = @5 - block ;; label = @6 - local.get 4 - i32.const 64 - i32.ne - br_if 0 (;@6;) - i32.const 0 - local.set 4 - block ;; label = @7 - loop ;; label = @8 - block ;; label = @9 - local.get 4 - i32.const 64 - i32.ne - br_if 0 (;@9;) - local.get 3 - f64.load offset=8 - local.get 3 - f64.load offset=16 - local.get 3 - f64.load offset=24 - local.get 3 - f64.load offset=32 - local.get 3 - f64.load offset=40 - local.get 3 - f64.load offset=48 - local.get 3 - f64.load offset=56 - local.get 3 - f64.load offset=64 - local.get 3 - f64.load offset=72 - local.get 3 - f64.load offset=80 - local.get 3 - f64.load offset=88 - local.get 3 - f64.load offset=96 - local.get 3 - f64.load offset=104 - local.get 3 - f64.load offset=112 - local.get 3 - f64.load offset=120 - local.get 3 - f64.load offset=128 - local.get 3 - i32.const 136 - i32.add - call $miden_prelude::stdlib::crypto::hashes::extern_blake3_hash_2to1 - local.get 3 - i32.const 264 - i32.add - local.get 3 - i32.const 136 - i32.add - i32.const 128 - memory.copy - local.get 3 - i32.const 416 - i32.add - i64.const 0 - i64.store - local.get 3 - i32.const 408 - i32.add - i64.const 0 - i64.store - local.get 3 - i32.const 392 - i32.add - i32.const 8 - i32.add - i64.const 0 - i64.store - local.get 3 - i64.const 0 - i64.store offset=392 - local.get 3 - i32.const 264 - i32.add - local.set 2 - i32.const 0 - local.set 4 - loop ;; label = @10 - local.get 4 - i32.const 32 - i32.eq - br_if 3 (;@7;) - local.get 3 - local.get 2 - f64.load - call $miden_prelude::intrinsics::felt::extern_as_u64 - i64.store offset=424 - local.get 3 - i32.const 392 - i32.add - local.get 4 - i32.add - i32.const 4 - local.get 3 - i32.const 424 - i32.add - i32.const 4 - i32.const 1048620 - call $core::slice::::copy_from_slice - local.get 4 - i32.const 4 - i32.add - local.set 4 - local.get 2 - i32.const 8 - i32.add - local.set 2 - br 0 (;@10;) - end - end - local.get 3 - i32.const 72 - i32.add - local.get 4 - i32.add - local.get 2 - i64.load32_u align=1 - call $miden_prelude::intrinsics::felt::extern_from_u64_unchecked - f64.store - local.get 4 - i32.const 8 - i32.add - local.set 4 - local.get 2 - i32.const 4 - i32.add - local.set 2 - br 0 (;@8;) - end - end - local.get 0 - local.get 3 - i64.load offset=392 - i64.store align=1 - local.get 0 - i32.const 24 - i32.add - local.get 3 - i32.const 392 - i32.add - i32.const 24 - i32.add - i64.load - i64.store align=1 - local.get 0 - i32.const 16 - i32.add - local.get 3 - i32.const 392 - i32.add - i32.const 16 - i32.add - i64.load - i64.store align=1 - local.get 0 - i32.const 8 - i32.add - local.get 3 - i32.const 392 - i32.add - i32.const 8 - i32.add - i64.load - i64.store align=1 - local.get 3 - i32.const 432 - i32.add - global.set $__stack_pointer - return - end - local.get 3 - i32.const 72 - i32.add - local.get 4 - i32.add - local.get 5 - f64.store - local.get 4 - i32.const 8 - i32.add - local.set 4 - br 0 (;@5;) - end - end - local.get 3 - i32.const 8 - i32.add - local.get 4 - i32.add - local.get 1 - i64.load32_u align=1 - call $miden_prelude::intrinsics::felt::extern_from_u64_unchecked - f64.store - local.get 4 - i32.const 8 - i32.add - local.set 4 - local.get 1 - i32.const 4 - i32.add - local.set 1 - br 0 (;@3;) - end - end - local.get 3 - i32.const 8 - i32.add - local.get 4 - i32.add - local.get 5 - f64.store - local.get 4 - i32.const 8 - i32.add - local.set 4 - br 0 (;@1;) - end - ) - (func $core::slice::::copy_from_slice::len_mismatch_fail (;4;) (type 3) (param i32 i32 i32) - unreachable - unreachable - ) - (func $core::slice::::copy_from_slice (;5;) (type 4) (param i32 i32 i32 i32 i32) - block ;; label = @1 - local.get 1 - local.get 3 - i32.ne - br_if 0 (;@1;) - local.get 0 - local.get 2 - local.get 1 - memory.copy - return - end local.get 1 + i32.load align=1 + local.get 1 + i32.load offset=4 align=1 + local.get 1 + i32.load offset=8 align=1 local.get 1 + i32.load offset=12 align=1 local.get 1 - call $core::slice::::copy_from_slice::len_mismatch_fail - unreachable + i32.load offset=16 align=1 + local.get 1 + i32.load offset=20 align=1 + local.get 1 + i32.load offset=24 align=1 + local.get 1 + i32.load offset=28 align=1 + local.get 2 + call $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 + local.get 0 + i32.const 24 + i32.add + local.get 2 + i32.const 24 + i32.add + i64.load align=1 + i64.store align=1 + local.get 0 + i32.const 16 + i32.add + local.get 2 + i32.const 16 + i32.add + i64.load align=1 + i64.store align=1 + local.get 0 + i32.const 8 + i32.add + local.get 2 + i32.const 8 + i32.add + i64.load align=1 + i64.store align=1 + local.get 0 + local.get 2 + i64.load align=1 + i64.store align=1 + local.get 2 + i32.const 32 + i32.add + global.set $__stack_pointer ) (table (;0;) 1 1 funcref) - (memory (;0;) 17) + (memory (;0;) 16) (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) (export "memory" (memory 0)) (export "entrypoint" (func $entrypoint)) - (data $.rodata (;0;) (i32.const 1048576) "~/sdk/prelude/src/stdlib/crypto/hashes.rs\00\00\00\00\00\10\00)\00\00\00\d1\00\00\00(\00\00\00") ) \ No newline at end of file diff --git a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.hir b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.hir index bd336693..cc32d5f9 100644 --- a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.hir +++ b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.hir @@ -46,7 +46,7 @@ (let (v8 i32) (const.i32 0)) (let (v9 u8) (trunc v8)) (let (v10 u32) (bitcast v0)) - (let (v11 u32) (cast v4)) + (let (v11 u32) (bitcast v4)) (let (v12 (ptr u8)) (inttoptr v11)) (memset v12 v10 v9) (br (block 2 v4))) @@ -56,9 +56,9 @@ (param i32) (block 0 (param v0 i32) (let (v1 i32) (const.i32 0)) - (let (v2 u32) (cast v0)) - (let (v3 u32) (mod.unchecked v2 2)) - (assertz v3) + (let (v2 u32) (bitcast v0)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) (let (v4 (ptr i32)) (inttoptr v2)) (let (v5 i32) (load v4)) (let (v6 i32) (const.i32 2)) @@ -70,10 +70,10 @@ (ret)) (block 2 (param v37 i32) (param v54 i32) - (let (v38 u32) (cast v37)) + (let (v38 u32) (bitcast v37)) (let (v39 u32) (add.checked v38 4)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) + (let (v40 u32) (mod.unchecked v39 4)) + (assertz 250 v40) (let (v41 (ptr i32)) (inttoptr v39)) (let (v42 i32) (load v41)) (let (v43 i32) (const.i32 -4)) @@ -92,32 +92,32 @@ (condbr v13 (block 2 v0 v5) (block 4))) (block 4 - (let (v14 u32) (cast v10)) + (let (v14 u32) (bitcast v10)) (let (v15 u32) (add.checked v14 4)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr i32)) (inttoptr v15)) (let (v18 i32) (load v17)) (let (v19 i32) (const.i32 3)) (let (v20 i32) (band v18 v19)) - (let (v21 u32) (cast v0)) + (let (v21 u32) (bitcast v0)) (let (v22 u32) (add.checked v21 4)) - (let (v23 u32) (mod.unchecked v22 2)) - (assertz v23) + (let (v23 u32) (mod.unchecked v22 4)) + (assertz 250 v23) (let (v24 (ptr i32)) (inttoptr v22)) (let (v25 i32) (load v24)) (let (v26 i32) (const.i32 -4)) (let (v27 i32) (band v25 v26)) (let (v28 i32) (bor v20 v27)) - (let (v29 u32) (cast v10)) + (let (v29 u32) (bitcast v10)) (let (v30 u32) (add.checked v29 4)) - (let (v31 u32) (mod.unchecked v30 2)) - (assertz v31) + (let (v31 u32) (mod.unchecked v30 4)) + (assertz 250 v31) (let (v32 (ptr i32)) (inttoptr v30)) (store v32 v28) - (let (v33 u32) (cast v0)) - (let (v34 u32) (mod.unchecked v33 2)) - (assertz v34) + (let (v33 u32) (bitcast v0)) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) (let (v35 (ptr i32)) (inttoptr v33)) (let (v36 i32) (load v35)) (br (block 2 v0 v36))) @@ -125,25 +125,25 @@ (block 5 (param v70 i32) (param v71 i32) (param v78 i32) (let (v72 i32) (const.i32 3)) (let (v73 i32) (band v71 v72)) - (let (v74 u32) (cast v70)) + (let (v74 u32) (bitcast v70)) (let (v75 u32) (add.checked v74 4)) - (let (v76 u32) (mod.unchecked v75 2)) - (assertz v76) + (let (v76 u32) (mod.unchecked v75 4)) + (assertz 250 v76) (let (v77 (ptr i32)) (inttoptr v75)) (store v77 v73) (let (v79 i32) (const.i32 3)) (let (v80 i32) (band v78 v79)) - (let (v81 u32) (cast v70)) - (let (v82 u32) (mod.unchecked v81 2)) - (assertz v82) + (let (v81 u32) (bitcast v70)) + (let (v82 u32) (mod.unchecked v81 4)) + (assertz 250 v82) (let (v83 (ptr i32)) (inttoptr v81)) (store v83 v80) (br (block 1))) (block 6 - (let (v48 u32) (cast v44)) - (let (v49 u32) (mod.unchecked v48 2)) - (assertz v49) + (let (v48 u32) (bitcast v44)) + (let (v49 u32) (mod.unchecked v48 4)) + (assertz 250 v49) (let (v50 (ptr i32)) (inttoptr v48)) (let (v51 i32) (load v50)) (let (v52 i32) (const.i32 3)) @@ -151,20 +151,20 @@ (let (v55 i32) (const.i32 -4)) (let (v56 i32) (band v54 v55)) (let (v57 i32) (bor v53 v56)) - (let (v58 u32) (cast v44)) - (let (v59 u32) (mod.unchecked v58 2)) - (assertz v59) + (let (v58 u32) (bitcast v44)) + (let (v59 u32) (mod.unchecked v58 4)) + (assertz 250 v59) (let (v60 (ptr i32)) (inttoptr v58)) (store v60 v57) - (let (v61 u32) (cast v37)) + (let (v61 u32) (bitcast v37)) (let (v62 u32) (add.checked v61 4)) - (let (v63 u32) (mod.unchecked v62 2)) - (assertz v63) + (let (v63 u32) (mod.unchecked v62 4)) + (assertz 250 v63) (let (v64 (ptr i32)) (inttoptr v62)) (let (v65 i32) (load v64)) - (let (v66 u32) (cast v37)) - (let (v67 u32) (mod.unchecked v66 2)) - (assertz v67) + (let (v66 u32) (bitcast v37)) + (let (v67 u32) (mod.unchecked v66 4)) + (assertz 250 v67) (let (v68 (ptr i32)) (inttoptr v66)) (let (v69 i32) (load v68)) (br (block 5 v37 v65 v69))) @@ -194,7 +194,7 @@ (let (v22 u32) (bitcast v20)) (let (v23 u32) (shr.wrapping v21 v22)) (let (v24 i32) (bitcast v23)) - (let (v25 u32) (cast v24)) + (let (v25 u32) (bitcast v24)) (let (v26 i32) (memory.grow v25)) (let (v27 i32) (const.i32 -1)) (let (v28 i1) (neq v26 v27)) @@ -206,15 +206,15 @@ (ret)) (block 2 (param v50 i32) (param v51 i32) (param v56 i32) - (let (v52 u32) (cast v50)) + (let (v52 u32) (bitcast v50)) (let (v53 u32) (add.checked v52 4)) - (let (v54 u32) (mod.unchecked v53 2)) - (assertz v54) + (let (v54 u32) (mod.unchecked v53 4)) + (assertz 250 v54) (let (v55 (ptr i32)) (inttoptr v53)) (store v55 v51) - (let (v57 u32) (cast v50)) - (let (v58 u32) (mod.unchecked v57 2)) - (assertz v58) + (let (v57 u32) (bitcast v50)) + (let (v58 u32) (mod.unchecked v57 4)) + (assertz 250 v58) (let (v59 (ptr i32)) (inttoptr v57)) (store v59 v56) (br (block 1))) @@ -224,10 +224,10 @@ (let (v34 u32) (bitcast v33)) (let (v35 i32) (shl.wrapping v26 v34)) (let (v36 i64) (const.i64 0)) - (let (v37 u32) (cast v35)) + (let (v37 u32) (bitcast v35)) (let (v38 u32) (add.checked v37 4)) - (let (v39 u32) (mod.unchecked v38 2)) - (assertz v39) + (let (v39 u32) (mod.unchecked v38 4)) + (assertz 250 v39) (let (v40 (ptr i64)) (inttoptr v38)) (store v40 v36) (let (v41 i32) (const.i32 -65536)) @@ -235,9 +235,9 @@ (let (v43 i32) (add.wrapping v35 v42)) (let (v44 i32) (const.i32 2)) (let (v45 i32) (bor v43 v44)) - (let (v46 u32) (cast v35)) - (let (v47 u32) (mod.unchecked v46 2)) - (assertz v47) + (let (v46 u32) (bitcast v35)) + (let (v47 u32) (mod.unchecked v46 4)) + (assertz 250 v47) (let (v48 (ptr i32)) (inttoptr v46)) (store v48 v45) (let (v49 i32) (const.i32 0)) @@ -261,9 +261,9 @@ (let (v10 i32) (const.i32 2)) (let (v11 u32) (bitcast v10)) (let (v12 i32) (shl.wrapping v0 v11)) - (let (v13 u32) (cast v2)) - (let (v14 u32) (mod.unchecked v13 2)) - (assertz v14) + (let (v13 u32) (bitcast v2)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) (let (v15 (ptr i32)) (inttoptr v13)) (let (v16 i32) (load v15)) (br (block 2 v16 v12 v9 v6 v2 v7))) @@ -291,9 +291,9 @@ (param v244 i32) (param v245 i32) (param v246 i32) - (let (v240 u32) (cast v238)) - (let (v241 u32) (mod.unchecked v240 2)) - (assertz v241) + (let (v240 u32) (bitcast v238)) + (let (v241 u32) (mod.unchecked v240 4)) + (assertz 250 v241) (let (v242 (ptr i32)) (inttoptr v240)) (store v242 v239) (br (block 2 v239 v243 v244 v245 v238 v246))) @@ -307,9 +307,9 @@ (block 7 (param v227 i32) (param v228 i32) (let (v229 i32) (const.i32 1)) (let (v230 i32) (bor v228 v229)) - (let (v231 u32) (cast v227)) - (let (v232 u32) (mod.unchecked v231 2)) - (assertz v232) + (let (v231 u32) (bitcast v227)) + (let (v232 u32) (mod.unchecked v231 4)) + (assertz 250 v232) (let (v233 (ptr i32)) (inttoptr v231)) (store v233 v230) (let (v234 i32) (const.i32 8)) @@ -319,14 +319,14 @@ (block 8 (let (v216 i32) (const.i32 -3)) (let (v217 i32) (band v145 v216)) - (let (v218 u32) (cast v122)) - (let (v219 u32) (mod.unchecked v218 2)) - (assertz v219) + (let (v218 u32) (bitcast v122)) + (let (v219 u32) (mod.unchecked v218 4)) + (assertz 250 v219) (let (v220 (ptr i32)) (inttoptr v218)) (store v220 v217) - (let (v221 u32) (cast v120)) - (let (v222 u32) (mod.unchecked v221 2)) - (assertz v222) + (let (v221 u32) (bitcast v120)) + (let (v222 u32) (mod.unchecked v221 4)) + (assertz 250 v222) (let (v223 (ptr i32)) (inttoptr v221)) (let (v224 i32) (load v223)) (let (v225 i32) (const.i32 2)) @@ -340,10 +340,10 @@ (param v56 i32) (param v59 i32) (param v247 i32) - (let (v23 u32) (cast v22)) + (let (v23 u32) (bitcast v22)) (let (v24 u32) (add.checked v23 8)) - (let (v25 u32) (mod.unchecked v24 2)) - (assertz v25) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) (let (v26 (ptr i32)) (inttoptr v24)) (let (v27 i32) (load v26)) (let (v28 i32) (const.i32 1)) @@ -356,16 +356,16 @@ (block 11 (let (v156 i32) (const.i32 -2)) (let (v157 i32) (band v27 v156)) - (let (v158 u32) (cast v22)) + (let (v158 u32) (bitcast v22)) (let (v159 u32) (add.checked v158 8)) - (let (v160 u32) (mod.unchecked v159 2)) - (assertz v160) + (let (v160 u32) (mod.unchecked v159 4)) + (assertz 250 v160) (let (v161 (ptr i32)) (inttoptr v159)) (store v161 v157) - (let (v162 u32) (cast v22)) + (let (v162 u32) (bitcast v22)) (let (v163 u32) (add.checked v162 4)) - (let (v164 u32) (mod.unchecked v163 2)) - (assertz v164) + (let (v164 u32) (mod.unchecked v163 4)) + (assertz 250 v164) (let (v165 (ptr i32)) (inttoptr v163)) (let (v166 i32) (load v165)) (let (v167 i32) (const.i32 -4)) @@ -374,9 +374,9 @@ (condbr v169 (block 22) (block 23))) (block 12 - (let (v31 u32) (cast v22)) - (let (v32 u32) (mod.unchecked v31 2)) - (assertz v32) + (let (v31 u32) (bitcast v22)) + (let (v32 u32) (mod.unchecked v31 4)) + (assertz 250 v32) (let (v33 (ptr i32)) (inttoptr v31)) (let (v34 i32) (load v33)) (let (v35 i32) (const.i32 -4)) @@ -406,34 +406,34 @@ (block 14 (let (v69 i32) (const.i32 0)) (let (v70 i32) (const.i32 0)) - (let (v71 u32) (cast v50)) - (let (v72 u32) (mod.unchecked v71 2)) - (assertz v72) + (let (v71 u32) (bitcast v50)) + (let (v72 u32) (mod.unchecked v71 4)) + (assertz 250 v72) (let (v73 (ptr i32)) (inttoptr v71)) (store v73 v70) (let (v74 i32) (const.i32 -8)) (let (v75 i32) (add.wrapping v50 v74)) (let (v76 i64) (const.i64 0)) - (let (v77 u32) (cast v75)) - (let (v78 u32) (mod.unchecked v77 2)) - (assertz v78) + (let (v77 u32) (bitcast v75)) + (let (v78 u32) (mod.unchecked v77 4)) + (assertz 250 v78) (let (v79 (ptr i64)) (inttoptr v77)) (store v79 v76) - (let (v80 u32) (cast v22)) - (let (v81 u32) (mod.unchecked v80 2)) - (assertz v81) + (let (v80 u32) (bitcast v22)) + (let (v81 u32) (mod.unchecked v80 4)) + (assertz 250 v81) (let (v82 (ptr i32)) (inttoptr v80)) (let (v83 i32) (load v82)) (let (v84 i32) (const.i32 -4)) (let (v85 i32) (band v83 v84)) - (let (v86 u32) (cast v75)) - (let (v87 u32) (mod.unchecked v86 2)) - (assertz v87) + (let (v86 u32) (bitcast v75)) + (let (v87 u32) (mod.unchecked v86 4)) + (assertz 250 v87) (let (v88 (ptr i32)) (inttoptr v86)) (store v88 v85) - (let (v89 u32) (cast v22)) - (let (v90 u32) (mod.unchecked v89 2)) - (assertz v90) + (let (v89 u32) (bitcast v22)) + (let (v90 u32) (mod.unchecked v89 4)) + (assertz 250 v90) (let (v91 (ptr i32)) (inttoptr v89)) (let (v92 i32) (load v91)) (let (v93 i32) (const.i32 2)) @@ -449,51 +449,51 @@ (block 16 (let (v60 i32) (const.i32 -4)) (let (v61 i32) (band v27 v60)) - (let (v62 u32) (cast v59)) - (let (v63 u32) (mod.unchecked v62 2)) - (assertz v63) + (let (v62 u32) (bitcast v59)) + (let (v63 u32) (mod.unchecked v62 4)) + (assertz 250 v63) (let (v64 (ptr i32)) (inttoptr v62)) (store v64 v61) - (let (v65 u32) (cast v22)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v65 u32) (bitcast v22)) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (let (v68 i32) (load v67)) (br (block 7 v22 v68))) (block 17 (param v120 i32) (param v121 i32) (param v122 i32) (let (v123 i32) (bor v121 v122)) - (let (v124 u32) (cast v120)) + (let (v124 u32) (bitcast v120)) (let (v125 u32) (add.checked v124 4)) - (let (v126 u32) (mod.unchecked v125 2)) - (assertz v126) + (let (v126 u32) (mod.unchecked v125 4)) + (assertz 250 v126) (let (v127 (ptr i32)) (inttoptr v125)) (store v127 v123) - (let (v128 u32) (cast v122)) + (let (v128 u32) (bitcast v122)) (let (v129 u32) (add.checked v128 8)) - (let (v130 u32) (mod.unchecked v129 2)) - (assertz v130) + (let (v130 u32) (mod.unchecked v129 4)) + (assertz 250 v130) (let (v131 (ptr i32)) (inttoptr v129)) (let (v132 i32) (load v131)) (let (v133 i32) (const.i32 -2)) (let (v134 i32) (band v132 v133)) - (let (v135 u32) (cast v122)) + (let (v135 u32) (bitcast v122)) (let (v136 u32) (add.checked v135 8)) - (let (v137 u32) (mod.unchecked v136 2)) - (assertz v137) + (let (v137 u32) (mod.unchecked v136 4)) + (assertz 250 v137) (let (v138 (ptr i32)) (inttoptr v136)) (store v138 v134) - (let (v139 u32) (cast v122)) - (let (v140 u32) (mod.unchecked v139 2)) - (assertz v140) + (let (v139 u32) (bitcast v122)) + (let (v140 u32) (mod.unchecked v139 4)) + (assertz 250 v140) (let (v141 (ptr i32)) (inttoptr v139)) (let (v142 i32) (load v141)) (let (v143 i32) (const.i32 3)) (let (v144 i32) (band v142 v143)) (let (v145 i32) (bor v144 v120)) - (let (v146 u32) (cast v122)) - (let (v147 u32) (mod.unchecked v146 2)) - (assertz v147) + (let (v146 u32) (bitcast v122)) + (let (v147 u32) (mod.unchecked v146 4)) + (assertz 250 v147) (let (v148 (ptr i32)) (inttoptr v146)) (store v148 v145) (let (v149 i32) (const.i32 2)) @@ -510,25 +510,25 @@ (condbr v100 (block 17 v75 v69 v22) (block 19))) (block 19 - (let (v101 u32) (cast v97)) + (let (v101 u32) (bitcast v97)) (let (v102 u32) (add.checked v101 4)) - (let (v103 u32) (mod.unchecked v102 2)) - (assertz v103) + (let (v103 u32) (mod.unchecked v102 4)) + (assertz 250 v103) (let (v104 (ptr i32)) (inttoptr v102)) (let (v105 i32) (load v104)) (let (v106 i32) (const.i32 3)) (let (v107 i32) (band v105 v106)) (let (v108 i32) (bor v107 v75)) - (let (v109 u32) (cast v97)) + (let (v109 u32) (bitcast v97)) (let (v110 u32) (add.checked v109 4)) - (let (v111 u32) (mod.unchecked v110 2)) - (assertz v111) + (let (v111 u32) (mod.unchecked v110 4)) + (assertz 250 v111) (let (v112 (ptr i32)) (inttoptr v110)) (store v112 v108) - (let (v113 u32) (cast v75)) + (let (v113 u32) (bitcast v75)) (let (v114 u32) (add.checked v113 4)) - (let (v115 u32) (mod.unchecked v114 2)) - (assertz v115) + (let (v115 u32) (mod.unchecked v114 4)) + (assertz 250 v115) (let (v116 (ptr i32)) (inttoptr v114)) (let (v117 i32) (load v116)) (let (v118 i32) (const.i32 3)) @@ -536,9 +536,9 @@ (br (block 17 v75 v119 v22))) (block 20 - (let (v152 u32) (cast v120)) - (let (v153 u32) (mod.unchecked v152 2)) - (assertz v153) + (let (v152 u32) (bitcast v120)) + (let (v153 u32) (mod.unchecked v152 4)) + (assertz 250 v153) (let (v154 (ptr i32)) (inttoptr v152)) (let (v155 i32) (load v154)) (br (block 7 v120 v155))) @@ -552,7 +552,7 @@ (param v214 i32) (param v249 i32) (call #wee_alloc::neighbors::Neighbors::remove v180) - (let (v181 u32) (cast v180)) + (let (v181 u32) (bitcast v180)) (let (v182 (ptr u8)) (inttoptr v181)) (let (v183 u8) (load v182)) (let (v184 i32) (zext v183)) @@ -565,7 +565,7 @@ (block 22 (let (v171 i32) (const.i32 0)) - (let (v172 u32) (cast v168)) + (let (v172 u32) (bitcast v168)) (let (v173 (ptr u8)) (inttoptr v172)) (let (v174 u8) (load v173)) (let (v175 i32) (zext v174)) @@ -586,24 +586,24 @@ (param v210 i32) (param v213 i32) (param v248 i32) - (let (v203 u32) (cast v200)) - (let (v204 u32) (mod.unchecked v203 2)) - (assertz v204) + (let (v203 u32) (bitcast v200)) + (let (v204 u32) (mod.unchecked v203 4)) + (assertz 250 v204) (let (v205 (ptr i32)) (inttoptr v203)) (store v205 v202) (br (block 9 v202 v207 v210 v213 v200 v248))) (block 25 - (let (v191 u32) (cast v190)) - (let (v192 u32) (mod.unchecked v191 2)) - (assertz v192) + (let (v191 u32) (bitcast v190)) + (let (v192 u32) (mod.unchecked v191 4)) + (assertz 250 v192) (let (v193 (ptr i32)) (inttoptr v191)) (let (v194 i32) (load v193)) (let (v195 i32) (const.i32 2)) (let (v196 i32) (bor v194 v195)) - (let (v197 u32) (cast v190)) - (let (v198 u32) (mod.unchecked v197 2)) - (assertz v198) + (let (v197 u32) (bitcast v190)) + (let (v198 u32) (mod.unchecked v197 4)) + (assertz 250 v198) (let (v199 (ptr i32)) (inttoptr v197)) (store v199 v196) (br (block 24 v201 v190 v208 v211 v214 v249))) @@ -642,15 +642,15 @@ (br (block 1 v100))) (block 3 - (let (v20 u32) (cast v0)) - (let (v21 u32) (mod.unchecked v20 2)) - (assertz v21) + (let (v20 u32) (bitcast v0)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) (let (v22 (ptr i32)) (inttoptr v20)) (let (v23 i32) (load v22)) - (let (v24 u32) (cast v7)) + (let (v24 u32) (bitcast v7)) (let (v25 u32) (add.checked v24 12)) - (let (v26 u32) (mod.unchecked v25 2)) - (assertz v26) + (let (v26 u32) (mod.unchecked v25 4)) + (assertz 250 v26) (let (v27 (ptr i32)) (inttoptr v25)) (store v27 v23) (let (v28 i32) (const.i32 3)) @@ -670,9 +670,9 @@ (block 4 (call #::new_cell_for_free_list v7 v7 v34 v16) - (let (v49 u32) (cast v7)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) + (let (v49 u32) (bitcast v7)) + (let (v50 u32) (mod.unchecked v49 4)) + (assertz 250 v50) (let (v51 (ptr i32)) (inttoptr v49)) (let (v52 i32) (load v51)) (let (v53 i1) (eq v52 0)) @@ -681,15 +681,15 @@ (condbr v55 (block 7) (block 8))) (block 5 - (let (v41 u32) (cast v7)) + (let (v41 u32) (bitcast v7)) (let (v42 u32) (add.checked v41 12)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) + (let (v43 u32) (mod.unchecked v42 4)) + (assertz 250 v43) (let (v44 (ptr i32)) (inttoptr v42)) (let (v45 i32) (load v44)) - (let (v46 u32) (cast v0)) - (let (v47 u32) (mod.unchecked v46 2)) - (assertz v47) + (let (v46 u32) (bitcast v0)) + (let (v47 u32) (mod.unchecked v46 4)) + (assertz 250 v47) (let (v48 (ptr i32)) (inttoptr v46)) (store v48 v45) (br (block 2 v7 v37))) @@ -699,57 +699,57 @@ (br (block 2 v96 v94))) (block 7 - (let (v64 u32) (cast v7)) + (let (v64 u32) (bitcast v7)) (let (v65 u32) (add.checked v64 4)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (let (v68 i32) (load v67)) - (let (v69 u32) (cast v7)) + (let (v69 u32) (bitcast v7)) (let (v70 u32) (add.checked v69 12)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) (let (v72 (ptr i32)) (inttoptr v70)) (let (v73 i32) (load v72)) - (let (v74 u32) (cast v68)) + (let (v74 u32) (bitcast v68)) (let (v75 u32) (add.checked v74 8)) - (let (v76 u32) (mod.unchecked v75 2)) - (assertz v76) + (let (v76 u32) (mod.unchecked v75 4)) + (assertz 250 v76) (let (v77 (ptr i32)) (inttoptr v75)) (store v77 v73) - (let (v78 u32) (cast v7)) + (let (v78 u32) (bitcast v7)) (let (v79 u32) (add.checked v78 12)) - (let (v80 u32) (mod.unchecked v79 2)) - (assertz v80) + (let (v80 u32) (mod.unchecked v79 4)) + (assertz 250 v80) (let (v81 (ptr i32)) (inttoptr v79)) (store v81 v68) (let (v82 i32) (const.i32 12)) (let (v83 i32) (add.wrapping v7 v82)) (let (v84 i32) (call #wee_alloc::alloc_first_fit v34 v16 v83)) - (let (v85 u32) (cast v7)) + (let (v85 u32) (bitcast v7)) (let (v86 u32) (add.checked v85 12)) - (let (v87 u32) (mod.unchecked v86 2)) - (assertz v87) + (let (v87 u32) (mod.unchecked v86 4)) + (assertz 250 v87) (let (v88 (ptr i32)) (inttoptr v86)) (let (v89 i32) (load v88)) - (let (v90 u32) (cast v0)) - (let (v91 u32) (mod.unchecked v90 2)) - (assertz v91) + (let (v90 u32) (bitcast v0)) + (let (v91 u32) (mod.unchecked v90 4)) + (assertz 250 v91) (let (v92 (ptr i32)) (inttoptr v90)) (store v92 v89) (let (v93 i1) (neq v84 0)) (condbr v93 (block 2 v7 v84) (block 9))) (block 8 - (let (v56 u32) (cast v7)) + (let (v56 u32) (bitcast v7)) (let (v57 u32) (add.checked v56 12)) - (let (v58 u32) (mod.unchecked v57 2)) - (assertz v58) + (let (v58 u32) (mod.unchecked v57 4)) + (assertz 250 v58) (let (v59 (ptr i32)) (inttoptr v57)) (let (v60 i32) (load v59)) - (let (v61 u32) (cast v0)) - (let (v62 u32) (mod.unchecked v61 2)) - (assertz v62) + (let (v61 u32) (bitcast v0)) + (let (v62 u32) (mod.unchecked v61 4)) + (assertz 250 v62) (let (v63 (ptr i32)) (inttoptr v61)) (store v63 v60) (br (block 6 v7))) @@ -772,69 +772,66 @@ (let (v8 i32) (const.i32 256)) (let (v9 i32) (const.i32 0)) (call #alloc::raw_vec::RawVec::try_allocate_in v7 v8 v9) - (let (v10 u32) (cast v4)) - (let (v11 u32) (add.checked v10 12)) - (let (v12 u32) (mod.unchecked v11 2)) - (assertz v12) + (let (v10 u32) (bitcast v4)) + (let (v11 u32) (add.checked v10 8)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) (let (v13 (ptr i32)) (inttoptr v11)) (let (v14 i32) (load v13)) - (let (v15 u32) (cast v4)) - (let (v16 u32) (add.checked v15 8)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) + (let (v15 u32) (bitcast v4)) + (let (v16 u32) (add.checked v15 4)) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) (let (v18 (ptr i32)) (inttoptr v16)) (let (v19 i32) (load v18)) - (let (v20 u32) (cast v4)) - (let (v21 u32) (add.checked v20 4)) - (let (v22 u32) (mod.unchecked v21 2)) - (assertz v22) - (let (v23 (ptr i32)) (inttoptr v21)) - (let (v24 i32) (load v23)) - (let (v25 i1) (eq v24 0)) - (let (v26 i32) (zext v25)) - (let (v27 i1) (neq v26 0)) - (condbr v27 (block 3) (block 4))) + (let (v20 i1) (eq v19 0)) + (let (v21 i32) (zext v20)) + (let (v22 i1) (neq v21 0)) + (condbr v22 (block 2) (block 3))) - (block 1) + (block 1 + (ret)) (block 2 - (call #alloc::raw_vec::capacity_overflow) - (unreachable)) + (let (v28 u32) (bitcast v4)) + (let (v29 u32) (add.checked v28 12)) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) + (let (v31 (ptr i32)) (inttoptr v29)) + (let (v32 i32) (load v31)) + (let [(v33 i32) (v34 felt)] (call (#miden::note #get_inputs) v32)) + (let (v35 i32) (const.i32 0)) + (let (v36 u32) (bitcast v0)) + (let (v37 u32) (add.checked v36 8)) + (let (v38 u32) (mod.unchecked v37 4)) + (assertz 250 v38) + (let (v39 (ptr i32)) (inttoptr v37)) + (store v39 v35) + (let (v40 u32) (bitcast v0)) + (let (v41 u32) (add.checked v40 4)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) + (let (v43 (ptr i32)) (inttoptr v41)) + (store v43 v32) + (let (v44 u32) (bitcast v0)) + (let (v45 u32) (mod.unchecked v44 4)) + (assertz 250 v45) + (let (v46 (ptr i32)) (inttoptr v44)) + (store v46 v14) + (let (v47 i32) (const.i32 16)) + (let (v48 i32) (add.wrapping v4 v47)) + (let (v49 (ptr i32)) (global.symbol #__stack_pointer)) + (store v49 v48) + (br (block 1))) (block 3 - (let [(v31 i32) (v32 felt)] (call (#miden::note #get_inputs) v14)) - (let (v33 i32) (const.i32 0)) - (let (v34 u32) (cast v0)) - (let (v35 u32) (add.checked v34 8)) - (let (v36 u32) (mod.unchecked v35 2)) - (assertz v36) - (let (v37 (ptr i32)) (inttoptr v35)) - (store v37 v33) - (let (v38 u32) (cast v0)) - (let (v39 u32) (add.checked v38 4)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) - (let (v41 (ptr i32)) (inttoptr v39)) - (store v41 v14) - (let (v42 u32) (cast v0)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) - (let (v44 (ptr i32)) (inttoptr v42)) - (store v44 v19) - (let (v45 i32) (const.i32 16)) - (let (v46 i32) (add.wrapping v4 v45)) - (let (v47 (ptr i32)) (global.symbol #__stack_pointer)) - (store v47 v46) - (ret)) - - (block 4 - (let (v28 i1) (eq v19 0)) - (let (v29 i32) (zext v28)) - (let (v30 i1) (neq v29 0)) - (condbr v30 (block 2) (block 5))) - - (block 5 - (call #alloc::alloc::handle_alloc_error v19 v14) + (let (v23 u32) (bitcast v4)) + (let (v24 u32) (add.checked v23 12)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) + (let (v26 (ptr i32)) (inttoptr v24)) + (let (v27 i32) (load v26)) + (call #alloc::raw_vec::handle_error v14 v27) (unreachable)) ) @@ -849,9 +846,9 @@ (ret)) (block 2 (param v62 i32) (param v64 i32) - (let (v65 u32) (cast v62)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v65 u32) (bitcast v62)) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (store v67 v64) (br (block 1))) @@ -867,10 +864,10 @@ (block 4 (let (v5 i64) (const.i64 17179869184)) - (let (v6 u32) (cast v0)) + (let (v6 u32) (bitcast v0)) (let (v7 u32) (add.checked v6 4)) - (let (v8 u32) (mod.unchecked v7 2)) - (assertz v8) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) (let (v9 (ptr i64)) (inttoptr v7)) (store v9 v5) (let (v10 i32) (const.i32 0)) @@ -889,10 +886,10 @@ (block 7 (let (v17 i32) (const.i32 0)) - (let (v18 u32) (cast v0)) + (let (v18 u32) (bitcast v0)) (let (v19 u32) (add.checked v18 4)) - (let (v20 u32) (mod.unchecked v19 2)) - (assertz v20) + (let (v20 u32) (mod.unchecked v19 4)) + (assertz 250 v20) (let (v21 (ptr i32)) (inttoptr v19)) (store v21 v17) (br (block 5 v0))) @@ -914,7 +911,7 @@ (block 10 (let (v26 i32) (const.i32 0)) - (let (v27 u32) (cast v26)) + (let (v27 u32) (bitcast v26)) (let (v28 u32) (add.checked v27 1048580)) (let (v29 (ptr u8)) (inttoptr v28)) (let (v30 u8) (load v29)) @@ -924,39 +921,39 @@ (br (block 8 v33 v0 v1 v24))) (block 11 - (let (v52 u32) (cast v40)) + (let (v52 u32) (bitcast v40)) (let (v53 u32) (add.checked v52 8)) - (let (v54 u32) (mod.unchecked v53 2)) - (assertz v54) + (let (v54 u32) (mod.unchecked v53 4)) + (assertz 250 v54) (let (v55 (ptr i32)) (inttoptr v53)) (store v55 v51) (let (v56 i32) (const.i32 4)) - (let (v57 u32) (cast v40)) + (let (v57 u32) (bitcast v40)) (let (v58 u32) (add.checked v57 4)) - (let (v59 u32) (mod.unchecked v58 2)) - (assertz v59) + (let (v59 u32) (mod.unchecked v58 4)) + (assertz 250 v59) (let (v60 (ptr i32)) (inttoptr v58)) (store v60 v56) (br (block 5 v40))) (block 12 - (let (v41 u32) (cast v40)) + (let (v41 u32) (bitcast v40)) (let (v42 u32) (add.checked v41 8)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) + (let (v43 u32) (mod.unchecked v42 4)) + (assertz 250 v43) (let (v44 (ptr i32)) (inttoptr v42)) (store v44 v36) - (let (v46 u32) (cast v40)) + (let (v46 u32) (bitcast v40)) (let (v47 u32) (add.checked v46 4)) - (let (v48 u32) (mod.unchecked v47 2)) - (assertz v48) + (let (v48 u32) (mod.unchecked v47 4)) + (assertz 250 v48) (let (v49 (ptr i32)) (inttoptr v47)) (store v49 v45) (let (v50 i32) (const.i32 0)) (br (block 2 v40 v50))) ) - (func (export #alloc::alloc::handle_alloc_error) + (func (export #alloc::raw_vec::handle_error) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) (unreachable)) @@ -964,14 +961,6 @@ (block 1) ) - (func (export #alloc::raw_vec::capacity_overflow) - - (block 0 - (unreachable)) - - (block 1) - ) - ;; Imports (func (import #miden::note #get_inputs) (param i32) (result i32 felt)) ) diff --git a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.masm b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.masm index d510f1e4..434f43ce 100644 --- a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.masm +++ b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.masm @@ -1,15 +1,3 @@ -# mod miden::note - -export.get_inputs - push.4294967295 - push.1 - push.0 - push.4294967295 - dup.4 - mem_storew - push.4 - end - # mod abi_transform_tx_kernel_get_inputs_4 use.miden::note @@ -19,84 +7,38 @@ export.entrypoint end -export."__rust_alloc" - push.1048576 - movup.2 - swap.1 - exec."::alloc" -end - - -export."__rust_alloc_zeroed" - push.1048576 +export."miden_tx_kernel_sys::get_inputs" + mem_load.0x00001000 + push.16 + u32wrapping_sub dup.1 - swap.2 - swap.3 swap.1 - exec."::alloc" dup.0 - eq.0 - neq.0 - if.true - swap.1 drop - else - push.0 - push.128 - u32and - movup.2 - dup.2 - dup.0 - push.2147483648 - u32lte - assert - push.0 - dup.2 - gte.0 - while.true - dup.1 - dup.1 - push.1 - u32overflowing_madd - assertz - dup.4 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - dup.2 - dup.2 - dup.2 - exec.::intrinsics::mem::load_sw - push.4294967040 - u32and - movup.5 - u32or - movdn.4 - exec.::intrinsics::mem::store_sw - u32wrapping_add.1 - dup.0 - dup.3 - u32gte - end - dropw - end -end - - -export."wee_alloc::neighbors::Neighbors::remove" + u32mod.16 dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw dup.0 - push.2147483648 - u32lte - assert + add.4 + u32assert + dup.1 + add.8 + u32assert + push.0 + push.256 + push.4 + dup.5 + swap.1 + u32wrapping_add + exec."alloc::raw_vec::RawVec::try_allocate_in" + dup.1 + u32mod.4 + assertz.err=250 dup.0 - u32mod.2 - assertz.err=0 dup.0 u32mod.16 dup.0 @@ -106,22 +48,26 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - push.2 - dup.1 swap.1 - u32and + u32mod.4 + assertz.err=250 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + eq.0 neq.0 if.true dup.1 - dup.0 - push.2147483648 - u32lte - assert - add.4 + add.12 u32assert dup.0 - u32mod.2 - assertz.err=0 dup.0 u32mod.16 dup.0 @@ -131,86 +77,359 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - push.4294967292 + dup.4 + add.8 + u32assert + dup.1 + exec.::miden::note::get_inputs + dup.7 + add.4 + u32assert + push.0 + dup.4 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + movup.8 dup.1 + movup.6 swap.1 - u32and dup.0 - eq.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.0 + movup.7 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.16 + movup.7 + swap.1 + u32wrapping_add + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + movup.2 + u32mod.4 + assertz.err=250 + movup.2 + u32mod.4 + assertz.err=250 + dropw + dropw + else + movup.2 + drop + swap.1 + add.12 + u32assert + dup.0 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + movup.2 + exec."alloc::raw_vec::handle_error" + u32mod.4 + assertz.err=250 + push.0 + assert + end +end + + +export."alloc::raw_vec::handle_error" + push.0 assert +end + + +export."alloc::raw_vec::RawVec::try_allocate_in" + dup.1 + neq.0 + if.true + dup.1 + push.536870912 + u32lt + push.0 + push.0 + push.4294967294 + movup.2 + cdrop + u32or neq.0 if.true - drop - dup.2 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - movup.3 - dup.0 - push.2147483648 - u32lte - assert - push.3 - movup.3 - swap.1 - u32and + push.2 dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.3 + u32shl movup.3 - swap.1 - u32and - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + neq.0 + if.true + push.4 + dup.1 + exec."__rust_alloc_zeroed" + dup.0 + eq.0 + neq.0 + if.true + movup.3 + swap.1 + drop + drop + dup.1 + add.8 + u32assert + dup.2 + add.4 + u32assert + dup.1 + movup.3 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + movup.2 + push.4 + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.1 + dup.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + else + swap.1 + drop + dup.1 + add.8 + u32assert + dup.2 + add.4 + u32assert + dup.1 + movup.3 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + movup.2 + dup.1 + movup.4 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.0 + dup.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + end + else + push.4 + dup.1 + exec."__rust_alloc" + dup.0 + eq.0 + neq.0 + if.true + movup.3 + swap.1 + drop + drop + dup.1 + add.8 + u32assert + dup.2 + add.4 + u32assert + dup.1 + movup.3 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + movup.2 + push.4 + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.1 + dup.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + else + swap.1 + drop + dup.1 + add.8 + u32assert + dup.2 + add.4 + u32assert + dup.1 + movup.3 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + movup.2 + dup.1 + movup.4 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.0 + dup.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + end + end else - swap.1 + movdn.2 + drop drop dup.0 - dup.0 - push.2147483648 - u32lte - assert - swap.1 - dup.0 - push.2147483648 - u32lte - assert - dup.3 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.4 - dup.0 - push.2147483648 - u32lte - assert add.4 u32assert + swap.1 + push.0 dup.2 dup.0 u32mod.16 @@ -220,15 +439,9 @@ export."wee_alloc::neighbors::Neighbors::remove" u32div.4 movup.2 u32div.16 - exec.::intrinsics::mem::load_sw - push.3 - u32and - push.4294967292 - movup.6 - swap.1 - u32and - u32or - dup.4 + exec.::intrinsics::mem::store_sw + push.1 + dup.1 dup.0 u32mod.16 dup.0 @@ -238,39 +451,86 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - dup.4 - dup.0 - push.2147483648 - u32lte - assert - movup.5 - dup.0 - push.2147483648 - u32lte - assert - dup.2 - dup.0 - u32mod.16 - dup.0 u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - push.3 - u32and - dup.4 - dup.0 - u32mod.16 - dup.0 + assertz.err=250 u32mod.4 + assertz.err=250 + end + else + movdn.2 + drop + drop + dup.0 + add.4 + u32assert + swap.1 + push.4.0 + dup.3 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_dw + push.0 + dup.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + end +end + + +export."__rust_alloc" + push.1048576 + movup.2 + swap.1 + exec."::alloc" +end + + +export."__rust_alloc_zeroed" + push.1048576 + dup.1 + swap.2 + swap.3 + swap.1 + exec."::alloc" + dup.0 + eq.0 + neq.0 + if.true + swap.1 drop + else + push.0 + push.128 + u32and + movup.2 + dup.2 + push.0 + dup.2 + gte.0 + while.true + dup.1 + dup.1 + push.1 + u32overflowing_madd + assertz + dup.4 swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - dup.0 dup.0 u32mod.16 dup.0 @@ -279,55 +539,137 @@ export."wee_alloc::neighbors::Neighbors::remove" u32div.4 movup.2 u32div.16 + dup.2 + dup.2 + dup.2 exec.::intrinsics::mem::load_sw - push.3 + push.4294967040 u32and - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 + movup.5 + u32or + movdn.4 exec.::intrinsics::mem::store_sw - swap.1 - u32mod.2 - assertz.err=0 - movup.2 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32wrapping_add.1 + dup.0 + dup.3 + u32gte end + dropw + end +end + + +export."::alloc" + push.1 + dup.2 + push.1 + u32gt + push.0 + push.0 + push.4294967294 + movup.2 + cdrop + u32or + neq.0 + movup.3 + swap.1 + cdrop + mem_load.0x00001000 + push.16 + u32wrapping_sub + dup.1 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.3 + eq.0 + neq.0 + if.true + swap.3 + movup.2 + drop + drop + push.16 + movup.2 + swap.1 + u32wrapping_add + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw else - push.4294967292 + dup.0 + add.12 + u32assert + dup.3 + dup.0 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + swap.1 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + push.12 dup.1 swap.1 - u32and + u32wrapping_add + push.3 + movup.5 + swap.1 + u32wrapping_add + push.2 + u32shr + dup.0 + dup.4 + movup.2 + swap.3 + movdn.2 + swap.1 + exec."wee_alloc::alloc_first_fit" dup.0 eq.0 neq.0 if.true drop dup.1 + dup.3 + dup.2 + dup.4 + dup.5 + exec."::new_cell_for_free_list" dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -337,32 +679,13 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - push.4294967292 - dup.1 - swap.1 - u32and - dup.0 eq.0 neq.0 if.true - drop - dup.2 - dup.0 - push.2147483648 - u32lte - assert + dup.1 add.4 u32assert - movup.3 dup.0 - push.2147483648 - u32lte - assert - push.3 - movup.3 - swap.1 - u32and - dup.2 dup.0 u32mod.16 dup.0 @@ -371,11 +694,16 @@ export."wee_alloc::neighbors::Neighbors::remove" u32div.4 movup.2 u32div.16 - exec.::intrinsics::mem::store_sw - push.3 - movup.3 - swap.1 - u32and + exec.::intrinsics::mem::load_sw + dup.0 + add.8 + u32assert + dup.4 + add.12 + u32assert + dup.5 + add.12 + u32assert dup.1 dup.0 u32mod.16 @@ -385,39 +713,44 @@ export."wee_alloc::neighbors::Neighbors::remove" u32div.4 movup.2 u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - else - swap.1 - drop + exec.::intrinsics::mem::load_sw + dup.3 dup.0 + u32mod.16 dup.0 - push.2147483648 - u32lte - assert + u32mod.4 swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw dup.0 - push.2147483648 - u32lte - assert - dup.3 + movup.4 + swap.1 dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.4 + u32mod.16 dup.0 - push.2147483648 - u32lte - assert - add.4 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + movup.7 + dup.6 + add.12 u32assert - dup.2 + push.12 + dup.8 + swap.1 + u32wrapping_add + swap.1 + swap.9 + swap.1 + swap.2 + swap.7 + exec."wee_alloc::alloc_first_fit" + dup.7 dup.0 u32mod.16 dup.0 @@ -427,14 +760,7 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - push.3 - u32and - push.4294967292 - movup.6 - swap.1 - u32and - u32or - dup.4 + dup.6 dup.0 u32mod.16 dup.0 @@ -444,17 +770,65 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - dup.4 - dup.0 - push.2147483648 - u32lte - assert movup.5 + u32mod.4 + assertz.err=250 + movup.6 + u32mod.4 + assertz.err=250 + swap.1 + u32mod.4 + assertz.err=250 + movup.2 + u32mod.4 + assertz.err=250 + swap.1 + u32mod.4 + assertz.err=250 + swap.1 + u32mod.4 + assertz.err=250 + dup.0 + neq.0 + if.true + push.16 + movup.2 + swap.1 + u32wrapping_add + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + else + drop + push.16 + u32wrapping_add + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.0 + end + else + movup.2 + swap.1 + drop + drop + swap.1 + dup.1 + add.12 + u32assert dup.0 - push.2147483648 - u32lte - assert - dup.2 dup.0 u32mod.16 dup.0 @@ -464,9 +838,7 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - push.3 - u32and - dup.4 + dup.2 dup.0 u32mod.16 dup.0 @@ -476,19 +848,10 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - dup.0 - dup.0 - u32mod.16 - dup.0 - u32mod.4 + push.16 + movup.3 swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - push.3 - u32and - dup.2 + u32wrapping_add dup.0 u32mod.16 dup.0 @@ -499,58 +862,22 @@ export."wee_alloc::neighbors::Neighbors::remove" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - movup.2 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + push.0 end else + swap.3 swap.1 drop - dup.0 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.2 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert + drop movup.2 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.3 - dup.0 - push.2147483648 - u32lte - assert - add.4 + dup.1 + add.12 u32assert - dup.4 dup.0 - push.2147483648 - u32lte - assert - dup.2 dup.0 u32mod.16 dup.0 @@ -560,9 +887,7 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - push.3 - u32and - dup.4 + dup.2 dup.0 u32mod.16 dup.0 @@ -571,11 +896,11 @@ export."wee_alloc::neighbors::Neighbors::remove" u32div.4 movup.2 u32div.16 - exec.::intrinsics::mem::load_sw - push.4294967292 - u32and - u32or - dup.5 + exec.::intrinsics::mem::store_sw + push.16 + movup.3 + swap.1 + u32wrapping_add dup.0 u32mod.16 dup.0 @@ -585,32 +910,60 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - dup.1 - u32mod.2 - assertz.err=0 - dup.0 + swap.1 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + end + end +end + + +export."wee_alloc::alloc_first_fit" + dup.2 + dup.0 + u32mod.4 + assertz.err=250 + push.0 + push.4294967295 + dup.4 + swap.1 + u32wrapping_add + push.0 + movup.5 + u32wrapping_sub + push.2 + movup.5 + swap.1 + u32shl + movup.4 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + movup.4 + swap.5 + movdn.4 + dup.0 + eq.0 + neq.0 + push.1 + while.true + if.true + dropw drop push.0 + else dup.0 - u32mod.16 + add.8 + u32assert dup.0 u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - swap.1 - u32mod.2 - assertz.err=0 - movup.4 - u32mod.2 - assertz.err=0 - movup.3 - u32mod.2 - assertz.err=0 - movup.2 - u32mod.2 - assertz.err=0 - swap.1 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -620,422 +973,7 @@ export."wee_alloc::neighbors::Neighbors::remove" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - push.4294967292 - dup.1 - swap.1 - u32and - dup.0 - eq.0 - neq.0 - if.true - drop - dup.2 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - movup.3 - dup.0 - push.2147483648 - u32lte - assert - push.3 - movup.3 - swap.1 - u32and - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.3 - movup.3 - swap.1 - u32and - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - else - swap.1 - drop - dup.0 - dup.0 - push.2147483648 - u32lte - assert - swap.1 - dup.0 - push.2147483648 - u32lte - assert - dup.3 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.4 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - push.3 - u32and - push.4294967292 - movup.6 - swap.1 - u32and - u32or - dup.4 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - dup.4 - dup.0 - push.2147483648 - u32lte - assert - movup.5 - dup.0 - push.2147483648 - u32lte - assert - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - push.3 - u32and - dup.4 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - dup.0 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - push.3 - u32and - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - swap.1 - u32mod.2 - assertz.err=0 - movup.2 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - end - end - end -end - - -export."::new_cell_for_free_list" - swap.1 - drop - push.3 - movup.3 - swap.1 - u32shl - push.512 - u32wrapping_add - push.2 - movup.3 - swap.1 - u32shl - dup.0 - dup.2 - u32gt - push.0 - push.0 - push.4294967294 - movup.2 - cdrop - u32or - neq.0 - cdrop - push.65543 - u32wrapping_add - dup.0 - push.16 - u32shr - dup.0 - push.2147483648 - u32lte - assert - push.4294967295 - push.4294967295 - dup.1 - swap.1 - neq - neq.0 - if.true - push.16 - u32shl - dup.0 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.1 - dup.0 - push.2147483648 - u32lte - assert - push.0.0 - dup.3 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_dw - dup.4 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - push.4294901760 - movup.5 - swap.1 - u32and - dup.4 - swap.1 - u32wrapping_add - push.2 - u32or - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - movup.4 - dup.0 - push.2147483648 - u32lte - assert - dup.1 - movup.5 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.0 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - else - drop - drop - dup.0 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - swap.1 - dup.0 - push.2147483648 - u32lte - assert - push.0 - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.1 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - end -end - - -export."wee_alloc::alloc_first_fit" - dup.2 - dup.0 - push.2147483648 - u32lte - assert - dup.0 - u32mod.2 - assertz.err=0 - push.0 - push.4294967295 - dup.4 - swap.1 - u32wrapping_add - push.0 - movup.5 - u32wrapping_sub - push.2 - movup.5 - swap.1 - u32shl - movup.4 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - movup.4 - swap.5 - movdn.4 - dup.0 - eq.0 - neq.0 - push.1 - while.true - if.true - dropw drop push.0 - else - dup.0 - dup.0 - push.2147483648 - u32lte - assert - add.8 - u32assert - dup.0 - u32mod.2 - assertz.err=0 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - push.1 + push.1 dup.1 swap.1 u32and @@ -1044,17 +982,9 @@ export."wee_alloc::alloc_first_fit" while.true if.true dup.1 - dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.2 - dup.0 - push.2147483648 - u32lte - assert add.4 u32assert push.4294967294 @@ -1072,11 +1002,11 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 swap.1 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -1096,10 +1026,6 @@ export."wee_alloc::alloc_first_fit" push.0 dup.1 dup.0 - push.2147483648 - u32lte - assert - dup.0 u32mod.16 dup.0 u32mod.4 @@ -1116,10 +1042,6 @@ export."wee_alloc::alloc_first_fit" cdrop swap.1 dup.0 - push.2147483648 - u32lte - assert - dup.0 u32mod.16 dup.0 u32mod.4 @@ -1137,10 +1059,6 @@ export."wee_alloc::alloc_first_fit" if.true dup.4 dup.0 - push.2147483648 - u32lte - assert - dup.0 dup.2 swap.1 dup.0 @@ -1152,18 +1070,14 @@ export."wee_alloc::alloc_first_fit" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - dup.0 + u32mod.4 + assertz.err=250 dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -1181,20 +1095,8 @@ export."wee_alloc::alloc_first_fit" push.1 else dup.0 - dup.0 - push.2147483648 - u32lte - assert dup.1 - dup.0 - push.2147483648 - u32lte - assert dup.6 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 u32mod.16 @@ -1229,23 +1131,19 @@ export."wee_alloc::alloc_first_fit" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - dup.0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -1269,10 +1167,6 @@ export."wee_alloc::alloc_first_fit" push.0 swap.1 dup.0 - push.2147483648 - u32lte - assert - dup.0 u32mod.16 dup.0 u32mod.4 @@ -1290,10 +1184,6 @@ export."wee_alloc::alloc_first_fit" if.true dup.4 dup.0 - push.2147483648 - u32lte - assert - dup.0 dup.2 swap.1 dup.0 @@ -1305,18 +1195,14 @@ export."wee_alloc::alloc_first_fit" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - dup.0 + u32mod.4 + assertz.err=250 dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -1334,20 +1220,8 @@ export."wee_alloc::alloc_first_fit" push.1 else dup.0 - dup.0 - push.2147483648 - u32lte - assert dup.1 - dup.0 - push.2147483648 - u32lte - assert dup.6 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 u32mod.16 @@ -1382,23 +1256,19 @@ export."wee_alloc::alloc_first_fit" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - dup.0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -1419,12 +1289,8 @@ export."wee_alloc::alloc_first_fit" else dup.1 dup.0 - push.2147483648 - u32lte - assert - dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -1461,10 +1327,6 @@ export."wee_alloc::alloc_first_fit" drop dup.4 dup.0 - push.2147483648 - u32lte - assert - dup.0 dup.2 swap.1 dup.0 @@ -1476,8 +1338,8 @@ export."wee_alloc::alloc_first_fit" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 eq.0 neq.0 @@ -1525,15 +1387,7 @@ export."wee_alloc::alloc_first_fit" swap.1 u32wrapping_add swap.1 - dup.0 - push.2147483648 - u32lte - assert dup.1 - dup.0 - push.2147483648 - u32lte - assert push.0 dup.2 dup.0 @@ -1546,15 +1400,7 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.2 - dup.0 - push.2147483648 - u32lte - assert dup.4 - dup.0 - push.2147483648 - u32lte - assert push.0.0 dup.4 dup.0 @@ -1567,10 +1413,6 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_dw dup.5 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 u32mod.16 @@ -1594,20 +1436,20 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 swap.1 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 swap.1 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 swap.1 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 push.0 swap.1 dup.0 @@ -1627,24 +1469,12 @@ export."wee_alloc::alloc_first_fit" if.true drop dup.1 - dup.0 - push.2147483648 - u32lte - assert add.4 u32assert dup.3 - dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.4 - dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.5 @@ -1663,10 +1493,6 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.4 - dup.0 - push.2147483648 - u32lte - assert dup.3 dup.0 u32mod.16 @@ -1690,10 +1516,6 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.5 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 u32mod.16 @@ -1723,20 +1545,20 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.3 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 push.2 movup.2 swap.1 @@ -1744,20 +1566,8 @@ export."wee_alloc::alloc_first_fit" neq.0 if.true movup.2 - dup.0 - push.2147483648 - u32lte - assert dup.2 - dup.0 - push.2147483648 - u32lte - assert dup.3 - dup.0 - push.2147483648 - u32lte - assert push.4294967293 movup.4 swap.1 @@ -1797,12 +1607,12 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 push.8 u32wrapping_add else @@ -1810,16 +1620,8 @@ export."wee_alloc::alloc_first_fit" swap.1 drop dup.0 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 - push.2147483648 - u32lte - assert - dup.0 dup.0 u32mod.16 dup.0 @@ -1842,10 +1644,10 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 push.8 u32wrapping_add end @@ -1858,24 +1660,12 @@ export."wee_alloc::alloc_first_fit" if.true drop dup.1 - dup.0 - push.2147483648 - u32lte - assert add.4 u32assert dup.3 - dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.4 - dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.5 @@ -1894,10 +1684,6 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.4 - dup.0 - push.2147483648 - u32lte - assert dup.3 dup.0 u32mod.16 @@ -1921,10 +1707,6 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.5 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 u32mod.16 @@ -1954,20 +1736,20 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.3 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 push.2 movup.2 swap.1 @@ -1975,20 +1757,8 @@ export."wee_alloc::alloc_first_fit" neq.0 if.true movup.2 - dup.0 - push.2147483648 - u32lte - assert dup.2 - dup.0 - push.2147483648 - u32lte - assert dup.3 - dup.0 - push.2147483648 - u32lte - assert push.4294967293 movup.4 swap.1 @@ -2028,12 +1798,12 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 push.8 u32wrapping_add else @@ -2041,16 +1811,8 @@ export."wee_alloc::alloc_first_fit" swap.1 drop dup.0 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 - push.2147483648 - u32lte - assert - dup.0 dup.0 u32mod.16 dup.0 @@ -2073,10 +1835,10 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 push.8 u32wrapping_add end @@ -2084,31 +1846,15 @@ export."wee_alloc::alloc_first_fit" swap.1 drop dup.0 - dup.0 - push.2147483648 - u32lte - assert add.4 u32assert swap.1 - dup.0 - push.2147483648 - u32lte - assert add.4 u32assert dup.2 - dup.0 - push.2147483648 - u32lte - assert add.4 u32assert dup.3 - dup.0 - push.2147483648 - u32lte - assert add.4 u32assert dup.2 @@ -2136,17 +1882,9 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.5 - dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.6 - dup.0 - push.2147483648 - u32lte - assert add.8 u32assert dup.2 @@ -2174,10 +1912,6 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.7 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 u32mod.16 @@ -2201,10 +1935,6 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw dup.8 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 u32mod.16 @@ -2234,29 +1964,29 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.3 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.3 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.3 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 movup.2 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 push.2 movup.2 swap.1 @@ -2264,20 +1994,8 @@ export."wee_alloc::alloc_first_fit" neq.0 if.true movup.2 - dup.0 - push.2147483648 - u32lte - assert dup.2 - dup.0 - push.2147483648 - u32lte - assert dup.3 - dup.0 - push.2147483648 - u32lte - assert push.4294967293 movup.4 swap.1 @@ -2317,12 +2035,12 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 push.8 u32wrapping_add else @@ -2330,16 +2048,8 @@ export."wee_alloc::alloc_first_fit" swap.1 drop dup.0 - dup.0 - push.2147483648 - u32lte - assert dup.1 dup.0 - push.2147483648 - u32lte - assert - dup.0 dup.0 u32mod.16 dup.0 @@ -2362,10 +2072,10 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 push.8 u32wrapping_add end @@ -2382,10 +2092,6 @@ export."wee_alloc::alloc_first_fit" drop dup.4 dup.0 - push.2147483648 - u32lte - assert - dup.0 dup.2 swap.1 dup.0 @@ -2397,8 +2103,8 @@ export."wee_alloc::alloc_first_fit" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 eq.0 neq.0 @@ -2414,20 +2120,8 @@ export."wee_alloc::alloc_first_fit" movup.3 drop movup.2 - dup.0 - push.2147483648 - u32lte - assert dup.2 - dup.0 - push.2147483648 - u32lte - assert dup.3 - dup.0 - push.2147483648 - u32lte - assert push.4294967292 movup.4 swap.1 @@ -2465,12 +2159,12 @@ export."wee_alloc::alloc_first_fit" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 push.8 u32wrapping_add push.0 @@ -2481,133 +2175,206 @@ export."wee_alloc::alloc_first_fit" end end end - end -end - - -export."::alloc" - push.1 - dup.2 - push.1 - u32gt - push.0 - push.0 - push.4294967294 - movup.2 - cdrop - u32or - neq.0 - movup.3 - swap.1 - cdrop - mem_load.0x00000000 - push.16 - u32wrapping_sub - dup.1 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - dup.3 - eq.0 - neq.0 - if.true - swap.3 - movup.2 - drop - drop - push.16 - movup.2 - swap.1 - u32wrapping_add - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw + end +end + + +export."wee_alloc::neighbors::Neighbors::remove" + dup.0 + dup.0 + u32mod.4 + assertz.err=250 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.2 + dup.1 + swap.1 + u32and + neq.0 + if.true + dup.1 + add.4 + u32assert + dup.0 + u32mod.4 + assertz.err=250 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.4294967292 + dup.1 + swap.1 + u32and + dup.0 + eq.0 + neq.0 + if.true + drop + dup.2 + add.4 + u32assert + movup.3 + push.3 + movup.3 + swap.1 + u32and + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.3 + movup.3 + swap.1 + u32and + dup.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + else + swap.1 + drop + dup.0 + swap.1 + dup.3 + add.4 + u32assert + dup.4 + add.4 + u32assert + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.3 + u32and + push.4294967292 + movup.6 + swap.1 + u32and + u32or + dup.4 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.4 + movup.5 + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.3 + u32and + dup.4 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.0 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.3 + u32and + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + swap.1 + u32mod.4 + assertz.err=250 + movup.2 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + swap.1 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + end else - dup.0 - dup.0 - push.2147483648 - u32lte - assert - add.12 - u32assert - dup.3 - dup.0 - push.2147483648 - u32lte - assert - dup.0 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - push.12 + push.4294967292 dup.1 swap.1 - u32wrapping_add - push.3 - movup.5 - swap.1 - u32wrapping_add - push.2 - u32shr - dup.0 - dup.4 - movup.2 - swap.3 - movdn.2 - swap.1 - exec."wee_alloc::alloc_first_fit" + u32and dup.0 eq.0 neq.0 if.true drop dup.1 + add.4 + u32assert dup.0 - push.2147483648 - u32lte - assert - dup.3 - dup.2 - dup.4 - dup.5 - exec."::new_cell_for_free_list" - dup.0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 dup.0 u32mod.16 dup.0 @@ -2617,58 +2384,24 @@ export."::alloc" movup.2 u32div.16 exec.::intrinsics::mem::load_sw + push.4294967292 + dup.1 + swap.1 + u32and + dup.0 eq.0 neq.0 if.true - dup.1 - dup.0 - push.2147483648 - u32lte - assert + drop + dup.2 add.4 u32assert - dup.0 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - dup.0 - dup.0 - push.2147483648 - u32lte - assert - add.8 - u32assert - dup.4 - dup.0 - push.2147483648 - u32lte - assert - add.12 - u32assert - dup.5 - dup.0 - push.2147483648 - u32lte - assert - add.12 - u32assert - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 + movup.3 + push.3 + movup.3 swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - dup.3 + u32and + dup.2 dup.0 u32mod.16 dup.0 @@ -2678,9 +2411,11 @@ export."::alloc" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - dup.0 - movup.4 + push.3 + movup.3 swap.1 + u32and + dup.1 dup.0 u32mod.16 dup.0 @@ -2690,29 +2425,22 @@ export."::alloc" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - movup.7 - dup.0 - push.2147483648 - u32lte - assert - dup.6 - dup.0 - push.2147483648 - u32lte - assert - add.12 - u32assert - push.12 - dup.8 - swap.1 - u32wrapping_add + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + else swap.1 - swap.9 + drop + dup.0 swap.1 - swap.2 - swap.7 - exec."wee_alloc::alloc_first_fit" - dup.7 + dup.3 + add.4 + u32assert + dup.4 + add.4 + u32assert + dup.2 dup.0 u32mod.16 dup.0 @@ -2722,7 +2450,14 @@ export."::alloc" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - dup.6 + push.3 + u32and + push.4294967292 + movup.6 + swap.1 + u32and + u32or + dup.4 dup.0 u32mod.16 dup.0 @@ -2730,75 +2465,11 @@ export."::alloc" swap.1 u32div.4 movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - movup.5 - u32mod.2 - assertz.err=0 - movup.6 - u32mod.2 - assertz.err=0 - swap.1 - u32mod.2 - assertz.err=0 - movup.2 - u32mod.2 - assertz.err=0 - swap.1 - u32mod.2 - assertz.err=0 - swap.1 - u32mod.2 - assertz.err=0 - dup.0 - neq.0 - if.true - push.16 - movup.2 - swap.1 - u32wrapping_add - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - else - drop - push.16 - u32wrapping_add - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.0 - end - else - movup.2 - swap.1 - drop - drop - swap.1 - dup.0 - push.2147483648 - u32lte - assert - dup.1 - dup.0 - push.2147483648 - u32lte - assert - add.12 - u32assert - dup.0 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.4 + movup.5 + dup.2 dup.0 u32mod.16 dup.0 @@ -2808,7 +2479,9 @@ export."::alloc" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - dup.2 + push.3 + u32and + dup.4 dup.0 u32mod.16 dup.0 @@ -2818,10 +2491,19 @@ export."::alloc" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - push.16 - movup.3 + dup.0 + dup.0 + u32mod.16 + dup.0 + u32mod.4 swap.1 - u32wrapping_add + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.3 + u32and + dup.2 dup.0 u32mod.16 dup.0 @@ -2832,30 +2514,50 @@ export."::alloc" u32div.16 exec.::intrinsics::mem::store_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - push.0 + u32mod.4 + assertz.err=250 + movup.2 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + swap.1 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 end else - swap.3 swap.1 drop - drop - movup.2 dup.0 - push.2147483648 - u32lte - assert - dup.1 - dup.0 - push.2147483648 - u32lte - assert - add.12 + add.4 + u32assert + dup.2 + add.4 + u32assert + movup.2 + add.4 + u32assert + dup.3 + add.4 u32assert + dup.4 + dup.2 + dup.0 + u32mod.16 dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.3 + u32and + dup.4 dup.0 u32mod.16 dup.0 @@ -2865,7 +2567,10 @@ export."::alloc" movup.2 u32div.16 exec.::intrinsics::mem::load_sw - dup.2 + push.4294967292 + u32and + u32or + dup.5 dup.0 u32mod.16 dup.0 @@ -2875,10 +2580,10 @@ export."::alloc" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - push.16 - movup.3 - swap.1 - u32wrapping_add + dup.1 + u32mod.4 + assertz.err=250 + dup.0 dup.0 u32mod.16 dup.0 @@ -2887,554 +2592,258 @@ export."::alloc" u32div.4 movup.2 u32div.16 - exec.::intrinsics::mem::store_sw + exec.::intrinsics::mem::load_sw swap.1 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - end - end -end - - -export."miden_tx_kernel_sys::get_inputs" - mem_load.0x00000000 - push.16 - u32wrapping_sub - dup.1 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - dup.0 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.1 - dup.0 - push.2147483648 - u32lte - assert - add.8 - u32assert - dup.2 - dup.0 - push.2147483648 - u32lte - assert - add.12 - u32assert - push.0 - push.256 - push.4 - dup.6 - swap.1 - u32wrapping_add - exec."alloc::raw_vec::RawVec::try_allocate_in" - dup.2 - u32mod.2 - assertz.err=0 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - movup.2 - u32mod.2 - assertz.err=0 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - movup.2 - u32mod.2 - assertz.err=0 - movup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::load_sw - eq.0 - neq.0 - if.true - dup.3 - dup.0 - push.2147483648 - u32lte - assert - add.8 - u32assert - dup.1 - exec.::miden::note::get_inputs - dup.6 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - push.0 - dup.4 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - movup.7 - dup.0 - push.2147483648 - u32lte - assert - dup.1 - movup.6 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - dup.0 - movup.6 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.16 - movup.6 - swap.1 - u32wrapping_add - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - movup.2 - u32mod.2 - assertz.err=0 - dropw - dropw - else - swap.3 - movup.2 - drop - drop - dup.0 - eq.0 - neq.0 - if.true - exec."alloc::raw_vec::capacity_overflow" - push.0 - assert - else - exec."alloc::alloc::handle_alloc_error" - push.0 - assert - end - end -end - - -export."alloc::raw_vec::RawVec::try_allocate_in" - dup.1 - neq.0 - if.true - dup.1 - push.536870912 - u32lt - push.0 - push.0 - push.4294967294 - movup.2 - cdrop - u32or - neq.0 - if.true - push.2 - dup.2 + u32mod.4 + assertz.err=250 + movup.4 + u32mod.4 + assertz.err=250 + movup.3 + u32mod.4 + assertz.err=250 + movup.2 + u32mod.4 + assertz.err=250 + swap.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 swap.1 - u32shl - movup.3 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.4294967292 + dup.1 + swap.1 + u32and + dup.0 + eq.0 neq.0 if.true - push.4 - dup.1 - exec."__rust_alloc_zeroed" + drop + dup.2 + add.4 + u32assert + movup.3 + push.3 + movup.3 + swap.1 + u32and + dup.2 dup.0 - eq.0 - neq.0 - if.true - movup.3 - swap.1 - drop - drop - dup.1 - dup.0 - push.2147483648 - u32lte - assert - add.8 - u32assert - dup.2 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.1 - movup.3 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - movup.2 - dup.0 - push.2147483648 - u32lte - assert - push.4 - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.1 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - else - swap.1 - drop - dup.1 - dup.0 - push.2147483648 - u32lte - assert - add.8 - u32assert - dup.2 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.1 - movup.3 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - movup.2 - dup.0 - push.2147483648 - u32lte - assert - dup.1 - movup.4 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.0 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - end - else - push.4 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.3 + movup.3 + swap.1 + u32and dup.1 - exec."__rust_alloc" dup.0 - eq.0 - neq.0 - if.true - movup.3 - swap.1 - drop - drop - dup.1 - dup.0 - push.2147483648 - u32lte - assert - add.8 - u32assert - dup.2 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.1 - movup.3 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - movup.2 - dup.0 - push.2147483648 - u32lte - assert - push.4 - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.1 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - else - swap.1 - drop - dup.1 - dup.0 - push.2147483648 - u32lte - assert - add.8 - u32assert - dup.2 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - dup.1 - movup.3 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - movup.2 - dup.0 - push.2147483648 - u32lte - assert - dup.1 - movup.4 - swap.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.0 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 - end + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + else + swap.1 + drop + dup.0 + swap.1 + dup.3 + add.4 + u32assert + dup.4 + add.4 + u32assert + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.3 + u32and + push.4294967292 + movup.6 + swap.1 + u32and + u32or + dup.4 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.4 + movup.5 + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.3 + u32and + dup.4 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + dup.0 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::load_sw + push.3 + u32and + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + swap.1 + u32mod.4 + assertz.err=250 + movup.2 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + swap.1 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 end - else - movdn.2 - drop - drop - dup.0 - dup.0 - push.2147483648 - u32lte - assert - add.4 - u32assert - swap.1 - dup.0 - push.2147483648 - u32lte - assert - push.0 - dup.2 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - push.1 - dup.1 - dup.0 - u32mod.16 - dup.0 - u32mod.4 - swap.1 - u32div.4 - movup.2 - u32div.16 - exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 end - else - movdn.2 - drop - drop + end +end + + +export."::new_cell_for_free_list" + swap.1 + drop + push.3 + movup.3 + swap.1 + u32shl + push.512 + u32wrapping_add + push.2 + movup.3 + swap.1 + u32shl + dup.0 + dup.2 + u32gt + push.0 + push.0 + push.4294967294 + movup.2 + cdrop + u32or + neq.0 + cdrop + push.65543 + u32wrapping_add + dup.0 + push.16 + u32shr + exec.::intrinsics::mem::memory_grow + push.4294967295 + dup.1 + swap.1 + neq + neq.0 + if.true + push.16 + u32shl + dup.0 + add.4 + u32assert + dup.1 + push.0.0 + dup.3 dup.0 + u32mod.16 dup.0 - push.2147483648 - u32lte - assert + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_dw + dup.4 add.4 u32assert + push.4294901760 + movup.5 swap.1 + u32and + dup.4 + swap.1 + u32wrapping_add + push.2 + u32or + dup.2 dup.0 - push.2147483648 - u32lte - assert - push.4.0 - dup.3 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + movup.4 + dup.1 + movup.5 + swap.1 dup.0 u32mod.16 dup.0 @@ -3443,8 +2852,45 @@ export."alloc::raw_vec::RawVec::try_allocate_in" u32div.4 movup.2 u32div.16 - exec.::intrinsics::mem::store_dw + exec.::intrinsics::mem::store_sw + push.0 + dup.1 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 + else + drop + drop + dup.0 + add.4 + u32assert + swap.1 push.0 + dup.2 + dup.0 + u32mod.16 + dup.0 + u32mod.4 + swap.1 + u32div.4 + movup.2 + u32div.16 + exec.::intrinsics::mem::store_sw + push.1 dup.1 dup.0 u32mod.16 @@ -3455,24 +2901,25 @@ export."alloc::raw_vec::RawVec::try_allocate_in" movup.2 u32div.16 exec.::intrinsics::mem::store_sw - u32mod.2 - assertz.err=0 - u32mod.2 - assertz.err=0 + u32mod.4 + assertz.err=250 + u32mod.4 + assertz.err=250 end end -export."alloc::alloc::handle_alloc_error" - push.0 assert -end - +# mod miden::note -export."alloc::raw_vec::capacity_overflow" - push.0 assert +export.get_inputs + push.4294967295 + push.1 + push.0 + push.4294967295 + dup.4 + mem_storew + dropw + push.4 end -begin - exec.::abi_transform_tx_kernel_get_inputs_4::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.wat b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.wat index 756031a9..2231ccad 100644 --- a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.wat +++ b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.wat @@ -6,7 +6,6 @@ (type (;4;) (func (param i32 i32 i32) (result i32))) (type (;5;) (func (param i32 i32 i32))) (type (;6;) (func (param i32 i32))) - (type (;7;) (func)) (import "miden::note" "get_inputs<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_note_get_inputs (;0;) (type 0))) (func $entrypoint (;1;) (type 1) (param i32) local.get 0 @@ -499,45 +498,37 @@ i32.const 0 call $alloc::raw_vec::RawVec::try_allocate_in local.get 1 - i32.load offset=12 - local.set 2 - local.get 1 i32.load offset=8 - local.set 3 + local.set 2 block ;; label = @1 - block ;; label = @2 - local.get 1 - i32.load offset=4 - i32.eqz - br_if 0 (;@2;) - local.get 3 - i32.eqz - br_if 1 (;@1;) - local.get 3 - local.get 2 - call $alloc::alloc::handle_alloc_error - unreachable - end - local.get 2 - call $miden_tx_kernel_sys::externs::extern_note_get_inputs - drop - local.get 0 - i32.const 0 - i32.store offset=8 - local.get 0 + local.get 1 + i32.load offset=4 + i32.eqz + br_if 0 (;@1;) local.get 2 - i32.store offset=4 - local.get 0 - local.get 3 - i32.store local.get 1 - i32.const 16 - i32.add - global.set $__stack_pointer - return + i32.load offset=12 + call $alloc::raw_vec::handle_error + unreachable end - call $alloc::raw_vec::capacity_overflow - unreachable + local.get 1 + i32.load offset=12 + local.tee 3 + call $miden_tx_kernel_sys::externs::extern_note_get_inputs + drop + local.get 0 + i32.const 0 + i32.store offset=8 + local.get 0 + local.get 3 + i32.store offset=4 + local.get 0 + local.get 2 + i32.store + local.get 1 + i32.const 16 + i32.add + global.set $__stack_pointer ) (func $alloc::raw_vec::RawVec::try_allocate_in (;9;) (type 5) (param i32 i32 i32) (local i32) @@ -613,11 +604,7 @@ local.get 1 i32.store ) - (func $alloc::alloc::handle_alloc_error (;10;) (type 6) (param i32 i32) - unreachable - unreachable - ) - (func $alloc::raw_vec::capacity_overflow (;11;) (type 7) + (func $alloc::raw_vec::handle_error (;10;) (type 6) (param i32 i32) unreachable unreachable ) diff --git a/tests/integration/expected/add_felt.masm b/tests/integration/expected/add_felt.masm index 6d7aa63b..4b8b4022 100644 --- a/tests/integration/expected/add_felt.masm +++ b/tests/integration/expected/add_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::add_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_i16.hir b/tests/integration/expected/add_i16.hir index 14a40125..ea529637 100644 --- a/tests/integration/expected/add_i16.hir +++ b/tests/integration/expected/add_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_bbf5fdc0851222e92e718cc0af28212663b61bc643024537b3041e4528ea338c + (module #test_rust_4a80dace0dddc4f08e0a7761b4e1d269aa474b6beb14702baa097a4626d593c1 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/add_i16.masm b/tests/integration/expected/add_i16.masm index b59823c5..a085c685 100644 --- a/tests/integration/expected/add_i16.masm +++ b/tests/integration/expected/add_i16.masm @@ -1,10 +1,7 @@ -# mod test_rust_bbf5fdc0851222e92e718cc0af28212663b61bc643024537b3041e4528ea338c +# mod test_rust_4a80dace0dddc4f08e0a7761b4e1d269aa474b6beb14702baa097a4626d593c1 export.entrypoint u32wrapping_add end -begin - exec.::test_rust_bbf5fdc0851222e92e718cc0af28212663b61bc643024537b3041e4528ea338c::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_i16.wat b/tests/integration/expected/add_i16.wat index 6b360432..7d5efb9e 100644 --- a/tests/integration/expected/add_i16.wat +++ b/tests/integration/expected/add_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_bbf5fdc0851222e92e718cc0af28212663b61bc643024537b3041e4528ea338c.wasm +(module $test_rust_4a80dace0dddc4f08e0a7761b4e1d269aa474b6beb14702baa097a4626d593c1.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/add_i32.hir b/tests/integration/expected/add_i32.hir index 1d19342d..6d7b67cf 100644 --- a/tests/integration/expected/add_i32.hir +++ b/tests/integration/expected/add_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_2e60443dc47eecaf44c0755d01375597814229ddd052f66a9a8f52569d4bee8b + (module #test_rust_cc3b19fe60136e21eb08ffee1b6d6f2a6534ca0afa46f10f5296cdb8f0adfc30 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/add_i32.masm b/tests/integration/expected/add_i32.masm index c81270d6..4e0d9ceb 100644 --- a/tests/integration/expected/add_i32.masm +++ b/tests/integration/expected/add_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_2e60443dc47eecaf44c0755d01375597814229ddd052f66a9a8f52569d4bee8b +# mod test_rust_cc3b19fe60136e21eb08ffee1b6d6f2a6534ca0afa46f10f5296cdb8f0adfc30 export.entrypoint u32wrapping_add end -begin - exec.::test_rust_2e60443dc47eecaf44c0755d01375597814229ddd052f66a9a8f52569d4bee8b::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_i32.wat b/tests/integration/expected/add_i32.wat index 94f7ac20..96d8d29e 100644 --- a/tests/integration/expected/add_i32.wat +++ b/tests/integration/expected/add_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_2e60443dc47eecaf44c0755d01375597814229ddd052f66a9a8f52569d4bee8b.wasm +(module $test_rust_cc3b19fe60136e21eb08ffee1b6d6f2a6534ca0afa46f10f5296cdb8f0adfc30.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/add_i64.hir b/tests/integration/expected/add_i64.hir index eea25938..ba44354e 100644 --- a/tests/integration/expected/add_i64.hir +++ b/tests/integration/expected/add_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_78c9e486e02020de38ab65bce982123aa9f38ccf330c940ad86e10e7e2912afa + (module #test_rust_069cf45252371f826e737bc3d7f808e1df77c97acac642efbaf976f4ab507131 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/add_i64.masm b/tests/integration/expected/add_i64.masm index 094a4b3f..66e0fe2d 100644 --- a/tests/integration/expected/add_i64.masm +++ b/tests/integration/expected/add_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_78c9e486e02020de38ab65bce982123aa9f38ccf330c940ad86e10e7e2912afa +# mod test_rust_069cf45252371f826e737bc3d7f808e1df77c97acac642efbaf976f4ab507131 export.entrypoint exec.::std::math::u64::wrapping_add end -begin - exec.::test_rust_78c9e486e02020de38ab65bce982123aa9f38ccf330c940ad86e10e7e2912afa::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_i64.wat b/tests/integration/expected/add_i64.wat index 11c52726..20d0ba78 100644 --- a/tests/integration/expected/add_i64.wat +++ b/tests/integration/expected/add_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_78c9e486e02020de38ab65bce982123aa9f38ccf330c940ad86e10e7e2912afa.wasm +(module $test_rust_069cf45252371f826e737bc3d7f808e1df77c97acac642efbaf976f4ab507131.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/add_i8.hir b/tests/integration/expected/add_i8.hir index 0a734b2a..838a7f89 100644 --- a/tests/integration/expected/add_i8.hir +++ b/tests/integration/expected/add_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_aa4e8ec18774f7791634833f5a14b633e4c1a7d4ec8ae07ec95668a9f3fb05d6 + (module #test_rust_3dc5f4de1f29681a88ff9608b56c29738ebfd35b5bf875f151de489b1c7e50f7 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/add_i8.masm b/tests/integration/expected/add_i8.masm index 08a187ea..73ca1024 100644 --- a/tests/integration/expected/add_i8.masm +++ b/tests/integration/expected/add_i8.masm @@ -1,10 +1,7 @@ -# mod test_rust_aa4e8ec18774f7791634833f5a14b633e4c1a7d4ec8ae07ec95668a9f3fb05d6 +# mod test_rust_3dc5f4de1f29681a88ff9608b56c29738ebfd35b5bf875f151de489b1c7e50f7 export.entrypoint u32wrapping_add end -begin - exec.::test_rust_aa4e8ec18774f7791634833f5a14b633e4c1a7d4ec8ae07ec95668a9f3fb05d6::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_i8.wat b/tests/integration/expected/add_i8.wat index 214f0a79..7f101004 100644 --- a/tests/integration/expected/add_i8.wat +++ b/tests/integration/expected/add_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_aa4e8ec18774f7791634833f5a14b633e4c1a7d4ec8ae07ec95668a9f3fb05d6.wasm +(module $test_rust_3dc5f4de1f29681a88ff9608b56c29738ebfd35b5bf875f151de489b1c7e50f7.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/add_u16.hir b/tests/integration/expected/add_u16.hir index 3f798df4..dd4cfe0c 100644 --- a/tests/integration/expected/add_u16.hir +++ b/tests/integration/expected/add_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_10c9fc505476d6021538a9abdcf2c4d73bd1d8cc42c25993867649bb63b4319d + (module #test_rust_711c7705576a28225a7e87d297c54811b91eb1b69f3f407376a0af96dcad37b2 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/add_u16.masm b/tests/integration/expected/add_u16.masm index c0f945e0..5637b6e0 100644 --- a/tests/integration/expected/add_u16.masm +++ b/tests/integration/expected/add_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_10c9fc505476d6021538a9abdcf2c4d73bd1d8cc42c25993867649bb63b4319d +# mod test_rust_711c7705576a28225a7e87d297c54811b91eb1b69f3f407376a0af96dcad37b2 export.entrypoint u32wrapping_add push.65535 u32and end -begin - exec.::test_rust_10c9fc505476d6021538a9abdcf2c4d73bd1d8cc42c25993867649bb63b4319d::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_u16.wat b/tests/integration/expected/add_u16.wat index 7d9d4729..28623e9e 100644 --- a/tests/integration/expected/add_u16.wat +++ b/tests/integration/expected/add_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_10c9fc505476d6021538a9abdcf2c4d73bd1d8cc42c25993867649bb63b4319d.wasm +(module $test_rust_711c7705576a28225a7e87d297c54811b91eb1b69f3f407376a0af96dcad37b2.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/add_u32.hir b/tests/integration/expected/add_u32.hir index ee934d5e..b70ef7da 100644 --- a/tests/integration/expected/add_u32.hir +++ b/tests/integration/expected/add_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_d6a5f6b2fb9509a2986e40a5ab057ae035f5eeb6fb66c1c0bd59648ee4c31a35 + (module #test_rust_ca3478b0c28e59b401b0d632fb0a1c51d0c45a319d503d2a2a705107e8aab84f ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/add_u32.masm b/tests/integration/expected/add_u32.masm index e48b0dcd..612f5bd9 100644 --- a/tests/integration/expected/add_u32.masm +++ b/tests/integration/expected/add_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_d6a5f6b2fb9509a2986e40a5ab057ae035f5eeb6fb66c1c0bd59648ee4c31a35 +# mod test_rust_ca3478b0c28e59b401b0d632fb0a1c51d0c45a319d503d2a2a705107e8aab84f export.entrypoint u32wrapping_add end -begin - exec.::test_rust_d6a5f6b2fb9509a2986e40a5ab057ae035f5eeb6fb66c1c0bd59648ee4c31a35::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_u32.wat b/tests/integration/expected/add_u32.wat index 87c21d87..93f93487 100644 --- a/tests/integration/expected/add_u32.wat +++ b/tests/integration/expected/add_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_d6a5f6b2fb9509a2986e40a5ab057ae035f5eeb6fb66c1c0bd59648ee4c31a35.wasm +(module $test_rust_ca3478b0c28e59b401b0d632fb0a1c51d0c45a319d503d2a2a705107e8aab84f.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/add_u64.hir b/tests/integration/expected/add_u64.hir index 5a954bcb..7f2c3f6b 100644 --- a/tests/integration/expected/add_u64.hir +++ b/tests/integration/expected/add_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_27208cf7b2bc95c69612a6c3f988bc5cc944dda110c0f0bcdf4c2e97066d261f + (module #test_rust_11c5a2e5412edeeffd507e0b820658a62ad960143f3b5167b2fe215d1ecfecfa ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/add_u64.masm b/tests/integration/expected/add_u64.masm index 880387f3..21d20476 100644 --- a/tests/integration/expected/add_u64.masm +++ b/tests/integration/expected/add_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_27208cf7b2bc95c69612a6c3f988bc5cc944dda110c0f0bcdf4c2e97066d261f +# mod test_rust_11c5a2e5412edeeffd507e0b820658a62ad960143f3b5167b2fe215d1ecfecfa export.entrypoint exec.::std::math::u64::wrapping_add end -begin - exec.::test_rust_27208cf7b2bc95c69612a6c3f988bc5cc944dda110c0f0bcdf4c2e97066d261f::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_u64.wat b/tests/integration/expected/add_u64.wat index 00e305c8..9ea5cbba 100644 --- a/tests/integration/expected/add_u64.wat +++ b/tests/integration/expected/add_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_27208cf7b2bc95c69612a6c3f988bc5cc944dda110c0f0bcdf4c2e97066d261f.wasm +(module $test_rust_11c5a2e5412edeeffd507e0b820658a62ad960143f3b5167b2fe215d1ecfecfa.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/add_u8.hir b/tests/integration/expected/add_u8.hir index 55f61144..6ec45e6c 100644 --- a/tests/integration/expected/add_u8.hir +++ b/tests/integration/expected/add_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_4a87475b2f9d8d15ad35a776ff173dc1470f87cacd0a8312306b9896bb828aa3 + (module #test_rust_195424540a8740c46e8ef057ffe65c7d2c73576a03c615db26b6ef1ef00d0357 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/add_u8.masm b/tests/integration/expected/add_u8.masm index 131a6706..4e7adf93 100644 --- a/tests/integration/expected/add_u8.masm +++ b/tests/integration/expected/add_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_4a87475b2f9d8d15ad35a776ff173dc1470f87cacd0a8312306b9896bb828aa3 +# mod test_rust_195424540a8740c46e8ef057ffe65c7d2c73576a03c615db26b6ef1ef00d0357 export.entrypoint u32wrapping_add push.255 u32and end -begin - exec.::test_rust_4a87475b2f9d8d15ad35a776ff173dc1470f87cacd0a8312306b9896bb828aa3::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/add_u8.wat b/tests/integration/expected/add_u8.wat index e5b13c34..fb425d3e 100644 --- a/tests/integration/expected/add_u8.wat +++ b/tests/integration/expected/add_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_4a87475b2f9d8d15ad35a776ff173dc1470f87cacd0a8312306b9896bb828aa3.wasm +(module $test_rust_195424540a8740c46e8ef057ffe65c7d2c73576a03c615db26b6ef1ef00d0357.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/and_bool.hir b/tests/integration/expected/and_bool.hir index 9ac7f866..3b8d3a59 100644 --- a/tests/integration/expected/and_bool.hir +++ b/tests/integration/expected/and_bool.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_4ac99d1101f79650c02e85b18d774a8cfc696b791a33e4cbd07338faa6df2814 + (module #test_rust_7ce7e9f0710d8cd1e27fed4812e6abf7f7325fdb538e7781120494f2bd2a9cab ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/and_bool.masm b/tests/integration/expected/and_bool.masm index ddef970f..37c06e60 100644 --- a/tests/integration/expected/and_bool.masm +++ b/tests/integration/expected/and_bool.masm @@ -1,10 +1,7 @@ -# mod test_rust_4ac99d1101f79650c02e85b18d774a8cfc696b791a33e4cbd07338faa6df2814 +# mod test_rust_7ce7e9f0710d8cd1e27fed4812e6abf7f7325fdb538e7781120494f2bd2a9cab export.entrypoint swap.1 u32and end -begin - exec.::test_rust_4ac99d1101f79650c02e85b18d774a8cfc696b791a33e4cbd07338faa6df2814::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/and_bool.wat b/tests/integration/expected/and_bool.wat index 3bddcf61..7340f6e2 100644 --- a/tests/integration/expected/and_bool.wat +++ b/tests/integration/expected/and_bool.wat @@ -1,4 +1,4 @@ -(module $test_rust_4ac99d1101f79650c02e85b18d774a8cfc696b791a33e4cbd07338faa6df2814.wasm +(module $test_rust_7ce7e9f0710d8cd1e27fed4812e6abf7f7325fdb538e7781120494f2bd2a9cab.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/band_i16.hir b/tests/integration/expected/band_i16.hir index 1c25668f..ca0e0fc2 100644 --- a/tests/integration/expected/band_i16.hir +++ b/tests/integration/expected/band_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c7e9cce9483c4fd7983b386cae179d4a54022802e0d6b932bccd80235b921c40 + (module #test_rust_2d07899decfc53ff76743115618445ad5a97172f61c9e54ea539ff55362f4dc5 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/band_i16.masm b/tests/integration/expected/band_i16.masm index 35361fe3..4e8beed5 100644 --- a/tests/integration/expected/band_i16.masm +++ b/tests/integration/expected/band_i16.masm @@ -1,10 +1,7 @@ -# mod test_rust_c7e9cce9483c4fd7983b386cae179d4a54022802e0d6b932bccd80235b921c40 +# mod test_rust_2d07899decfc53ff76743115618445ad5a97172f61c9e54ea539ff55362f4dc5 export.entrypoint u32and end -begin - exec.::test_rust_c7e9cce9483c4fd7983b386cae179d4a54022802e0d6b932bccd80235b921c40::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/band_i16.wat b/tests/integration/expected/band_i16.wat index 4a74cd24..78a915f8 100644 --- a/tests/integration/expected/band_i16.wat +++ b/tests/integration/expected/band_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_c7e9cce9483c4fd7983b386cae179d4a54022802e0d6b932bccd80235b921c40.wasm +(module $test_rust_2d07899decfc53ff76743115618445ad5a97172f61c9e54ea539ff55362f4dc5.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/band_i32.hir b/tests/integration/expected/band_i32.hir index 3dcc96b6..bc1aa2e0 100644 --- a/tests/integration/expected/band_i32.hir +++ b/tests/integration/expected/band_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_8391b0d837d3b65b33c6b68ea552987952048935f4c45fadd58b81ea8ba141d9 + (module #test_rust_3c1243f6bf89d22ea186e66208b1ad921f7332ce215ea72d1d9f2c00cea6323b ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/band_i32.masm b/tests/integration/expected/band_i32.masm index 90f8e6ad..283fd3c8 100644 --- a/tests/integration/expected/band_i32.masm +++ b/tests/integration/expected/band_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_8391b0d837d3b65b33c6b68ea552987952048935f4c45fadd58b81ea8ba141d9 +# mod test_rust_3c1243f6bf89d22ea186e66208b1ad921f7332ce215ea72d1d9f2c00cea6323b export.entrypoint u32and end -begin - exec.::test_rust_8391b0d837d3b65b33c6b68ea552987952048935f4c45fadd58b81ea8ba141d9::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/band_i32.wat b/tests/integration/expected/band_i32.wat index 78064f54..4feb9c53 100644 --- a/tests/integration/expected/band_i32.wat +++ b/tests/integration/expected/band_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_8391b0d837d3b65b33c6b68ea552987952048935f4c45fadd58b81ea8ba141d9.wasm +(module $test_rust_3c1243f6bf89d22ea186e66208b1ad921f7332ce215ea72d1d9f2c00cea6323b.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/band_i64.hir b/tests/integration/expected/band_i64.hir index b960a9b2..204b566b 100644 --- a/tests/integration/expected/band_i64.hir +++ b/tests/integration/expected/band_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_e0a0c73e267170746d23527e7bebc6ba880b828e73598793b934a688e2bd8869 + (module #test_rust_fda5d5f9a96ae19c191d7fceb423c1b36b7cf8dd7d7c4ca8e768b8305e8195fc ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/band_i64.masm b/tests/integration/expected/band_i64.masm index f884b71f..f80aeca4 100644 --- a/tests/integration/expected/band_i64.masm +++ b/tests/integration/expected/band_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_e0a0c73e267170746d23527e7bebc6ba880b828e73598793b934a688e2bd8869 +# mod test_rust_fda5d5f9a96ae19c191d7fceb423c1b36b7cf8dd7d7c4ca8e768b8305e8195fc export.entrypoint exec.::std::math::u64::and end -begin - exec.::test_rust_e0a0c73e267170746d23527e7bebc6ba880b828e73598793b934a688e2bd8869::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/band_i64.wat b/tests/integration/expected/band_i64.wat index 7ffe4b20..37bf0542 100644 --- a/tests/integration/expected/band_i64.wat +++ b/tests/integration/expected/band_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_e0a0c73e267170746d23527e7bebc6ba880b828e73598793b934a688e2bd8869.wasm +(module $test_rust_fda5d5f9a96ae19c191d7fceb423c1b36b7cf8dd7d7c4ca8e768b8305e8195fc.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/band_i8.hir b/tests/integration/expected/band_i8.hir index c81cbbd3..b25eaac9 100644 --- a/tests/integration/expected/band_i8.hir +++ b/tests/integration/expected/band_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_645dc02b90fa56981e2f5305f2d8f5067bb8cdc2eb91b610298ef135bd758d31 + (module #test_rust_82b97b60f6c2bdfdaa5412831eebdefbd9fcecdcda5ab71592efdf9c8f0a3fb8 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/band_i8.masm b/tests/integration/expected/band_i8.masm index 18cfd5ed..dc859243 100644 --- a/tests/integration/expected/band_i8.masm +++ b/tests/integration/expected/band_i8.masm @@ -1,10 +1,7 @@ -# mod test_rust_645dc02b90fa56981e2f5305f2d8f5067bb8cdc2eb91b610298ef135bd758d31 +# mod test_rust_82b97b60f6c2bdfdaa5412831eebdefbd9fcecdcda5ab71592efdf9c8f0a3fb8 export.entrypoint u32and end -begin - exec.::test_rust_645dc02b90fa56981e2f5305f2d8f5067bb8cdc2eb91b610298ef135bd758d31::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/band_i8.wat b/tests/integration/expected/band_i8.wat index 9100fdae..4fbb7f96 100644 --- a/tests/integration/expected/band_i8.wat +++ b/tests/integration/expected/band_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_645dc02b90fa56981e2f5305f2d8f5067bb8cdc2eb91b610298ef135bd758d31.wasm +(module $test_rust_82b97b60f6c2bdfdaa5412831eebdefbd9fcecdcda5ab71592efdf9c8f0a3fb8.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/band_u16.hir b/tests/integration/expected/band_u16.hir index f11129bf..e46a41c7 100644 --- a/tests/integration/expected/band_u16.hir +++ b/tests/integration/expected/band_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_552e799f48de5fcc388eaa5128c9842db9a9500f75f852887a429dbe8c67d810 + (module #test_rust_62f08a4fd4cafb7db864c24731da8dab986b2b5c2d54b53e960972953f553406 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/band_u16.masm b/tests/integration/expected/band_u16.masm index 296fa77e..6a56e1eb 100644 --- a/tests/integration/expected/band_u16.masm +++ b/tests/integration/expected/band_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_552e799f48de5fcc388eaa5128c9842db9a9500f75f852887a429dbe8c67d810 +# mod test_rust_62f08a4fd4cafb7db864c24731da8dab986b2b5c2d54b53e960972953f553406 export.entrypoint u32and end -begin - exec.::test_rust_552e799f48de5fcc388eaa5128c9842db9a9500f75f852887a429dbe8c67d810::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/band_u16.wat b/tests/integration/expected/band_u16.wat index 9e3a2471..8a1b955b 100644 --- a/tests/integration/expected/band_u16.wat +++ b/tests/integration/expected/band_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_552e799f48de5fcc388eaa5128c9842db9a9500f75f852887a429dbe8c67d810.wasm +(module $test_rust_62f08a4fd4cafb7db864c24731da8dab986b2b5c2d54b53e960972953f553406.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/band_u32.hir b/tests/integration/expected/band_u32.hir index 0b6f9d8b..83b48723 100644 --- a/tests/integration/expected/band_u32.hir +++ b/tests/integration/expected/band_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_03ecb06cdac4759a31c320b67e5a88995c8e5b0260bc540636a10106839a7c13 + (module #test_rust_c4f32e60d0da9da73a9d4beef2081fc955bd8750a29571f11f6916287436cbe3 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/band_u32.masm b/tests/integration/expected/band_u32.masm index 40a646e5..847d9021 100644 --- a/tests/integration/expected/band_u32.masm +++ b/tests/integration/expected/band_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_03ecb06cdac4759a31c320b67e5a88995c8e5b0260bc540636a10106839a7c13 +# mod test_rust_c4f32e60d0da9da73a9d4beef2081fc955bd8750a29571f11f6916287436cbe3 export.entrypoint u32and end -begin - exec.::test_rust_03ecb06cdac4759a31c320b67e5a88995c8e5b0260bc540636a10106839a7c13::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/band_u32.wat b/tests/integration/expected/band_u32.wat index 2128d89d..3a74a85b 100644 --- a/tests/integration/expected/band_u32.wat +++ b/tests/integration/expected/band_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_03ecb06cdac4759a31c320b67e5a88995c8e5b0260bc540636a10106839a7c13.wasm +(module $test_rust_c4f32e60d0da9da73a9d4beef2081fc955bd8750a29571f11f6916287436cbe3.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/band_u64.hir b/tests/integration/expected/band_u64.hir index 50219f5d..c2980897 100644 --- a/tests/integration/expected/band_u64.hir +++ b/tests/integration/expected/band_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_58d7204f3fc254e23472b478c3b85fe2825f6a8bca174445a43d135a3b5c1f65 + (module #test_rust_4c7e8f3e1741ccb4a5bbbee6f13443e5deb9c528380592d13a046312348bd927 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/band_u64.masm b/tests/integration/expected/band_u64.masm index 750f18bf..7c6d13a4 100644 --- a/tests/integration/expected/band_u64.masm +++ b/tests/integration/expected/band_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_58d7204f3fc254e23472b478c3b85fe2825f6a8bca174445a43d135a3b5c1f65 +# mod test_rust_4c7e8f3e1741ccb4a5bbbee6f13443e5deb9c528380592d13a046312348bd927 export.entrypoint exec.::std::math::u64::and end -begin - exec.::test_rust_58d7204f3fc254e23472b478c3b85fe2825f6a8bca174445a43d135a3b5c1f65::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/band_u64.wat b/tests/integration/expected/band_u64.wat index 9c9b9b33..1cb7da5e 100644 --- a/tests/integration/expected/band_u64.wat +++ b/tests/integration/expected/band_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_58d7204f3fc254e23472b478c3b85fe2825f6a8bca174445a43d135a3b5c1f65.wasm +(module $test_rust_4c7e8f3e1741ccb4a5bbbee6f13443e5deb9c528380592d13a046312348bd927.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/band_u8.hir b/tests/integration/expected/band_u8.hir index 2264593a..1e6ae42f 100644 --- a/tests/integration/expected/band_u8.hir +++ b/tests/integration/expected/band_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_dc5c0d94136b471b7115e3df5c99cd5b9ebfb25f4c88e0039211a30936a42650 + (module #test_rust_bcd6febe71cae37427fa9ff25c42a5ecaea8f1ac799aa86f8a46e3d07ab1bc01 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/band_u8.masm b/tests/integration/expected/band_u8.masm index 80f8cf16..78cb1ed5 100644 --- a/tests/integration/expected/band_u8.masm +++ b/tests/integration/expected/band_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_dc5c0d94136b471b7115e3df5c99cd5b9ebfb25f4c88e0039211a30936a42650 +# mod test_rust_bcd6febe71cae37427fa9ff25c42a5ecaea8f1ac799aa86f8a46e3d07ab1bc01 export.entrypoint u32and end -begin - exec.::test_rust_dc5c0d94136b471b7115e3df5c99cd5b9ebfb25f4c88e0039211a30936a42650::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/band_u8.wat b/tests/integration/expected/band_u8.wat index d5ade8ee..6ebc5c41 100644 --- a/tests/integration/expected/band_u8.wat +++ b/tests/integration/expected/band_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_dc5c0d94136b471b7115e3df5c99cd5b9ebfb25f4c88e0039211a30936a42650.wasm +(module $test_rust_bcd6febe71cae37427fa9ff25c42a5ecaea8f1ac799aa86f8a46e3d07ab1bc01.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bnot_bool.hir b/tests/integration/expected/bnot_bool.hir index 4e5141df..903dbe8e 100644 --- a/tests/integration/expected/bnot_bool.hir +++ b/tests/integration/expected/bnot_bool.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_9eeb808d5b84e9923aca025d19ce8860aa1591ec14e265ab55978490184941f9 + (module #test_rust_145320f8e700bf6bdf185aeb1dafe222a5808453dd3ade85b6f787389bf30c0f ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_bool.masm b/tests/integration/expected/bnot_bool.masm index 441e4fea..ea095087 100644 --- a/tests/integration/expected/bnot_bool.masm +++ b/tests/integration/expected/bnot_bool.masm @@ -1,10 +1,7 @@ -# mod test_rust_9eeb808d5b84e9923aca025d19ce8860aa1591ec14e265ab55978490184941f9 +# mod test_rust_145320f8e700bf6bdf185aeb1dafe222a5808453dd3ade85b6f787389bf30c0f export.entrypoint push.1 u32xor end -begin - exec.::test_rust_9eeb808d5b84e9923aca025d19ce8860aa1591ec14e265ab55978490184941f9::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_bool.wat b/tests/integration/expected/bnot_bool.wat index 131009e3..3a0c5f5c 100644 --- a/tests/integration/expected/bnot_bool.wat +++ b/tests/integration/expected/bnot_bool.wat @@ -1,4 +1,4 @@ -(module $test_rust_9eeb808d5b84e9923aca025d19ce8860aa1591ec14e265ab55978490184941f9.wasm +(module $test_rust_145320f8e700bf6bdf185aeb1dafe222a5808453dd3ade85b6f787389bf30c0f.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) local.get 0 diff --git a/tests/integration/expected/bnot_i16.hir b/tests/integration/expected/bnot_i16.hir index b404a3f5..6b9e33d6 100644 --- a/tests/integration/expected/bnot_i16.hir +++ b/tests/integration/expected/bnot_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_8fa57435a0704052eef5cf543da239dc56a277e303737da31ead024a9331a727 + (module #test_rust_00cddfae3f036b7f10355e9d273eb1131e732db63a7ac33f728895e93a394b99 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_i16.masm b/tests/integration/expected/bnot_i16.masm index d03f1a2e..45549a1a 100644 --- a/tests/integration/expected/bnot_i16.masm +++ b/tests/integration/expected/bnot_i16.masm @@ -1,10 +1,7 @@ -# mod test_rust_8fa57435a0704052eef5cf543da239dc56a277e303737da31ead024a9331a727 +# mod test_rust_00cddfae3f036b7f10355e9d273eb1131e732db63a7ac33f728895e93a394b99 export.entrypoint push.4294967295 u32xor end -begin - exec.::test_rust_8fa57435a0704052eef5cf543da239dc56a277e303737da31ead024a9331a727::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_i16.wat b/tests/integration/expected/bnot_i16.wat index 0d7895a1..943ca98e 100644 --- a/tests/integration/expected/bnot_i16.wat +++ b/tests/integration/expected/bnot_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_8fa57435a0704052eef5cf543da239dc56a277e303737da31ead024a9331a727.wasm +(module $test_rust_00cddfae3f036b7f10355e9d273eb1131e732db63a7ac33f728895e93a394b99.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) local.get 0 diff --git a/tests/integration/expected/bnot_i32.hir b/tests/integration/expected/bnot_i32.hir index 092b4490..c8a2364b 100644 --- a/tests/integration/expected/bnot_i32.hir +++ b/tests/integration/expected/bnot_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_2025dc1efddce491d35a4bd97da58ce6432ab90aaa631eb386fc77f975594744 + (module #test_rust_597108c1534cd7c973774710a354c519e8a9ce32a5a499ffe5839f4fea0cd83b ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_i32.masm b/tests/integration/expected/bnot_i32.masm index eeec38c4..6b016c35 100644 --- a/tests/integration/expected/bnot_i32.masm +++ b/tests/integration/expected/bnot_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_2025dc1efddce491d35a4bd97da58ce6432ab90aaa631eb386fc77f975594744 +# mod test_rust_597108c1534cd7c973774710a354c519e8a9ce32a5a499ffe5839f4fea0cd83b export.entrypoint push.4294967295 u32xor end -begin - exec.::test_rust_2025dc1efddce491d35a4bd97da58ce6432ab90aaa631eb386fc77f975594744::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_i32.wat b/tests/integration/expected/bnot_i32.wat index 482f939b..eec2d981 100644 --- a/tests/integration/expected/bnot_i32.wat +++ b/tests/integration/expected/bnot_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_2025dc1efddce491d35a4bd97da58ce6432ab90aaa631eb386fc77f975594744.wasm +(module $test_rust_597108c1534cd7c973774710a354c519e8a9ce32a5a499ffe5839f4fea0cd83b.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) local.get 0 diff --git a/tests/integration/expected/bnot_i64.hir b/tests/integration/expected/bnot_i64.hir index d08a5773..aac32032 100644 --- a/tests/integration/expected/bnot_i64.hir +++ b/tests/integration/expected/bnot_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_ff865e52272c093f5144cff6a9db4151834b1a864d3d64dad00a8486c26bf17a + (module #test_rust_318a80316e6bca93f0a48d41942655ffb321d8d6c62d387f9037272e5ec565e3 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_i64.masm b/tests/integration/expected/bnot_i64.masm index b509f250..471e52cb 100644 --- a/tests/integration/expected/bnot_i64.masm +++ b/tests/integration/expected/bnot_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_ff865e52272c093f5144cff6a9db4151834b1a864d3d64dad00a8486c26bf17a +# mod test_rust_318a80316e6bca93f0a48d41942655ffb321d8d6c62d387f9037272e5ec565e3 export.entrypoint push.4294967295.4294967295 exec.::std::math::u64::xor end -begin - exec.::test_rust_ff865e52272c093f5144cff6a9db4151834b1a864d3d64dad00a8486c26bf17a::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_i64.wat b/tests/integration/expected/bnot_i64.wat index a634e453..8c8895f8 100644 --- a/tests/integration/expected/bnot_i64.wat +++ b/tests/integration/expected/bnot_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_ff865e52272c093f5144cff6a9db4151834b1a864d3d64dad00a8486c26bf17a.wasm +(module $test_rust_318a80316e6bca93f0a48d41942655ffb321d8d6c62d387f9037272e5ec565e3.wasm (type (;0;) (func (param i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64) (result i64) local.get 0 diff --git a/tests/integration/expected/bnot_i8.hir b/tests/integration/expected/bnot_i8.hir index 331909a7..b4c9ba76 100644 --- a/tests/integration/expected/bnot_i8.hir +++ b/tests/integration/expected/bnot_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_3095798ff760882614d43aafa09c1c7941995bb5b9a48187009a712b0d3ac930 + (module #test_rust_694a3a0d438c5be6815982d68ba790c15be6f3f7ce15158c74a6f5adbb86596f ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_i8.masm b/tests/integration/expected/bnot_i8.masm index 83529812..6217c38d 100644 --- a/tests/integration/expected/bnot_i8.masm +++ b/tests/integration/expected/bnot_i8.masm @@ -1,10 +1,7 @@ -# mod test_rust_3095798ff760882614d43aafa09c1c7941995bb5b9a48187009a712b0d3ac930 +# mod test_rust_694a3a0d438c5be6815982d68ba790c15be6f3f7ce15158c74a6f5adbb86596f export.entrypoint push.4294967295 u32xor end -begin - exec.::test_rust_3095798ff760882614d43aafa09c1c7941995bb5b9a48187009a712b0d3ac930::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_i8.wat b/tests/integration/expected/bnot_i8.wat index e5d125f1..0d150dfe 100644 --- a/tests/integration/expected/bnot_i8.wat +++ b/tests/integration/expected/bnot_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_3095798ff760882614d43aafa09c1c7941995bb5b9a48187009a712b0d3ac930.wasm +(module $test_rust_694a3a0d438c5be6815982d68ba790c15be6f3f7ce15158c74a6f5adbb86596f.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) local.get 0 diff --git a/tests/integration/expected/bnot_u16.hir b/tests/integration/expected/bnot_u16.hir index f20c1096..ec45e445 100644 --- a/tests/integration/expected/bnot_u16.hir +++ b/tests/integration/expected/bnot_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_de134871bf4e9b290991577707ea002a2485be8d7e8cec745b7e9faf22aff5dd + (module #test_rust_df76c987a66b14b20c7ce818414abfb720a4e3e74eb3dc8015560af9bdb3fee4 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_u16.masm b/tests/integration/expected/bnot_u16.masm index b95dca74..00c1cecc 100644 --- a/tests/integration/expected/bnot_u16.masm +++ b/tests/integration/expected/bnot_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_de134871bf4e9b290991577707ea002a2485be8d7e8cec745b7e9faf22aff5dd +# mod test_rust_df76c987a66b14b20c7ce818414abfb720a4e3e74eb3dc8015560af9bdb3fee4 export.entrypoint push.65535 u32xor end -begin - exec.::test_rust_de134871bf4e9b290991577707ea002a2485be8d7e8cec745b7e9faf22aff5dd::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_u16.wat b/tests/integration/expected/bnot_u16.wat index 9dbf0330..4e4b3036 100644 --- a/tests/integration/expected/bnot_u16.wat +++ b/tests/integration/expected/bnot_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_de134871bf4e9b290991577707ea002a2485be8d7e8cec745b7e9faf22aff5dd.wasm +(module $test_rust_df76c987a66b14b20c7ce818414abfb720a4e3e74eb3dc8015560af9bdb3fee4.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) local.get 0 diff --git a/tests/integration/expected/bnot_u32.hir b/tests/integration/expected/bnot_u32.hir index 479ec4de..5044aa4e 100644 --- a/tests/integration/expected/bnot_u32.hir +++ b/tests/integration/expected/bnot_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_e7047e5fc0fbd81c45f586a2e1236121815ef43b08b645ca6cfa83914a40321c + (module #test_rust_a762cb529f6595cbdce20fb1385e8ed3f8f4c23824a512b32f3818d297badb1c ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_u32.masm b/tests/integration/expected/bnot_u32.masm index 46459eee..0e9b0686 100644 --- a/tests/integration/expected/bnot_u32.masm +++ b/tests/integration/expected/bnot_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_e7047e5fc0fbd81c45f586a2e1236121815ef43b08b645ca6cfa83914a40321c +# mod test_rust_a762cb529f6595cbdce20fb1385e8ed3f8f4c23824a512b32f3818d297badb1c export.entrypoint push.4294967295 u32xor end -begin - exec.::test_rust_e7047e5fc0fbd81c45f586a2e1236121815ef43b08b645ca6cfa83914a40321c::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_u32.wat b/tests/integration/expected/bnot_u32.wat index 67dc60e8..d8ebe72d 100644 --- a/tests/integration/expected/bnot_u32.wat +++ b/tests/integration/expected/bnot_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_e7047e5fc0fbd81c45f586a2e1236121815ef43b08b645ca6cfa83914a40321c.wasm +(module $test_rust_a762cb529f6595cbdce20fb1385e8ed3f8f4c23824a512b32f3818d297badb1c.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) local.get 0 diff --git a/tests/integration/expected/bnot_u64.hir b/tests/integration/expected/bnot_u64.hir index 6dcb5f6c..7f88707e 100644 --- a/tests/integration/expected/bnot_u64.hir +++ b/tests/integration/expected/bnot_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_ea8702a3bb1d585901491e69ce53966b652b3ff0f4bb262e492dde9341f66195 + (module #test_rust_18ecee456448c6244ca46633baac3f3f6281f50c0c17dc427e781fb02b614132 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_u64.masm b/tests/integration/expected/bnot_u64.masm index 48dc6efe..2843f40b 100644 --- a/tests/integration/expected/bnot_u64.masm +++ b/tests/integration/expected/bnot_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_ea8702a3bb1d585901491e69ce53966b652b3ff0f4bb262e492dde9341f66195 +# mod test_rust_18ecee456448c6244ca46633baac3f3f6281f50c0c17dc427e781fb02b614132 export.entrypoint push.4294967295.4294967295 exec.::std::math::u64::xor end -begin - exec.::test_rust_ea8702a3bb1d585901491e69ce53966b652b3ff0f4bb262e492dde9341f66195::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_u64.wat b/tests/integration/expected/bnot_u64.wat index 8dbec5ed..5b6b674d 100644 --- a/tests/integration/expected/bnot_u64.wat +++ b/tests/integration/expected/bnot_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_ea8702a3bb1d585901491e69ce53966b652b3ff0f4bb262e492dde9341f66195.wasm +(module $test_rust_18ecee456448c6244ca46633baac3f3f6281f50c0c17dc427e781fb02b614132.wasm (type (;0;) (func (param i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64) (result i64) local.get 0 diff --git a/tests/integration/expected/bnot_u8.hir b/tests/integration/expected/bnot_u8.hir index 1e9b1c44..e2212080 100644 --- a/tests/integration/expected/bnot_u8.hir +++ b/tests/integration/expected/bnot_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_35b25eb77e4cb9a7ed55da7b9ee04431e564770fc0ccf796f4543d6e0f9e813f + (module #test_rust_eaff6a2806ce4f4f18d6c1d65cab18383e6ac9921c310c1866b5b554b743d7e8 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bnot_u8.masm b/tests/integration/expected/bnot_u8.masm index 3c27c7d2..391e013e 100644 --- a/tests/integration/expected/bnot_u8.masm +++ b/tests/integration/expected/bnot_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_35b25eb77e4cb9a7ed55da7b9ee04431e564770fc0ccf796f4543d6e0f9e813f +# mod test_rust_eaff6a2806ce4f4f18d6c1d65cab18383e6ac9921c310c1866b5b554b743d7e8 export.entrypoint push.255 u32xor end -begin - exec.::test_rust_35b25eb77e4cb9a7ed55da7b9ee04431e564770fc0ccf796f4543d6e0f9e813f::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bnot_u8.wat b/tests/integration/expected/bnot_u8.wat index d0b3f33c..f7d2ff4d 100644 --- a/tests/integration/expected/bnot_u8.wat +++ b/tests/integration/expected/bnot_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_35b25eb77e4cb9a7ed55da7b9ee04431e564770fc0ccf796f4543d6e0f9e813f.wasm +(module $test_rust_eaff6a2806ce4f4f18d6c1d65cab18383e6ac9921c310c1866b5b554b743d7e8.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) local.get 0 diff --git a/tests/integration/expected/bor_i16.hir b/tests/integration/expected/bor_i16.hir index 477a7f72..542aaa10 100644 --- a/tests/integration/expected/bor_i16.hir +++ b/tests/integration/expected/bor_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_8c8a3ab08866a8cdf13f461d225bc40cc694eab7818133d8e81630fc58c00003 + (module #test_rust_8dcae0a39212d4ad89597641a65bcf61179a7ecf222225943d30d5d6d1cceed9 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bor_i16.masm b/tests/integration/expected/bor_i16.masm index 985c5cc6..1ec5c00b 100644 --- a/tests/integration/expected/bor_i16.masm +++ b/tests/integration/expected/bor_i16.masm @@ -1,10 +1,7 @@ -# mod test_rust_8c8a3ab08866a8cdf13f461d225bc40cc694eab7818133d8e81630fc58c00003 +# mod test_rust_8dcae0a39212d4ad89597641a65bcf61179a7ecf222225943d30d5d6d1cceed9 export.entrypoint u32or end -begin - exec.::test_rust_8c8a3ab08866a8cdf13f461d225bc40cc694eab7818133d8e81630fc58c00003::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bor_i16.wat b/tests/integration/expected/bor_i16.wat index 146ea02f..0ec60d96 100644 --- a/tests/integration/expected/bor_i16.wat +++ b/tests/integration/expected/bor_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_8c8a3ab08866a8cdf13f461d225bc40cc694eab7818133d8e81630fc58c00003.wasm +(module $test_rust_8dcae0a39212d4ad89597641a65bcf61179a7ecf222225943d30d5d6d1cceed9.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bor_i32.hir b/tests/integration/expected/bor_i32.hir index 59889bbb..b950e33d 100644 --- a/tests/integration/expected/bor_i32.hir +++ b/tests/integration/expected/bor_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_ffcb4feca7e38ee8605b734c387b996462f7f0070d3e33c2a53fda99a685897e + (module #test_rust_8de4f7a3511ae02636986e75ade7e321e0708f1826bcbc6aad48f37af323b92d ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bor_i32.masm b/tests/integration/expected/bor_i32.masm index 57cc0d48..9f4ef066 100644 --- a/tests/integration/expected/bor_i32.masm +++ b/tests/integration/expected/bor_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_ffcb4feca7e38ee8605b734c387b996462f7f0070d3e33c2a53fda99a685897e +# mod test_rust_8de4f7a3511ae02636986e75ade7e321e0708f1826bcbc6aad48f37af323b92d export.entrypoint u32or end -begin - exec.::test_rust_ffcb4feca7e38ee8605b734c387b996462f7f0070d3e33c2a53fda99a685897e::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bor_i32.wat b/tests/integration/expected/bor_i32.wat index c11fb1f2..347400bd 100644 --- a/tests/integration/expected/bor_i32.wat +++ b/tests/integration/expected/bor_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_ffcb4feca7e38ee8605b734c387b996462f7f0070d3e33c2a53fda99a685897e.wasm +(module $test_rust_8de4f7a3511ae02636986e75ade7e321e0708f1826bcbc6aad48f37af323b92d.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bor_i64.hir b/tests/integration/expected/bor_i64.hir index 30991c6e..360f06d4 100644 --- a/tests/integration/expected/bor_i64.hir +++ b/tests/integration/expected/bor_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_f61670fcd2208ab3221b5dfc585ca07c6b67db9f0b9623622bc906c855f0548a + (module #test_rust_f251de15b0f1cb5576431f7d54bb74bf9a7d3ecd44df0dab5c9d48f9fbc8fc10 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bor_i64.masm b/tests/integration/expected/bor_i64.masm index 8e1d078c..4ee529fe 100644 --- a/tests/integration/expected/bor_i64.masm +++ b/tests/integration/expected/bor_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_f61670fcd2208ab3221b5dfc585ca07c6b67db9f0b9623622bc906c855f0548a +# mod test_rust_f251de15b0f1cb5576431f7d54bb74bf9a7d3ecd44df0dab5c9d48f9fbc8fc10 export.entrypoint exec.::std::math::u64::or end -begin - exec.::test_rust_f61670fcd2208ab3221b5dfc585ca07c6b67db9f0b9623622bc906c855f0548a::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bor_i64.wat b/tests/integration/expected/bor_i64.wat index e2816afa..0e465cf6 100644 --- a/tests/integration/expected/bor_i64.wat +++ b/tests/integration/expected/bor_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_f61670fcd2208ab3221b5dfc585ca07c6b67db9f0b9623622bc906c855f0548a.wasm +(module $test_rust_f251de15b0f1cb5576431f7d54bb74bf9a7d3ecd44df0dab5c9d48f9fbc8fc10.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/bor_i8.hir b/tests/integration/expected/bor_i8.hir index 4aa2a3f9..bc260913 100644 --- a/tests/integration/expected/bor_i8.hir +++ b/tests/integration/expected/bor_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_3c3c09a69dc74dba99e46fa37b6b592780b19270274db6be94fbda8283613174 + (module #test_rust_e78a5011ab26b989caa809c67e9a8c1aa75b6ed66a6d08724f2ade857dd972e7 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bor_i8.masm b/tests/integration/expected/bor_i8.masm index 1235443f..3a7ef3ae 100644 --- a/tests/integration/expected/bor_i8.masm +++ b/tests/integration/expected/bor_i8.masm @@ -1,10 +1,7 @@ -# mod test_rust_3c3c09a69dc74dba99e46fa37b6b592780b19270274db6be94fbda8283613174 +# mod test_rust_e78a5011ab26b989caa809c67e9a8c1aa75b6ed66a6d08724f2ade857dd972e7 export.entrypoint u32or end -begin - exec.::test_rust_3c3c09a69dc74dba99e46fa37b6b592780b19270274db6be94fbda8283613174::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bor_i8.wat b/tests/integration/expected/bor_i8.wat index dfb266df..f4ee5fe7 100644 --- a/tests/integration/expected/bor_i8.wat +++ b/tests/integration/expected/bor_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_3c3c09a69dc74dba99e46fa37b6b592780b19270274db6be94fbda8283613174.wasm +(module $test_rust_e78a5011ab26b989caa809c67e9a8c1aa75b6ed66a6d08724f2ade857dd972e7.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bor_u16.hir b/tests/integration/expected/bor_u16.hir index f3312aa3..0ba3532a 100644 --- a/tests/integration/expected/bor_u16.hir +++ b/tests/integration/expected/bor_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_10d8c002ebbe90dc0a59554ee1570001dc61801e8d9f0ddf8b981a086284c00d + (module #test_rust_dc995daa9cb678e867fa3a5c4e0179784bd1e7d08c037d55bd2297656517604d ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bor_u16.masm b/tests/integration/expected/bor_u16.masm index f2e644a0..cf6d4969 100644 --- a/tests/integration/expected/bor_u16.masm +++ b/tests/integration/expected/bor_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_10d8c002ebbe90dc0a59554ee1570001dc61801e8d9f0ddf8b981a086284c00d +# mod test_rust_dc995daa9cb678e867fa3a5c4e0179784bd1e7d08c037d55bd2297656517604d export.entrypoint u32or end -begin - exec.::test_rust_10d8c002ebbe90dc0a59554ee1570001dc61801e8d9f0ddf8b981a086284c00d::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bor_u16.wat b/tests/integration/expected/bor_u16.wat index f4d9034e..9dfcff93 100644 --- a/tests/integration/expected/bor_u16.wat +++ b/tests/integration/expected/bor_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_10d8c002ebbe90dc0a59554ee1570001dc61801e8d9f0ddf8b981a086284c00d.wasm +(module $test_rust_dc995daa9cb678e867fa3a5c4e0179784bd1e7d08c037d55bd2297656517604d.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bor_u32.hir b/tests/integration/expected/bor_u32.hir index 655dcf83..6bc5897b 100644 --- a/tests/integration/expected/bor_u32.hir +++ b/tests/integration/expected/bor_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_051fe51f50265dba6f2bf7289cceb8e7ed3693a0fa020cc6c2202f54677db6b4 + (module #test_rust_77d8f367326a058c1e380ac8136670434cfbc1e8dc697dc19201190d8465e015 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bor_u32.masm b/tests/integration/expected/bor_u32.masm index c5cb3261..70ba7b1b 100644 --- a/tests/integration/expected/bor_u32.masm +++ b/tests/integration/expected/bor_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_051fe51f50265dba6f2bf7289cceb8e7ed3693a0fa020cc6c2202f54677db6b4 +# mod test_rust_77d8f367326a058c1e380ac8136670434cfbc1e8dc697dc19201190d8465e015 export.entrypoint u32or end -begin - exec.::test_rust_051fe51f50265dba6f2bf7289cceb8e7ed3693a0fa020cc6c2202f54677db6b4::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bor_u32.wat b/tests/integration/expected/bor_u32.wat index e5917ca0..6e4ba91d 100644 --- a/tests/integration/expected/bor_u32.wat +++ b/tests/integration/expected/bor_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_051fe51f50265dba6f2bf7289cceb8e7ed3693a0fa020cc6c2202f54677db6b4.wasm +(module $test_rust_77d8f367326a058c1e380ac8136670434cfbc1e8dc697dc19201190d8465e015.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bor_u64.hir b/tests/integration/expected/bor_u64.hir index 0a1f3c05..a11f3784 100644 --- a/tests/integration/expected/bor_u64.hir +++ b/tests/integration/expected/bor_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_a36e5a904380c75fd8b96d09d475a0edde266aa140bffce24b7ef37f7b2f70c8 + (module #test_rust_ba6ec59331d835edc07f1b6d30f780b5afe487a33c70884f73400189c17cefa6 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bor_u64.masm b/tests/integration/expected/bor_u64.masm index c63d3d8c..9e3ccc6f 100644 --- a/tests/integration/expected/bor_u64.masm +++ b/tests/integration/expected/bor_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_a36e5a904380c75fd8b96d09d475a0edde266aa140bffce24b7ef37f7b2f70c8 +# mod test_rust_ba6ec59331d835edc07f1b6d30f780b5afe487a33c70884f73400189c17cefa6 export.entrypoint exec.::std::math::u64::or end -begin - exec.::test_rust_a36e5a904380c75fd8b96d09d475a0edde266aa140bffce24b7ef37f7b2f70c8::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bor_u64.wat b/tests/integration/expected/bor_u64.wat index 5241999d..fcedf5b3 100644 --- a/tests/integration/expected/bor_u64.wat +++ b/tests/integration/expected/bor_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_a36e5a904380c75fd8b96d09d475a0edde266aa140bffce24b7ef37f7b2f70c8.wasm +(module $test_rust_ba6ec59331d835edc07f1b6d30f780b5afe487a33c70884f73400189c17cefa6.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/bor_u8.hir b/tests/integration/expected/bor_u8.hir index 8a1dd334..9a977274 100644 --- a/tests/integration/expected/bor_u8.hir +++ b/tests/integration/expected/bor_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_0e3d57c8c71f555a8cdba009047c4bf2655b2539ddd5bc24847e650a14566381 + (module #test_rust_627a21fd177d4525d8fc796d148d944ac1c73323757235a4c20ab90db532b285 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bor_u8.masm b/tests/integration/expected/bor_u8.masm index b661acca..271f826c 100644 --- a/tests/integration/expected/bor_u8.masm +++ b/tests/integration/expected/bor_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_0e3d57c8c71f555a8cdba009047c4bf2655b2539ddd5bc24847e650a14566381 +# mod test_rust_627a21fd177d4525d8fc796d148d944ac1c73323757235a4c20ab90db532b285 export.entrypoint u32or end -begin - exec.::test_rust_0e3d57c8c71f555a8cdba009047c4bf2655b2539ddd5bc24847e650a14566381::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bor_u8.wat b/tests/integration/expected/bor_u8.wat index 1807b5c1..ee5e7d34 100644 --- a/tests/integration/expected/bor_u8.wat +++ b/tests/integration/expected/bor_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_0e3d57c8c71f555a8cdba009047c4bf2655b2539ddd5bc24847e650a14566381.wasm +(module $test_rust_627a21fd177d4525d8fc796d148d944ac1c73323757235a4c20ab90db532b285.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bxor_i16.hir b/tests/integration/expected/bxor_i16.hir index f4340641..e745afcb 100644 --- a/tests/integration/expected/bxor_i16.hir +++ b/tests/integration/expected/bxor_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_31340dea94d5815fdbeada64122d75ef52c31ef664b9bdb97f25dc50403c962e + (module #test_rust_06b51ddbcc44da2e5b8841fa052397384b0f5d4eefe1a6761fd89258dd630db1 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bxor_i16.masm b/tests/integration/expected/bxor_i16.masm index 76473bab..3ea7d86e 100644 --- a/tests/integration/expected/bxor_i16.masm +++ b/tests/integration/expected/bxor_i16.masm @@ -1,10 +1,7 @@ -# mod test_rust_31340dea94d5815fdbeada64122d75ef52c31ef664b9bdb97f25dc50403c962e +# mod test_rust_06b51ddbcc44da2e5b8841fa052397384b0f5d4eefe1a6761fd89258dd630db1 export.entrypoint u32xor end -begin - exec.::test_rust_31340dea94d5815fdbeada64122d75ef52c31ef664b9bdb97f25dc50403c962e::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bxor_i16.wat b/tests/integration/expected/bxor_i16.wat index 8ea701c8..84914476 100644 --- a/tests/integration/expected/bxor_i16.wat +++ b/tests/integration/expected/bxor_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_31340dea94d5815fdbeada64122d75ef52c31ef664b9bdb97f25dc50403c962e.wasm +(module $test_rust_06b51ddbcc44da2e5b8841fa052397384b0f5d4eefe1a6761fd89258dd630db1.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bxor_i32.hir b/tests/integration/expected/bxor_i32.hir index 175a6683..a1199302 100644 --- a/tests/integration/expected/bxor_i32.hir +++ b/tests/integration/expected/bxor_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_595d33f8d41bf8d0b48b19b9d0d717b2001169c6dacb943b6933b7ac892d670e + (module #test_rust_be5e210e7912f50da791746e584735851a9fd43e799bd41c0fbdf5eeef96d97f ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bxor_i32.masm b/tests/integration/expected/bxor_i32.masm index 371103c6..c6381824 100644 --- a/tests/integration/expected/bxor_i32.masm +++ b/tests/integration/expected/bxor_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_595d33f8d41bf8d0b48b19b9d0d717b2001169c6dacb943b6933b7ac892d670e +# mod test_rust_be5e210e7912f50da791746e584735851a9fd43e799bd41c0fbdf5eeef96d97f export.entrypoint u32xor end -begin - exec.::test_rust_595d33f8d41bf8d0b48b19b9d0d717b2001169c6dacb943b6933b7ac892d670e::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bxor_i32.wat b/tests/integration/expected/bxor_i32.wat index 803c5858..84522da2 100644 --- a/tests/integration/expected/bxor_i32.wat +++ b/tests/integration/expected/bxor_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_595d33f8d41bf8d0b48b19b9d0d717b2001169c6dacb943b6933b7ac892d670e.wasm +(module $test_rust_be5e210e7912f50da791746e584735851a9fd43e799bd41c0fbdf5eeef96d97f.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bxor_i64.hir b/tests/integration/expected/bxor_i64.hir index 99945f15..cde4b91d 100644 --- a/tests/integration/expected/bxor_i64.hir +++ b/tests/integration/expected/bxor_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_117752e0a1737725f344ccfdf0b276478964ba6f83baa028adbb8709f99078ab + (module #test_rust_885212eb58b38aa5817a1cd1ea309cf5ebf56542a26e25486674166aaa47f2cb ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bxor_i64.masm b/tests/integration/expected/bxor_i64.masm index e3c5accd..62542aad 100644 --- a/tests/integration/expected/bxor_i64.masm +++ b/tests/integration/expected/bxor_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_117752e0a1737725f344ccfdf0b276478964ba6f83baa028adbb8709f99078ab +# mod test_rust_885212eb58b38aa5817a1cd1ea309cf5ebf56542a26e25486674166aaa47f2cb export.entrypoint exec.::std::math::u64::xor end -begin - exec.::test_rust_117752e0a1737725f344ccfdf0b276478964ba6f83baa028adbb8709f99078ab::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bxor_i64.wat b/tests/integration/expected/bxor_i64.wat index ece3375c..64cd448c 100644 --- a/tests/integration/expected/bxor_i64.wat +++ b/tests/integration/expected/bxor_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_117752e0a1737725f344ccfdf0b276478964ba6f83baa028adbb8709f99078ab.wasm +(module $test_rust_885212eb58b38aa5817a1cd1ea309cf5ebf56542a26e25486674166aaa47f2cb.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/bxor_i8.hir b/tests/integration/expected/bxor_i8.hir index 7c1cbeba..21f8d344 100644 --- a/tests/integration/expected/bxor_i8.hir +++ b/tests/integration/expected/bxor_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c64e2a982ef5596c6379542467e047153ae5c1824246ef4cbe06b327d51be74a + (module #test_rust_356739565a7fab5b3bf9f65a371ce7f192583c0220bd25c5fee3d50220aadf20 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bxor_i8.masm b/tests/integration/expected/bxor_i8.masm index d2cadab1..b7a6aa25 100644 --- a/tests/integration/expected/bxor_i8.masm +++ b/tests/integration/expected/bxor_i8.masm @@ -1,10 +1,7 @@ -# mod test_rust_c64e2a982ef5596c6379542467e047153ae5c1824246ef4cbe06b327d51be74a +# mod test_rust_356739565a7fab5b3bf9f65a371ce7f192583c0220bd25c5fee3d50220aadf20 export.entrypoint u32xor end -begin - exec.::test_rust_c64e2a982ef5596c6379542467e047153ae5c1824246ef4cbe06b327d51be74a::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bxor_i8.wat b/tests/integration/expected/bxor_i8.wat index edd4bcf6..d25949d7 100644 --- a/tests/integration/expected/bxor_i8.wat +++ b/tests/integration/expected/bxor_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_c64e2a982ef5596c6379542467e047153ae5c1824246ef4cbe06b327d51be74a.wasm +(module $test_rust_356739565a7fab5b3bf9f65a371ce7f192583c0220bd25c5fee3d50220aadf20.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bxor_u16.hir b/tests/integration/expected/bxor_u16.hir index 7764be0d..06f0ecde 100644 --- a/tests/integration/expected/bxor_u16.hir +++ b/tests/integration/expected/bxor_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_edfc84a713511234ff9afc4c89c4fd998413355e149a7e331eaec655163d9afe + (module #test_rust_1b43125ada2df0a7389224838e3cc4580de7ac09a86583219a3c08992ca30695 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bxor_u16.masm b/tests/integration/expected/bxor_u16.masm index 0fa05aa7..fc0403e3 100644 --- a/tests/integration/expected/bxor_u16.masm +++ b/tests/integration/expected/bxor_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_edfc84a713511234ff9afc4c89c4fd998413355e149a7e331eaec655163d9afe +# mod test_rust_1b43125ada2df0a7389224838e3cc4580de7ac09a86583219a3c08992ca30695 export.entrypoint u32xor end -begin - exec.::test_rust_edfc84a713511234ff9afc4c89c4fd998413355e149a7e331eaec655163d9afe::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bxor_u16.wat b/tests/integration/expected/bxor_u16.wat index 563b1744..921b3907 100644 --- a/tests/integration/expected/bxor_u16.wat +++ b/tests/integration/expected/bxor_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_edfc84a713511234ff9afc4c89c4fd998413355e149a7e331eaec655163d9afe.wasm +(module $test_rust_1b43125ada2df0a7389224838e3cc4580de7ac09a86583219a3c08992ca30695.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bxor_u32.hir b/tests/integration/expected/bxor_u32.hir index 4e456ce2..80344d81 100644 --- a/tests/integration/expected/bxor_u32.hir +++ b/tests/integration/expected/bxor_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_972d35b4c4e5a4bf3450bff55d3407152f81ce2206ea8e96de43f1800f0f5f59 + (module #test_rust_8adee8c8a1d96eeb275124845b60cbff14dd0510589dd0280f2e41e39371d112 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bxor_u32.masm b/tests/integration/expected/bxor_u32.masm index 3304ba86..675bd1ed 100644 --- a/tests/integration/expected/bxor_u32.masm +++ b/tests/integration/expected/bxor_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_972d35b4c4e5a4bf3450bff55d3407152f81ce2206ea8e96de43f1800f0f5f59 +# mod test_rust_8adee8c8a1d96eeb275124845b60cbff14dd0510589dd0280f2e41e39371d112 export.entrypoint u32xor end -begin - exec.::test_rust_972d35b4c4e5a4bf3450bff55d3407152f81ce2206ea8e96de43f1800f0f5f59::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bxor_u32.wat b/tests/integration/expected/bxor_u32.wat index 642abf7a..b446e271 100644 --- a/tests/integration/expected/bxor_u32.wat +++ b/tests/integration/expected/bxor_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_972d35b4c4e5a4bf3450bff55d3407152f81ce2206ea8e96de43f1800f0f5f59.wasm +(module $test_rust_8adee8c8a1d96eeb275124845b60cbff14dd0510589dd0280f2e41e39371d112.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/bxor_u64.hir b/tests/integration/expected/bxor_u64.hir index 7469ed0c..615cdc39 100644 --- a/tests/integration/expected/bxor_u64.hir +++ b/tests/integration/expected/bxor_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c6f75363967986e957272f956f2d22dd9a7b83b7c3e6522902813b6809fddc5c + (module #test_rust_0ac0889968c0147e0b9ffdf298215e3c144b2f0574e12a5a7110797b6cd692a5 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bxor_u64.masm b/tests/integration/expected/bxor_u64.masm index 46d97a85..c82a35e0 100644 --- a/tests/integration/expected/bxor_u64.masm +++ b/tests/integration/expected/bxor_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_c6f75363967986e957272f956f2d22dd9a7b83b7c3e6522902813b6809fddc5c +# mod test_rust_0ac0889968c0147e0b9ffdf298215e3c144b2f0574e12a5a7110797b6cd692a5 export.entrypoint exec.::std::math::u64::xor end -begin - exec.::test_rust_c6f75363967986e957272f956f2d22dd9a7b83b7c3e6522902813b6809fddc5c::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bxor_u64.wat b/tests/integration/expected/bxor_u64.wat index 59ceb8dc..a2cb976b 100644 --- a/tests/integration/expected/bxor_u64.wat +++ b/tests/integration/expected/bxor_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_c6f75363967986e957272f956f2d22dd9a7b83b7c3e6522902813b6809fddc5c.wasm +(module $test_rust_0ac0889968c0147e0b9ffdf298215e3c144b2f0574e12a5a7110797b6cd692a5.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/bxor_u8.hir b/tests/integration/expected/bxor_u8.hir index 594c2530..ee2c04ab 100644 --- a/tests/integration/expected/bxor_u8.hir +++ b/tests/integration/expected/bxor_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_3bc685af363b80b89b9cea6b01602a2b50a6c4a8978e24e239a9e9fac3fdccb4 + (module #test_rust_4d8ea78f0f6f413d2e269f1030408eff2561031d16e66341c04b75f1a2e08afe ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/bxor_u8.masm b/tests/integration/expected/bxor_u8.masm index 45147c54..b036e7b9 100644 --- a/tests/integration/expected/bxor_u8.masm +++ b/tests/integration/expected/bxor_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_3bc685af363b80b89b9cea6b01602a2b50a6c4a8978e24e239a9e9fac3fdccb4 +# mod test_rust_4d8ea78f0f6f413d2e269f1030408eff2561031d16e66341c04b75f1a2e08afe export.entrypoint u32xor end -begin - exec.::test_rust_3bc685af363b80b89b9cea6b01602a2b50a6c4a8978e24e239a9e9fac3fdccb4::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/bxor_u8.wat b/tests/integration/expected/bxor_u8.wat index 5f14341d..e2a0d431 100644 --- a/tests/integration/expected/bxor_u8.wat +++ b/tests/integration/expected/bxor_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_3bc685af363b80b89b9cea6b01602a2b50a6c4a8978e24e239a9e9fac3fdccb4.wasm +(module $test_rust_4d8ea78f0f6f413d2e269f1030408eff2561031d16e66341c04b75f1a2e08afe.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/components/add_wasm_component.hir b/tests/integration/expected/components/add_wasm_component.hir index 9bd6a5a8..2f034ae9 100644 --- a/tests/integration/expected/components/add_wasm_component.hir +++ b/tests/integration/expected/components/add_wasm_component.hir @@ -1,6 +1,9 @@ (component ;; Modules (module #add_wasm_component + ;; Data Segments + (data (mut) (offset 1048576) 0x01000000) + ;; Constants (const (id 0) 0x00100000) @@ -16,20 +19,9 @@ (ret)) ) - (func (export #miden:add-package/add-interface@1.0.0#add) - (param i32) (param i32) (result i32) - (block 0 (param v0 i32) (param v1 i32) - (call #wit_bindgen::rt::run_ctors_once) - (let (v3 i32) (add.wrapping v1 v0)) - (br (block 1 v3))) - - (block 1 (param v2 i32) - (ret v2)) - ) - (func (export #__rust_alloc) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) - (let (v3 i32) (const.i32 1048576)) + (let (v3 i32) (const.i32 1048580)) (let (v4 i32) (call #::alloc v3 v1 v0)) (br (block 1 v4))) @@ -41,7 +33,7 @@ (param i32) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) (let (v5 i32) (const.i32 0)) - (let (v6 i32) (const.i32 1048576)) + (let (v6 i32) (const.i32 1048580)) (let (v7 i32) (call #::alloc v6 v2 v3)) (let (v8 i1) (eq v7 0)) (let (v9 i32) (zext v8)) @@ -61,499 +53,596 @@ (let (v14 i32) (sext v13)) (let (v15 i1) (neq v14 0)) (let (v16 i32) (select v15 v1 v3)) - (let (v17 u32) (cast v7)) + (let (v17 u32) (bitcast v7)) (let (v18 (ptr u8)) (inttoptr v17)) - (let (v19 u32) (cast v0)) + (let (v19 u32) (bitcast v0)) (let (v20 (ptr u8)) (inttoptr v19)) (memcpy v20 v18 v16) - (let (v21 i32) (const.i32 1048576)) + (let (v21 i32) (const.i32 1048580)) (call #::dealloc v21 v0 v2 v1) (br (block 2 v7))) ) + (func (export #miden:add-package/add-interface@1.0.0#add) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (call #wit_bindgen_rt::run_ctors_once) + (let (v3 i32) (add.wrapping v1 v0)) + (br (block 1 v3))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #wit_bindgen_rt::cabi_realloc) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i1) (neq v1 0)) + (condbr v5 (block 4) (block 5))) + + (block 1 (param v4 i32) + (ret v4)) + + (block 2 (param v19 i32) + (br (block 1 v19))) + + (block 3 (param v17 i32) + (let (v18 i1) (neq v17 0)) + (condbr v18 (block 2 v17) (block 7))) + + (block 4 + (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) + (br (block 3 v16))) + + (block 5 + (let (v6 i1) (eq v3 0)) + (let (v7 i32) (zext v6)) + (let (v8 i1) (neq v7 0)) + (condbr v8 (block 2 v2) (block 6))) + + (block 6 + (let (v9 i32) (const.i32 0)) + (let (v10 u32) (bitcast v9)) + (let (v11 u32) (add.checked v10 1048584)) + (let (v12 (ptr u8)) (inttoptr v11)) + (let (v13 u8) (load v12)) + (let (v14 i32) (zext v13)) + (let (v15 i32) (call #__rust_alloc v3 v2)) + (br (block 3 v15))) + + (block 7 + (unreachable)) + ) + + (func (export #wit_bindgen_rt::run_ctors_once) + (block 0 + (let (v0 i32) (const.i32 0)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (add.checked v1 1048585)) + (let (v3 (ptr u8)) (inttoptr v2)) + (let (v4 u8) (load v3)) + (let (v5 i32) (zext v4)) + (let (v6 i1) (neq v5 0)) + (condbr v6 (block 2) (block 3))) + + (block 1 + (ret)) + + (block 2 + (br (block 1))) + + (block 3 + (call #__wasm_call_ctors) + (let (v7 i32) (const.i32 0)) + (let (v8 i32) (const.i32 1)) + (let (v9 u32) (bitcast v8)) + (let (v10 u8) (trunc v9)) + (let (v11 u32) (bitcast v7)) + (let (v12 u32) (add.checked v11 1048585)) + (let (v13 (ptr u8)) (inttoptr v12)) + (store v13 v10) + (br (block 2))) + ) + (func (export #wee_alloc::alloc_first_fit) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (let (v4 i32) (const.i32 0)) - (let (v5 u32) (cast v2)) - (let (v6 u32) (mod.unchecked v5 2)) - (assertz v6) + (let (v5 u32) (bitcast v2)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) (let (v7 (ptr i32)) (inttoptr v5)) (let (v8 i32) (load v7)) - (let (v9 i1) (eq v8 0)) - (let (v10 i32) (zext v9)) - (let (v11 i1) (neq v10 0)) - (condbr v11 (block 2) (block 3))) + (let (v9 i1) (neq v8 0)) + (condbr v9 (block 2) (block 3))) (block 1 (param v3 i32) (ret v3)) (block 2 - (let (v330 i32) (const.i32 0)) - (br (block 1 v330))) + (let (v11 i32) (const.i32 -1)) + (let (v12 i32) (add.wrapping v1 v11)) + (let (v13 i32) (const.i32 0)) + (let (v14 i32) (sub.wrapping v13 v1)) + (let (v15 i32) (const.i32 2)) + (let (v16 u32) (bitcast v15)) + (let (v17 i32) (shl.wrapping v0 v16)) + (br (block 4 v8 v2 v17 v14 v12))) (block 3 - (let (v12 i32) (const.i32 -1)) - (let (v13 i32) (add.wrapping v1 v12)) - (let (v14 i32) (const.i32 0)) - (let (v15 i32) (sub.wrapping v14 v1)) - (let (v16 i32) (const.i32 2)) - (let (v17 u32) (bitcast v16)) - (let (v18 i32) (shl.wrapping v0 v17)) - (br (block 4 v8 v2 v18 v15 v13))) + (let (v10 i32) (const.i32 0)) + (ret v10)) (block 4 - (param v19 i32) - (param v160 i32) - (param v171 i32) - (param v185 i32) + (param v18 i32) + (param v169 i32) + (param v182 i32) (param v197 i32) - (let (v20 i32) (const.i32 8)) - (let (v21 i32) (add.wrapping v19 v20)) - (let (v22 u32) (cast v19)) - (let (v23 u32) (add.checked v22 8)) - (let (v24 u32) (mod.unchecked v23 2)) - (assertz v24) - (let (v25 (ptr i32)) (inttoptr v23)) - (let (v26 i32) (load v25)) - (let (v27 i32) (const.i32 1)) - (let (v28 i32) (band v26 v27)) - (let (v29 i1) (neq v28 0)) - (condbr v29 (block 7) (block 8))) + (param v210 i32) + (let (v19 u32) (bitcast v18)) + (let (v20 u32) (add.checked v19 8)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) + (let (v22 (ptr i32)) (inttoptr v20)) + (let (v23 i32) (load v22)) + (let (v24 i32) (const.i32 1)) + (let (v25 i32) (band v23 v24)) + (let (v26 i1) (neq v25 0)) + (condbr v26 (block 7) (block 8))) (block 5 - (br (block 2))) + (let (v344 i32) (const.i32 0)) + (br (block 1 v344))) (block 6 - (param v161 i32) - (param v168 i32) - (param v170 i32) - (param v184 i32) + (param v172 i32) + (param v179 i32) + (param v181 i32) (param v196 i32) - (param v204 i32) - (param v205 i32) - (let (v162 u32) (cast v161)) - (let (v163 u32) (mod.unchecked v162 2)) - (assertz v163) - (let (v164 (ptr i32)) (inttoptr v162)) - (let (v165 i32) (load v164)) - (let (v166 i32) (const.i32 -4)) - (let (v167 i32) (band v165 v166)) - (let (v169 i32) (sub.wrapping v167 v168)) - (let (v176 u32) (bitcast v169)) - (let (v177 u32) (bitcast v170)) - (let (v178 i1) (lt v176 v177)) - (let (v179 i32) (sext v178)) - (let (v180 i1) (neq v179 0)) - (condbr v180 (block 21 v204 v205 v170 v184 v196) (block 22))) + (param v209 i32) + (param v218 i32) + (param v219 i32) + (let (v173 u32) (bitcast v172)) + (let (v174 u32) (mod.unchecked v173 4)) + (assertz 250 v174) + (let (v175 (ptr i32)) (inttoptr v173)) + (let (v176 i32) (load v175)) + (let (v177 i32) (const.i32 -4)) + (let (v178 i32) (band v176 v177)) + (let (v180 i32) (sub.wrapping v178 v179)) + (let (v188 u32) (bitcast v180)) + (let (v189 u32) (bitcast v181)) + (let (v190 i1) (lt v188 v189)) + (let (v191 i32) (sext v190)) + (let (v192 i1) (neq v191 0)) + (condbr v192 (block 22 v218 v219 v181 v196 v209) (block 23))) (block 7 - (br (block 9 v21 v26 v19 v160 v171 v185 v197))) + (br (block 9 v18 v23 v169 v182 v197 v210))) (block 8 - (br (block 6 v19 v21 v171 v185 v197 v160 v26))) + (let (v27 i32) (const.i32 8)) + (let (v28 i32) (add.wrapping v18 v27)) + (br (block 6 v18 v28 v182 v197 v210 v169 v23))) (block 9 + (param v29 i32) (param v30 i32) - (param v31 i32) - (param v37 i32) - (param v144 i32) - (param v174 i32) - (param v188 i32) - (param v200 i32) - (let (v32 i32) (const.i32 -2)) - (let (v33 i32) (band v31 v32)) - (let (v34 u32) (cast v30)) - (let (v35 u32) (mod.unchecked v34 2)) - (assertz v35) + (param v156 i32) + (param v187 i32) + (param v202 i32) + (param v215 i32) + (let (v31 i32) (const.i32 -2)) + (let (v32 i32) (band v30 v31)) + (let (v33 u32) (bitcast v29)) + (let (v34 u32) (add.checked v33 8)) + (let (v35 u32) (mod.unchecked v34 4)) + (assertz 250 v35) (let (v36 (ptr i32)) (inttoptr v34)) - (store v36 v33) - (let (v38 u32) (cast v37)) - (let (v39 u32) (add.checked v38 4)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) - (let (v41 (ptr i32)) (inttoptr v39)) - (let (v42 i32) (load v41)) - (let (v43 i32) (const.i32 -4)) - (let (v44 i32) (band v42 v43)) - (let (v45 u32) (cast v44)) - (let (v46 u32) (mod.unchecked v45 2)) - (assertz v46) - (let (v47 (ptr i32)) (inttoptr v45)) - (let (v48 i32) (load v47)) - (let (v49 u32) (cast v37)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr i32)) (inttoptr v49)) - (let (v52 i32) (load v51)) - (let (v53 i32) (const.i32 -4)) - (let (v54 i32) (band v52 v53)) - (let (v55 i1) (neq v54 0)) - (condbr v55 (block 13) (block 14))) + (store v36 v32) + (let (v37 u32) (bitcast v29)) + (let (v38 u32) (add.checked v37 4)) + (let (v39 u32) (mod.unchecked v38 4)) + (assertz 250 v39) + (let (v40 (ptr i32)) (inttoptr v38)) + (let (v41 i32) (load v40)) + (let (v42 i32) (const.i32 -4)) + (let (v43 i32) (band v41 v42)) + (let (v44 i1) (neq v43 0)) + (condbr v44 (block 12) (block 13))) (block 10 - (br (block 6 v146 v151 v172 v186 v198 v142 v156))) + (let (v170 i32) (const.i32 8)) + (let (v171 i32) (add.wrapping v157 v170)) + (br (block 6 v157 v171 v183 v198 v211 v152 v165))) (block 11 - (param v112 i32) - (param v113 i32) - (param v120 i32) - (param v131 i32) - (param v143 i32) - (param v173 i32) - (param v187 i32) - (param v199 i32) - (let (v114 i32) (const.i32 3)) - (let (v115 i32) (band v113 v114)) - (let (v116 u32) (cast v112)) - (let (v117 u32) (add.checked v116 4)) - (let (v118 u32) (mod.unchecked v117 2)) - (assertz v118) - (let (v119 (ptr i32)) (inttoptr v117)) - (store v119 v115) - (let (v121 i32) (const.i32 3)) - (let (v122 i32) (band v120 v121)) - (let (v123 u32) (cast v112)) - (let (v124 u32) (mod.unchecked v123 2)) - (assertz v124) - (let (v125 (ptr i32)) (inttoptr v123)) - (store v125 v122) - (let (v126 i32) (const.i32 2)) - (let (v127 i32) (band v120 v126)) - (let (v128 i1) (eq v127 0)) - (let (v129 i32) (zext v128)) - (let (v130 i1) (neq v129 0)) - (condbr v130 (block 18 v143 v131 v173 v187 v199) (block 19))) + (param v55 i32) + (param v75 i32) + (param v122 i32) + (param v142 i32) + (param v155 i32) + (param v186 i32) + (param v201 i32) + (param v214 i32) + (let (v56 u32) (bitcast v55)) + (let (v57 u32) (mod.unchecked v56 4)) + (assertz 250 v57) + (let (v58 (ptr i32)) (inttoptr v56)) + (let (v59 i32) (load v58)) + (let (v60 i32) (const.i32 -4)) + (let (v61 i32) (band v59 v60)) + (let (v62 i1) (eq v61 0)) + (let (v63 i32) (zext v62)) + (let (v64 i1) (neq v63 0)) + (condbr v64 (block 14 v75 v59 v55 v122 v142 v155 v186 v201 v214) (block 15))) (block 12 - (param v93 i32) - (param v94 i32) - (param v97 i32) - (param v102 i32) - (param v132 i32) - (param v145 i32) - (param v175 i32) - (param v189 i32) - (param v201 i32) - (let (v95 i32) (const.i32 3)) - (let (v96 i32) (band v94 v95)) - (let (v98 i32) (bor v96 v97)) - (let (v99 u32) (cast v93)) - (let (v100 u32) (mod.unchecked v99 2)) - (assertz v100) - (let (v101 (ptr i32)) (inttoptr v99)) - (store v101 v98) - (let (v103 u32) (cast v102)) - (let (v104 u32) (add.checked v103 4)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) - (let (v106 (ptr i32)) (inttoptr v104)) - (let (v107 i32) (load v106)) - (let (v108 u32) (cast v102)) - (let (v109 u32) (mod.unchecked v108 2)) - (assertz v109) - (let (v110 (ptr i32)) (inttoptr v108)) - (let (v111 i32) (load v110)) - (br (block 11 v102 v107 v111 v132 v145 v175 v189 v201))) + (let (v46 i32) (const.i32 0)) + (let (v47 u32) (bitcast v43)) + (let (v48 (ptr u8)) (inttoptr v47)) + (let (v49 u8) (load v48)) + (let (v50 i32) (zext v49)) + (let (v51 i32) (const.i32 1)) + (let (v52 i32) (band v50 v51)) + (let (v53 i1) (neq v52 0)) + (let (v54 i32) (select v53 v46 v43)) + (br (block 11 v29 v43 v41 v54 v156 v187 v202 v215))) (block 13 - (let (v56 i32) (const.i32 2)) - (let (v57 i32) (band v52 v56)) - (let (v58 i1) (eq v57 0)) - (let (v59 i32) (zext v58)) - (let (v60 i1) (neq v59 0)) - (condbr v60 (block 15) (block 16))) + (let (v45 i32) (const.i32 0)) + (br (block 11 v29 v43 v41 v45 v156 v187 v202 v215))) (block 14 - (br (block 12 v44 v48 v54 v37 v44 v144 v174 v188 v200))) + (param v92 i32) + (param v102 i32) + (param v109 i32) + (param v121 i32) + (param v141 i32) + (param v154 i32) + (param v185 i32) + (param v200 i32) + (param v213 i32) + (let (v93 i1) (eq v92 0)) + (let (v94 i32) (zext v93)) + (let (v95 i1) (neq v94 0)) + (condbr v95 (block 17 v109 v121 v102 v141 v154 v185 v200 v213) (block 18))) (block 15 - (let (v61 u32) (cast v54)) - (let (v62 u32) (add.checked v61 4)) - (let (v63 u32) (mod.unchecked v62 2)) - (assertz v63) - (let (v64 (ptr i32)) (inttoptr v62)) - (let (v65 i32) (load v64)) - (let (v66 i32) (const.i32 3)) - (let (v67 i32) (band v65 v66)) - (let (v68 i32) (bor v67 v44)) - (let (v69 u32) (cast v54)) - (let (v70 u32) (add.checked v69 4)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) - (let (v72 (ptr i32)) (inttoptr v70)) - (store v72 v68) - (let (v73 u32) (cast v37)) - (let (v74 u32) (mod.unchecked v73 2)) - (assertz v74) - (let (v75 (ptr i32)) (inttoptr v73)) - (let (v76 i32) (load v75)) - (let (v77 u32) (cast v37)) - (let (v78 u32) (add.checked v77 4)) - (let (v79 u32) (mod.unchecked v78 2)) - (assertz v79) - (let (v80 (ptr i32)) (inttoptr v78)) - (let (v81 i32) (load v80)) - (let (v82 i32) (const.i32 -4)) - (let (v83 i32) (band v81 v82)) - (let (v84 i1) (eq v83 0)) - (let (v85 i32) (zext v84)) - (let (v86 i1) (neq v85 0)) - (condbr v86 (block 11 v37 v81 v76 v44 v144 v174 v188 v200) (block 17))) + (let (v65 i32) (const.i32 2)) + (let (v66 i32) (band v59 v65)) + (let (v67 i1) (neq v66 0)) + (condbr v67 (block 14 v75 v59 v55 v122 v142 v155 v186 v201 v214) (block 16))) (block 16 - (br (block 12 v44 v48 v54 v37 v44 v144 v174 v188 v200))) + (let (v68 u32) (bitcast v61)) + (let (v69 u32) (add.checked v68 4)) + (let (v70 u32) (mod.unchecked v69 4)) + (assertz 250 v70) + (let (v71 (ptr i32)) (inttoptr v69)) + (let (v72 i32) (load v71)) + (let (v73 i32) (const.i32 3)) + (let (v74 i32) (band v72 v73)) + (let (v76 i32) (bor v74 v75)) + (let (v77 u32) (bitcast v61)) + (let (v78 u32) (add.checked v77 4)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) + (let (v80 (ptr i32)) (inttoptr v78)) + (store v80 v76) + (let (v81 u32) (bitcast v55)) + (let (v82 u32) (add.checked v81 4)) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) + (let (v84 (ptr i32)) (inttoptr v82)) + (let (v85 i32) (load v84)) + (let (v86 i32) (const.i32 -4)) + (let (v87 i32) (band v85 v86)) + (let (v88 u32) (bitcast v55)) + (let (v89 u32) (mod.unchecked v88 4)) + (assertz 250 v89) + (let (v90 (ptr i32)) (inttoptr v88)) + (let (v91 i32) (load v90)) + (br (block 14 v87 v91 v55 v85 v142 v155 v186 v201 v214))) (block 17 - (let (v87 i32) (const.i32 -4)) - (let (v88 i32) (band v76 v87)) - (let (v89 u32) (cast v83)) - (let (v90 u32) (mod.unchecked v89 2)) - (assertz v90) - (let (v91 (ptr i32)) (inttoptr v89)) - (let (v92 i32) (load v91)) - (br (block 12 v83 v92 v88 v37 v44 v144 v174 v188 v200))) + (param v119 i32) + (param v120 i32) + (param v129 i32) + (param v140 i32) + (param v153 i32) + (param v184 i32) + (param v199 i32) + (param v212 i32) + (let (v123 i32) (const.i32 3)) + (let (v124 i32) (band v120 v123)) + (let (v125 u32) (bitcast v119)) + (let (v126 u32) (add.checked v125 4)) + (let (v127 u32) (mod.unchecked v126 4)) + (assertz 250 v127) + (let (v128 (ptr i32)) (inttoptr v126)) + (store v128 v124) + (let (v130 i32) (const.i32 3)) + (let (v131 i32) (band v129 v130)) + (let (v132 u32) (bitcast v119)) + (let (v133 u32) (mod.unchecked v132 4)) + (assertz 250 v133) + (let (v134 (ptr i32)) (inttoptr v132)) + (store v134 v131) + (let (v135 i32) (const.i32 2)) + (let (v136 i32) (band v129 v135)) + (let (v137 i1) (eq v136 0)) + (let (v138 i32) (zext v137)) + (let (v139 i1) (neq v138 0)) + (condbr v139 (block 19 v153 v140 v184 v199 v212) (block 20))) (block 18 - (param v142 i32) - (param v146 i32) - (param v172 i32) - (param v186 i32) - (param v198 i32) - (let (v147 u32) (cast v142)) - (let (v148 u32) (mod.unchecked v147 2)) - (assertz v148) - (let (v149 (ptr i32)) (inttoptr v147)) - (store v149 v146) - (let (v150 i32) (const.i32 8)) - (let (v151 i32) (add.wrapping v146 v150)) - (let (v152 u32) (cast v146)) - (let (v153 u32) (add.checked v152 8)) - (let (v154 u32) (mod.unchecked v153 2)) - (assertz v154) - (let (v155 (ptr i32)) (inttoptr v153)) - (let (v156 i32) (load v155)) - (let (v157 i32) (const.i32 1)) - (let (v158 i32) (band v156 v157)) - (let (v159 i1) (neq v158 0)) - (condbr v159 (block 9 v151 v156 v146 v142 v172 v186 v198) (block 20))) + (let (v96 u32) (bitcast v92)) + (let (v97 u32) (mod.unchecked v96 4)) + (assertz 250 v97) + (let (v98 (ptr i32)) (inttoptr v96)) + (let (v99 i32) (load v98)) + (let (v100 i32) (const.i32 3)) + (let (v101 i32) (band v99 v100)) + (let (v103 i32) (const.i32 -4)) + (let (v104 i32) (band v102 v103)) + (let (v105 i32) (bor v101 v104)) + (let (v106 u32) (bitcast v92)) + (let (v107 u32) (mod.unchecked v106 4)) + (assertz 250 v107) + (let (v108 (ptr i32)) (inttoptr v106)) + (store v108 v105) + (let (v110 u32) (bitcast v109)) + (let (v111 u32) (add.checked v110 4)) + (let (v112 u32) (mod.unchecked v111 4)) + (assertz 250 v112) + (let (v113 (ptr i32)) (inttoptr v111)) + (let (v114 i32) (load v113)) + (let (v115 u32) (bitcast v109)) + (let (v116 u32) (mod.unchecked v115 4)) + (assertz 250 v116) + (let (v117 (ptr i32)) (inttoptr v115)) + (let (v118 i32) (load v117)) + (br (block 17 v109 v114 v118 v141 v154 v185 v200 v213))) (block 19 - (let (v133 u32) (cast v131)) - (let (v134 u32) (mod.unchecked v133 2)) - (assertz v134) - (let (v135 (ptr i32)) (inttoptr v133)) - (let (v136 i32) (load v135)) - (let (v137 i32) (const.i32 2)) - (let (v138 i32) (bor v136 v137)) - (let (v139 u32) (cast v131)) - (let (v140 u32) (mod.unchecked v139 2)) - (assertz v140) - (let (v141 (ptr i32)) (inttoptr v139)) - (store v141 v138) - (br (block 18 v143 v131 v173 v187 v199))) + (param v152 i32) + (param v157 i32) + (param v183 i32) + (param v198 i32) + (param v211 i32) + (let (v158 u32) (bitcast v152)) + (let (v159 u32) (mod.unchecked v158 4)) + (assertz 250 v159) + (let (v160 (ptr i32)) (inttoptr v158)) + (store v160 v157) + (let (v161 u32) (bitcast v157)) + (let (v162 u32) (add.checked v161 8)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) + (let (v164 (ptr i32)) (inttoptr v162)) + (let (v165 i32) (load v164)) + (let (v166 i32) (const.i32 1)) + (let (v167 i32) (band v165 v166)) + (let (v168 i1) (neq v167 0)) + (condbr v168 (block 9 v157 v165 v152 v183 v198 v211) (block 21))) (block 20 - (br (block 10))) + (let (v143 u32) (bitcast v140)) + (let (v144 u32) (mod.unchecked v143 4)) + (assertz 250 v144) + (let (v145 (ptr i32)) (inttoptr v143)) + (let (v146 i32) (load v145)) + (let (v147 i32) (const.i32 2)) + (let (v148 i32) (bor v146 v147)) + (let (v149 u32) (bitcast v140)) + (let (v150 u32) (mod.unchecked v149 4)) + (assertz 250 v150) + (let (v151 (ptr i32)) (inttoptr v149)) + (store v151 v148) + (br (block 19 v153 v140 v184 v199 v212))) (block 21 - (param v321 i32) - (param v322 i32) - (param v327 i32) - (param v328 i32) - (param v329 i32) - (let (v323 u32) (cast v321)) - (let (v324 u32) (mod.unchecked v323 2)) - (assertz v324) - (let (v325 (ptr i32)) (inttoptr v323)) - (store v325 v322) - (let (v326 i1) (neq v322 0)) - (condbr v326 (block 4 v322 v321 v327 v328 v329) (block 32))) + (br (block 10))) (block 22 - (let (v181 i32) (const.i32 72)) - (let (v182 i32) (add.wrapping v168 v181)) - (let (v183 i32) (sub.wrapping v167 v170)) - (let (v190 i32) (band v183 v184)) - (let (v191 u32) (bitcast v182)) - (let (v192 u32) (bitcast v190)) - (let (v193 i1) (lte v191 v192)) - (let (v194 i32) (sext v193)) - (let (v195 i1) (neq v194 0)) - (condbr v195 (block 24) (block 25))) - - (block 23 (param v312 i32) (param v313 i32) - (let (v314 i32) (const.i32 1)) - (let (v315 i32) (bor v313 v314)) - (let (v316 u32) (cast v312)) - (let (v317 u32) (mod.unchecked v316 2)) - (assertz v317) - (let (v318 (ptr i32)) (inttoptr v316)) - (store v318 v315) - (let (v319 i32) (const.i32 8)) - (let (v320 i32) (add.wrapping v312 v319)) - (ret v320)) - - (block 24 - (let (v215 i32) (const.i32 0)) - (let (v216 i32) (const.i32 0)) - (let (v217 u32) (cast v190)) - (let (v218 u32) (mod.unchecked v217 2)) - (assertz v218) - (let (v219 (ptr i32)) (inttoptr v217)) - (store v219 v216) - (let (v220 i32) (const.i32 -8)) - (let (v221 i32) (add.wrapping v190 v220)) - (let (v222 i64) (const.i64 0)) - (let (v223 u32) (cast v221)) - (let (v224 u32) (mod.unchecked v223 2)) - (assertz v224) - (let (v225 (ptr i64)) (inttoptr v223)) - (store v225 v222) - (let (v226 u32) (cast v161)) - (let (v227 u32) (mod.unchecked v226 2)) - (assertz v227) - (let (v228 (ptr i32)) (inttoptr v226)) - (let (v229 i32) (load v228)) - (let (v230 i32) (const.i32 -4)) - (let (v231 i32) (band v229 v230)) - (let (v232 u32) (cast v221)) - (let (v233 u32) (mod.unchecked v232 2)) - (assertz v233) - (let (v234 (ptr i32)) (inttoptr v232)) - (store v234 v231) - (let (v235 u32) (cast v161)) - (let (v236 u32) (mod.unchecked v235 2)) - (assertz v236) - (let (v237 (ptr i32)) (inttoptr v235)) - (let (v238 i32) (load v237)) - (let (v239 i32) (const.i32 -4)) - (let (v240 i32) (band v238 v239)) - (let (v241 i1) (eq v240 0)) - (let (v242 i32) (zext v241)) - (let (v243 i1) (neq v242 0)) - (condbr v243 (block 27 v221 v215 v161 v168) (block 28))) + (param v335 i32) + (param v336 i32) + (param v341 i32) + (param v342 i32) + (param v343 i32) + (let (v337 u32) (bitcast v335)) + (let (v338 u32) (mod.unchecked v337 4)) + (assertz 250 v338) + (let (v339 (ptr i32)) (inttoptr v337)) + (store v339 v336) + (let (v340 i1) (neq v336 0)) + (condbr v340 (block 4 v336 v335 v341 v342 v343) (block 33))) + + (block 23 + (let (v193 i32) (const.i32 72)) + (let (v194 i32) (add.wrapping v179 v193)) + (let (v195 i32) (sub.wrapping v178 v181)) + (let (v203 i32) (band v195 v196)) + (let (v204 u32) (bitcast v194)) + (let (v205 u32) (bitcast v203)) + (let (v206 i1) (lte v204 v205)) + (let (v207 i32) (sext v206)) + (let (v208 i1) (neq v207 0)) + (condbr v208 (block 25) (block 26))) + + (block 24 (param v326 i32) (param v327 i32) + (let (v328 i32) (const.i32 1)) + (let (v329 i32) (bor v327 v328)) + (let (v330 u32) (bitcast v326)) + (let (v331 u32) (mod.unchecked v330 4)) + (assertz 250 v331) + (let (v332 (ptr i32)) (inttoptr v330)) + (store v332 v329) + (let (v333 i32) (const.i32 8)) + (let (v334 i32) (add.wrapping v326 v333)) + (ret v334)) (block 25 - (let (v202 i32) (band v196 v168)) - (let (v203 i1) (neq v202 0)) - (condbr v203 (block 21 v204 v205 v170 v184 v196) (block 26))) + (let (v229 i32) (const.i32 0)) + (let (v230 i32) (const.i32 0)) + (let (v231 u32) (bitcast v203)) + (let (v232 u32) (mod.unchecked v231 4)) + (assertz 250 v232) + (let (v233 (ptr i32)) (inttoptr v231)) + (store v233 v230) + (let (v234 i32) (const.i32 -8)) + (let (v235 i32) (add.wrapping v203 v234)) + (let (v236 i64) (const.i64 0)) + (let (v237 u32) (bitcast v235)) + (let (v238 u32) (mod.unchecked v237 4)) + (assertz 250 v238) + (let (v239 (ptr i64)) (inttoptr v237)) + (store v239 v236) + (let (v240 u32) (bitcast v172)) + (let (v241 u32) (mod.unchecked v240 4)) + (assertz 250 v241) + (let (v242 (ptr i32)) (inttoptr v240)) + (let (v243 i32) (load v242)) + (let (v244 i32) (const.i32 -4)) + (let (v245 i32) (band v243 v244)) + (let (v246 u32) (bitcast v235)) + (let (v247 u32) (mod.unchecked v246 4)) + (assertz 250 v247) + (let (v248 (ptr i32)) (inttoptr v246)) + (store v248 v245) + (let (v249 u32) (bitcast v172)) + (let (v250 u32) (mod.unchecked v249 4)) + (assertz 250 v250) + (let (v251 (ptr i32)) (inttoptr v249)) + (let (v252 i32) (load v251)) + (let (v253 i32) (const.i32 -4)) + (let (v254 i32) (band v252 v253)) + (let (v255 i1) (eq v254 0)) + (let (v256 i32) (zext v255)) + (let (v257 i1) (neq v256 0)) + (condbr v257 (block 28 v235 v229 v172 v179) (block 29))) (block 26 - (let (v206 i32) (const.i32 -4)) - (let (v207 i32) (band v205 v206)) - (let (v208 u32) (cast v204)) - (let (v209 u32) (mod.unchecked v208 2)) - (assertz v209) - (let (v210 (ptr i32)) (inttoptr v208)) - (store v210 v207) - (let (v211 u32) (cast v161)) - (let (v212 u32) (mod.unchecked v211 2)) - (assertz v212) - (let (v213 (ptr i32)) (inttoptr v211)) - (let (v214 i32) (load v213)) - (br (block 23 v161 v214))) + (let (v216 i32) (band v209 v179)) + (let (v217 i1) (neq v216 0)) + (condbr v217 (block 22 v218 v219 v181 v196 v209) (block 27))) (block 27 - (param v266 i32) - (param v267 i32) - (param v268 i32) - (param v274 i32) - (let (v269 i32) (bor v267 v268)) - (let (v270 u32) (cast v266)) - (let (v271 u32) (add.checked v270 4)) - (let (v272 u32) (mod.unchecked v271 2)) - (assertz v272) - (let (v273 (ptr i32)) (inttoptr v271)) - (store v273 v269) - (let (v275 u32) (cast v274)) - (let (v276 u32) (mod.unchecked v275 2)) - (assertz v276) - (let (v277 (ptr i32)) (inttoptr v275)) - (let (v278 i32) (load v277)) - (let (v279 i32) (const.i32 -2)) - (let (v280 i32) (band v278 v279)) - (let (v281 u32) (cast v274)) - (let (v282 u32) (mod.unchecked v281 2)) - (assertz v282) - (let (v283 (ptr i32)) (inttoptr v281)) - (store v283 v280) - (let (v284 u32) (cast v268)) - (let (v285 u32) (mod.unchecked v284 2)) - (assertz v285) - (let (v286 (ptr i32)) (inttoptr v284)) - (let (v287 i32) (load v286)) - (let (v288 i32) (const.i32 3)) - (let (v289 i32) (band v287 v288)) - (let (v290 i32) (bor v289 v266)) - (let (v291 u32) (cast v268)) - (let (v292 u32) (mod.unchecked v291 2)) - (assertz v292) - (let (v293 (ptr i32)) (inttoptr v291)) - (store v293 v290) - (let (v294 i32) (const.i32 2)) - (let (v295 i32) (band v287 v294)) - (let (v296 i1) (neq v295 0)) - (condbr v296 (block 30) (block 31))) + (let (v220 i32) (const.i32 -4)) + (let (v221 i32) (band v219 v220)) + (let (v222 u32) (bitcast v218)) + (let (v223 u32) (mod.unchecked v222 4)) + (assertz 250 v223) + (let (v224 (ptr i32)) (inttoptr v222)) + (store v224 v221) + (let (v225 u32) (bitcast v172)) + (let (v226 u32) (mod.unchecked v225 4)) + (assertz 250 v226) + (let (v227 (ptr i32)) (inttoptr v225)) + (let (v228 i32) (load v227)) + (br (block 24 v172 v228))) (block 28 - (let (v244 i32) (const.i32 2)) - (let (v245 i32) (band v238 v244)) - (let (v246 i1) (neq v245 0)) - (condbr v246 (block 27 v221 v215 v161 v168) (block 29))) + (param v280 i32) + (param v281 i32) + (param v282 i32) + (param v288 i32) + (let (v283 i32) (bor v281 v282)) + (let (v284 u32) (bitcast v280)) + (let (v285 u32) (add.checked v284 4)) + (let (v286 u32) (mod.unchecked v285 4)) + (assertz 250 v286) + (let (v287 (ptr i32)) (inttoptr v285)) + (store v287 v283) + (let (v289 u32) (bitcast v288)) + (let (v290 u32) (mod.unchecked v289 4)) + (assertz 250 v290) + (let (v291 (ptr i32)) (inttoptr v289)) + (let (v292 i32) (load v291)) + (let (v293 i32) (const.i32 -2)) + (let (v294 i32) (band v292 v293)) + (let (v295 u32) (bitcast v288)) + (let (v296 u32) (mod.unchecked v295 4)) + (assertz 250 v296) + (let (v297 (ptr i32)) (inttoptr v295)) + (store v297 v294) + (let (v298 u32) (bitcast v282)) + (let (v299 u32) (mod.unchecked v298 4)) + (assertz 250 v299) + (let (v300 (ptr i32)) (inttoptr v298)) + (let (v301 i32) (load v300)) + (let (v302 i32) (const.i32 3)) + (let (v303 i32) (band v301 v302)) + (let (v304 i32) (bor v303 v280)) + (let (v305 u32) (bitcast v282)) + (let (v306 u32) (mod.unchecked v305 4)) + (assertz 250 v306) + (let (v307 (ptr i32)) (inttoptr v305)) + (store v307 v304) + (let (v308 i32) (const.i32 2)) + (let (v309 i32) (band v301 v308)) + (let (v310 i1) (neq v309 0)) + (condbr v310 (block 31) (block 32))) (block 29 - (let (v247 u32) (cast v240)) - (let (v248 u32) (add.checked v247 4)) - (let (v249 u32) (mod.unchecked v248 2)) - (assertz v249) - (let (v250 (ptr i32)) (inttoptr v248)) - (let (v251 i32) (load v250)) - (let (v252 i32) (const.i32 3)) - (let (v253 i32) (band v251 v252)) - (let (v254 i32) (bor v253 v221)) - (let (v255 u32) (cast v240)) - (let (v256 u32) (add.checked v255 4)) - (let (v257 u32) (mod.unchecked v256 2)) - (assertz v257) - (let (v258 (ptr i32)) (inttoptr v256)) - (store v258 v254) - (let (v259 u32) (cast v221)) - (let (v260 u32) (add.checked v259 4)) - (let (v261 u32) (mod.unchecked v260 2)) - (assertz v261) - (let (v262 (ptr i32)) (inttoptr v260)) - (let (v263 i32) (load v262)) - (let (v264 i32) (const.i32 3)) - (let (v265 i32) (band v263 v264)) - (br (block 27 v221 v265 v161 v168))) + (let (v258 i32) (const.i32 2)) + (let (v259 i32) (band v252 v258)) + (let (v260 i1) (neq v259 0)) + (condbr v260 (block 28 v235 v229 v172 v179) (block 30))) (block 30 - (let (v301 i32) (const.i32 -3)) - (let (v302 i32) (band v290 v301)) - (let (v303 u32) (cast v268)) - (let (v304 u32) (mod.unchecked v303 2)) - (assertz v304) - (let (v305 (ptr i32)) (inttoptr v303)) - (store v305 v302) - (let (v306 u32) (cast v266)) - (let (v307 u32) (mod.unchecked v306 2)) - (assertz v307) - (let (v308 (ptr i32)) (inttoptr v306)) - (let (v309 i32) (load v308)) - (let (v310 i32) (const.i32 2)) - (let (v311 i32) (bor v309 v310)) - (br (block 23 v266 v311))) + (let (v261 u32) (bitcast v254)) + (let (v262 u32) (add.checked v261 4)) + (let (v263 u32) (mod.unchecked v262 4)) + (assertz 250 v263) + (let (v264 (ptr i32)) (inttoptr v262)) + (let (v265 i32) (load v264)) + (let (v266 i32) (const.i32 3)) + (let (v267 i32) (band v265 v266)) + (let (v268 i32) (bor v267 v235)) + (let (v269 u32) (bitcast v254)) + (let (v270 u32) (add.checked v269 4)) + (let (v271 u32) (mod.unchecked v270 4)) + (assertz 250 v271) + (let (v272 (ptr i32)) (inttoptr v270)) + (store v272 v268) + (let (v273 u32) (bitcast v235)) + (let (v274 u32) (add.checked v273 4)) + (let (v275 u32) (mod.unchecked v274 4)) + (assertz 250 v275) + (let (v276 (ptr i32)) (inttoptr v274)) + (let (v277 i32) (load v276)) + (let (v278 i32) (const.i32 3)) + (let (v279 i32) (band v277 v278)) + (br (block 28 v235 v279 v172 v179))) (block 31 - (let (v297 u32) (cast v266)) - (let (v298 u32) (mod.unchecked v297 2)) - (assertz v298) - (let (v299 (ptr i32)) (inttoptr v297)) - (let (v300 i32) (load v299)) - (br (block 23 v266 v300))) + (let (v315 i32) (const.i32 -3)) + (let (v316 i32) (band v304 v315)) + (let (v317 u32) (bitcast v282)) + (let (v318 u32) (mod.unchecked v317 4)) + (assertz 250 v318) + (let (v319 (ptr i32)) (inttoptr v317)) + (store v319 v316) + (let (v320 u32) (bitcast v280)) + (let (v321 u32) (mod.unchecked v320 4)) + (assertz 250 v321) + (let (v322 (ptr i32)) (inttoptr v320)) + (let (v323 i32) (load v322)) + (let (v324 i32) (const.i32 2)) + (let (v325 i32) (bor v323 v324)) + (br (block 24 v280 v325))) (block 32 + (let (v311 u32) (bitcast v280)) + (let (v312 u32) (mod.unchecked v311 4)) + (assertz 250 v312) + (let (v313 (ptr i32)) (inttoptr v311)) + (let (v314 i32) (load v313)) + (br (block 24 v280 v314))) + + (block 33 (br (block 5))) ) @@ -580,15 +669,15 @@ (br (block 1 v102))) (block 3 - (let (v10 u32) (cast v0)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (let (v10 u32) (bitcast v0)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr i32)) (inttoptr v10)) (let (v13 i32) (load v12)) - (let (v14 u32) (cast v7)) + (let (v14 u32) (bitcast v7)) (let (v15 u32) (add.checked v14 12)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr i32)) (inttoptr v15)) (store v17 v13) (let (v18 i32) (const.i32 3)) @@ -608,15 +697,15 @@ (br (block 2 v7 v1))) (block 5 (param v88 i32) (param v89 i32) (param v103 i32) - (let (v90 u32) (cast v89)) + (let (v90 u32) (bitcast v89)) (let (v91 u32) (add.checked v90 12)) - (let (v92 u32) (mod.unchecked v91 2)) - (assertz v92) + (let (v92 u32) (mod.unchecked v91 4)) + (assertz 250 v92) (let (v93 (ptr i32)) (inttoptr v91)) (let (v94 i32) (load v93)) - (let (v95 u32) (cast v88)) - (let (v96 u32) (mod.unchecked v95 2)) - (assertz v96) + (let (v95 u32) (bitcast v88)) + (let (v96 u32) (mod.unchecked v95 4)) + (assertz 250 v96) (let (v97 (ptr i32)) (inttoptr v95)) (store v97 v94) (br (block 2 v89 v103))) @@ -642,7 +731,7 @@ (let (v46 u32) (bitcast v44)) (let (v47 u32) (shr.wrapping v45 v46)) (let (v48 i32) (bitcast v47)) - (let (v49 u32) (cast v48)) + (let (v49 u32) (bitcast v48)) (let (v50 i32) (memory.grow v49)) (let (v51 i32) (const.i32 -1)) (let (v52 i1) (neq v50 v51)) @@ -655,22 +744,22 @@ (let (v57 u32) (bitcast v56)) (let (v58 i32) (shl.wrapping v50 v57)) (let (v59 i32) (const.i32 0)) - (let (v60 u32) (cast v58)) + (let (v60 u32) (bitcast v58)) (let (v61 u32) (add.checked v60 4)) - (let (v62 u32) (mod.unchecked v61 2)) - (assertz v62) + (let (v62 u32) (mod.unchecked v61 4)) + (assertz 250 v62) (let (v63 (ptr i32)) (inttoptr v61)) (store v63 v59) - (let (v64 u32) (cast v7)) + (let (v64 u32) (bitcast v7)) (let (v65 u32) (add.checked v64 12)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (let (v68 i32) (load v67)) - (let (v69 u32) (cast v58)) + (let (v69 u32) (bitcast v58)) (let (v70 u32) (add.checked v69 8)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) (let (v72 (ptr i32)) (inttoptr v70)) (store v72 v68) (let (v73 i32) (const.i32 -65536)) @@ -678,15 +767,15 @@ (let (v75 i32) (add.wrapping v58 v74)) (let (v76 i32) (const.i32 2)) (let (v77 i32) (bor v75 v76)) - (let (v78 u32) (cast v58)) - (let (v79 u32) (mod.unchecked v78 2)) - (assertz v79) + (let (v78 u32) (bitcast v58)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) (let (v80 (ptr i32)) (inttoptr v78)) (store v80 v77) - (let (v81 u32) (cast v7)) + (let (v81 u32) (bitcast v7)) (let (v82 u32) (add.checked v81 12)) - (let (v83 u32) (mod.unchecked v82 2)) - (assertz v83) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) (let (v84 (ptr i32)) (inttoptr v82)) (store v84 v58) (let (v85 i32) (const.i32 12)) @@ -721,36 +810,36 @@ (condbr v10 (block 2) (block 4))) (block 4 - (let (v11 u32) (cast v0)) - (let (v12 u32) (mod.unchecked v11 2)) - (assertz v12) + (let (v11 u32) (bitcast v0)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) (let (v13 (ptr i32)) (inttoptr v11)) (let (v14 i32) (load v13)) (let (v15 i32) (const.i32 0)) - (let (v16 u32) (cast v1)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) (let (v18 (ptr i32)) (inttoptr v16)) (store v18 v15) (let (v19 i32) (const.i32 -8)) (let (v20 i32) (add.wrapping v1 v19)) - (let (v21 u32) (cast v20)) - (let (v22 u32) (mod.unchecked v21 2)) - (assertz v22) + (let (v21 u32) (bitcast v20)) + (let (v22 u32) (mod.unchecked v21 4)) + (assertz 250 v22) (let (v23 (ptr i32)) (inttoptr v21)) (let (v24 i32) (load v23)) (let (v25 i32) (const.i32 -2)) (let (v26 i32) (band v24 v25)) - (let (v27 u32) (cast v20)) - (let (v28 u32) (mod.unchecked v27 2)) - (assertz v28) + (let (v27 u32) (bitcast v20)) + (let (v28 u32) (mod.unchecked v27 4)) + (assertz 250 v28) (let (v29 (ptr i32)) (inttoptr v27)) (store v29 v26) (let (v30 i32) (const.i32 4)) (let (v31 i32) (add.wrapping v20 v30)) - (let (v32 u32) (cast v31)) - (let (v33 u32) (mod.unchecked v32 2)) - (assertz v33) + (let (v32 u32) (bitcast v31)) + (let (v33 u32) (mod.unchecked v32 4)) + (assertz 250 v33) (let (v34 (ptr i32)) (inttoptr v32)) (let (v35 i32) (load v34)) (let (v36 i32) (const.i32 -4)) @@ -761,9 +850,9 @@ (condbr v40 (block 10 v24 v1 v20 v14 v0) (block 11))) (block 5 (param v181 i32) (param v187 i32) - (let (v189 u32) (cast v181)) - (let (v190 u32) (mod.unchecked v189 2)) - (assertz v190) + (let (v189 u32) (bitcast v181)) + (let (v190 u32) (mod.unchecked v189 4)) + (assertz 250 v190) (let (v191 (ptr i32)) (inttoptr v189)) (store v191 v187) (br (block 2))) @@ -773,9 +862,9 @@ (param v177 i32) (param v186 i32) (param v188 i32) - (let (v178 u32) (cast v176)) - (let (v179 u32) (mod.unchecked v178 2)) - (assertz v179) + (let (v178 u32) (bitcast v176)) + (let (v179 u32) (mod.unchecked v178 4)) + (assertz 250 v179) (let (v180 (ptr i32)) (inttoptr v178)) (store v180 v177) (br (block 5 v186 v188))) @@ -784,7 +873,7 @@ (br (block 5 v182 v172))) (block 8 - (let (v147 u32) (cast v52)) + (let (v147 u32) (bitcast v52)) (let (v148 (ptr u8)) (inttoptr v147)) (let (v149 u8) (load v148)) (let (v150 i32) (zext v149)) @@ -813,9 +902,9 @@ (condbr v55 (block 6 v154 v175 v185 v165) (block 13))) (block 11 - (let (v41 u32) (cast v37)) - (let (v42 u32) (mod.unchecked v41 2)) - (assertz v42) + (let (v41 u32) (bitcast v37)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) (let (v43 (ptr i32)) (inttoptr v41)) (let (v44 i32) (load v43)) (let (v45 i32) (const.i32 1)) @@ -849,16 +938,16 @@ (param v183 i32) (let (v119 i32) (const.i32 3)) (let (v120 i32) (band v118 v119)) - (let (v121 u32) (cast v117)) - (let (v122 u32) (mod.unchecked v121 2)) - (assertz v122) + (let (v121 u32) (bitcast v117)) + (let (v122 u32) (mod.unchecked v121 4)) + (assertz 250 v122) (let (v123 (ptr i32)) (inttoptr v121)) (store v123 v120) (let (v126 i32) (const.i32 3)) (let (v127 i32) (band v125 v126)) - (let (v128 u32) (cast v124)) - (let (v129 u32) (mod.unchecked v128 2)) - (assertz v129) + (let (v128 u32) (bitcast v124)) + (let (v129 u32) (mod.unchecked v128 4)) + (assertz 250 v129) (let (v130 (ptr i32)) (inttoptr v128)) (store v130 v127) (let (v131 i32) (const.i32 2)) @@ -882,19 +971,19 @@ (let (v101 i32) (const.i32 3)) (let (v102 i32) (band v100 v101)) (let (v103 i32) (bor v99 v102)) - (let (v104 u32) (cast v96)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) + (let (v104 u32) (bitcast v96)) + (let (v105 u32) (mod.unchecked v104 4)) + (assertz 250 v105) (let (v106 (ptr i32)) (inttoptr v104)) (store v106 v103) - (let (v108 u32) (cast v107)) - (let (v109 u32) (mod.unchecked v108 2)) - (assertz v109) + (let (v108 u32) (bitcast v107)) + (let (v109 u32) (mod.unchecked v108 4)) + (assertz 250 v109) (let (v110 (ptr i32)) (inttoptr v108)) (let (v111 i32) (load v110)) - (let (v113 u32) (cast v112)) - (let (v114 u32) (mod.unchecked v113 2)) - (assertz v114) + (let (v113 u32) (bitcast v112)) + (let (v114 u32) (mod.unchecked v113 4)) + (assertz 250 v114) (let (v115 (ptr i32)) (inttoptr v113)) (let (v116 i32) (load v115)) (br (block 15 v107 v111 v112 v116 v137 v174 v184))) @@ -909,29 +998,29 @@ (br (block 16 v37 v26 v44 v31 v20 v37 v14 v0))) (block 19 - (let (v67 u32) (cast v62)) + (let (v67 u32) (bitcast v62)) (let (v68 u32) (add.checked v67 4)) - (let (v69 u32) (mod.unchecked v68 2)) - (assertz v69) + (let (v69 u32) (mod.unchecked v68 4)) + (assertz 250 v69) (let (v70 (ptr i32)) (inttoptr v68)) (let (v71 i32) (load v70)) (let (v72 i32) (const.i32 3)) (let (v73 i32) (band v71 v72)) (let (v74 i32) (bor v73 v37)) - (let (v75 u32) (cast v62)) + (let (v75 u32) (bitcast v62)) (let (v76 u32) (add.checked v75 4)) - (let (v77 u32) (mod.unchecked v76 2)) - (assertz v77) + (let (v77 u32) (mod.unchecked v76 4)) + (assertz 250 v77) (let (v78 (ptr i32)) (inttoptr v76)) (store v78 v74) - (let (v79 u32) (cast v20)) - (let (v80 u32) (mod.unchecked v79 2)) - (assertz v80) + (let (v79 u32) (bitcast v20)) + (let (v80 u32) (mod.unchecked v79 4)) + (assertz 250 v80) (let (v81 (ptr i32)) (inttoptr v79)) (let (v82 i32) (load v81)) - (let (v83 u32) (cast v31)) - (let (v84 u32) (mod.unchecked v83 2)) - (assertz v84) + (let (v83 u32) (bitcast v31)) + (let (v84 u32) (mod.unchecked v83 4)) + (assertz 250 v84) (let (v85 (ptr i32)) (inttoptr v83)) (let (v86 i32) (load v85)) (let (v87 i32) (const.i32 -4)) @@ -942,120 +1031,61 @@ (condbr v91 (block 15 v31 v86 v20 v82 v37 v14 v0) (block 20))) (block 20 - (let (v92 u32) (cast v88)) - (let (v93 u32) (mod.unchecked v92 2)) - (assertz v93) + (let (v92 u32) (bitcast v88)) + (let (v93 u32) (mod.unchecked v92 4)) + (assertz 250 v93) (let (v94 (ptr i32)) (inttoptr v92)) (let (v95 i32) (load v94)) (br (block 16 v88 v82 v95 v31 v20 v37 v14 v0))) (block 21 - (let (v138 u32) (cast v136)) - (let (v139 u32) (mod.unchecked v138 2)) - (assertz v139) + (let (v138 u32) (bitcast v136)) + (let (v139 u32) (mod.unchecked v138 4)) + (assertz 250 v139) (let (v140 (ptr i32)) (inttoptr v138)) (let (v141 i32) (load v140)) (let (v142 i32) (const.i32 2)) (let (v143 i32) (bor v141 v142)) - (let (v144 u32) (cast v136)) - (let (v145 u32) (mod.unchecked v144 2)) - (assertz v145) + (let (v144 u32) (bitcast v136)) + (let (v145 u32) (mod.unchecked v144 4)) + (assertz 250 v145) (let (v146 (ptr i32)) (inttoptr v144)) (store v146 v143) (br (block 7 v173 v183))) (block 22 - (let (v155 u32) (cast v52)) + (let (v155 u32) (bitcast v52)) (let (v156 u32) (add.checked v155 8)) - (let (v157 u32) (mod.unchecked v156 2)) - (assertz v157) + (let (v157 u32) (mod.unchecked v156 4)) + (assertz 250 v157) (let (v158 (ptr i32)) (inttoptr v156)) (let (v159 i32) (load v158)) (let (v160 i32) (const.i32 -4)) (let (v161 i32) (band v159 v160)) - (let (v162 u32) (cast v154)) - (let (v163 u32) (mod.unchecked v162 2)) - (assertz v163) + (let (v162 u32) (bitcast v154)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) (let (v164 (ptr i32)) (inttoptr v162)) (store v164 v161) (let (v166 i32) (const.i32 1)) (let (v167 i32) (bor v165 v166)) - (let (v168 u32) (cast v52)) + (let (v168 u32) (bitcast v52)) (let (v169 u32) (add.checked v168 8)) - (let (v170 u32) (mod.unchecked v169 2)) - (assertz v170) + (let (v170 u32) (mod.unchecked v169 4)) + (assertz 250 v170) (let (v171 (ptr i32)) (inttoptr v169)) (store v171 v167) (br (block 7 v175 v185))) ) - (func (export #wit_bindgen::rt::run_ctors_once) - (block 0 - (let (v0 i32) (const.i32 0)) - (let (v1 u32) (cast v0)) - (let (v2 u32) (add.checked v1 1048581)) - (let (v3 (ptr u8)) (inttoptr v2)) - (let (v4 u8) (load v3)) - (let (v5 i32) (zext v4)) - (let (v6 i1) (neq v5 0)) - (condbr v6 (block 2) (block 3))) - - (block 1 - (ret)) - - (block 2 - (br (block 1))) - - (block 3 - (call #__wasm_call_ctors) - (let (v7 i32) (const.i32 0)) - (let (v8 i32) (const.i32 1)) - (let (v9 u8) (trunc v8)) - (let (v10 u32) (cast v7)) - (let (v11 u32) (add.checked v10 1048581)) - (let (v12 (ptr u8)) (inttoptr v11)) - (store v12 v9) - (br (block 2))) - ) - (func (export #cabi_realloc) (param i32) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) - (let (v5 i1) (neq v1 0)) - (condbr v5 (block 4) (block 5))) + (let (v5 i32) (call #wit_bindgen_rt::cabi_realloc v0 v1 v2 v3)) + (br (block 1 v5))) (block 1 (param v4 i32) (ret v4)) - - (block 2 (param v19 i32) - (br (block 1 v19))) - - (block 3 (param v17 i32) - (let (v18 i1) (neq v17 0)) - (condbr v18 (block 2 v17) (block 7))) - - (block 4 - (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) - (br (block 3 v16))) - - (block 5 - (let (v6 i1) (eq v3 0)) - (let (v7 i32) (zext v6)) - (let (v8 i1) (neq v7 0)) - (condbr v8 (block 2 v2) (block 6))) - - (block 6 - (let (v9 i32) (const.i32 0)) - (let (v10 u32) (cast v9)) - (let (v11 u32) (add.checked v10 1048580)) - (let (v12 (ptr u8)) (inttoptr v11)) - (let (v13 u8) (load v12)) - (let (v14 i32) (zext v13)) - (let (v15 i32) (call #__rust_alloc v3 v2)) - (br (block 3 v15))) - - (block 7 - (unreachable)) ) ) diff --git a/tests/integration/expected/components/add_wasm_component.wat b/tests/integration/expected/components/add_wasm_component.wat index c9358ef5..1034420f 100644 --- a/tests/integration/expected/components/add_wasm_component.wat +++ b/tests/integration/expected/components/add_wasm_component.wat @@ -6,22 +6,16 @@ (type (;3;) (func (param i32 i32 i32) (result i32))) (type (;4;) (func (param i32 i32 i32 i32))) (func $__wasm_call_ctors (;0;) (type 0)) - (func $miden:add-package/add-interface@1.0.0#add (;1;) (type 1) (param i32 i32) (result i32) - call $wit_bindgen::rt::run_ctors_once - local.get 1 - local.get 0 - i32.add - ) - (func $__rust_alloc (;2;) (type 1) (param i32 i32) (result i32) - i32.const 1048576 + (func $__rust_alloc (;1;) (type 1) (param i32 i32) (result i32) + i32.const 1048580 local.get 1 local.get 0 call $::alloc ) - (func $__rust_realloc (;3;) (type 2) (param i32 i32 i32 i32) (result i32) + (func $__rust_realloc (;2;) (type 2) (param i32 i32 i32 i32) (result i32) (local i32) block ;; label = @1 - i32.const 1048576 + i32.const 1048580 local.get 2 local.get 3 call $::alloc @@ -37,7 +31,7 @@ i32.lt_u select memory.copy - i32.const 1048576 + i32.const 1048580 local.get 0 local.get 2 local.get 1 @@ -45,309 +39,361 @@ end local.get 4 ) - (func $wee_alloc::alloc_first_fit (;4;) (type 3) (param i32 i32 i32) (result i32) - (local i32 i32 i32 i32 i32 i32) + (func $miden:add-package/add-interface@1.0.0#add (;3;) (type 1) (param i32 i32) (result i32) + call $wit_bindgen_rt::run_ctors_once + local.get 1 + local.get 0 + i32.add + ) + (func $wit_bindgen_rt::cabi_realloc (;4;) (type 2) (param i32 i32 i32 i32) (result i32) + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + local.get 1 + br_if 0 (;@3;) + local.get 3 + i32.eqz + br_if 2 (;@1;) + i32.const 0 + i32.load8_u offset=1048584 + drop + local.get 3 + local.get 2 + call $__rust_alloc + local.set 2 + br 1 (;@2;) + end + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $__rust_realloc + local.set 2 + end + local.get 2 + br_if 0 (;@1;) + unreachable + unreachable + end + local.get 2 + ) + (func $wit_bindgen_rt::run_ctors_once (;5;) (type 0) + block ;; label = @1 + i32.const 0 + i32.load8_u offset=1048585 + br_if 0 (;@1;) + call $__wasm_call_ctors + i32.const 0 + i32.const 1 + i32.store8 offset=1048585 + end + ) + (func $wee_alloc::alloc_first_fit (;6;) (type 3) (param i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 2 i32.load local.tee 3 - i32.eqz br_if 0 (;@1;) - local.get 1 - i32.const -1 - i32.add - local.set 4 i32.const 0 - local.get 1 - i32.sub - local.set 5 - local.get 0 - i32.const 2 - i32.shl - local.set 6 - loop ;; label = @2 - local.get 3 - i32.const 8 - i32.add - local.set 7 + return + end + local.get 1 + i32.const -1 + i32.add + local.set 4 + i32.const 0 + local.get 1 + i32.sub + local.set 5 + local.get 0 + i32.const 2 + i32.shl + local.set 6 + loop ;; label = @1 + block ;; label = @2 block ;; label = @3 + local.get 3 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) + local.get 3 + i32.const 8 + i32.add + local.set 0 + br 1 (;@2;) + end + loop ;; label = @3 + local.get 3 + local.get 1 + i32.const -2 + i32.and + i32.store offset=8 block ;; label = @4 - local.get 3 - i32.load offset=8 - local.tee 0 + block ;; label = @5 + local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 + i32.and + local.tee 0 + br_if 0 (;@5;) + i32.const 0 + local.set 8 + br 1 (;@4;) + end + i32.const 0 + local.get 0 + local.get 0 + i32.load8_u i32.const 1 i32.and - br_if 0 (;@4;) - local.get 3 - local.set 1 - br 1 (;@3;) + select + local.set 8 end - loop ;; label = @4 - local.get 7 - local.get 0 - i32.const -2 - i32.and - i32.store + block ;; label = @4 local.get 3 - i32.load offset=4 + i32.load + local.tee 1 i32.const -4 i32.and - local.tee 1 - i32.load - local.set 7 - block ;; label = @5 - block ;; label = @6 - block ;; label = @7 - local.get 3 - i32.load - local.tee 8 - i32.const -4 - i32.and - local.tee 0 - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - block ;; label = @7 - local.get 8 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - local.get 0 - local.get 0 - i32.load offset=4 - i32.const 3 - i32.and - local.get 1 - i32.or - i32.store offset=4 - local.get 3 - i32.load - local.set 0 - local.get 3 - i32.load offset=4 - local.tee 7 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 1 (;@5;) - local.get 0 - i32.const -4 - i32.and - local.set 0 - local.get 8 - i32.load - local.set 7 - end - local.get 8 - local.get 7 - i32.const 3 - i32.and - local.get 0 - i32.or - i32.store - local.get 3 - i32.load offset=4 - local.set 7 - local.get 3 - i32.load - local.set 0 - end - local.get 3 - local.get 7 + local.tee 9 + i32.eqz + br_if 0 (;@4;) + local.get 1 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 9 + local.get 9 + i32.load offset=4 i32.const 3 i32.and + local.get 0 + i32.or i32.store offset=4 local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 + i32.and + local.set 0 + local.get 3 + i32.load + local.set 1 + end + block ;; label = @4 + local.get 0 + i32.eqz + br_if 0 (;@4;) + local.get 0 local.get 0 + i32.load i32.const 3 i32.and - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@5;) - local.get 1 - local.get 1 - i32.load - i32.const 2 - i32.or - i32.store - end - local.get 2 local.get 1 + i32.const -4 + i32.and + i32.or i32.store - local.get 1 - i32.const 8 - i32.add + local.get 3 + i32.load offset=4 local.set 7 + local.get 3 + i32.load + local.set 1 + end + local.get 3 + local.get 7 + i32.const 3 + i32.and + i32.store offset=4 + local.get 3 + local.get 1 + i32.const 3 + i32.and + i32.store + block ;; label = @4 local.get 1 - local.set 3 - local.get 1 - i32.load offset=8 - local.tee 0 - i32.const 1 + i32.const 2 i32.and + i32.eqz br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load + i32.const 2 + i32.or + i32.store end + local.get 2 + local.get 8 + i32.store + local.get 8 + local.set 3 + local.get 8 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) end + local.get 8 + i32.const 8 + i32.add + local.set 0 + local.get 8 + local.set 3 + end + block ;; label = @2 + local.get 3 + i32.load + i32.const -4 + i32.and + local.tee 8 + local.get 0 + i32.sub + local.get 6 + i32.lt_u + br_if 0 (;@2;) block ;; label = @3 + block ;; label = @4 + local.get 0 + i32.const 72 + i32.add + local.get 8 + local.get 6 + i32.sub + local.get 5 + i32.and + local.tee 8 + i32.le_u + br_if 0 (;@4;) + local.get 4 + local.get 0 + i32.and + br_if 2 (;@2;) + local.get 2 + local.get 1 + i32.const -4 + i32.and + i32.store + local.get 3 + i32.load + local.set 0 + local.get 3 + local.set 1 + br 1 (;@3;) + end + i32.const 0 + local.set 7 + local.get 8 + i32.const 0 + i32.store + local.get 8 + i32.const -8 + i32.add + local.tee 1 + i64.const 0 + i64.store align=4 local.get 1 + local.get 3 i32.load i32.const -4 i32.and - local.tee 3 - local.get 7 - i32.sub - local.get 6 - i32.lt_u - br_if 0 (;@3;) + i32.store block ;; label = @4 - block ;; label = @5 - local.get 7 - i32.const 72 - i32.add - local.get 3 - local.get 6 - i32.sub - local.get 5 - i32.and - local.tee 3 - i32.le_u - br_if 0 (;@5;) - local.get 4 - local.get 7 - i32.and - br_if 2 (;@3;) - local.get 2 - local.get 0 - i32.const -4 - i32.and - i32.store - local.get 1 - i32.load - local.set 0 - local.get 1 - local.set 3 - br 1 (;@4;) - end - i32.const 0 - local.set 0 - local.get 3 - i32.const 0 - i32.store local.get 3 - i32.const -8 - i32.add - local.tee 3 - i64.const 0 - i64.store align=4 - local.get 3 - local.get 1 i32.load + local.tee 9 i32.const -4 i32.and - i32.store - block ;; label = @5 - local.get 1 - i32.load - local.tee 2 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 0 (;@5;) - local.get 2 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 8 - local.get 8 - i32.load offset=4 - i32.const 3 - i32.and - local.get 3 - i32.or - i32.store offset=4 - local.get 3 - i32.load offset=4 - i32.const 3 - i32.and - local.set 0 - end - local.get 3 - local.get 0 - local.get 1 - i32.or - i32.store offset=4 - local.get 7 - local.get 7 - i32.load - i32.const -2 + local.tee 8 + i32.eqz + br_if 0 (;@4;) + local.get 9 + i32.const 2 i32.and - i32.store - local.get 1 - local.get 1 - i32.load - local.tee 0 + br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load offset=4 i32.const 3 i32.and - local.get 3 + local.get 1 i32.or - local.tee 7 - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 3 - i32.load - local.set 0 - br 1 (;@4;) - end + i32.store offset=4 local.get 1 - local.get 7 - i32.const -3 + i32.load offset=4 + i32.const 3 i32.and - i32.store - local.get 3 - i32.load - i32.const 2 - i32.or - local.set 0 + local.set 7 end + local.get 1 + local.get 7 local.get 3 + i32.or + i32.store offset=4 local.get 0 - i32.const 1 + local.get 0 + i32.load + i32.const -2 + i32.and + i32.store + local.get 3 + local.get 3 + i32.load + local.tee 0 + i32.const 3 + i32.and + local.get 1 i32.or + local.tee 8 i32.store + block ;; label = @4 + local.get 0 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 1 + i32.load + local.set 0 + br 1 (;@3;) + end local.get 3 - i32.const 8 - i32.add - return + local.get 8 + i32.const -3 + i32.and + i32.store + local.get 1 + i32.load + i32.const 2 + i32.or + local.set 0 end - local.get 2 + local.get 1 local.get 0 + i32.const 1 + i32.or i32.store - local.get 0 - local.set 3 - local.get 0 - br_if 0 (;@2;) + local.get 1 + i32.const 8 + i32.add + return end + local.get 2 + local.get 1 + i32.store + local.get 1 + local.set 3 + local.get 1 + br_if 0 (;@1;) end i32.const 0 ) - (func $::alloc (;5;) (type 3) (param i32 i32 i32) (result i32) + (func $::alloc (;7;) (type 3) (param i32 i32 i32) (result i32) (local i32 i32 i32) global.get $__stack_pointer i32.const 16 @@ -451,7 +497,7 @@ global.set $__stack_pointer local.get 2 ) - (func $::dealloc (;6;) (type 4) (param i32 i32 i32 i32) + (func $::dealloc (;8;) (type 4) (param i32 i32 i32 i32) (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 1 @@ -624,55 +670,22 @@ i32.store end ) - (func $wit_bindgen::rt::run_ctors_once (;7;) (type 0) - block ;; label = @1 - i32.const 0 - i32.load8_u offset=1048581 - br_if 0 (;@1;) - call $__wasm_call_ctors - i32.const 0 - i32.const 1 - i32.store8 offset=1048581 - end - ) - (func $cabi_realloc (;8;) (type 2) (param i32 i32 i32 i32) (result i32) - block ;; label = @1 - block ;; label = @2 - block ;; label = @3 - local.get 1 - br_if 0 (;@3;) - local.get 3 - i32.eqz - br_if 2 (;@1;) - i32.const 0 - i32.load8_u offset=1048580 - drop - local.get 3 - local.get 2 - call $__rust_alloc - local.set 2 - br 1 (;@2;) - end - local.get 0 - local.get 1 - local.get 2 - local.get 3 - call $__rust_realloc - local.set 2 - end - local.get 2 - br_if 0 (;@1;) - unreachable - unreachable - end + (func $cabi_realloc (;9;) (type 2) (param i32 i32 i32 i32) (result i32) + local.get 0 + local.get 1 local.get 2 + local.get 3 + call $wit_bindgen_rt::cabi_realloc ) - (table (;0;) 1 1 funcref) + (table (;0;) 2 2 funcref) (memory (;0;) 17) (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) (export "memory" (memory 0)) (export "miden:add-package/add-interface@1.0.0#add" (func $miden:add-package/add-interface@1.0.0#add)) (export "cabi_realloc" (func $cabi_realloc)) + (export "cabi_realloc_wit_bindgen_0_28_0" (func $wit_bindgen_rt::cabi_realloc)) + (elem (;0;) (i32.const 1) func $cabi_realloc) + (data $.rodata (;0;) (i32.const 1048576) "\01\00\00\00") ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) diff --git a/tests/integration/expected/components/inc_wasm_component.hir b/tests/integration/expected/components/inc_wasm_component.hir index 0c28d8e3..a3c5cbb7 100644 --- a/tests/integration/expected/components/inc_wasm_component.hir +++ b/tests/integration/expected/components/inc_wasm_component.hir @@ -4,6 +4,9 @@ ;; Modules (module #inc_wasm_component + ;; Data Segments + (data (mut) (offset 1048576) 0x01000000) + ;; Constants (const (id 0) 0x00100000) @@ -19,20 +22,9 @@ (ret)) ) - (func (export #inc) (param i32) (result i32) - (block 0 (param v0 i32) - (call #wit_bindgen::rt::run_ctors_once) - (let (v2 i32) (const.i32 1)) - (let (v3 i32) (call (#miden:add-package/add-interface@1.0.0 #add) v0 v2)) - (br (block 1 v3))) - - (block 1 (param v1 i32) - (ret v1)) - ) - (func (export #__rust_alloc) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) - (let (v3 i32) (const.i32 1048576)) + (let (v3 i32) (const.i32 1048580)) (let (v4 i32) (call #::alloc v3 v1 v0)) (br (block 1 v4))) @@ -44,7 +36,7 @@ (param i32) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) (let (v5 i32) (const.i32 0)) - (let (v6 i32) (const.i32 1048576)) + (let (v6 i32) (const.i32 1048580)) (let (v7 i32) (call #::alloc v6 v2 v3)) (let (v8 i1) (eq v7 0)) (let (v9 i32) (zext v8)) @@ -64,499 +56,596 @@ (let (v14 i32) (sext v13)) (let (v15 i1) (neq v14 0)) (let (v16 i32) (select v15 v1 v3)) - (let (v17 u32) (cast v7)) + (let (v17 u32) (bitcast v7)) (let (v18 (ptr u8)) (inttoptr v17)) - (let (v19 u32) (cast v0)) + (let (v19 u32) (bitcast v0)) (let (v20 (ptr u8)) (inttoptr v19)) (memcpy v20 v18 v16) - (let (v21 i32) (const.i32 1048576)) + (let (v21 i32) (const.i32 1048580)) (call #::dealloc v21 v0 v2 v1) (br (block 2 v7))) ) + (func (export #inc) (param i32) (result i32) + (block 0 (param v0 i32) + (call #wit_bindgen_rt::run_ctors_once) + (let (v2 i32) (const.i32 1)) + (let (v3 i32) (call (#miden:add-package/add-interface@1.0.0 #add) v0 v2)) + (br (block 1 v3))) + + (block 1 (param v1 i32) + (ret v1)) + ) + + (func (export #wit_bindgen_rt::cabi_realloc) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i1) (neq v1 0)) + (condbr v5 (block 4) (block 5))) + + (block 1 (param v4 i32) + (ret v4)) + + (block 2 (param v19 i32) + (br (block 1 v19))) + + (block 3 (param v17 i32) + (let (v18 i1) (neq v17 0)) + (condbr v18 (block 2 v17) (block 7))) + + (block 4 + (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) + (br (block 3 v16))) + + (block 5 + (let (v6 i1) (eq v3 0)) + (let (v7 i32) (zext v6)) + (let (v8 i1) (neq v7 0)) + (condbr v8 (block 2 v2) (block 6))) + + (block 6 + (let (v9 i32) (const.i32 0)) + (let (v10 u32) (bitcast v9)) + (let (v11 u32) (add.checked v10 1048584)) + (let (v12 (ptr u8)) (inttoptr v11)) + (let (v13 u8) (load v12)) + (let (v14 i32) (zext v13)) + (let (v15 i32) (call #__rust_alloc v3 v2)) + (br (block 3 v15))) + + (block 7 + (unreachable)) + ) + + (func (export #wit_bindgen_rt::run_ctors_once) + (block 0 + (let (v0 i32) (const.i32 0)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (add.checked v1 1048585)) + (let (v3 (ptr u8)) (inttoptr v2)) + (let (v4 u8) (load v3)) + (let (v5 i32) (zext v4)) + (let (v6 i1) (neq v5 0)) + (condbr v6 (block 2) (block 3))) + + (block 1 + (ret)) + + (block 2 + (br (block 1))) + + (block 3 + (call #__wasm_call_ctors) + (let (v7 i32) (const.i32 0)) + (let (v8 i32) (const.i32 1)) + (let (v9 u32) (bitcast v8)) + (let (v10 u8) (trunc v9)) + (let (v11 u32) (bitcast v7)) + (let (v12 u32) (add.checked v11 1048585)) + (let (v13 (ptr u8)) (inttoptr v12)) + (store v13 v10) + (br (block 2))) + ) + (func (export #wee_alloc::alloc_first_fit) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (let (v4 i32) (const.i32 0)) - (let (v5 u32) (cast v2)) - (let (v6 u32) (mod.unchecked v5 2)) - (assertz v6) + (let (v5 u32) (bitcast v2)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) (let (v7 (ptr i32)) (inttoptr v5)) (let (v8 i32) (load v7)) - (let (v9 i1) (eq v8 0)) - (let (v10 i32) (zext v9)) - (let (v11 i1) (neq v10 0)) - (condbr v11 (block 2) (block 3))) + (let (v9 i1) (neq v8 0)) + (condbr v9 (block 2) (block 3))) (block 1 (param v3 i32) (ret v3)) (block 2 - (let (v330 i32) (const.i32 0)) - (br (block 1 v330))) + (let (v11 i32) (const.i32 -1)) + (let (v12 i32) (add.wrapping v1 v11)) + (let (v13 i32) (const.i32 0)) + (let (v14 i32) (sub.wrapping v13 v1)) + (let (v15 i32) (const.i32 2)) + (let (v16 u32) (bitcast v15)) + (let (v17 i32) (shl.wrapping v0 v16)) + (br (block 4 v8 v2 v17 v14 v12))) (block 3 - (let (v12 i32) (const.i32 -1)) - (let (v13 i32) (add.wrapping v1 v12)) - (let (v14 i32) (const.i32 0)) - (let (v15 i32) (sub.wrapping v14 v1)) - (let (v16 i32) (const.i32 2)) - (let (v17 u32) (bitcast v16)) - (let (v18 i32) (shl.wrapping v0 v17)) - (br (block 4 v8 v2 v18 v15 v13))) + (let (v10 i32) (const.i32 0)) + (ret v10)) (block 4 - (param v19 i32) - (param v160 i32) - (param v171 i32) - (param v185 i32) + (param v18 i32) + (param v169 i32) + (param v182 i32) (param v197 i32) - (let (v20 i32) (const.i32 8)) - (let (v21 i32) (add.wrapping v19 v20)) - (let (v22 u32) (cast v19)) - (let (v23 u32) (add.checked v22 8)) - (let (v24 u32) (mod.unchecked v23 2)) - (assertz v24) - (let (v25 (ptr i32)) (inttoptr v23)) - (let (v26 i32) (load v25)) - (let (v27 i32) (const.i32 1)) - (let (v28 i32) (band v26 v27)) - (let (v29 i1) (neq v28 0)) - (condbr v29 (block 7) (block 8))) + (param v210 i32) + (let (v19 u32) (bitcast v18)) + (let (v20 u32) (add.checked v19 8)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) + (let (v22 (ptr i32)) (inttoptr v20)) + (let (v23 i32) (load v22)) + (let (v24 i32) (const.i32 1)) + (let (v25 i32) (band v23 v24)) + (let (v26 i1) (neq v25 0)) + (condbr v26 (block 7) (block 8))) (block 5 - (br (block 2))) + (let (v344 i32) (const.i32 0)) + (br (block 1 v344))) (block 6 - (param v161 i32) - (param v168 i32) - (param v170 i32) - (param v184 i32) + (param v172 i32) + (param v179 i32) + (param v181 i32) (param v196 i32) - (param v204 i32) - (param v205 i32) - (let (v162 u32) (cast v161)) - (let (v163 u32) (mod.unchecked v162 2)) - (assertz v163) - (let (v164 (ptr i32)) (inttoptr v162)) - (let (v165 i32) (load v164)) - (let (v166 i32) (const.i32 -4)) - (let (v167 i32) (band v165 v166)) - (let (v169 i32) (sub.wrapping v167 v168)) - (let (v176 u32) (bitcast v169)) - (let (v177 u32) (bitcast v170)) - (let (v178 i1) (lt v176 v177)) - (let (v179 i32) (sext v178)) - (let (v180 i1) (neq v179 0)) - (condbr v180 (block 21 v204 v205 v170 v184 v196) (block 22))) + (param v209 i32) + (param v218 i32) + (param v219 i32) + (let (v173 u32) (bitcast v172)) + (let (v174 u32) (mod.unchecked v173 4)) + (assertz 250 v174) + (let (v175 (ptr i32)) (inttoptr v173)) + (let (v176 i32) (load v175)) + (let (v177 i32) (const.i32 -4)) + (let (v178 i32) (band v176 v177)) + (let (v180 i32) (sub.wrapping v178 v179)) + (let (v188 u32) (bitcast v180)) + (let (v189 u32) (bitcast v181)) + (let (v190 i1) (lt v188 v189)) + (let (v191 i32) (sext v190)) + (let (v192 i1) (neq v191 0)) + (condbr v192 (block 22 v218 v219 v181 v196 v209) (block 23))) (block 7 - (br (block 9 v21 v26 v19 v160 v171 v185 v197))) + (br (block 9 v18 v23 v169 v182 v197 v210))) (block 8 - (br (block 6 v19 v21 v171 v185 v197 v160 v26))) + (let (v27 i32) (const.i32 8)) + (let (v28 i32) (add.wrapping v18 v27)) + (br (block 6 v18 v28 v182 v197 v210 v169 v23))) (block 9 + (param v29 i32) (param v30 i32) - (param v31 i32) - (param v37 i32) - (param v144 i32) - (param v174 i32) - (param v188 i32) - (param v200 i32) - (let (v32 i32) (const.i32 -2)) - (let (v33 i32) (band v31 v32)) - (let (v34 u32) (cast v30)) - (let (v35 u32) (mod.unchecked v34 2)) - (assertz v35) + (param v156 i32) + (param v187 i32) + (param v202 i32) + (param v215 i32) + (let (v31 i32) (const.i32 -2)) + (let (v32 i32) (band v30 v31)) + (let (v33 u32) (bitcast v29)) + (let (v34 u32) (add.checked v33 8)) + (let (v35 u32) (mod.unchecked v34 4)) + (assertz 250 v35) (let (v36 (ptr i32)) (inttoptr v34)) - (store v36 v33) - (let (v38 u32) (cast v37)) - (let (v39 u32) (add.checked v38 4)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) - (let (v41 (ptr i32)) (inttoptr v39)) - (let (v42 i32) (load v41)) - (let (v43 i32) (const.i32 -4)) - (let (v44 i32) (band v42 v43)) - (let (v45 u32) (cast v44)) - (let (v46 u32) (mod.unchecked v45 2)) - (assertz v46) - (let (v47 (ptr i32)) (inttoptr v45)) - (let (v48 i32) (load v47)) - (let (v49 u32) (cast v37)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr i32)) (inttoptr v49)) - (let (v52 i32) (load v51)) - (let (v53 i32) (const.i32 -4)) - (let (v54 i32) (band v52 v53)) - (let (v55 i1) (neq v54 0)) - (condbr v55 (block 13) (block 14))) + (store v36 v32) + (let (v37 u32) (bitcast v29)) + (let (v38 u32) (add.checked v37 4)) + (let (v39 u32) (mod.unchecked v38 4)) + (assertz 250 v39) + (let (v40 (ptr i32)) (inttoptr v38)) + (let (v41 i32) (load v40)) + (let (v42 i32) (const.i32 -4)) + (let (v43 i32) (band v41 v42)) + (let (v44 i1) (neq v43 0)) + (condbr v44 (block 12) (block 13))) (block 10 - (br (block 6 v146 v151 v172 v186 v198 v142 v156))) + (let (v170 i32) (const.i32 8)) + (let (v171 i32) (add.wrapping v157 v170)) + (br (block 6 v157 v171 v183 v198 v211 v152 v165))) (block 11 - (param v112 i32) - (param v113 i32) - (param v120 i32) - (param v131 i32) - (param v143 i32) - (param v173 i32) - (param v187 i32) - (param v199 i32) - (let (v114 i32) (const.i32 3)) - (let (v115 i32) (band v113 v114)) - (let (v116 u32) (cast v112)) - (let (v117 u32) (add.checked v116 4)) - (let (v118 u32) (mod.unchecked v117 2)) - (assertz v118) - (let (v119 (ptr i32)) (inttoptr v117)) - (store v119 v115) - (let (v121 i32) (const.i32 3)) - (let (v122 i32) (band v120 v121)) - (let (v123 u32) (cast v112)) - (let (v124 u32) (mod.unchecked v123 2)) - (assertz v124) - (let (v125 (ptr i32)) (inttoptr v123)) - (store v125 v122) - (let (v126 i32) (const.i32 2)) - (let (v127 i32) (band v120 v126)) - (let (v128 i1) (eq v127 0)) - (let (v129 i32) (zext v128)) - (let (v130 i1) (neq v129 0)) - (condbr v130 (block 18 v143 v131 v173 v187 v199) (block 19))) + (param v55 i32) + (param v75 i32) + (param v122 i32) + (param v142 i32) + (param v155 i32) + (param v186 i32) + (param v201 i32) + (param v214 i32) + (let (v56 u32) (bitcast v55)) + (let (v57 u32) (mod.unchecked v56 4)) + (assertz 250 v57) + (let (v58 (ptr i32)) (inttoptr v56)) + (let (v59 i32) (load v58)) + (let (v60 i32) (const.i32 -4)) + (let (v61 i32) (band v59 v60)) + (let (v62 i1) (eq v61 0)) + (let (v63 i32) (zext v62)) + (let (v64 i1) (neq v63 0)) + (condbr v64 (block 14 v75 v59 v55 v122 v142 v155 v186 v201 v214) (block 15))) (block 12 - (param v93 i32) - (param v94 i32) - (param v97 i32) - (param v102 i32) - (param v132 i32) - (param v145 i32) - (param v175 i32) - (param v189 i32) - (param v201 i32) - (let (v95 i32) (const.i32 3)) - (let (v96 i32) (band v94 v95)) - (let (v98 i32) (bor v96 v97)) - (let (v99 u32) (cast v93)) - (let (v100 u32) (mod.unchecked v99 2)) - (assertz v100) - (let (v101 (ptr i32)) (inttoptr v99)) - (store v101 v98) - (let (v103 u32) (cast v102)) - (let (v104 u32) (add.checked v103 4)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) - (let (v106 (ptr i32)) (inttoptr v104)) - (let (v107 i32) (load v106)) - (let (v108 u32) (cast v102)) - (let (v109 u32) (mod.unchecked v108 2)) - (assertz v109) - (let (v110 (ptr i32)) (inttoptr v108)) - (let (v111 i32) (load v110)) - (br (block 11 v102 v107 v111 v132 v145 v175 v189 v201))) + (let (v46 i32) (const.i32 0)) + (let (v47 u32) (bitcast v43)) + (let (v48 (ptr u8)) (inttoptr v47)) + (let (v49 u8) (load v48)) + (let (v50 i32) (zext v49)) + (let (v51 i32) (const.i32 1)) + (let (v52 i32) (band v50 v51)) + (let (v53 i1) (neq v52 0)) + (let (v54 i32) (select v53 v46 v43)) + (br (block 11 v29 v43 v41 v54 v156 v187 v202 v215))) (block 13 - (let (v56 i32) (const.i32 2)) - (let (v57 i32) (band v52 v56)) - (let (v58 i1) (eq v57 0)) - (let (v59 i32) (zext v58)) - (let (v60 i1) (neq v59 0)) - (condbr v60 (block 15) (block 16))) + (let (v45 i32) (const.i32 0)) + (br (block 11 v29 v43 v41 v45 v156 v187 v202 v215))) (block 14 - (br (block 12 v44 v48 v54 v37 v44 v144 v174 v188 v200))) + (param v92 i32) + (param v102 i32) + (param v109 i32) + (param v121 i32) + (param v141 i32) + (param v154 i32) + (param v185 i32) + (param v200 i32) + (param v213 i32) + (let (v93 i1) (eq v92 0)) + (let (v94 i32) (zext v93)) + (let (v95 i1) (neq v94 0)) + (condbr v95 (block 17 v109 v121 v102 v141 v154 v185 v200 v213) (block 18))) (block 15 - (let (v61 u32) (cast v54)) - (let (v62 u32) (add.checked v61 4)) - (let (v63 u32) (mod.unchecked v62 2)) - (assertz v63) - (let (v64 (ptr i32)) (inttoptr v62)) - (let (v65 i32) (load v64)) - (let (v66 i32) (const.i32 3)) - (let (v67 i32) (band v65 v66)) - (let (v68 i32) (bor v67 v44)) - (let (v69 u32) (cast v54)) - (let (v70 u32) (add.checked v69 4)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) - (let (v72 (ptr i32)) (inttoptr v70)) - (store v72 v68) - (let (v73 u32) (cast v37)) - (let (v74 u32) (mod.unchecked v73 2)) - (assertz v74) - (let (v75 (ptr i32)) (inttoptr v73)) - (let (v76 i32) (load v75)) - (let (v77 u32) (cast v37)) - (let (v78 u32) (add.checked v77 4)) - (let (v79 u32) (mod.unchecked v78 2)) - (assertz v79) - (let (v80 (ptr i32)) (inttoptr v78)) - (let (v81 i32) (load v80)) - (let (v82 i32) (const.i32 -4)) - (let (v83 i32) (band v81 v82)) - (let (v84 i1) (eq v83 0)) - (let (v85 i32) (zext v84)) - (let (v86 i1) (neq v85 0)) - (condbr v86 (block 11 v37 v81 v76 v44 v144 v174 v188 v200) (block 17))) + (let (v65 i32) (const.i32 2)) + (let (v66 i32) (band v59 v65)) + (let (v67 i1) (neq v66 0)) + (condbr v67 (block 14 v75 v59 v55 v122 v142 v155 v186 v201 v214) (block 16))) (block 16 - (br (block 12 v44 v48 v54 v37 v44 v144 v174 v188 v200))) + (let (v68 u32) (bitcast v61)) + (let (v69 u32) (add.checked v68 4)) + (let (v70 u32) (mod.unchecked v69 4)) + (assertz 250 v70) + (let (v71 (ptr i32)) (inttoptr v69)) + (let (v72 i32) (load v71)) + (let (v73 i32) (const.i32 3)) + (let (v74 i32) (band v72 v73)) + (let (v76 i32) (bor v74 v75)) + (let (v77 u32) (bitcast v61)) + (let (v78 u32) (add.checked v77 4)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) + (let (v80 (ptr i32)) (inttoptr v78)) + (store v80 v76) + (let (v81 u32) (bitcast v55)) + (let (v82 u32) (add.checked v81 4)) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) + (let (v84 (ptr i32)) (inttoptr v82)) + (let (v85 i32) (load v84)) + (let (v86 i32) (const.i32 -4)) + (let (v87 i32) (band v85 v86)) + (let (v88 u32) (bitcast v55)) + (let (v89 u32) (mod.unchecked v88 4)) + (assertz 250 v89) + (let (v90 (ptr i32)) (inttoptr v88)) + (let (v91 i32) (load v90)) + (br (block 14 v87 v91 v55 v85 v142 v155 v186 v201 v214))) (block 17 - (let (v87 i32) (const.i32 -4)) - (let (v88 i32) (band v76 v87)) - (let (v89 u32) (cast v83)) - (let (v90 u32) (mod.unchecked v89 2)) - (assertz v90) - (let (v91 (ptr i32)) (inttoptr v89)) - (let (v92 i32) (load v91)) - (br (block 12 v83 v92 v88 v37 v44 v144 v174 v188 v200))) + (param v119 i32) + (param v120 i32) + (param v129 i32) + (param v140 i32) + (param v153 i32) + (param v184 i32) + (param v199 i32) + (param v212 i32) + (let (v123 i32) (const.i32 3)) + (let (v124 i32) (band v120 v123)) + (let (v125 u32) (bitcast v119)) + (let (v126 u32) (add.checked v125 4)) + (let (v127 u32) (mod.unchecked v126 4)) + (assertz 250 v127) + (let (v128 (ptr i32)) (inttoptr v126)) + (store v128 v124) + (let (v130 i32) (const.i32 3)) + (let (v131 i32) (band v129 v130)) + (let (v132 u32) (bitcast v119)) + (let (v133 u32) (mod.unchecked v132 4)) + (assertz 250 v133) + (let (v134 (ptr i32)) (inttoptr v132)) + (store v134 v131) + (let (v135 i32) (const.i32 2)) + (let (v136 i32) (band v129 v135)) + (let (v137 i1) (eq v136 0)) + (let (v138 i32) (zext v137)) + (let (v139 i1) (neq v138 0)) + (condbr v139 (block 19 v153 v140 v184 v199 v212) (block 20))) (block 18 - (param v142 i32) - (param v146 i32) - (param v172 i32) - (param v186 i32) - (param v198 i32) - (let (v147 u32) (cast v142)) - (let (v148 u32) (mod.unchecked v147 2)) - (assertz v148) - (let (v149 (ptr i32)) (inttoptr v147)) - (store v149 v146) - (let (v150 i32) (const.i32 8)) - (let (v151 i32) (add.wrapping v146 v150)) - (let (v152 u32) (cast v146)) - (let (v153 u32) (add.checked v152 8)) - (let (v154 u32) (mod.unchecked v153 2)) - (assertz v154) - (let (v155 (ptr i32)) (inttoptr v153)) - (let (v156 i32) (load v155)) - (let (v157 i32) (const.i32 1)) - (let (v158 i32) (band v156 v157)) - (let (v159 i1) (neq v158 0)) - (condbr v159 (block 9 v151 v156 v146 v142 v172 v186 v198) (block 20))) + (let (v96 u32) (bitcast v92)) + (let (v97 u32) (mod.unchecked v96 4)) + (assertz 250 v97) + (let (v98 (ptr i32)) (inttoptr v96)) + (let (v99 i32) (load v98)) + (let (v100 i32) (const.i32 3)) + (let (v101 i32) (band v99 v100)) + (let (v103 i32) (const.i32 -4)) + (let (v104 i32) (band v102 v103)) + (let (v105 i32) (bor v101 v104)) + (let (v106 u32) (bitcast v92)) + (let (v107 u32) (mod.unchecked v106 4)) + (assertz 250 v107) + (let (v108 (ptr i32)) (inttoptr v106)) + (store v108 v105) + (let (v110 u32) (bitcast v109)) + (let (v111 u32) (add.checked v110 4)) + (let (v112 u32) (mod.unchecked v111 4)) + (assertz 250 v112) + (let (v113 (ptr i32)) (inttoptr v111)) + (let (v114 i32) (load v113)) + (let (v115 u32) (bitcast v109)) + (let (v116 u32) (mod.unchecked v115 4)) + (assertz 250 v116) + (let (v117 (ptr i32)) (inttoptr v115)) + (let (v118 i32) (load v117)) + (br (block 17 v109 v114 v118 v141 v154 v185 v200 v213))) (block 19 - (let (v133 u32) (cast v131)) - (let (v134 u32) (mod.unchecked v133 2)) - (assertz v134) - (let (v135 (ptr i32)) (inttoptr v133)) - (let (v136 i32) (load v135)) - (let (v137 i32) (const.i32 2)) - (let (v138 i32) (bor v136 v137)) - (let (v139 u32) (cast v131)) - (let (v140 u32) (mod.unchecked v139 2)) - (assertz v140) - (let (v141 (ptr i32)) (inttoptr v139)) - (store v141 v138) - (br (block 18 v143 v131 v173 v187 v199))) + (param v152 i32) + (param v157 i32) + (param v183 i32) + (param v198 i32) + (param v211 i32) + (let (v158 u32) (bitcast v152)) + (let (v159 u32) (mod.unchecked v158 4)) + (assertz 250 v159) + (let (v160 (ptr i32)) (inttoptr v158)) + (store v160 v157) + (let (v161 u32) (bitcast v157)) + (let (v162 u32) (add.checked v161 8)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) + (let (v164 (ptr i32)) (inttoptr v162)) + (let (v165 i32) (load v164)) + (let (v166 i32) (const.i32 1)) + (let (v167 i32) (band v165 v166)) + (let (v168 i1) (neq v167 0)) + (condbr v168 (block 9 v157 v165 v152 v183 v198 v211) (block 21))) (block 20 - (br (block 10))) + (let (v143 u32) (bitcast v140)) + (let (v144 u32) (mod.unchecked v143 4)) + (assertz 250 v144) + (let (v145 (ptr i32)) (inttoptr v143)) + (let (v146 i32) (load v145)) + (let (v147 i32) (const.i32 2)) + (let (v148 i32) (bor v146 v147)) + (let (v149 u32) (bitcast v140)) + (let (v150 u32) (mod.unchecked v149 4)) + (assertz 250 v150) + (let (v151 (ptr i32)) (inttoptr v149)) + (store v151 v148) + (br (block 19 v153 v140 v184 v199 v212))) (block 21 - (param v321 i32) - (param v322 i32) - (param v327 i32) - (param v328 i32) - (param v329 i32) - (let (v323 u32) (cast v321)) - (let (v324 u32) (mod.unchecked v323 2)) - (assertz v324) - (let (v325 (ptr i32)) (inttoptr v323)) - (store v325 v322) - (let (v326 i1) (neq v322 0)) - (condbr v326 (block 4 v322 v321 v327 v328 v329) (block 32))) + (br (block 10))) (block 22 - (let (v181 i32) (const.i32 72)) - (let (v182 i32) (add.wrapping v168 v181)) - (let (v183 i32) (sub.wrapping v167 v170)) - (let (v190 i32) (band v183 v184)) - (let (v191 u32) (bitcast v182)) - (let (v192 u32) (bitcast v190)) - (let (v193 i1) (lte v191 v192)) - (let (v194 i32) (sext v193)) - (let (v195 i1) (neq v194 0)) - (condbr v195 (block 24) (block 25))) - - (block 23 (param v312 i32) (param v313 i32) - (let (v314 i32) (const.i32 1)) - (let (v315 i32) (bor v313 v314)) - (let (v316 u32) (cast v312)) - (let (v317 u32) (mod.unchecked v316 2)) - (assertz v317) - (let (v318 (ptr i32)) (inttoptr v316)) - (store v318 v315) - (let (v319 i32) (const.i32 8)) - (let (v320 i32) (add.wrapping v312 v319)) - (ret v320)) - - (block 24 - (let (v215 i32) (const.i32 0)) - (let (v216 i32) (const.i32 0)) - (let (v217 u32) (cast v190)) - (let (v218 u32) (mod.unchecked v217 2)) - (assertz v218) - (let (v219 (ptr i32)) (inttoptr v217)) - (store v219 v216) - (let (v220 i32) (const.i32 -8)) - (let (v221 i32) (add.wrapping v190 v220)) - (let (v222 i64) (const.i64 0)) - (let (v223 u32) (cast v221)) - (let (v224 u32) (mod.unchecked v223 2)) - (assertz v224) - (let (v225 (ptr i64)) (inttoptr v223)) - (store v225 v222) - (let (v226 u32) (cast v161)) - (let (v227 u32) (mod.unchecked v226 2)) - (assertz v227) - (let (v228 (ptr i32)) (inttoptr v226)) - (let (v229 i32) (load v228)) - (let (v230 i32) (const.i32 -4)) - (let (v231 i32) (band v229 v230)) - (let (v232 u32) (cast v221)) - (let (v233 u32) (mod.unchecked v232 2)) - (assertz v233) - (let (v234 (ptr i32)) (inttoptr v232)) - (store v234 v231) - (let (v235 u32) (cast v161)) - (let (v236 u32) (mod.unchecked v235 2)) - (assertz v236) - (let (v237 (ptr i32)) (inttoptr v235)) - (let (v238 i32) (load v237)) - (let (v239 i32) (const.i32 -4)) - (let (v240 i32) (band v238 v239)) - (let (v241 i1) (eq v240 0)) - (let (v242 i32) (zext v241)) - (let (v243 i1) (neq v242 0)) - (condbr v243 (block 27 v221 v215 v161 v168) (block 28))) + (param v335 i32) + (param v336 i32) + (param v341 i32) + (param v342 i32) + (param v343 i32) + (let (v337 u32) (bitcast v335)) + (let (v338 u32) (mod.unchecked v337 4)) + (assertz 250 v338) + (let (v339 (ptr i32)) (inttoptr v337)) + (store v339 v336) + (let (v340 i1) (neq v336 0)) + (condbr v340 (block 4 v336 v335 v341 v342 v343) (block 33))) + + (block 23 + (let (v193 i32) (const.i32 72)) + (let (v194 i32) (add.wrapping v179 v193)) + (let (v195 i32) (sub.wrapping v178 v181)) + (let (v203 i32) (band v195 v196)) + (let (v204 u32) (bitcast v194)) + (let (v205 u32) (bitcast v203)) + (let (v206 i1) (lte v204 v205)) + (let (v207 i32) (sext v206)) + (let (v208 i1) (neq v207 0)) + (condbr v208 (block 25) (block 26))) + + (block 24 (param v326 i32) (param v327 i32) + (let (v328 i32) (const.i32 1)) + (let (v329 i32) (bor v327 v328)) + (let (v330 u32) (bitcast v326)) + (let (v331 u32) (mod.unchecked v330 4)) + (assertz 250 v331) + (let (v332 (ptr i32)) (inttoptr v330)) + (store v332 v329) + (let (v333 i32) (const.i32 8)) + (let (v334 i32) (add.wrapping v326 v333)) + (ret v334)) (block 25 - (let (v202 i32) (band v196 v168)) - (let (v203 i1) (neq v202 0)) - (condbr v203 (block 21 v204 v205 v170 v184 v196) (block 26))) + (let (v229 i32) (const.i32 0)) + (let (v230 i32) (const.i32 0)) + (let (v231 u32) (bitcast v203)) + (let (v232 u32) (mod.unchecked v231 4)) + (assertz 250 v232) + (let (v233 (ptr i32)) (inttoptr v231)) + (store v233 v230) + (let (v234 i32) (const.i32 -8)) + (let (v235 i32) (add.wrapping v203 v234)) + (let (v236 i64) (const.i64 0)) + (let (v237 u32) (bitcast v235)) + (let (v238 u32) (mod.unchecked v237 4)) + (assertz 250 v238) + (let (v239 (ptr i64)) (inttoptr v237)) + (store v239 v236) + (let (v240 u32) (bitcast v172)) + (let (v241 u32) (mod.unchecked v240 4)) + (assertz 250 v241) + (let (v242 (ptr i32)) (inttoptr v240)) + (let (v243 i32) (load v242)) + (let (v244 i32) (const.i32 -4)) + (let (v245 i32) (band v243 v244)) + (let (v246 u32) (bitcast v235)) + (let (v247 u32) (mod.unchecked v246 4)) + (assertz 250 v247) + (let (v248 (ptr i32)) (inttoptr v246)) + (store v248 v245) + (let (v249 u32) (bitcast v172)) + (let (v250 u32) (mod.unchecked v249 4)) + (assertz 250 v250) + (let (v251 (ptr i32)) (inttoptr v249)) + (let (v252 i32) (load v251)) + (let (v253 i32) (const.i32 -4)) + (let (v254 i32) (band v252 v253)) + (let (v255 i1) (eq v254 0)) + (let (v256 i32) (zext v255)) + (let (v257 i1) (neq v256 0)) + (condbr v257 (block 28 v235 v229 v172 v179) (block 29))) (block 26 - (let (v206 i32) (const.i32 -4)) - (let (v207 i32) (band v205 v206)) - (let (v208 u32) (cast v204)) - (let (v209 u32) (mod.unchecked v208 2)) - (assertz v209) - (let (v210 (ptr i32)) (inttoptr v208)) - (store v210 v207) - (let (v211 u32) (cast v161)) - (let (v212 u32) (mod.unchecked v211 2)) - (assertz v212) - (let (v213 (ptr i32)) (inttoptr v211)) - (let (v214 i32) (load v213)) - (br (block 23 v161 v214))) + (let (v216 i32) (band v209 v179)) + (let (v217 i1) (neq v216 0)) + (condbr v217 (block 22 v218 v219 v181 v196 v209) (block 27))) (block 27 - (param v266 i32) - (param v267 i32) - (param v268 i32) - (param v274 i32) - (let (v269 i32) (bor v267 v268)) - (let (v270 u32) (cast v266)) - (let (v271 u32) (add.checked v270 4)) - (let (v272 u32) (mod.unchecked v271 2)) - (assertz v272) - (let (v273 (ptr i32)) (inttoptr v271)) - (store v273 v269) - (let (v275 u32) (cast v274)) - (let (v276 u32) (mod.unchecked v275 2)) - (assertz v276) - (let (v277 (ptr i32)) (inttoptr v275)) - (let (v278 i32) (load v277)) - (let (v279 i32) (const.i32 -2)) - (let (v280 i32) (band v278 v279)) - (let (v281 u32) (cast v274)) - (let (v282 u32) (mod.unchecked v281 2)) - (assertz v282) - (let (v283 (ptr i32)) (inttoptr v281)) - (store v283 v280) - (let (v284 u32) (cast v268)) - (let (v285 u32) (mod.unchecked v284 2)) - (assertz v285) - (let (v286 (ptr i32)) (inttoptr v284)) - (let (v287 i32) (load v286)) - (let (v288 i32) (const.i32 3)) - (let (v289 i32) (band v287 v288)) - (let (v290 i32) (bor v289 v266)) - (let (v291 u32) (cast v268)) - (let (v292 u32) (mod.unchecked v291 2)) - (assertz v292) - (let (v293 (ptr i32)) (inttoptr v291)) - (store v293 v290) - (let (v294 i32) (const.i32 2)) - (let (v295 i32) (band v287 v294)) - (let (v296 i1) (neq v295 0)) - (condbr v296 (block 30) (block 31))) + (let (v220 i32) (const.i32 -4)) + (let (v221 i32) (band v219 v220)) + (let (v222 u32) (bitcast v218)) + (let (v223 u32) (mod.unchecked v222 4)) + (assertz 250 v223) + (let (v224 (ptr i32)) (inttoptr v222)) + (store v224 v221) + (let (v225 u32) (bitcast v172)) + (let (v226 u32) (mod.unchecked v225 4)) + (assertz 250 v226) + (let (v227 (ptr i32)) (inttoptr v225)) + (let (v228 i32) (load v227)) + (br (block 24 v172 v228))) (block 28 - (let (v244 i32) (const.i32 2)) - (let (v245 i32) (band v238 v244)) - (let (v246 i1) (neq v245 0)) - (condbr v246 (block 27 v221 v215 v161 v168) (block 29))) + (param v280 i32) + (param v281 i32) + (param v282 i32) + (param v288 i32) + (let (v283 i32) (bor v281 v282)) + (let (v284 u32) (bitcast v280)) + (let (v285 u32) (add.checked v284 4)) + (let (v286 u32) (mod.unchecked v285 4)) + (assertz 250 v286) + (let (v287 (ptr i32)) (inttoptr v285)) + (store v287 v283) + (let (v289 u32) (bitcast v288)) + (let (v290 u32) (mod.unchecked v289 4)) + (assertz 250 v290) + (let (v291 (ptr i32)) (inttoptr v289)) + (let (v292 i32) (load v291)) + (let (v293 i32) (const.i32 -2)) + (let (v294 i32) (band v292 v293)) + (let (v295 u32) (bitcast v288)) + (let (v296 u32) (mod.unchecked v295 4)) + (assertz 250 v296) + (let (v297 (ptr i32)) (inttoptr v295)) + (store v297 v294) + (let (v298 u32) (bitcast v282)) + (let (v299 u32) (mod.unchecked v298 4)) + (assertz 250 v299) + (let (v300 (ptr i32)) (inttoptr v298)) + (let (v301 i32) (load v300)) + (let (v302 i32) (const.i32 3)) + (let (v303 i32) (band v301 v302)) + (let (v304 i32) (bor v303 v280)) + (let (v305 u32) (bitcast v282)) + (let (v306 u32) (mod.unchecked v305 4)) + (assertz 250 v306) + (let (v307 (ptr i32)) (inttoptr v305)) + (store v307 v304) + (let (v308 i32) (const.i32 2)) + (let (v309 i32) (band v301 v308)) + (let (v310 i1) (neq v309 0)) + (condbr v310 (block 31) (block 32))) (block 29 - (let (v247 u32) (cast v240)) - (let (v248 u32) (add.checked v247 4)) - (let (v249 u32) (mod.unchecked v248 2)) - (assertz v249) - (let (v250 (ptr i32)) (inttoptr v248)) - (let (v251 i32) (load v250)) - (let (v252 i32) (const.i32 3)) - (let (v253 i32) (band v251 v252)) - (let (v254 i32) (bor v253 v221)) - (let (v255 u32) (cast v240)) - (let (v256 u32) (add.checked v255 4)) - (let (v257 u32) (mod.unchecked v256 2)) - (assertz v257) - (let (v258 (ptr i32)) (inttoptr v256)) - (store v258 v254) - (let (v259 u32) (cast v221)) - (let (v260 u32) (add.checked v259 4)) - (let (v261 u32) (mod.unchecked v260 2)) - (assertz v261) - (let (v262 (ptr i32)) (inttoptr v260)) - (let (v263 i32) (load v262)) - (let (v264 i32) (const.i32 3)) - (let (v265 i32) (band v263 v264)) - (br (block 27 v221 v265 v161 v168))) + (let (v258 i32) (const.i32 2)) + (let (v259 i32) (band v252 v258)) + (let (v260 i1) (neq v259 0)) + (condbr v260 (block 28 v235 v229 v172 v179) (block 30))) (block 30 - (let (v301 i32) (const.i32 -3)) - (let (v302 i32) (band v290 v301)) - (let (v303 u32) (cast v268)) - (let (v304 u32) (mod.unchecked v303 2)) - (assertz v304) - (let (v305 (ptr i32)) (inttoptr v303)) - (store v305 v302) - (let (v306 u32) (cast v266)) - (let (v307 u32) (mod.unchecked v306 2)) - (assertz v307) - (let (v308 (ptr i32)) (inttoptr v306)) - (let (v309 i32) (load v308)) - (let (v310 i32) (const.i32 2)) - (let (v311 i32) (bor v309 v310)) - (br (block 23 v266 v311))) + (let (v261 u32) (bitcast v254)) + (let (v262 u32) (add.checked v261 4)) + (let (v263 u32) (mod.unchecked v262 4)) + (assertz 250 v263) + (let (v264 (ptr i32)) (inttoptr v262)) + (let (v265 i32) (load v264)) + (let (v266 i32) (const.i32 3)) + (let (v267 i32) (band v265 v266)) + (let (v268 i32) (bor v267 v235)) + (let (v269 u32) (bitcast v254)) + (let (v270 u32) (add.checked v269 4)) + (let (v271 u32) (mod.unchecked v270 4)) + (assertz 250 v271) + (let (v272 (ptr i32)) (inttoptr v270)) + (store v272 v268) + (let (v273 u32) (bitcast v235)) + (let (v274 u32) (add.checked v273 4)) + (let (v275 u32) (mod.unchecked v274 4)) + (assertz 250 v275) + (let (v276 (ptr i32)) (inttoptr v274)) + (let (v277 i32) (load v276)) + (let (v278 i32) (const.i32 3)) + (let (v279 i32) (band v277 v278)) + (br (block 28 v235 v279 v172 v179))) (block 31 - (let (v297 u32) (cast v266)) - (let (v298 u32) (mod.unchecked v297 2)) - (assertz v298) - (let (v299 (ptr i32)) (inttoptr v297)) - (let (v300 i32) (load v299)) - (br (block 23 v266 v300))) + (let (v315 i32) (const.i32 -3)) + (let (v316 i32) (band v304 v315)) + (let (v317 u32) (bitcast v282)) + (let (v318 u32) (mod.unchecked v317 4)) + (assertz 250 v318) + (let (v319 (ptr i32)) (inttoptr v317)) + (store v319 v316) + (let (v320 u32) (bitcast v280)) + (let (v321 u32) (mod.unchecked v320 4)) + (assertz 250 v321) + (let (v322 (ptr i32)) (inttoptr v320)) + (let (v323 i32) (load v322)) + (let (v324 i32) (const.i32 2)) + (let (v325 i32) (bor v323 v324)) + (br (block 24 v280 v325))) (block 32 + (let (v311 u32) (bitcast v280)) + (let (v312 u32) (mod.unchecked v311 4)) + (assertz 250 v312) + (let (v313 (ptr i32)) (inttoptr v311)) + (let (v314 i32) (load v313)) + (br (block 24 v280 v314))) + + (block 33 (br (block 5))) ) @@ -583,15 +672,15 @@ (br (block 1 v102))) (block 3 - (let (v10 u32) (cast v0)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (let (v10 u32) (bitcast v0)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr i32)) (inttoptr v10)) (let (v13 i32) (load v12)) - (let (v14 u32) (cast v7)) + (let (v14 u32) (bitcast v7)) (let (v15 u32) (add.checked v14 12)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr i32)) (inttoptr v15)) (store v17 v13) (let (v18 i32) (const.i32 3)) @@ -611,15 +700,15 @@ (br (block 2 v7 v1))) (block 5 (param v88 i32) (param v89 i32) (param v103 i32) - (let (v90 u32) (cast v89)) + (let (v90 u32) (bitcast v89)) (let (v91 u32) (add.checked v90 12)) - (let (v92 u32) (mod.unchecked v91 2)) - (assertz v92) + (let (v92 u32) (mod.unchecked v91 4)) + (assertz 250 v92) (let (v93 (ptr i32)) (inttoptr v91)) (let (v94 i32) (load v93)) - (let (v95 u32) (cast v88)) - (let (v96 u32) (mod.unchecked v95 2)) - (assertz v96) + (let (v95 u32) (bitcast v88)) + (let (v96 u32) (mod.unchecked v95 4)) + (assertz 250 v96) (let (v97 (ptr i32)) (inttoptr v95)) (store v97 v94) (br (block 2 v89 v103))) @@ -645,7 +734,7 @@ (let (v46 u32) (bitcast v44)) (let (v47 u32) (shr.wrapping v45 v46)) (let (v48 i32) (bitcast v47)) - (let (v49 u32) (cast v48)) + (let (v49 u32) (bitcast v48)) (let (v50 i32) (memory.grow v49)) (let (v51 i32) (const.i32 -1)) (let (v52 i1) (neq v50 v51)) @@ -658,22 +747,22 @@ (let (v57 u32) (bitcast v56)) (let (v58 i32) (shl.wrapping v50 v57)) (let (v59 i32) (const.i32 0)) - (let (v60 u32) (cast v58)) + (let (v60 u32) (bitcast v58)) (let (v61 u32) (add.checked v60 4)) - (let (v62 u32) (mod.unchecked v61 2)) - (assertz v62) + (let (v62 u32) (mod.unchecked v61 4)) + (assertz 250 v62) (let (v63 (ptr i32)) (inttoptr v61)) (store v63 v59) - (let (v64 u32) (cast v7)) + (let (v64 u32) (bitcast v7)) (let (v65 u32) (add.checked v64 12)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (let (v68 i32) (load v67)) - (let (v69 u32) (cast v58)) + (let (v69 u32) (bitcast v58)) (let (v70 u32) (add.checked v69 8)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) (let (v72 (ptr i32)) (inttoptr v70)) (store v72 v68) (let (v73 i32) (const.i32 -65536)) @@ -681,15 +770,15 @@ (let (v75 i32) (add.wrapping v58 v74)) (let (v76 i32) (const.i32 2)) (let (v77 i32) (bor v75 v76)) - (let (v78 u32) (cast v58)) - (let (v79 u32) (mod.unchecked v78 2)) - (assertz v79) + (let (v78 u32) (bitcast v58)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) (let (v80 (ptr i32)) (inttoptr v78)) (store v80 v77) - (let (v81 u32) (cast v7)) + (let (v81 u32) (bitcast v7)) (let (v82 u32) (add.checked v81 12)) - (let (v83 u32) (mod.unchecked v82 2)) - (assertz v83) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) (let (v84 (ptr i32)) (inttoptr v82)) (store v84 v58) (let (v85 i32) (const.i32 12)) @@ -724,36 +813,36 @@ (condbr v10 (block 2) (block 4))) (block 4 - (let (v11 u32) (cast v0)) - (let (v12 u32) (mod.unchecked v11 2)) - (assertz v12) + (let (v11 u32) (bitcast v0)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) (let (v13 (ptr i32)) (inttoptr v11)) (let (v14 i32) (load v13)) (let (v15 i32) (const.i32 0)) - (let (v16 u32) (cast v1)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) (let (v18 (ptr i32)) (inttoptr v16)) (store v18 v15) (let (v19 i32) (const.i32 -8)) (let (v20 i32) (add.wrapping v1 v19)) - (let (v21 u32) (cast v20)) - (let (v22 u32) (mod.unchecked v21 2)) - (assertz v22) + (let (v21 u32) (bitcast v20)) + (let (v22 u32) (mod.unchecked v21 4)) + (assertz 250 v22) (let (v23 (ptr i32)) (inttoptr v21)) (let (v24 i32) (load v23)) (let (v25 i32) (const.i32 -2)) (let (v26 i32) (band v24 v25)) - (let (v27 u32) (cast v20)) - (let (v28 u32) (mod.unchecked v27 2)) - (assertz v28) + (let (v27 u32) (bitcast v20)) + (let (v28 u32) (mod.unchecked v27 4)) + (assertz 250 v28) (let (v29 (ptr i32)) (inttoptr v27)) (store v29 v26) (let (v30 i32) (const.i32 4)) (let (v31 i32) (add.wrapping v20 v30)) - (let (v32 u32) (cast v31)) - (let (v33 u32) (mod.unchecked v32 2)) - (assertz v33) + (let (v32 u32) (bitcast v31)) + (let (v33 u32) (mod.unchecked v32 4)) + (assertz 250 v33) (let (v34 (ptr i32)) (inttoptr v32)) (let (v35 i32) (load v34)) (let (v36 i32) (const.i32 -4)) @@ -764,9 +853,9 @@ (condbr v40 (block 10 v24 v1 v20 v14 v0) (block 11))) (block 5 (param v181 i32) (param v187 i32) - (let (v189 u32) (cast v181)) - (let (v190 u32) (mod.unchecked v189 2)) - (assertz v190) + (let (v189 u32) (bitcast v181)) + (let (v190 u32) (mod.unchecked v189 4)) + (assertz 250 v190) (let (v191 (ptr i32)) (inttoptr v189)) (store v191 v187) (br (block 2))) @@ -776,9 +865,9 @@ (param v177 i32) (param v186 i32) (param v188 i32) - (let (v178 u32) (cast v176)) - (let (v179 u32) (mod.unchecked v178 2)) - (assertz v179) + (let (v178 u32) (bitcast v176)) + (let (v179 u32) (mod.unchecked v178 4)) + (assertz 250 v179) (let (v180 (ptr i32)) (inttoptr v178)) (store v180 v177) (br (block 5 v186 v188))) @@ -787,7 +876,7 @@ (br (block 5 v182 v172))) (block 8 - (let (v147 u32) (cast v52)) + (let (v147 u32) (bitcast v52)) (let (v148 (ptr u8)) (inttoptr v147)) (let (v149 u8) (load v148)) (let (v150 i32) (zext v149)) @@ -816,9 +905,9 @@ (condbr v55 (block 6 v154 v175 v185 v165) (block 13))) (block 11 - (let (v41 u32) (cast v37)) - (let (v42 u32) (mod.unchecked v41 2)) - (assertz v42) + (let (v41 u32) (bitcast v37)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) (let (v43 (ptr i32)) (inttoptr v41)) (let (v44 i32) (load v43)) (let (v45 i32) (const.i32 1)) @@ -852,16 +941,16 @@ (param v183 i32) (let (v119 i32) (const.i32 3)) (let (v120 i32) (band v118 v119)) - (let (v121 u32) (cast v117)) - (let (v122 u32) (mod.unchecked v121 2)) - (assertz v122) + (let (v121 u32) (bitcast v117)) + (let (v122 u32) (mod.unchecked v121 4)) + (assertz 250 v122) (let (v123 (ptr i32)) (inttoptr v121)) (store v123 v120) (let (v126 i32) (const.i32 3)) (let (v127 i32) (band v125 v126)) - (let (v128 u32) (cast v124)) - (let (v129 u32) (mod.unchecked v128 2)) - (assertz v129) + (let (v128 u32) (bitcast v124)) + (let (v129 u32) (mod.unchecked v128 4)) + (assertz 250 v129) (let (v130 (ptr i32)) (inttoptr v128)) (store v130 v127) (let (v131 i32) (const.i32 2)) @@ -885,19 +974,19 @@ (let (v101 i32) (const.i32 3)) (let (v102 i32) (band v100 v101)) (let (v103 i32) (bor v99 v102)) - (let (v104 u32) (cast v96)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) + (let (v104 u32) (bitcast v96)) + (let (v105 u32) (mod.unchecked v104 4)) + (assertz 250 v105) (let (v106 (ptr i32)) (inttoptr v104)) (store v106 v103) - (let (v108 u32) (cast v107)) - (let (v109 u32) (mod.unchecked v108 2)) - (assertz v109) + (let (v108 u32) (bitcast v107)) + (let (v109 u32) (mod.unchecked v108 4)) + (assertz 250 v109) (let (v110 (ptr i32)) (inttoptr v108)) (let (v111 i32) (load v110)) - (let (v113 u32) (cast v112)) - (let (v114 u32) (mod.unchecked v113 2)) - (assertz v114) + (let (v113 u32) (bitcast v112)) + (let (v114 u32) (mod.unchecked v113 4)) + (assertz 250 v114) (let (v115 (ptr i32)) (inttoptr v113)) (let (v116 i32) (load v115)) (br (block 15 v107 v111 v112 v116 v137 v174 v184))) @@ -912,29 +1001,29 @@ (br (block 16 v37 v26 v44 v31 v20 v37 v14 v0))) (block 19 - (let (v67 u32) (cast v62)) + (let (v67 u32) (bitcast v62)) (let (v68 u32) (add.checked v67 4)) - (let (v69 u32) (mod.unchecked v68 2)) - (assertz v69) + (let (v69 u32) (mod.unchecked v68 4)) + (assertz 250 v69) (let (v70 (ptr i32)) (inttoptr v68)) (let (v71 i32) (load v70)) (let (v72 i32) (const.i32 3)) (let (v73 i32) (band v71 v72)) (let (v74 i32) (bor v73 v37)) - (let (v75 u32) (cast v62)) + (let (v75 u32) (bitcast v62)) (let (v76 u32) (add.checked v75 4)) - (let (v77 u32) (mod.unchecked v76 2)) - (assertz v77) + (let (v77 u32) (mod.unchecked v76 4)) + (assertz 250 v77) (let (v78 (ptr i32)) (inttoptr v76)) (store v78 v74) - (let (v79 u32) (cast v20)) - (let (v80 u32) (mod.unchecked v79 2)) - (assertz v80) + (let (v79 u32) (bitcast v20)) + (let (v80 u32) (mod.unchecked v79 4)) + (assertz 250 v80) (let (v81 (ptr i32)) (inttoptr v79)) (let (v82 i32) (load v81)) - (let (v83 u32) (cast v31)) - (let (v84 u32) (mod.unchecked v83 2)) - (assertz v84) + (let (v83 u32) (bitcast v31)) + (let (v84 u32) (mod.unchecked v83 4)) + (assertz 250 v84) (let (v85 (ptr i32)) (inttoptr v83)) (let (v86 i32) (load v85)) (let (v87 i32) (const.i32 -4)) @@ -945,120 +1034,61 @@ (condbr v91 (block 15 v31 v86 v20 v82 v37 v14 v0) (block 20))) (block 20 - (let (v92 u32) (cast v88)) - (let (v93 u32) (mod.unchecked v92 2)) - (assertz v93) + (let (v92 u32) (bitcast v88)) + (let (v93 u32) (mod.unchecked v92 4)) + (assertz 250 v93) (let (v94 (ptr i32)) (inttoptr v92)) (let (v95 i32) (load v94)) (br (block 16 v88 v82 v95 v31 v20 v37 v14 v0))) (block 21 - (let (v138 u32) (cast v136)) - (let (v139 u32) (mod.unchecked v138 2)) - (assertz v139) + (let (v138 u32) (bitcast v136)) + (let (v139 u32) (mod.unchecked v138 4)) + (assertz 250 v139) (let (v140 (ptr i32)) (inttoptr v138)) (let (v141 i32) (load v140)) (let (v142 i32) (const.i32 2)) (let (v143 i32) (bor v141 v142)) - (let (v144 u32) (cast v136)) - (let (v145 u32) (mod.unchecked v144 2)) - (assertz v145) + (let (v144 u32) (bitcast v136)) + (let (v145 u32) (mod.unchecked v144 4)) + (assertz 250 v145) (let (v146 (ptr i32)) (inttoptr v144)) (store v146 v143) (br (block 7 v173 v183))) (block 22 - (let (v155 u32) (cast v52)) + (let (v155 u32) (bitcast v52)) (let (v156 u32) (add.checked v155 8)) - (let (v157 u32) (mod.unchecked v156 2)) - (assertz v157) + (let (v157 u32) (mod.unchecked v156 4)) + (assertz 250 v157) (let (v158 (ptr i32)) (inttoptr v156)) (let (v159 i32) (load v158)) (let (v160 i32) (const.i32 -4)) (let (v161 i32) (band v159 v160)) - (let (v162 u32) (cast v154)) - (let (v163 u32) (mod.unchecked v162 2)) - (assertz v163) + (let (v162 u32) (bitcast v154)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) (let (v164 (ptr i32)) (inttoptr v162)) (store v164 v161) (let (v166 i32) (const.i32 1)) (let (v167 i32) (bor v165 v166)) - (let (v168 u32) (cast v52)) + (let (v168 u32) (bitcast v52)) (let (v169 u32) (add.checked v168 8)) - (let (v170 u32) (mod.unchecked v169 2)) - (assertz v170) + (let (v170 u32) (mod.unchecked v169 4)) + (assertz 250 v170) (let (v171 (ptr i32)) (inttoptr v169)) (store v171 v167) (br (block 7 v175 v185))) ) - (func (export #wit_bindgen::rt::run_ctors_once) - (block 0 - (let (v0 i32) (const.i32 0)) - (let (v1 u32) (cast v0)) - (let (v2 u32) (add.checked v1 1048581)) - (let (v3 (ptr u8)) (inttoptr v2)) - (let (v4 u8) (load v3)) - (let (v5 i32) (zext v4)) - (let (v6 i1) (neq v5 0)) - (condbr v6 (block 2) (block 3))) - - (block 1 - (ret)) - - (block 2 - (br (block 1))) - - (block 3 - (call #__wasm_call_ctors) - (let (v7 i32) (const.i32 0)) - (let (v8 i32) (const.i32 1)) - (let (v9 u8) (trunc v8)) - (let (v10 u32) (cast v7)) - (let (v11 u32) (add.checked v10 1048581)) - (let (v12 (ptr u8)) (inttoptr v11)) - (store v12 v9) - (br (block 2))) - ) - (func (export #cabi_realloc) (param i32) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) - (let (v5 i1) (neq v1 0)) - (condbr v5 (block 4) (block 5))) + (let (v5 i32) (call #wit_bindgen_rt::cabi_realloc v0 v1 v2 v3)) + (br (block 1 v5))) (block 1 (param v4 i32) (ret v4)) - - (block 2 (param v19 i32) - (br (block 1 v19))) - - (block 3 (param v17 i32) - (let (v18 i1) (neq v17 0)) - (condbr v18 (block 2 v17) (block 7))) - - (block 4 - (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) - (br (block 3 v16))) - - (block 5 - (let (v6 i1) (eq v3 0)) - (let (v7 i32) (zext v6)) - (let (v8 i1) (neq v7 0)) - (condbr v8 (block 2 v2) (block 6))) - - (block 6 - (let (v9 i32) (const.i32 0)) - (let (v10 u32) (cast v9)) - (let (v11 u32) (add.checked v10 1048580)) - (let (v12 (ptr u8)) (inttoptr v11)) - (let (v13 u8) (load v12)) - (let (v14 i32) (zext v13)) - (let (v15 i32) (call #__rust_alloc v3 v2)) - (br (block 3 v15))) - - (block 7 - (unreachable)) ) ;; Imports diff --git a/tests/integration/expected/components/inc_wasm_component.wat b/tests/integration/expected/components/inc_wasm_component.wat index 48063992..bd5c00de 100644 --- a/tests/integration/expected/components/inc_wasm_component.wat +++ b/tests/integration/expected/components/inc_wasm_component.wat @@ -9,28 +9,22 @@ (core module (;0;) (type (;0;) (func (param i32 i32) (result i32))) (type (;1;) (func)) - (type (;2;) (func (param i32) (result i32))) - (type (;3;) (func (param i32 i32 i32 i32) (result i32))) + (type (;2;) (func (param i32 i32 i32 i32) (result i32))) + (type (;3;) (func (param i32) (result i32))) (type (;4;) (func (param i32 i32 i32) (result i32))) (type (;5;) (func (param i32 i32 i32 i32))) (import "miden:add-package/add-interface@1.0.0" "add" (func $inc_wasm_component::bindings::miden::add_package::add_interface::add::wit_import (;0;) (type 0))) (func $__wasm_call_ctors (;1;) (type 1)) - (func $inc (;2;) (type 2) (param i32) (result i32) - call $wit_bindgen::rt::run_ctors_once - local.get 0 - i32.const 1 - call $inc_wasm_component::bindings::miden::add_package::add_interface::add::wit_import - ) - (func $__rust_alloc (;3;) (type 0) (param i32 i32) (result i32) - i32.const 1048576 + (func $__rust_alloc (;2;) (type 0) (param i32 i32) (result i32) + i32.const 1048580 local.get 1 local.get 0 call $::alloc ) - (func $__rust_realloc (;4;) (type 3) (param i32 i32 i32 i32) (result i32) + (func $__rust_realloc (;3;) (type 2) (param i32 i32 i32 i32) (result i32) (local i32) block ;; label = @1 - i32.const 1048576 + i32.const 1048580 local.get 2 local.get 3 call $::alloc @@ -46,7 +40,7 @@ i32.lt_u select memory.copy - i32.const 1048576 + i32.const 1048580 local.get 0 local.get 2 local.get 1 @@ -54,309 +48,361 @@ end local.get 4 ) - (func $wee_alloc::alloc_first_fit (;5;) (type 4) (param i32 i32 i32) (result i32) - (local i32 i32 i32 i32 i32 i32) + (func $inc (;4;) (type 3) (param i32) (result i32) + call $wit_bindgen_rt::run_ctors_once + local.get 0 + i32.const 1 + call $inc_wasm_component::bindings::miden::add_package::add_interface::add::wit_import + ) + (func $wit_bindgen_rt::cabi_realloc (;5;) (type 2) (param i32 i32 i32 i32) (result i32) + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + local.get 1 + br_if 0 (;@3;) + local.get 3 + i32.eqz + br_if 2 (;@1;) + i32.const 0 + i32.load8_u offset=1048584 + drop + local.get 3 + local.get 2 + call $__rust_alloc + local.set 2 + br 1 (;@2;) + end + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $__rust_realloc + local.set 2 + end + local.get 2 + br_if 0 (;@1;) + unreachable + unreachable + end + local.get 2 + ) + (func $wit_bindgen_rt::run_ctors_once (;6;) (type 1) + block ;; label = @1 + i32.const 0 + i32.load8_u offset=1048585 + br_if 0 (;@1;) + call $__wasm_call_ctors + i32.const 0 + i32.const 1 + i32.store8 offset=1048585 + end + ) + (func $wee_alloc::alloc_first_fit (;7;) (type 4) (param i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 2 i32.load local.tee 3 - i32.eqz br_if 0 (;@1;) - local.get 1 - i32.const -1 - i32.add - local.set 4 i32.const 0 - local.get 1 - i32.sub - local.set 5 - local.get 0 - i32.const 2 - i32.shl - local.set 6 - loop ;; label = @2 - local.get 3 - i32.const 8 - i32.add - local.set 7 + return + end + local.get 1 + i32.const -1 + i32.add + local.set 4 + i32.const 0 + local.get 1 + i32.sub + local.set 5 + local.get 0 + i32.const 2 + i32.shl + local.set 6 + loop ;; label = @1 + block ;; label = @2 block ;; label = @3 + local.get 3 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) + local.get 3 + i32.const 8 + i32.add + local.set 0 + br 1 (;@2;) + end + loop ;; label = @3 + local.get 3 + local.get 1 + i32.const -2 + i32.and + i32.store offset=8 block ;; label = @4 - local.get 3 - i32.load offset=8 - local.tee 0 + block ;; label = @5 + local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 + i32.and + local.tee 0 + br_if 0 (;@5;) + i32.const 0 + local.set 8 + br 1 (;@4;) + end + i32.const 0 + local.get 0 + local.get 0 + i32.load8_u i32.const 1 i32.and - br_if 0 (;@4;) - local.get 3 - local.set 1 - br 1 (;@3;) + select + local.set 8 end - loop ;; label = @4 - local.get 7 - local.get 0 - i32.const -2 - i32.and - i32.store + block ;; label = @4 local.get 3 - i32.load offset=4 + i32.load + local.tee 1 i32.const -4 i32.and - local.tee 1 - i32.load - local.set 7 - block ;; label = @5 - block ;; label = @6 - block ;; label = @7 - local.get 3 - i32.load - local.tee 8 - i32.const -4 - i32.and - local.tee 0 - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - block ;; label = @7 - local.get 8 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - local.get 0 - local.get 0 - i32.load offset=4 - i32.const 3 - i32.and - local.get 1 - i32.or - i32.store offset=4 - local.get 3 - i32.load - local.set 0 - local.get 3 - i32.load offset=4 - local.tee 7 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 1 (;@5;) - local.get 0 - i32.const -4 - i32.and - local.set 0 - local.get 8 - i32.load - local.set 7 - end - local.get 8 - local.get 7 - i32.const 3 - i32.and - local.get 0 - i32.or - i32.store - local.get 3 - i32.load offset=4 - local.set 7 - local.get 3 - i32.load - local.set 0 - end - local.get 3 - local.get 7 + local.tee 9 + i32.eqz + br_if 0 (;@4;) + local.get 1 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 9 + local.get 9 + i32.load offset=4 i32.const 3 i32.and + local.get 0 + i32.or i32.store offset=4 local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 + i32.and + local.set 0 + local.get 3 + i32.load + local.set 1 + end + block ;; label = @4 + local.get 0 + i32.eqz + br_if 0 (;@4;) + local.get 0 local.get 0 + i32.load i32.const 3 i32.and - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@5;) - local.get 1 - local.get 1 - i32.load - i32.const 2 - i32.or - i32.store - end - local.get 2 local.get 1 + i32.const -4 + i32.and + i32.or i32.store - local.get 1 - i32.const 8 - i32.add + local.get 3 + i32.load offset=4 local.set 7 + local.get 3 + i32.load + local.set 1 + end + local.get 3 + local.get 7 + i32.const 3 + i32.and + i32.store offset=4 + local.get 3 + local.get 1 + i32.const 3 + i32.and + i32.store + block ;; label = @4 local.get 1 - local.set 3 - local.get 1 - i32.load offset=8 - local.tee 0 - i32.const 1 + i32.const 2 i32.and + i32.eqz br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load + i32.const 2 + i32.or + i32.store end + local.get 2 + local.get 8 + i32.store + local.get 8 + local.set 3 + local.get 8 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) end + local.get 8 + i32.const 8 + i32.add + local.set 0 + local.get 8 + local.set 3 + end + block ;; label = @2 + local.get 3 + i32.load + i32.const -4 + i32.and + local.tee 8 + local.get 0 + i32.sub + local.get 6 + i32.lt_u + br_if 0 (;@2;) block ;; label = @3 + block ;; label = @4 + local.get 0 + i32.const 72 + i32.add + local.get 8 + local.get 6 + i32.sub + local.get 5 + i32.and + local.tee 8 + i32.le_u + br_if 0 (;@4;) + local.get 4 + local.get 0 + i32.and + br_if 2 (;@2;) + local.get 2 + local.get 1 + i32.const -4 + i32.and + i32.store + local.get 3 + i32.load + local.set 0 + local.get 3 + local.set 1 + br 1 (;@3;) + end + i32.const 0 + local.set 7 + local.get 8 + i32.const 0 + i32.store + local.get 8 + i32.const -8 + i32.add + local.tee 1 + i64.const 0 + i64.store align=4 local.get 1 + local.get 3 i32.load i32.const -4 i32.and - local.tee 3 - local.get 7 - i32.sub - local.get 6 - i32.lt_u - br_if 0 (;@3;) + i32.store block ;; label = @4 - block ;; label = @5 - local.get 7 - i32.const 72 - i32.add - local.get 3 - local.get 6 - i32.sub - local.get 5 - i32.and - local.tee 3 - i32.le_u - br_if 0 (;@5;) - local.get 4 - local.get 7 - i32.and - br_if 2 (;@3;) - local.get 2 - local.get 0 - i32.const -4 - i32.and - i32.store - local.get 1 - i32.load - local.set 0 - local.get 1 - local.set 3 - br 1 (;@4;) - end - i32.const 0 - local.set 0 - local.get 3 - i32.const 0 - i32.store local.get 3 - i32.const -8 - i32.add - local.tee 3 - i64.const 0 - i64.store align=4 - local.get 3 - local.get 1 i32.load + local.tee 9 i32.const -4 i32.and - i32.store - block ;; label = @5 - local.get 1 - i32.load - local.tee 2 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 0 (;@5;) - local.get 2 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 8 - local.get 8 - i32.load offset=4 - i32.const 3 - i32.and - local.get 3 - i32.or - i32.store offset=4 - local.get 3 - i32.load offset=4 - i32.const 3 - i32.and - local.set 0 - end - local.get 3 - local.get 0 - local.get 1 - i32.or - i32.store offset=4 - local.get 7 - local.get 7 - i32.load - i32.const -2 + local.tee 8 + i32.eqz + br_if 0 (;@4;) + local.get 9 + i32.const 2 i32.and - i32.store - local.get 1 - local.get 1 - i32.load - local.tee 0 + br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load offset=4 i32.const 3 i32.and - local.get 3 + local.get 1 i32.or - local.tee 7 - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 3 - i32.load - local.set 0 - br 1 (;@4;) - end + i32.store offset=4 local.get 1 - local.get 7 - i32.const -3 + i32.load offset=4 + i32.const 3 i32.and - i32.store - local.get 3 - i32.load - i32.const 2 - i32.or - local.set 0 + local.set 7 end + local.get 1 + local.get 7 local.get 3 + i32.or + i32.store offset=4 local.get 0 - i32.const 1 + local.get 0 + i32.load + i32.const -2 + i32.and + i32.store + local.get 3 + local.get 3 + i32.load + local.tee 0 + i32.const 3 + i32.and + local.get 1 i32.or + local.tee 8 i32.store + block ;; label = @4 + local.get 0 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 1 + i32.load + local.set 0 + br 1 (;@3;) + end local.get 3 - i32.const 8 - i32.add - return + local.get 8 + i32.const -3 + i32.and + i32.store + local.get 1 + i32.load + i32.const 2 + i32.or + local.set 0 end - local.get 2 + local.get 1 local.get 0 + i32.const 1 + i32.or i32.store - local.get 0 - local.set 3 - local.get 0 - br_if 0 (;@2;) + local.get 1 + i32.const 8 + i32.add + return end + local.get 2 + local.get 1 + i32.store + local.get 1 + local.set 3 + local.get 1 + br_if 0 (;@1;) end i32.const 0 ) - (func $::alloc (;6;) (type 4) (param i32 i32 i32) (result i32) + (func $::alloc (;8;) (type 4) (param i32 i32 i32) (result i32) (local i32 i32 i32) global.get $__stack_pointer i32.const 16 @@ -460,7 +506,7 @@ global.set $__stack_pointer local.get 2 ) - (func $::dealloc (;7;) (type 5) (param i32 i32 i32 i32) + (func $::dealloc (;9;) (type 5) (param i32 i32 i32 i32) (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 1 @@ -633,55 +679,22 @@ i32.store end ) - (func $wit_bindgen::rt::run_ctors_once (;8;) (type 1) - block ;; label = @1 - i32.const 0 - i32.load8_u offset=1048581 - br_if 0 (;@1;) - call $__wasm_call_ctors - i32.const 0 - i32.const 1 - i32.store8 offset=1048581 - end - ) - (func $cabi_realloc (;9;) (type 3) (param i32 i32 i32 i32) (result i32) - block ;; label = @1 - block ;; label = @2 - block ;; label = @3 - local.get 1 - br_if 0 (;@3;) - local.get 3 - i32.eqz - br_if 2 (;@1;) - i32.const 0 - i32.load8_u offset=1048580 - drop - local.get 3 - local.get 2 - call $__rust_alloc - local.set 2 - br 1 (;@2;) - end - local.get 0 - local.get 1 - local.get 2 - local.get 3 - call $__rust_realloc - local.set 2 - end - local.get 2 - br_if 0 (;@1;) - unreachable - unreachable - end + (func $cabi_realloc (;10;) (type 2) (param i32 i32 i32 i32) (result i32) + local.get 0 + local.get 1 local.get 2 + local.get 3 + call $wit_bindgen_rt::cabi_realloc ) - (table (;0;) 1 1 funcref) + (table (;0;) 2 2 funcref) (memory (;0;) 17) (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) (export "memory" (memory 0)) (export "inc" (func $inc)) (export "cabi_realloc" (func $cabi_realloc)) + (export "cabi_realloc_wit_bindgen_0_28_0" (func $wit_bindgen_rt::cabi_realloc)) + (elem (;0;) (i32.const 1) func $cabi_realloc) + (data $.rodata (;0;) (i32.const 1048576) "\01\00\00\00") ) (alias export 0 "add" (func (;0;))) (core func (;0;) (canon lower (func 0))) diff --git a/tests/integration/expected/core::cmp::max_u8_u8.hir b/tests/integration/expected/core::cmp::max_u8_u8.hir index 8467940d..64b11cf7 100644 --- a/tests/integration/expected/core::cmp::max_u8_u8.hir +++ b/tests/integration/expected/core::cmp::max_u8_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_f7759899e22f63a0775d28e9c7ef5ab9f7c15f0ecdcbb147be10732d60d6a670 + (module #test_rust_935eefccf7923abc0816d374d2bb37d5149355aa52de63cf39d63cd92d8ee41d ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/core::cmp::max_u8_u8.masm b/tests/integration/expected/core::cmp::max_u8_u8.masm index fb821155..ed725025 100644 --- a/tests/integration/expected/core::cmp::max_u8_u8.masm +++ b/tests/integration/expected/core::cmp::max_u8_u8.masm @@ -1,4 +1,4 @@ -# mod test_rust_f7759899e22f63a0775d28e9c7ef5ab9f7c15f0ecdcbb147be10732d60d6a670 +# mod test_rust_935eefccf7923abc0816d374d2bb37d5149355aa52de63cf39d63cd92d8ee41d export.entrypoint dup.0 @@ -15,6 +15,3 @@ export.entrypoint end -begin - exec.::test_rust_f7759899e22f63a0775d28e9c7ef5ab9f7c15f0ecdcbb147be10732d60d6a670::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/core::cmp::max_u8_u8.wat b/tests/integration/expected/core::cmp::max_u8_u8.wat index 00173e92..02d34a40 100644 --- a/tests/integration/expected/core::cmp::max_u8_u8.wat +++ b/tests/integration/expected/core::cmp::max_u8_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_f7759899e22f63a0775d28e9c7ef5ab9f7c15f0ecdcbb147be10732d60d6a670.wasm +(module $test_rust_935eefccf7923abc0816d374d2bb37d5149355aa52de63cf39d63cd92d8ee41d.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/core::cmp::min_i32_i32.hir b/tests/integration/expected/core::cmp::min_i32_i32.hir index eafa3174..4a5433d2 100644 --- a/tests/integration/expected/core::cmp::min_i32_i32.hir +++ b/tests/integration/expected/core::cmp::min_i32_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_3600450f3e72a1f743c6e31ae5af681197ee981ecfeb91d43b6e974ed76234f5 + (module #test_rust_7ebd625ebc756910f700d1547e5bf4cc2c32a85181b0c8e5a3b9113c39335db7 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/core::cmp::min_i32_i32.masm b/tests/integration/expected/core::cmp::min_i32_i32.masm index 4b0f0376..34375c73 100644 --- a/tests/integration/expected/core::cmp::min_i32_i32.masm +++ b/tests/integration/expected/core::cmp::min_i32_i32.masm @@ -1,4 +1,4 @@ -# mod test_rust_3600450f3e72a1f743c6e31ae5af681197ee981ecfeb91d43b6e974ed76234f5 +# mod test_rust_7ebd625ebc756910f700d1547e5bf4cc2c32a85181b0c8e5a3b9113c39335db7 export.entrypoint dup.0 @@ -15,6 +15,3 @@ export.entrypoint end -begin - exec.::test_rust_3600450f3e72a1f743c6e31ae5af681197ee981ecfeb91d43b6e974ed76234f5::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/core::cmp::min_i32_i32.wat b/tests/integration/expected/core::cmp::min_i32_i32.wat index 0e9e5669..1b862cf7 100644 --- a/tests/integration/expected/core::cmp::min_i32_i32.wat +++ b/tests/integration/expected/core::cmp::min_i32_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_3600450f3e72a1f743c6e31ae5af681197ee981ecfeb91d43b6e974ed76234f5.wasm +(module $test_rust_7ebd625ebc756910f700d1547e5bf4cc2c32a85181b0c8e5a3b9113c39335db7.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/core::cmp::min_u32_u32.hir b/tests/integration/expected/core::cmp::min_u32_u32.hir index 8a9a7712..4744072e 100644 --- a/tests/integration/expected/core::cmp::min_u32_u32.hir +++ b/tests/integration/expected/core::cmp::min_u32_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_aab7d18351a2f72394a3b7378df684e6f669a8fdda46072c5953ab949ae4658f + (module #test_rust_2130eab9306152f86439d4a8076319464ef487ebdd8d670f656fd73a23036fa5 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/core::cmp::min_u32_u32.masm b/tests/integration/expected/core::cmp::min_u32_u32.masm index e98df4fe..9102295e 100644 --- a/tests/integration/expected/core::cmp::min_u32_u32.masm +++ b/tests/integration/expected/core::cmp::min_u32_u32.masm @@ -1,4 +1,4 @@ -# mod test_rust_aab7d18351a2f72394a3b7378df684e6f669a8fdda46072c5953ab949ae4658f +# mod test_rust_2130eab9306152f86439d4a8076319464ef487ebdd8d670f656fd73a23036fa5 export.entrypoint dup.0 @@ -15,6 +15,3 @@ export.entrypoint end -begin - exec.::test_rust_aab7d18351a2f72394a3b7378df684e6f669a8fdda46072c5953ab949ae4658f::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/core::cmp::min_u32_u32.wat b/tests/integration/expected/core::cmp::min_u32_u32.wat index c9d5edfa..98f49967 100644 --- a/tests/integration/expected/core::cmp::min_u32_u32.wat +++ b/tests/integration/expected/core::cmp::min_u32_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_aab7d18351a2f72394a3b7378df684e6f669a8fdda46072c5953ab949ae4658f.wasm +(module $test_rust_2130eab9306152f86439d4a8076319464ef487ebdd8d670f656fd73a23036fa5.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/core::cmp::min_u8_u8.hir b/tests/integration/expected/core::cmp::min_u8_u8.hir index ea9c6a6e..52a221f0 100644 --- a/tests/integration/expected/core::cmp::min_u8_u8.hir +++ b/tests/integration/expected/core::cmp::min_u8_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_f375c28fa7a7eb4019af213b30f4b291d676b6561c189149b599ddca30004add + (module #test_rust_3114079be600d0d34a20fede92f64baec1c63ae3845306ba2de322513ab73343 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/core::cmp::min_u8_u8.masm b/tests/integration/expected/core::cmp::min_u8_u8.masm index 7d48daf1..9535c941 100644 --- a/tests/integration/expected/core::cmp::min_u8_u8.masm +++ b/tests/integration/expected/core::cmp::min_u8_u8.masm @@ -1,4 +1,4 @@ -# mod test_rust_f375c28fa7a7eb4019af213b30f4b291d676b6561c189149b599ddca30004add +# mod test_rust_3114079be600d0d34a20fede92f64baec1c63ae3845306ba2de322513ab73343 export.entrypoint dup.0 @@ -15,6 +15,3 @@ export.entrypoint end -begin - exec.::test_rust_f375c28fa7a7eb4019af213b30f4b291d676b6561c189149b599ddca30004add::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/core::cmp::min_u8_u8.wat b/tests/integration/expected/core::cmp::min_u8_u8.wat index 8dfea840..dfdef52a 100644 --- a/tests/integration/expected/core::cmp::min_u8_u8.wat +++ b/tests/integration/expected/core::cmp::min_u8_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_f375c28fa7a7eb4019af213b30f4b291d676b6561c189149b599ddca30004add.wasm +(module $test_rust_3114079be600d0d34a20fede92f64baec1c63ae3845306ba2de322513ab73343.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/div_felt.masm b/tests/integration/expected/div_felt.masm index 417796af..feef22ba 100644 --- a/tests/integration/expected/div_felt.masm +++ b/tests/integration/expected/div_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::div_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_felt.masm b/tests/integration/expected/eq_felt.masm index fd0637c1..bab4b735 100644 --- a/tests/integration/expected/eq_felt.masm +++ b/tests/integration/expected/eq_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::eq_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_i16.hir b/tests/integration/expected/eq_i16.hir index 57bd5208..bc617caa 100644 --- a/tests/integration/expected/eq_i16.hir +++ b/tests/integration/expected/eq_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_d3eecc0932c0745000688bf699bae5c588052144cdbc0bc7c4ab37c3cc14cd7b + (module #test_rust_2f29f68fe27c60920a7ea2ddd41d7b6f088aaca71b06fe98e8543c00277965f4 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/eq_i16.masm b/tests/integration/expected/eq_i16.masm index ccfdf5d0..b1d06722 100644 --- a/tests/integration/expected/eq_i16.masm +++ b/tests/integration/expected/eq_i16.masm @@ -1,10 +1,7 @@ -# mod test_rust_d3eecc0932c0745000688bf699bae5c588052144cdbc0bc7c4ab37c3cc14cd7b +# mod test_rust_2f29f68fe27c60920a7ea2ddd41d7b6f088aaca71b06fe98e8543c00277965f4 export.entrypoint swap.1 eq end -begin - exec.::test_rust_d3eecc0932c0745000688bf699bae5c588052144cdbc0bc7c4ab37c3cc14cd7b::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_i16.wat b/tests/integration/expected/eq_i16.wat index 08ddc735..35a6a6a9 100644 --- a/tests/integration/expected/eq_i16.wat +++ b/tests/integration/expected/eq_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_d3eecc0932c0745000688bf699bae5c588052144cdbc0bc7c4ab37c3cc14cd7b.wasm +(module $test_rust_2f29f68fe27c60920a7ea2ddd41d7b6f088aaca71b06fe98e8543c00277965f4.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/eq_i32.hir b/tests/integration/expected/eq_i32.hir index 8dfa3d23..7afb9581 100644 --- a/tests/integration/expected/eq_i32.hir +++ b/tests/integration/expected/eq_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_535f5a5a2d649df390220a07008a31a5226ad26f1cf27c7849e47c754842ec03 + (module #test_rust_c28e7308ea5f55f6d78b6647cb9c8148700b1b42240fe9786556265f83fcda8f ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/eq_i32.masm b/tests/integration/expected/eq_i32.masm index 2d403e85..b1f094ef 100644 --- a/tests/integration/expected/eq_i32.masm +++ b/tests/integration/expected/eq_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_535f5a5a2d649df390220a07008a31a5226ad26f1cf27c7849e47c754842ec03 +# mod test_rust_c28e7308ea5f55f6d78b6647cb9c8148700b1b42240fe9786556265f83fcda8f export.entrypoint swap.1 eq end -begin - exec.::test_rust_535f5a5a2d649df390220a07008a31a5226ad26f1cf27c7849e47c754842ec03::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_i32.wat b/tests/integration/expected/eq_i32.wat index ecbd03e1..7084d5fd 100644 --- a/tests/integration/expected/eq_i32.wat +++ b/tests/integration/expected/eq_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_535f5a5a2d649df390220a07008a31a5226ad26f1cf27c7849e47c754842ec03.wasm +(module $test_rust_c28e7308ea5f55f6d78b6647cb9c8148700b1b42240fe9786556265f83fcda8f.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/eq_i64.hir b/tests/integration/expected/eq_i64.hir index c83365c6..c30ce7c0 100644 --- a/tests/integration/expected/eq_i64.hir +++ b/tests/integration/expected/eq_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c0b1348123b7005d1a5f70ddc2c38a3fc27e908c3656adebf0eae90cdbc8959d + (module #test_rust_335e8b9940dcc6e8b83a7c4b5c50143e223e0f4e2cb269440866b6f3f4a0d5a6 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/eq_i64.masm b/tests/integration/expected/eq_i64.masm index 5a63e279..c2ec4286 100644 --- a/tests/integration/expected/eq_i64.masm +++ b/tests/integration/expected/eq_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_c0b1348123b7005d1a5f70ddc2c38a3fc27e908c3656adebf0eae90cdbc8959d +# mod test_rust_335e8b9940dcc6e8b83a7c4b5c50143e223e0f4e2cb269440866b6f3f4a0d5a6 export.entrypoint movdn.3 movdn.3 exec.::std::math::u64::eq end -begin - exec.::test_rust_c0b1348123b7005d1a5f70ddc2c38a3fc27e908c3656adebf0eae90cdbc8959d::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_i64.wat b/tests/integration/expected/eq_i64.wat index 84956c72..7b9db9cd 100644 --- a/tests/integration/expected/eq_i64.wat +++ b/tests/integration/expected/eq_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_c0b1348123b7005d1a5f70ddc2c38a3fc27e908c3656adebf0eae90cdbc8959d.wasm +(module $test_rust_335e8b9940dcc6e8b83a7c4b5c50143e223e0f4e2cb269440866b6f3f4a0d5a6.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/eq_i8.hir b/tests/integration/expected/eq_i8.hir index ff8eea07..a9a6df2d 100644 --- a/tests/integration/expected/eq_i8.hir +++ b/tests/integration/expected/eq_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_58aae86db503f25d519c45a178d348c9fa62ad89779c3a7beb32041962ccbd8a + (module #test_rust_d32112fcece9e923c53ef0e7e530a320a042569dc27aa4e4b1682a14933a630b ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/eq_i8.masm b/tests/integration/expected/eq_i8.masm index 9ac1d29f..606f7ed5 100644 --- a/tests/integration/expected/eq_i8.masm +++ b/tests/integration/expected/eq_i8.masm @@ -1,10 +1,7 @@ -# mod test_rust_58aae86db503f25d519c45a178d348c9fa62ad89779c3a7beb32041962ccbd8a +# mod test_rust_d32112fcece9e923c53ef0e7e530a320a042569dc27aa4e4b1682a14933a630b export.entrypoint swap.1 eq end -begin - exec.::test_rust_58aae86db503f25d519c45a178d348c9fa62ad89779c3a7beb32041962ccbd8a::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_i8.wat b/tests/integration/expected/eq_i8.wat index 8627fe4b..f472fc8a 100644 --- a/tests/integration/expected/eq_i8.wat +++ b/tests/integration/expected/eq_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_58aae86db503f25d519c45a178d348c9fa62ad89779c3a7beb32041962ccbd8a.wasm +(module $test_rust_d32112fcece9e923c53ef0e7e530a320a042569dc27aa4e4b1682a14933a630b.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/eq_u16.hir b/tests/integration/expected/eq_u16.hir index 1dba8335..7c2a5c3e 100644 --- a/tests/integration/expected/eq_u16.hir +++ b/tests/integration/expected/eq_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_bf5c0ccc66e1188e428efe75b85c06065d267030df6b1c191b2ee935ea27795d + (module #test_rust_8fbd508d452e6be7333d34171256184bccb35bce63b4c4b324a68dfa222b449a ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/eq_u16.masm b/tests/integration/expected/eq_u16.masm index 0c7a9cbb..3418a8a4 100644 --- a/tests/integration/expected/eq_u16.masm +++ b/tests/integration/expected/eq_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_bf5c0ccc66e1188e428efe75b85c06065d267030df6b1c191b2ee935ea27795d +# mod test_rust_8fbd508d452e6be7333d34171256184bccb35bce63b4c4b324a68dfa222b449a export.entrypoint swap.1 eq end -begin - exec.::test_rust_bf5c0ccc66e1188e428efe75b85c06065d267030df6b1c191b2ee935ea27795d::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_u16.wat b/tests/integration/expected/eq_u16.wat index 90fa5b02..9da87152 100644 --- a/tests/integration/expected/eq_u16.wat +++ b/tests/integration/expected/eq_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_bf5c0ccc66e1188e428efe75b85c06065d267030df6b1c191b2ee935ea27795d.wasm +(module $test_rust_8fbd508d452e6be7333d34171256184bccb35bce63b4c4b324a68dfa222b449a.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/eq_u32.hir b/tests/integration/expected/eq_u32.hir index 67ef862b..1946c509 100644 --- a/tests/integration/expected/eq_u32.hir +++ b/tests/integration/expected/eq_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_8fb01b80f31505a22343d7c26e3474f1160b5bf9f9048fa61561f108ac0be95e + (module #test_rust_1ec18cd34684e347de59c6bcc66cf36588b84dc96b83ce847862c54131b73875 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/eq_u32.masm b/tests/integration/expected/eq_u32.masm index 2085e42d..114e0239 100644 --- a/tests/integration/expected/eq_u32.masm +++ b/tests/integration/expected/eq_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_8fb01b80f31505a22343d7c26e3474f1160b5bf9f9048fa61561f108ac0be95e +# mod test_rust_1ec18cd34684e347de59c6bcc66cf36588b84dc96b83ce847862c54131b73875 export.entrypoint swap.1 eq end -begin - exec.::test_rust_8fb01b80f31505a22343d7c26e3474f1160b5bf9f9048fa61561f108ac0be95e::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_u32.wat b/tests/integration/expected/eq_u32.wat index be065654..d462760d 100644 --- a/tests/integration/expected/eq_u32.wat +++ b/tests/integration/expected/eq_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_8fb01b80f31505a22343d7c26e3474f1160b5bf9f9048fa61561f108ac0be95e.wasm +(module $test_rust_1ec18cd34684e347de59c6bcc66cf36588b84dc96b83ce847862c54131b73875.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/eq_u64.hir b/tests/integration/expected/eq_u64.hir index b1dde716..d1c253ae 100644 --- a/tests/integration/expected/eq_u64.hir +++ b/tests/integration/expected/eq_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_23a27398cbfb7447cb610e7b877565f4e43d633b55f98504051b93381d40740f + (module #test_rust_d3f2b162735bb643456cb68c71d6be70cdb8e4267c7ef3c9cdef6fcfdb77c2cc ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/eq_u64.masm b/tests/integration/expected/eq_u64.masm index 83b39b9b..80c8f8d6 100644 --- a/tests/integration/expected/eq_u64.masm +++ b/tests/integration/expected/eq_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_23a27398cbfb7447cb610e7b877565f4e43d633b55f98504051b93381d40740f +# mod test_rust_d3f2b162735bb643456cb68c71d6be70cdb8e4267c7ef3c9cdef6fcfdb77c2cc export.entrypoint movdn.3 movdn.3 exec.::std::math::u64::eq end -begin - exec.::test_rust_23a27398cbfb7447cb610e7b877565f4e43d633b55f98504051b93381d40740f::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_u64.wat b/tests/integration/expected/eq_u64.wat index 6c4b5c73..54b20c02 100644 --- a/tests/integration/expected/eq_u64.wat +++ b/tests/integration/expected/eq_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_23a27398cbfb7447cb610e7b877565f4e43d633b55f98504051b93381d40740f.wasm +(module $test_rust_d3f2b162735bb643456cb68c71d6be70cdb8e4267c7ef3c9cdef6fcfdb77c2cc.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/eq_u8.hir b/tests/integration/expected/eq_u8.hir index 2a6c8d7b..4ee310db 100644 --- a/tests/integration/expected/eq_u8.hir +++ b/tests/integration/expected/eq_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_016edfcf5844ac44aa96bfe0cfac241307bf2ff2adbb955edec051f22a2332a9 + (module #test_rust_6b299c822e52963f8b3c87b898b867e2147f25b53bb5c38ab829254425824be5 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/eq_u8.masm b/tests/integration/expected/eq_u8.masm index 56691b19..b9536473 100644 --- a/tests/integration/expected/eq_u8.masm +++ b/tests/integration/expected/eq_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_016edfcf5844ac44aa96bfe0cfac241307bf2ff2adbb955edec051f22a2332a9 +# mod test_rust_6b299c822e52963f8b3c87b898b867e2147f25b53bb5c38ab829254425824be5 export.entrypoint swap.1 eq end -begin - exec.::test_rust_016edfcf5844ac44aa96bfe0cfac241307bf2ff2adbb955edec051f22a2332a9::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/eq_u8.wat b/tests/integration/expected/eq_u8.wat index f6a30d68..8189c739 100644 --- a/tests/integration/expected/eq_u8.wat +++ b/tests/integration/expected/eq_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_016edfcf5844ac44aa96bfe0cfac241307bf2ff2adbb955edec051f22a2332a9.wasm +(module $test_rust_6b299c822e52963f8b3c87b898b867e2147f25b53bb5c38ab829254425824be5.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/fib.masm b/tests/integration/expected/fib.masm index 17350d3b..6096c201 100644 --- a/tests/integration/expected/fib.masm +++ b/tests/integration/expected/fib.masm @@ -31,6 +31,3 @@ export.fib end -begin - exec.::miden_integration_tests_rust_fib_wasm::fib -end \ No newline at end of file diff --git a/tests/integration/expected/fib.wat b/tests/integration/expected/fib.wat index d9ca4b11..580653ea 100644 --- a/tests/integration/expected/fib.wat +++ b/tests/integration/expected/fib.wat @@ -28,7 +28,6 @@ br 0 (;@1;) end ) - (table (;0;) 1 1 funcref) (memory (;0;) 16) (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) (global (;1;) i32 i32.const 1048576) diff --git a/tests/integration/expected/ge_felt.masm b/tests/integration/expected/ge_felt.masm index 112445d8..5b8b2d1b 100644 --- a/tests/integration/expected/ge_felt.masm +++ b/tests/integration/expected/ge_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::ge_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/ge_i32.hir b/tests/integration/expected/ge_i32.hir index 8a951459..0aceff9f 100644 --- a/tests/integration/expected/ge_i32.hir +++ b/tests/integration/expected/ge_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_b5a16d8e45971748fdabfee5a7354fe518e1b20b063ef55a834be10882ad716d + (module #test_rust_c0f27bd914ea4f9a33c6502694b5eeace55ed7a40a907b0c5fd68e0aa656a56b ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/ge_i32.masm b/tests/integration/expected/ge_i32.masm index 40e63c88..1a09454e 100644 --- a/tests/integration/expected/ge_i32.masm +++ b/tests/integration/expected/ge_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_b5a16d8e45971748fdabfee5a7354fe518e1b20b063ef55a834be10882ad716d +# mod test_rust_c0f27bd914ea4f9a33c6502694b5eeace55ed7a40a907b0c5fd68e0aa656a56b export.entrypoint swap.1 exec.::intrinsics::i32::is_gte end -begin - exec.::test_rust_b5a16d8e45971748fdabfee5a7354fe518e1b20b063ef55a834be10882ad716d::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/ge_i32.wat b/tests/integration/expected/ge_i32.wat index 105e561e..502095ec 100644 --- a/tests/integration/expected/ge_i32.wat +++ b/tests/integration/expected/ge_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_b5a16d8e45971748fdabfee5a7354fe518e1b20b063ef55a834be10882ad716d.wasm +(module $test_rust_c0f27bd914ea4f9a33c6502694b5eeace55ed7a40a907b0c5fd68e0aa656a56b.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/ge_i64.hir b/tests/integration/expected/ge_i64.hir index 43003332..165f912d 100644 --- a/tests/integration/expected/ge_i64.hir +++ b/tests/integration/expected/ge_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_2ee6501ff8a77a19c4a25cd2840520d20a9e501f962168a16a1a108d1b3b4844 + (module #test_rust_1dc910df9e5ef302ee236233065a2a50427fb4ff2db8591dcc6713f05a95d77a ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/ge_i64.masm b/tests/integration/expected/ge_i64.masm index d12b85b2..39752f12 100644 --- a/tests/integration/expected/ge_i64.masm +++ b/tests/integration/expected/ge_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_2ee6501ff8a77a19c4a25cd2840520d20a9e501f962168a16a1a108d1b3b4844 +# mod test_rust_1dc910df9e5ef302ee236233065a2a50427fb4ff2db8591dcc6713f05a95d77a export.entrypoint movdn.3 movdn.3 exec.::intrinsics::i64::gte end -begin - exec.::test_rust_2ee6501ff8a77a19c4a25cd2840520d20a9e501f962168a16a1a108d1b3b4844::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/ge_i64.wat b/tests/integration/expected/ge_i64.wat index d73fa9f0..dd121bf6 100644 --- a/tests/integration/expected/ge_i64.wat +++ b/tests/integration/expected/ge_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_2ee6501ff8a77a19c4a25cd2840520d20a9e501f962168a16a1a108d1b3b4844.wasm +(module $test_rust_1dc910df9e5ef302ee236233065a2a50427fb4ff2db8591dcc6713f05a95d77a.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/ge_u16.hir b/tests/integration/expected/ge_u16.hir index e2133226..fbbcf429 100644 --- a/tests/integration/expected/ge_u16.hir +++ b/tests/integration/expected/ge_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_76b95aeb59987e43311d2fb22a7021b58c09a51fe7457153d1a9986095f5038e + (module #test_rust_0eeac93afe2a6fee749f5e48efe12f98e2e005f6a92fa7f020166662c68c1750 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/ge_u16.masm b/tests/integration/expected/ge_u16.masm index 4024202e..8ffcb9ae 100644 --- a/tests/integration/expected/ge_u16.masm +++ b/tests/integration/expected/ge_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_76b95aeb59987e43311d2fb22a7021b58c09a51fe7457153d1a9986095f5038e +# mod test_rust_0eeac93afe2a6fee749f5e48efe12f98e2e005f6a92fa7f020166662c68c1750 export.entrypoint swap.1 u32gte end -begin - exec.::test_rust_76b95aeb59987e43311d2fb22a7021b58c09a51fe7457153d1a9986095f5038e::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/ge_u16.wat b/tests/integration/expected/ge_u16.wat index d7462572..23bfec6e 100644 --- a/tests/integration/expected/ge_u16.wat +++ b/tests/integration/expected/ge_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_76b95aeb59987e43311d2fb22a7021b58c09a51fe7457153d1a9986095f5038e.wasm +(module $test_rust_0eeac93afe2a6fee749f5e48efe12f98e2e005f6a92fa7f020166662c68c1750.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/ge_u32.hir b/tests/integration/expected/ge_u32.hir index 164a3c7f..85ed05ff 100644 --- a/tests/integration/expected/ge_u32.hir +++ b/tests/integration/expected/ge_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_4b383341d2a4f164848503ecab5dd829402a229128ea4077a78bae27c6cd0885 + (module #test_rust_4fa5dff76055193b0eab22d64f4284da486889ba07bebda7bae15ce0af5473af ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/ge_u32.masm b/tests/integration/expected/ge_u32.masm index d2f04834..7dd8988a 100644 --- a/tests/integration/expected/ge_u32.masm +++ b/tests/integration/expected/ge_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_4b383341d2a4f164848503ecab5dd829402a229128ea4077a78bae27c6cd0885 +# mod test_rust_4fa5dff76055193b0eab22d64f4284da486889ba07bebda7bae15ce0af5473af export.entrypoint swap.1 u32gte end -begin - exec.::test_rust_4b383341d2a4f164848503ecab5dd829402a229128ea4077a78bae27c6cd0885::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/ge_u32.wat b/tests/integration/expected/ge_u32.wat index dfaf4728..3ead6d43 100644 --- a/tests/integration/expected/ge_u32.wat +++ b/tests/integration/expected/ge_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_4b383341d2a4f164848503ecab5dd829402a229128ea4077a78bae27c6cd0885.wasm +(module $test_rust_4fa5dff76055193b0eab22d64f4284da486889ba07bebda7bae15ce0af5473af.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/ge_u64.hir b/tests/integration/expected/ge_u64.hir index 314b571a..344f246f 100644 --- a/tests/integration/expected/ge_u64.hir +++ b/tests/integration/expected/ge_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_d7aa757365ea28f9212f6c02f3c66b808689f2ebcbf480919e5d4f46796057c4 + (module #test_rust_77837611a2574dae16586d25d91d315da506c432500ce2d6c4234173b9ea07b2 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/ge_u64.masm b/tests/integration/expected/ge_u64.masm index d0f4741f..b9b9e7d8 100644 --- a/tests/integration/expected/ge_u64.masm +++ b/tests/integration/expected/ge_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_d7aa757365ea28f9212f6c02f3c66b808689f2ebcbf480919e5d4f46796057c4 +# mod test_rust_77837611a2574dae16586d25d91d315da506c432500ce2d6c4234173b9ea07b2 export.entrypoint movdn.3 movdn.3 exec.::std::math::u64::gte end -begin - exec.::test_rust_d7aa757365ea28f9212f6c02f3c66b808689f2ebcbf480919e5d4f46796057c4::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/ge_u64.wat b/tests/integration/expected/ge_u64.wat index 78c297c6..65453aee 100644 --- a/tests/integration/expected/ge_u64.wat +++ b/tests/integration/expected/ge_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_d7aa757365ea28f9212f6c02f3c66b808689f2ebcbf480919e5d4f46796057c4.wasm +(module $test_rust_77837611a2574dae16586d25d91d315da506c432500ce2d6c4234173b9ea07b2.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/ge_u8.hir b/tests/integration/expected/ge_u8.hir index ddbba497..064d0cc3 100644 --- a/tests/integration/expected/ge_u8.hir +++ b/tests/integration/expected/ge_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_54b0c7ea89a992ede15df4270d53ad3910db016fdef9484347e14e8583439818 + (module #test_rust_e66ace9d45878034c39e91c35eb5f67915dc01fb5a1ed5c34627e3bb99107855 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/ge_u8.masm b/tests/integration/expected/ge_u8.masm index aa694d1f..14681b3c 100644 --- a/tests/integration/expected/ge_u8.masm +++ b/tests/integration/expected/ge_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_54b0c7ea89a992ede15df4270d53ad3910db016fdef9484347e14e8583439818 +# mod test_rust_e66ace9d45878034c39e91c35eb5f67915dc01fb5a1ed5c34627e3bb99107855 export.entrypoint swap.1 u32gte end -begin - exec.::test_rust_54b0c7ea89a992ede15df4270d53ad3910db016fdef9484347e14e8583439818::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/ge_u8.wat b/tests/integration/expected/ge_u8.wat index 21286350..cc253bfc 100644 --- a/tests/integration/expected/ge_u8.wat +++ b/tests/integration/expected/ge_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_54b0c7ea89a992ede15df4270d53ad3910db016fdef9484347e14e8583439818.wasm +(module $test_rust_e66ace9d45878034c39e91c35eb5f67915dc01fb5a1ed5c34627e3bb99107855.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/gt_felt.masm b/tests/integration/expected/gt_felt.masm index 41e9994b..6da744d4 100644 --- a/tests/integration/expected/gt_felt.masm +++ b/tests/integration/expected/gt_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::gt_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/gt_i32.hir b/tests/integration/expected/gt_i32.hir index 41f6d2c0..dee3370d 100644 --- a/tests/integration/expected/gt_i32.hir +++ b/tests/integration/expected/gt_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_b5c4c7a4d7b24d8bd326c64565f6f00c5acdaaabb321e953eac6c8606d72ef20 + (module #test_rust_dcf68bbd3d38962baca8bcc39895a74e9f927a15ae1af780f83843028d53154e ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/gt_i32.masm b/tests/integration/expected/gt_i32.masm index ff8cc5e3..104bd0b7 100644 --- a/tests/integration/expected/gt_i32.masm +++ b/tests/integration/expected/gt_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_b5c4c7a4d7b24d8bd326c64565f6f00c5acdaaabb321e953eac6c8606d72ef20 +# mod test_rust_dcf68bbd3d38962baca8bcc39895a74e9f927a15ae1af780f83843028d53154e export.entrypoint swap.1 exec.::intrinsics::i32::is_gt end -begin - exec.::test_rust_b5c4c7a4d7b24d8bd326c64565f6f00c5acdaaabb321e953eac6c8606d72ef20::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/gt_i32.wat b/tests/integration/expected/gt_i32.wat index ff95319a..80ba0577 100644 --- a/tests/integration/expected/gt_i32.wat +++ b/tests/integration/expected/gt_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_b5c4c7a4d7b24d8bd326c64565f6f00c5acdaaabb321e953eac6c8606d72ef20.wasm +(module $test_rust_dcf68bbd3d38962baca8bcc39895a74e9f927a15ae1af780f83843028d53154e.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/gt_i64.hir b/tests/integration/expected/gt_i64.hir index 47579fa5..2391ac9a 100644 --- a/tests/integration/expected/gt_i64.hir +++ b/tests/integration/expected/gt_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_15919ca657a122785ad28a3d4a007eef46d4172892e2a47881723e6bf2b86e76 + (module #test_rust_ceadd0c619424ea8897ac24b5176dad699485353543e7607a12bdee342a50966 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/gt_i64.masm b/tests/integration/expected/gt_i64.masm index 449ea67f..ff1907cb 100644 --- a/tests/integration/expected/gt_i64.masm +++ b/tests/integration/expected/gt_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_15919ca657a122785ad28a3d4a007eef46d4172892e2a47881723e6bf2b86e76 +# mod test_rust_ceadd0c619424ea8897ac24b5176dad699485353543e7607a12bdee342a50966 export.entrypoint movdn.3 movdn.3 exec.::intrinsics::i64::gt end -begin - exec.::test_rust_15919ca657a122785ad28a3d4a007eef46d4172892e2a47881723e6bf2b86e76::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/gt_i64.wat b/tests/integration/expected/gt_i64.wat index 1475d27a..d2365888 100644 --- a/tests/integration/expected/gt_i64.wat +++ b/tests/integration/expected/gt_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_15919ca657a122785ad28a3d4a007eef46d4172892e2a47881723e6bf2b86e76.wasm +(module $test_rust_ceadd0c619424ea8897ac24b5176dad699485353543e7607a12bdee342a50966.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/gt_u16.hir b/tests/integration/expected/gt_u16.hir index a24d7fca..3a36d99f 100644 --- a/tests/integration/expected/gt_u16.hir +++ b/tests/integration/expected/gt_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_1f3e71115fc0280c196e968bdc849a389f4cde61e22ba8a528fd4008c3dda439 + (module #test_rust_f264d3777d3a68a4fab468d26338823b06e58dd59c87e8d6f2fc2d0d672bb1cd ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/gt_u16.masm b/tests/integration/expected/gt_u16.masm index 97ed8ea6..5f0c5bf3 100644 --- a/tests/integration/expected/gt_u16.masm +++ b/tests/integration/expected/gt_u16.masm @@ -1,4 +1,4 @@ -# mod test_rust_1f3e71115fc0280c196e968bdc849a389f4cde61e22ba8a528fd4008c3dda439 +# mod test_rust_f264d3777d3a68a4fab468d26338823b06e58dd59c87e8d6f2fc2d0d672bb1cd export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_1f3e71115fc0280c196e968bdc849a389f4cde61e22ba8a528fd4008c3dda439::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/gt_u16.wat b/tests/integration/expected/gt_u16.wat index fb659a0b..c201cd3b 100644 --- a/tests/integration/expected/gt_u16.wat +++ b/tests/integration/expected/gt_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_1f3e71115fc0280c196e968bdc849a389f4cde61e22ba8a528fd4008c3dda439.wasm +(module $test_rust_f264d3777d3a68a4fab468d26338823b06e58dd59c87e8d6f2fc2d0d672bb1cd.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/gt_u32.hir b/tests/integration/expected/gt_u32.hir index a97e9a93..5707d237 100644 --- a/tests/integration/expected/gt_u32.hir +++ b/tests/integration/expected/gt_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_f66b00d2943bd052f7b96df788d9cc219d5cb5010e618d725b01c3c203d038f2 + (module #test_rust_1e85457275952da03652b53164a185a9463cbfd5807e6d9eeae9b23a1844e96e ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/gt_u32.masm b/tests/integration/expected/gt_u32.masm index b637d3bf..70270946 100644 --- a/tests/integration/expected/gt_u32.masm +++ b/tests/integration/expected/gt_u32.masm @@ -1,4 +1,4 @@ -# mod test_rust_f66b00d2943bd052f7b96df788d9cc219d5cb5010e618d725b01c3c203d038f2 +# mod test_rust_1e85457275952da03652b53164a185a9463cbfd5807e6d9eeae9b23a1844e96e export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_f66b00d2943bd052f7b96df788d9cc219d5cb5010e618d725b01c3c203d038f2::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/gt_u32.wat b/tests/integration/expected/gt_u32.wat index 77372a63..d1ad2ab7 100644 --- a/tests/integration/expected/gt_u32.wat +++ b/tests/integration/expected/gt_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_f66b00d2943bd052f7b96df788d9cc219d5cb5010e618d725b01c3c203d038f2.wasm +(module $test_rust_1e85457275952da03652b53164a185a9463cbfd5807e6d9eeae9b23a1844e96e.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/gt_u64.hir b/tests/integration/expected/gt_u64.hir index b492f820..4536e74a 100644 --- a/tests/integration/expected/gt_u64.hir +++ b/tests/integration/expected/gt_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_13e458487ee822c3170246e3d2f96d94c33aaeba06fbf2afb5b35562d2e307a7 + (module #test_rust_70753af3178921ed6f0c2f66b095a4c78bd32e752ad580a8203438bf231ba0db ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/gt_u64.masm b/tests/integration/expected/gt_u64.masm index f312f127..b420cc05 100644 --- a/tests/integration/expected/gt_u64.masm +++ b/tests/integration/expected/gt_u64.masm @@ -1,4 +1,4 @@ -# mod test_rust_13e458487ee822c3170246e3d2f96d94c33aaeba06fbf2afb5b35562d2e307a7 +# mod test_rust_70753af3178921ed6f0c2f66b095a4c78bd32e752ad580a8203438bf231ba0db export.entrypoint movdn.3 @@ -13,6 +13,3 @@ export.entrypoint end -begin - exec.::test_rust_13e458487ee822c3170246e3d2f96d94c33aaeba06fbf2afb5b35562d2e307a7::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/gt_u64.wat b/tests/integration/expected/gt_u64.wat index a1c1cd34..8a497d6d 100644 --- a/tests/integration/expected/gt_u64.wat +++ b/tests/integration/expected/gt_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_13e458487ee822c3170246e3d2f96d94c33aaeba06fbf2afb5b35562d2e307a7.wasm +(module $test_rust_70753af3178921ed6f0c2f66b095a4c78bd32e752ad580a8203438bf231ba0db.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/gt_u8.hir b/tests/integration/expected/gt_u8.hir index c470dbd7..374a89f0 100644 --- a/tests/integration/expected/gt_u8.hir +++ b/tests/integration/expected/gt_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_9ff23d66c653e992b6e1b92ca070ee51c8fb198f18a46cf1f931db5256d81673 + (module #test_rust_c2720ddf3b4d450003b652cb7974691bccf82cfb40715e2a2f4ac9445d02156e ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/gt_u8.masm b/tests/integration/expected/gt_u8.masm index 6c1248e1..a22cbe0b 100644 --- a/tests/integration/expected/gt_u8.masm +++ b/tests/integration/expected/gt_u8.masm @@ -1,4 +1,4 @@ -# mod test_rust_9ff23d66c653e992b6e1b92ca070ee51c8fb198f18a46cf1f931db5256d81673 +# mod test_rust_c2720ddf3b4d450003b652cb7974691bccf82cfb40715e2a2f4ac9445d02156e export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_9ff23d66c653e992b6e1b92ca070ee51c8fb198f18a46cf1f931db5256d81673::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/gt_u8.wat b/tests/integration/expected/gt_u8.wat index 56b088d7..f64a0833 100644 --- a/tests/integration/expected/gt_u8.wat +++ b/tests/integration/expected/gt_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_9ff23d66c653e992b6e1b92ca070ee51c8fb198f18a46cf1f931db5256d81673.wasm +(module $test_rust_c2720ddf3b4d450003b652cb7974691bccf82cfb40715e2a2f4ac9445d02156e.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/le_felt.masm b/tests/integration/expected/le_felt.masm index 161ac98f..a772379e 100644 --- a/tests/integration/expected/le_felt.masm +++ b/tests/integration/expected/le_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::le_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/le_i32.hir b/tests/integration/expected/le_i32.hir index 6d4e85ec..dfcb5559 100644 --- a/tests/integration/expected/le_i32.hir +++ b/tests/integration/expected/le_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_2547a2f32c92592d4bfa9373573e807eaabb826474a09c0d18558272e7d39cfb + (module #test_rust_26428c714af584632b95b2863903e39a0f8601727e3054ad7ebaedf128da35c7 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/le_i32.masm b/tests/integration/expected/le_i32.masm index e9e9f645..81992171 100644 --- a/tests/integration/expected/le_i32.masm +++ b/tests/integration/expected/le_i32.masm @@ -1,4 +1,4 @@ -# mod test_rust_2547a2f32c92592d4bfa9373573e807eaabb826474a09c0d18558272e7d39cfb +# mod test_rust_26428c714af584632b95b2863903e39a0f8601727e3054ad7ebaedf128da35c7 export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_2547a2f32c92592d4bfa9373573e807eaabb826474a09c0d18558272e7d39cfb::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/le_i32.wat b/tests/integration/expected/le_i32.wat index 0b6c8044..f36494da 100644 --- a/tests/integration/expected/le_i32.wat +++ b/tests/integration/expected/le_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_2547a2f32c92592d4bfa9373573e807eaabb826474a09c0d18558272e7d39cfb.wasm +(module $test_rust_26428c714af584632b95b2863903e39a0f8601727e3054ad7ebaedf128da35c7.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/le_i64.hir b/tests/integration/expected/le_i64.hir index 6bbb281e..128916b0 100644 --- a/tests/integration/expected/le_i64.hir +++ b/tests/integration/expected/le_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_6444fe228a17691781a2af32da1344e74a7e10dc79e1450dd7003f23aa7e1668 + (module #test_rust_c4a9c74221b4f52c7cc028d994d8735ad8985dec62b6a6980159d497d7c3fa93 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/le_i64.masm b/tests/integration/expected/le_i64.masm index c55d3be9..ed88167d 100644 --- a/tests/integration/expected/le_i64.masm +++ b/tests/integration/expected/le_i64.masm @@ -1,4 +1,4 @@ -# mod test_rust_6444fe228a17691781a2af32da1344e74a7e10dc79e1450dd7003f23aa7e1668 +# mod test_rust_c4a9c74221b4f52c7cc028d994d8735ad8985dec62b6a6980159d497d7c3fa93 export.entrypoint movdn.3 @@ -13,6 +13,3 @@ export.entrypoint end -begin - exec.::test_rust_6444fe228a17691781a2af32da1344e74a7e10dc79e1450dd7003f23aa7e1668::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/le_i64.wat b/tests/integration/expected/le_i64.wat index c85c873c..6001d4ed 100644 --- a/tests/integration/expected/le_i64.wat +++ b/tests/integration/expected/le_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_6444fe228a17691781a2af32da1344e74a7e10dc79e1450dd7003f23aa7e1668.wasm +(module $test_rust_c4a9c74221b4f52c7cc028d994d8735ad8985dec62b6a6980159d497d7c3fa93.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/le_u16.hir b/tests/integration/expected/le_u16.hir index 89a6d657..92a905bf 100644 --- a/tests/integration/expected/le_u16.hir +++ b/tests/integration/expected/le_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_ff0a06076c996bca51493fe83ecb25fcda9ae22252704c128b49117365264974 + (module #test_rust_aaaa272f39ec3f234fd119869db2d6791ce4b1e8d3f284fe6c212db33f480554 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/le_u16.masm b/tests/integration/expected/le_u16.masm index af1c122f..74411e04 100644 --- a/tests/integration/expected/le_u16.masm +++ b/tests/integration/expected/le_u16.masm @@ -1,4 +1,4 @@ -# mod test_rust_ff0a06076c996bca51493fe83ecb25fcda9ae22252704c128b49117365264974 +# mod test_rust_aaaa272f39ec3f234fd119869db2d6791ce4b1e8d3f284fe6c212db33f480554 export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_ff0a06076c996bca51493fe83ecb25fcda9ae22252704c128b49117365264974::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/le_u16.wat b/tests/integration/expected/le_u16.wat index 3eac5c4b..7e571d9d 100644 --- a/tests/integration/expected/le_u16.wat +++ b/tests/integration/expected/le_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_ff0a06076c996bca51493fe83ecb25fcda9ae22252704c128b49117365264974.wasm +(module $test_rust_aaaa272f39ec3f234fd119869db2d6791ce4b1e8d3f284fe6c212db33f480554.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/le_u32.hir b/tests/integration/expected/le_u32.hir index 0dd64c93..3ab52806 100644 --- a/tests/integration/expected/le_u32.hir +++ b/tests/integration/expected/le_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_aff644298d59a2158f6ae144827fc2b770a194d67e975abfa140b084f4532a88 + (module #test_rust_cdcf596bb19cb80fff51986e5bc56794a88886a743030b2648f5742396b13095 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/le_u32.masm b/tests/integration/expected/le_u32.masm index 567d1999..4179417d 100644 --- a/tests/integration/expected/le_u32.masm +++ b/tests/integration/expected/le_u32.masm @@ -1,4 +1,4 @@ -# mod test_rust_aff644298d59a2158f6ae144827fc2b770a194d67e975abfa140b084f4532a88 +# mod test_rust_cdcf596bb19cb80fff51986e5bc56794a88886a743030b2648f5742396b13095 export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_aff644298d59a2158f6ae144827fc2b770a194d67e975abfa140b084f4532a88::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/le_u32.wat b/tests/integration/expected/le_u32.wat index afb4e8b3..707314bc 100644 --- a/tests/integration/expected/le_u32.wat +++ b/tests/integration/expected/le_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_aff644298d59a2158f6ae144827fc2b770a194d67e975abfa140b084f4532a88.wasm +(module $test_rust_cdcf596bb19cb80fff51986e5bc56794a88886a743030b2648f5742396b13095.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/le_u64.hir b/tests/integration/expected/le_u64.hir index 06f321b5..1af33c0d 100644 --- a/tests/integration/expected/le_u64.hir +++ b/tests/integration/expected/le_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_69378fc28b651907f6da9d172849f6508608d73a8f473d4d9da76003ce49d703 + (module #test_rust_907925d5e81fd1c82255ae3aa7232016c43e62c6867115675920cfe0d85013b1 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/le_u64.masm b/tests/integration/expected/le_u64.masm index dab4840e..c3aa2f96 100644 --- a/tests/integration/expected/le_u64.masm +++ b/tests/integration/expected/le_u64.masm @@ -1,4 +1,4 @@ -# mod test_rust_69378fc28b651907f6da9d172849f6508608d73a8f473d4d9da76003ce49d703 +# mod test_rust_907925d5e81fd1c82255ae3aa7232016c43e62c6867115675920cfe0d85013b1 export.entrypoint movdn.3 @@ -13,6 +13,3 @@ export.entrypoint end -begin - exec.::test_rust_69378fc28b651907f6da9d172849f6508608d73a8f473d4d9da76003ce49d703::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/le_u64.wat b/tests/integration/expected/le_u64.wat index 9de054e8..01c542b3 100644 --- a/tests/integration/expected/le_u64.wat +++ b/tests/integration/expected/le_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_69378fc28b651907f6da9d172849f6508608d73a8f473d4d9da76003ce49d703.wasm +(module $test_rust_907925d5e81fd1c82255ae3aa7232016c43e62c6867115675920cfe0d85013b1.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/le_u8.hir b/tests/integration/expected/le_u8.hir index a95c7bdb..a5f33154 100644 --- a/tests/integration/expected/le_u8.hir +++ b/tests/integration/expected/le_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_90833d097291d3eaef34c669d42686006454d4265170e39f4f3da9191cdf4b91 + (module #test_rust_aace3f1ae4da30ba44b3c078c978343b282544139b496703f5f6a78953f42b7e ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/le_u8.masm b/tests/integration/expected/le_u8.masm index 5e974b0d..1d879a9b 100644 --- a/tests/integration/expected/le_u8.masm +++ b/tests/integration/expected/le_u8.masm @@ -1,4 +1,4 @@ -# mod test_rust_90833d097291d3eaef34c669d42686006454d4265170e39f4f3da9191cdf4b91 +# mod test_rust_aace3f1ae4da30ba44b3c078c978343b282544139b496703f5f6a78953f42b7e export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_90833d097291d3eaef34c669d42686006454d4265170e39f4f3da9191cdf4b91::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/le_u8.wat b/tests/integration/expected/le_u8.wat index 0e4092d0..1bf7fcf2 100644 --- a/tests/integration/expected/le_u8.wat +++ b/tests/integration/expected/le_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_90833d097291d3eaef34c669d42686006454d4265170e39f4f3da9191cdf4b91.wasm +(module $test_rust_aace3f1ae4da30ba44b3c078c978343b282544139b496703f5f6a78953f42b7e.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/lt_felt.masm b/tests/integration/expected/lt_felt.masm index 71fcf74f..a8a8df45 100644 --- a/tests/integration/expected/lt_felt.masm +++ b/tests/integration/expected/lt_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::lt_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/lt_i32.hir b/tests/integration/expected/lt_i32.hir index 54e1112a..3cf24438 100644 --- a/tests/integration/expected/lt_i32.hir +++ b/tests/integration/expected/lt_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_84df8ef1a9768a3c82cf6a429a2e219f615a8e12f995c5b24b9ec404f4cd19d8 + (module #test_rust_57859c51c85389425b294750a9837d618293dd384d0b8582ca4c8bd6789e363e ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/lt_i32.masm b/tests/integration/expected/lt_i32.masm index d0c61984..8ec02cc7 100644 --- a/tests/integration/expected/lt_i32.masm +++ b/tests/integration/expected/lt_i32.masm @@ -1,4 +1,4 @@ -# mod test_rust_84df8ef1a9768a3c82cf6a429a2e219f615a8e12f995c5b24b9ec404f4cd19d8 +# mod test_rust_57859c51c85389425b294750a9837d618293dd384d0b8582ca4c8bd6789e363e export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_84df8ef1a9768a3c82cf6a429a2e219f615a8e12f995c5b24b9ec404f4cd19d8::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/lt_i32.wat b/tests/integration/expected/lt_i32.wat index 04ec4c99..0280aea0 100644 --- a/tests/integration/expected/lt_i32.wat +++ b/tests/integration/expected/lt_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_84df8ef1a9768a3c82cf6a429a2e219f615a8e12f995c5b24b9ec404f4cd19d8.wasm +(module $test_rust_57859c51c85389425b294750a9837d618293dd384d0b8582ca4c8bd6789e363e.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/lt_i64.hir b/tests/integration/expected/lt_i64.hir index 44be499c..2f224a17 100644 --- a/tests/integration/expected/lt_i64.hir +++ b/tests/integration/expected/lt_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_7dbe71f32e529d8482d0aa84e113b7e26e7d927fd65c6080de644d81c221a38e + (module #test_rust_228292094cebd3f423ea05660793b4754a31411dd7db56529b976b81e4d7066b ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/lt_i64.masm b/tests/integration/expected/lt_i64.masm index cfa8bcd6..e119b34d 100644 --- a/tests/integration/expected/lt_i64.masm +++ b/tests/integration/expected/lt_i64.masm @@ -1,4 +1,4 @@ -# mod test_rust_7dbe71f32e529d8482d0aa84e113b7e26e7d927fd65c6080de644d81c221a38e +# mod test_rust_228292094cebd3f423ea05660793b4754a31411dd7db56529b976b81e4d7066b export.entrypoint movdn.3 @@ -13,6 +13,3 @@ export.entrypoint end -begin - exec.::test_rust_7dbe71f32e529d8482d0aa84e113b7e26e7d927fd65c6080de644d81c221a38e::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/lt_i64.wat b/tests/integration/expected/lt_i64.wat index 3362919a..1d3f8d9e 100644 --- a/tests/integration/expected/lt_i64.wat +++ b/tests/integration/expected/lt_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_7dbe71f32e529d8482d0aa84e113b7e26e7d927fd65c6080de644d81c221a38e.wasm +(module $test_rust_228292094cebd3f423ea05660793b4754a31411dd7db56529b976b81e4d7066b.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/lt_u16.hir b/tests/integration/expected/lt_u16.hir index 52e3701a..c045e3c4 100644 --- a/tests/integration/expected/lt_u16.hir +++ b/tests/integration/expected/lt_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_5c07628ec4d9ea05c0cb5402aea23aecccfbd786cb513f138b2395cb26c88212 + (module #test_rust_0899dac7a0388d3cd5c5447bcaf230146812c2c0ca4ede178224db721afe9aba ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/lt_u16.masm b/tests/integration/expected/lt_u16.masm index 7618d42a..6e1cef3e 100644 --- a/tests/integration/expected/lt_u16.masm +++ b/tests/integration/expected/lt_u16.masm @@ -1,4 +1,4 @@ -# mod test_rust_5c07628ec4d9ea05c0cb5402aea23aecccfbd786cb513f138b2395cb26c88212 +# mod test_rust_0899dac7a0388d3cd5c5447bcaf230146812c2c0ca4ede178224db721afe9aba export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_5c07628ec4d9ea05c0cb5402aea23aecccfbd786cb513f138b2395cb26c88212::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/lt_u16.wat b/tests/integration/expected/lt_u16.wat index 0d8c64fb..07bc0891 100644 --- a/tests/integration/expected/lt_u16.wat +++ b/tests/integration/expected/lt_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_5c07628ec4d9ea05c0cb5402aea23aecccfbd786cb513f138b2395cb26c88212.wasm +(module $test_rust_0899dac7a0388d3cd5c5447bcaf230146812c2c0ca4ede178224db721afe9aba.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/lt_u32.hir b/tests/integration/expected/lt_u32.hir index 9d1898f8..04795a1e 100644 --- a/tests/integration/expected/lt_u32.hir +++ b/tests/integration/expected/lt_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_45460c08654d9d3094bce49c28f5a6b58c45ccd05649e7fb3ea9dee19871f5aa + (module #test_rust_b1f1b13a84c328e970f28e0b366623db73f213249bdf37e4787af5f64f69adf1 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/lt_u32.masm b/tests/integration/expected/lt_u32.masm index 10f3a475..4b06252b 100644 --- a/tests/integration/expected/lt_u32.masm +++ b/tests/integration/expected/lt_u32.masm @@ -1,4 +1,4 @@ -# mod test_rust_45460c08654d9d3094bce49c28f5a6b58c45ccd05649e7fb3ea9dee19871f5aa +# mod test_rust_b1f1b13a84c328e970f28e0b366623db73f213249bdf37e4787af5f64f69adf1 export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_45460c08654d9d3094bce49c28f5a6b58c45ccd05649e7fb3ea9dee19871f5aa::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/lt_u32.wat b/tests/integration/expected/lt_u32.wat index 8a3b036b..3b58372d 100644 --- a/tests/integration/expected/lt_u32.wat +++ b/tests/integration/expected/lt_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_45460c08654d9d3094bce49c28f5a6b58c45ccd05649e7fb3ea9dee19871f5aa.wasm +(module $test_rust_b1f1b13a84c328e970f28e0b366623db73f213249bdf37e4787af5f64f69adf1.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/lt_u64.hir b/tests/integration/expected/lt_u64.hir index 880179be..b827c507 100644 --- a/tests/integration/expected/lt_u64.hir +++ b/tests/integration/expected/lt_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c98b7739945dc08395282d607729efe3ca4da8a1e950e1d84c04448a51a87b71 + (module #test_rust_32f5b5ff2aa96482da580eb924797236536a4ae0cbbb6d7daa491e9293c00bda ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/lt_u64.masm b/tests/integration/expected/lt_u64.masm index b4598015..bb8075c1 100644 --- a/tests/integration/expected/lt_u64.masm +++ b/tests/integration/expected/lt_u64.masm @@ -1,4 +1,4 @@ -# mod test_rust_c98b7739945dc08395282d607729efe3ca4da8a1e950e1d84c04448a51a87b71 +# mod test_rust_32f5b5ff2aa96482da580eb924797236536a4ae0cbbb6d7daa491e9293c00bda export.entrypoint movdn.3 @@ -13,6 +13,3 @@ export.entrypoint end -begin - exec.::test_rust_c98b7739945dc08395282d607729efe3ca4da8a1e950e1d84c04448a51a87b71::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/lt_u64.wat b/tests/integration/expected/lt_u64.wat index a3d316b4..4ef4020f 100644 --- a/tests/integration/expected/lt_u64.wat +++ b/tests/integration/expected/lt_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_c98b7739945dc08395282d607729efe3ca4da8a1e950e1d84c04448a51a87b71.wasm +(module $test_rust_32f5b5ff2aa96482da580eb924797236536a4ae0cbbb6d7daa491e9293c00bda.wasm (type (;0;) (func (param i64 i64) (result i32))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i32) local.get 0 diff --git a/tests/integration/expected/lt_u8.hir b/tests/integration/expected/lt_u8.hir index 0e308b7a..40f9b092 100644 --- a/tests/integration/expected/lt_u8.hir +++ b/tests/integration/expected/lt_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_3af3eb760fd15a611df682ed67144a5abe767c638e3c0c928720d59e06e5a5ee + (module #test_rust_ddc15fe9df7100cbbcc5a51f3d4d29284c4cf43fb071224bc37b218c1758db30 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/lt_u8.masm b/tests/integration/expected/lt_u8.masm index 8b805135..5b561234 100644 --- a/tests/integration/expected/lt_u8.masm +++ b/tests/integration/expected/lt_u8.masm @@ -1,4 +1,4 @@ -# mod test_rust_3af3eb760fd15a611df682ed67144a5abe767c638e3c0c928720d59e06e5a5ee +# mod test_rust_ddc15fe9df7100cbbcc5a51f3d4d29284c4cf43fb071224bc37b218c1758db30 export.entrypoint swap.1 @@ -12,6 +12,3 @@ export.entrypoint end -begin - exec.::test_rust_3af3eb760fd15a611df682ed67144a5abe767c638e3c0c928720d59e06e5a5ee::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/lt_u8.wat b/tests/integration/expected/lt_u8.wat index f5dfb69c..e811e6ec 100644 --- a/tests/integration/expected/lt_u8.wat +++ b/tests/integration/expected/lt_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_3af3eb760fd15a611df682ed67144a5abe767c638e3c0c928720d59e06e5a5ee.wasm +(module $test_rust_ddc15fe9df7100cbbcc5a51f3d4d29284c4cf43fb071224bc37b218c1758db30.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/mul_felt.masm b/tests/integration/expected/mul_felt.masm index 7196b857..00dd1135 100644 --- a/tests/integration/expected/mul_felt.masm +++ b/tests/integration/expected/mul_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::mul_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/mul_i32.hir b/tests/integration/expected/mul_i32.hir index 620be4d5..309b695c 100644 --- a/tests/integration/expected/mul_i32.hir +++ b/tests/integration/expected/mul_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_ad50b5f77c3af9c4039e595ae60a63c21aabcfcfe6d7e4eb39c9a0571800567c + (module #test_rust_262e71c5bff4a385e1ce68a8feb20203bbf0c528647e9c602609c0808d505876 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/mul_i32.masm b/tests/integration/expected/mul_i32.masm index 99c77c42..56b4b612 100644 --- a/tests/integration/expected/mul_i32.masm +++ b/tests/integration/expected/mul_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_ad50b5f77c3af9c4039e595ae60a63c21aabcfcfe6d7e4eb39c9a0571800567c +# mod test_rust_262e71c5bff4a385e1ce68a8feb20203bbf0c528647e9c602609c0808d505876 export.entrypoint exec.::intrinsics::i32::wrapping_mul end -begin - exec.::test_rust_ad50b5f77c3af9c4039e595ae60a63c21aabcfcfe6d7e4eb39c9a0571800567c::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/mul_i32.wat b/tests/integration/expected/mul_i32.wat index 68ac811e..0fb0b034 100644 --- a/tests/integration/expected/mul_i32.wat +++ b/tests/integration/expected/mul_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_ad50b5f77c3af9c4039e595ae60a63c21aabcfcfe6d7e4eb39c9a0571800567c.wasm +(module $test_rust_262e71c5bff4a385e1ce68a8feb20203bbf0c528647e9c602609c0808d505876.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/mul_i64.hir b/tests/integration/expected/mul_i64.hir index e79b3a2e..f5bb7abf 100644 --- a/tests/integration/expected/mul_i64.hir +++ b/tests/integration/expected/mul_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_d198e4586ddbf636e13d54de6b8a762c46fcea564f56b93e29a16b5649e747f5 + (module #test_rust_4fa4a84dc2c1fe1a2bc729c72d5e78982ba8edf5490a729e66438056dcb06101 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/mul_i64.masm b/tests/integration/expected/mul_i64.masm index 27c91945..1a6eda6f 100644 --- a/tests/integration/expected/mul_i64.masm +++ b/tests/integration/expected/mul_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_d198e4586ddbf636e13d54de6b8a762c46fcea564f56b93e29a16b5649e747f5 +# mod test_rust_4fa4a84dc2c1fe1a2bc729c72d5e78982ba8edf5490a729e66438056dcb06101 export.entrypoint exec.::intrinsics::i64::wrapping_mul end -begin - exec.::test_rust_d198e4586ddbf636e13d54de6b8a762c46fcea564f56b93e29a16b5649e747f5::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/mul_i64.wat b/tests/integration/expected/mul_i64.wat index 044b6a0b..ce0bdc6a 100644 --- a/tests/integration/expected/mul_i64.wat +++ b/tests/integration/expected/mul_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_d198e4586ddbf636e13d54de6b8a762c46fcea564f56b93e29a16b5649e747f5.wasm +(module $test_rust_4fa4a84dc2c1fe1a2bc729c72d5e78982ba8edf5490a729e66438056dcb06101.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/mul_u16.hir b/tests/integration/expected/mul_u16.hir index 64275bce..b85066c2 100644 --- a/tests/integration/expected/mul_u16.hir +++ b/tests/integration/expected/mul_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_2bf114751d03877d5976d178c9e1b38128ac81ec9976827c560835e1917c4441 + (module #test_rust_742f0d1b5e8390cf229b8c736825d5c524abf07a2bec3f4109afcc68d1547946 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/mul_u16.masm b/tests/integration/expected/mul_u16.masm index be7d8461..2162a097 100644 --- a/tests/integration/expected/mul_u16.masm +++ b/tests/integration/expected/mul_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_2bf114751d03877d5976d178c9e1b38128ac81ec9976827c560835e1917c4441 +# mod test_rust_742f0d1b5e8390cf229b8c736825d5c524abf07a2bec3f4109afcc68d1547946 export.entrypoint exec.::intrinsics::i32::wrapping_mul push.65535 u32and end -begin - exec.::test_rust_2bf114751d03877d5976d178c9e1b38128ac81ec9976827c560835e1917c4441::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/mul_u16.wat b/tests/integration/expected/mul_u16.wat index 472e9ae2..ac50cee5 100644 --- a/tests/integration/expected/mul_u16.wat +++ b/tests/integration/expected/mul_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_2bf114751d03877d5976d178c9e1b38128ac81ec9976827c560835e1917c4441.wasm +(module $test_rust_742f0d1b5e8390cf229b8c736825d5c524abf07a2bec3f4109afcc68d1547946.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/mul_u32.hir b/tests/integration/expected/mul_u32.hir index 0bec63a3..8d42ad96 100644 --- a/tests/integration/expected/mul_u32.hir +++ b/tests/integration/expected/mul_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_6eb39070e5a29f3624423f3b1c62b5df4ad908d273be81bfb0da39e84fb59be1 + (module #test_rust_b88e2ce441d27c44cb7d5b1e9a0fdde312f6e4c8ba7ce98f46069c983aef0f27 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/mul_u32.masm b/tests/integration/expected/mul_u32.masm index 6574a529..944ecdab 100644 --- a/tests/integration/expected/mul_u32.masm +++ b/tests/integration/expected/mul_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_6eb39070e5a29f3624423f3b1c62b5df4ad908d273be81bfb0da39e84fb59be1 +# mod test_rust_b88e2ce441d27c44cb7d5b1e9a0fdde312f6e4c8ba7ce98f46069c983aef0f27 export.entrypoint exec.::intrinsics::i32::wrapping_mul end -begin - exec.::test_rust_6eb39070e5a29f3624423f3b1c62b5df4ad908d273be81bfb0da39e84fb59be1::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/mul_u32.wat b/tests/integration/expected/mul_u32.wat index 224a0b69..f90d24a0 100644 --- a/tests/integration/expected/mul_u32.wat +++ b/tests/integration/expected/mul_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_6eb39070e5a29f3624423f3b1c62b5df4ad908d273be81bfb0da39e84fb59be1.wasm +(module $test_rust_b88e2ce441d27c44cb7d5b1e9a0fdde312f6e4c8ba7ce98f46069c983aef0f27.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/mul_u64.hir b/tests/integration/expected/mul_u64.hir index e10c171f..d0a2c942 100644 --- a/tests/integration/expected/mul_u64.hir +++ b/tests/integration/expected/mul_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_873d7388fcc4ee534ec2730026c14ba8e8b6f0fcb2133a11b18c2b4c23407376 + (module #test_rust_ac7483d8e665bc8618c926c4a827af8cc8b060db1a400373319417a1045674f6 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/mul_u64.masm b/tests/integration/expected/mul_u64.masm index c2d7af4d..3b87e668 100644 --- a/tests/integration/expected/mul_u64.masm +++ b/tests/integration/expected/mul_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_873d7388fcc4ee534ec2730026c14ba8e8b6f0fcb2133a11b18c2b4c23407376 +# mod test_rust_ac7483d8e665bc8618c926c4a827af8cc8b060db1a400373319417a1045674f6 export.entrypoint exec.::intrinsics::i64::wrapping_mul end -begin - exec.::test_rust_873d7388fcc4ee534ec2730026c14ba8e8b6f0fcb2133a11b18c2b4c23407376::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/mul_u64.wat b/tests/integration/expected/mul_u64.wat index b1bd6ab1..9aab11d0 100644 --- a/tests/integration/expected/mul_u64.wat +++ b/tests/integration/expected/mul_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_873d7388fcc4ee534ec2730026c14ba8e8b6f0fcb2133a11b18c2b4c23407376.wasm +(module $test_rust_ac7483d8e665bc8618c926c4a827af8cc8b060db1a400373319417a1045674f6.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 1 diff --git a/tests/integration/expected/mul_u8.hir b/tests/integration/expected/mul_u8.hir index b34e8043..10ea42fb 100644 --- a/tests/integration/expected/mul_u8.hir +++ b/tests/integration/expected/mul_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_e557e8c2e11bc35c8a219dc14251faf969af186526834f40cf61132c24bfdefe + (module #test_rust_ca665f22f7b5ce9ba2e09ff8053ec1ab7a69e93524c27a02273f65f21b7b3e9a ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/mul_u8.masm b/tests/integration/expected/mul_u8.masm index 417512f1..e6dc9366 100644 --- a/tests/integration/expected/mul_u8.masm +++ b/tests/integration/expected/mul_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_e557e8c2e11bc35c8a219dc14251faf969af186526834f40cf61132c24bfdefe +# mod test_rust_ca665f22f7b5ce9ba2e09ff8053ec1ab7a69e93524c27a02273f65f21b7b3e9a export.entrypoint exec.::intrinsics::i32::wrapping_mul push.255 u32and end -begin - exec.::test_rust_e557e8c2e11bc35c8a219dc14251faf969af186526834f40cf61132c24bfdefe::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/mul_u8.wat b/tests/integration/expected/mul_u8.wat index 3af5de35..65768278 100644 --- a/tests/integration/expected/mul_u8.wat +++ b/tests/integration/expected/mul_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_e557e8c2e11bc35c8a219dc14251faf969af186526834f40cf61132c24bfdefe.wasm +(module $test_rust_ca665f22f7b5ce9ba2e09ff8053ec1ab7a69e93524c27a02273f65f21b7b3e9a.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 1 diff --git a/tests/integration/expected/neg_felt.masm b/tests/integration/expected/neg_felt.masm index b70bd089..3a7aa763 100644 --- a/tests/integration/expected/neg_felt.masm +++ b/tests/integration/expected/neg_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::neg_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/neg_i16.hir b/tests/integration/expected/neg_i16.hir index 4e5d4eca..ac10683d 100644 --- a/tests/integration/expected/neg_i16.hir +++ b/tests/integration/expected/neg_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_8885ff83d4718aec39ee91baf1b6d9155897ac6940d8acb4ee8af80ac24d7630 + (module #test_rust_ba1c5a590d707919e2a80d5ac961624d71143891517702d79d0d07e5430ec666 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/neg_i16.masm b/tests/integration/expected/neg_i16.masm index 86263e52..be7b74b7 100644 --- a/tests/integration/expected/neg_i16.masm +++ b/tests/integration/expected/neg_i16.masm @@ -1,10 +1,7 @@ -# mod test_rust_8885ff83d4718aec39ee91baf1b6d9155897ac6940d8acb4ee8af80ac24d7630 +# mod test_rust_ba1c5a590d707919e2a80d5ac961624d71143891517702d79d0d07e5430ec666 export.entrypoint push.0 swap.1 u32wrapping_sub end -begin - exec.::test_rust_8885ff83d4718aec39ee91baf1b6d9155897ac6940d8acb4ee8af80ac24d7630::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/neg_i16.wat b/tests/integration/expected/neg_i16.wat index 66715dce..12f5f714 100644 --- a/tests/integration/expected/neg_i16.wat +++ b/tests/integration/expected/neg_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_8885ff83d4718aec39ee91baf1b6d9155897ac6940d8acb4ee8af80ac24d7630.wasm +(module $test_rust_ba1c5a590d707919e2a80d5ac961624d71143891517702d79d0d07e5430ec666.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) i32.const 0 diff --git a/tests/integration/expected/neg_i32.hir b/tests/integration/expected/neg_i32.hir index 67482486..7badaf76 100644 --- a/tests/integration/expected/neg_i32.hir +++ b/tests/integration/expected/neg_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_4d99fac9eee91dee5488ef87e46cd372efb54cac7088374c284c7fe1d592975b + (module #test_rust_c8278a646eb10b96eaa494478de597b1874226f5f5037ee4923d9049413f8317 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/neg_i32.masm b/tests/integration/expected/neg_i32.masm index 1b6712e5..378047ff 100644 --- a/tests/integration/expected/neg_i32.masm +++ b/tests/integration/expected/neg_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_4d99fac9eee91dee5488ef87e46cd372efb54cac7088374c284c7fe1d592975b +# mod test_rust_c8278a646eb10b96eaa494478de597b1874226f5f5037ee4923d9049413f8317 export.entrypoint push.0 swap.1 u32wrapping_sub end -begin - exec.::test_rust_4d99fac9eee91dee5488ef87e46cd372efb54cac7088374c284c7fe1d592975b::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/neg_i32.wat b/tests/integration/expected/neg_i32.wat index 5df52918..e4c6ab84 100644 --- a/tests/integration/expected/neg_i32.wat +++ b/tests/integration/expected/neg_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_4d99fac9eee91dee5488ef87e46cd372efb54cac7088374c284c7fe1d592975b.wasm +(module $test_rust_c8278a646eb10b96eaa494478de597b1874226f5f5037ee4923d9049413f8317.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) i32.const 0 diff --git a/tests/integration/expected/neg_i64.hir b/tests/integration/expected/neg_i64.hir index 45c0c5ce..73b59d58 100644 --- a/tests/integration/expected/neg_i64.hir +++ b/tests/integration/expected/neg_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c8167195a46a2ae0e4078c05a9d8411edc352c67e27b8061209b0705ca4830c7 + (module #test_rust_01dcb6fbaad510deb917ef5e283ccfaa280559139455d99f8b7c76af466af9dd ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/neg_i64.masm b/tests/integration/expected/neg_i64.masm index 80d466ae..fdb3f2c1 100644 --- a/tests/integration/expected/neg_i64.masm +++ b/tests/integration/expected/neg_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_c8167195a46a2ae0e4078c05a9d8411edc352c67e27b8061209b0705ca4830c7 +# mod test_rust_01dcb6fbaad510deb917ef5e283ccfaa280559139455d99f8b7c76af466af9dd export.entrypoint push.0.0 movdn.3 movdn.3 exec.::std::math::u64::wrapping_sub end -begin - exec.::test_rust_c8167195a46a2ae0e4078c05a9d8411edc352c67e27b8061209b0705ca4830c7::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/neg_i64.wat b/tests/integration/expected/neg_i64.wat index 63ec8c4b..03e8c917 100644 --- a/tests/integration/expected/neg_i64.wat +++ b/tests/integration/expected/neg_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_c8167195a46a2ae0e4078c05a9d8411edc352c67e27b8061209b0705ca4830c7.wasm +(module $test_rust_01dcb6fbaad510deb917ef5e283ccfaa280559139455d99f8b7c76af466af9dd.wasm (type (;0;) (func (param i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64) (result i64) i64.const 0 diff --git a/tests/integration/expected/neg_i8.hir b/tests/integration/expected/neg_i8.hir index f67cc7fb..69d5ff09 100644 --- a/tests/integration/expected/neg_i8.hir +++ b/tests/integration/expected/neg_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_a39cb19de351625b19b45683e68f0c391a8f9d3ac2c0b47dfe1db9e27887fc29 + (module #test_rust_c284c5e58a865bc45e93bf2024b2c204ef39187b90a2cf9cc04c023ea2f4fe6d ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/neg_i8.masm b/tests/integration/expected/neg_i8.masm index ce06cbc5..46209a74 100644 --- a/tests/integration/expected/neg_i8.masm +++ b/tests/integration/expected/neg_i8.masm @@ -1,10 +1,7 @@ -# mod test_rust_a39cb19de351625b19b45683e68f0c391a8f9d3ac2c0b47dfe1db9e27887fc29 +# mod test_rust_c284c5e58a865bc45e93bf2024b2c204ef39187b90a2cf9cc04c023ea2f4fe6d export.entrypoint push.0 swap.1 u32wrapping_sub end -begin - exec.::test_rust_a39cb19de351625b19b45683e68f0c391a8f9d3ac2c0b47dfe1db9e27887fc29::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/neg_i8.wat b/tests/integration/expected/neg_i8.wat index a607522b..38fbf8db 100644 --- a/tests/integration/expected/neg_i8.wat +++ b/tests/integration/expected/neg_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_a39cb19de351625b19b45683e68f0c391a8f9d3ac2c0b47dfe1db9e27887fc29.wasm +(module $test_rust_c284c5e58a865bc45e93bf2024b2c204ef39187b90a2cf9cc04c023ea2f4fe6d.wasm (type (;0;) (func (param i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32) (result i32) i32.const 0 diff --git a/tests/integration/expected/or_bool.hir b/tests/integration/expected/or_bool.hir index 78622c16..68058486 100644 --- a/tests/integration/expected/or_bool.hir +++ b/tests/integration/expected/or_bool.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_b27aa658e891a67a41e3a9a972e49580fe9cb8844832b2b63b81e01624e5acca + (module #test_rust_fcd39ca2fcbe5490a38db6dfe57f9ead120d9b7ced8d4170a040c64bd03b0413 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/or_bool.masm b/tests/integration/expected/or_bool.masm index 24c0b2b4..65970c3b 100644 --- a/tests/integration/expected/or_bool.masm +++ b/tests/integration/expected/or_bool.masm @@ -1,10 +1,7 @@ -# mod test_rust_b27aa658e891a67a41e3a9a972e49580fe9cb8844832b2b63b81e01624e5acca +# mod test_rust_fcd39ca2fcbe5490a38db6dfe57f9ead120d9b7ced8d4170a040c64bd03b0413 export.entrypoint swap.1 u32or end -begin - exec.::test_rust_b27aa658e891a67a41e3a9a972e49580fe9cb8844832b2b63b81e01624e5acca::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/or_bool.wat b/tests/integration/expected/or_bool.wat index 18323199..3f519e2a 100644 --- a/tests/integration/expected/or_bool.wat +++ b/tests/integration/expected/or_bool.wat @@ -1,4 +1,4 @@ -(module $test_rust_b27aa658e891a67a41e3a9a972e49580fe9cb8844832b2b63b81e01624e5acca.wasm +(module $test_rust_fcd39ca2fcbe5490a38db6dfe57f9ead120d9b7ced8d4170a040c64bd03b0413.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/rust_sdk_account_test/miden_sdk_account_test.hir b/tests/integration/expected/rust_sdk_account_test/miden_sdk_account_test.hir index 1883f5ac..b457b359 100644 --- a/tests/integration/expected/rust_sdk_account_test/miden_sdk_account_test.hir +++ b/tests/integration/expected/rust_sdk_account_test/miden_sdk_account_test.hir @@ -2,16 +2,11 @@ ;; Component Imports (lower ((digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi canon) (param felt) (param felt) (param felt) (param felt) (result felt felt felt felt)))) (#miden::account #add_asset) (lower ((digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi canon) (param felt) (param felt) (param felt) (param felt) (result felt felt felt felt)))) (#miden::account #remove_asset) - (lower ((digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi canon) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt)))) (#miden:stdlib/std_crypto_dsa #rpo_falcon512_verify) - (lower ((digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi canon) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param i32) (param i32) (result felt felt felt felt felt felt felt felt felt felt felt felt i32)))) (#miden:stdlib/std_mem #pipe_double_words_to_memory) - (lower ((digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi canon) (param felt) (param i32) (result felt felt felt felt i32)))) (#miden:stdlib/std_mem #pipe_words_to_memory) - (lower ((digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi canon) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (result felt felt felt felt felt felt felt felt)))) (#std::crypto_hashes #blake3_hash_2to1) + (lower ((digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi canon) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32 i32 i32 i32 i32 i32 i32 i32)))) (#std::crypto::hashes::blake3 #hash_2to1) + (lower ((digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi canon) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param i32) (param i32) (result felt felt felt felt felt felt felt felt felt felt felt felt i32)))) (#std::mem #pipe_double_words_to_memory) ;; Modules (module #miden_sdk_account_test - ;; Data Segments - (data (mut) (offset 1048576) 0x7e2f73646b2f7374646c69622d7379732f7372632f7374646c69622f63727970746f2f6861736865732e7273000010002c0000008a00000028000000000010002c000000d000000028000000) - ;; Constants (const (id 0) 0x00100000) @@ -28,32 +23,32 @@ (let (v4 i32) (sub.wrapping v2 v3)) (let (v5 (ptr i32)) (global.symbol #__stack_pointer)) (store v5 v4) - (let (v6 u32) (cast v0)) - (let (v7 u32) (mod.unchecked v6 2)) - (assertz v7) + (let (v6 u32) (bitcast v0)) + (let (v7 u32) (mod.unchecked v6 4)) + (assertz 250 v7) (let (v8 (ptr i32)) (inttoptr v6)) (let (v9 i32) (load v8)) - (let (v10 u32) (cast v9)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (let (v10 u32) (bitcast v9)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr i32)) (inttoptr v10)) (let (v13 i32) (load v12)) - (let (v14 u32) (cast v4)) + (let (v14 u32) (bitcast v4)) (let (v15 u32) (add.checked v14 12)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr i32)) (inttoptr v15)) (store v17 v13) - (let (v18 u32) (cast v9)) + (let (v18 u32) (bitcast v9)) (let (v19 u32) (add.checked v18 8)) - (let (v20 u32) (mod.unchecked v19 2)) - (assertz v20) + (let (v20 u32) (mod.unchecked v19 4)) + (assertz 250 v20) (let (v21 (ptr i32)) (inttoptr v19)) (let (v22 i32) (load v21)) - (let (v23 u32) (cast v4)) + (let (v23 u32) (bitcast v4)) (let (v24 u32) (add.checked v23 8)) - (let (v25 u32) (mod.unchecked v24 2)) - (assertz v25) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) (let (v26 (ptr i32)) (inttoptr v24)) (store v26 v22) (let (v27 i32) (const.i32 8)) @@ -73,9 +68,9 @@ (param i32) (block 0 (param v0 i32) (let (v1 i32) (const.i32 0)) - (let (v2 u32) (cast v0)) - (let (v3 u32) (mod.unchecked v2 2)) - (assertz v3) + (let (v2 u32) (bitcast v0)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) (let (v4 (ptr i32)) (inttoptr v2)) (let (v5 i32) (load v4)) (let (v6 i1) (eq v5 0)) @@ -90,10 +85,10 @@ (br (block 1))) (block 3 - (let (v9 u32) (cast v0)) + (let (v9 u32) (bitcast v0)) (let (v10 u32) (add.checked v9 4)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr i32)) (inttoptr v10)) (let (v13 i32) (load v12)) (let (v14 i32) (const.i32 2)) @@ -123,7 +118,7 @@ (let (v8 i32) (const.i32 0)) (let (v9 u8) (trunc v8)) (let (v10 u32) (bitcast v2)) - (let (v11 u32) (cast v4)) + (let (v11 u32) (bitcast v4)) (let (v12 (ptr u8)) (inttoptr v11)) (memset v12 v10 v9) (br (block 2 v4))) @@ -131,7 +126,7 @@ (func (export #__rust_dealloc) (param i32) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) - (let (v3 i32) (const.i32 1048652)) + (let (v3 i32) (const.i32 1048576)) (call #::dealloc v3 v0 v2 v1) (br (block 1))) @@ -148,10 +143,10 @@ (let (v4 i32) (sub.wrapping v2 v3)) (let (v5 (ptr i32)) (global.symbol #__stack_pointer)) (store v5 v4) - (let (v6 u32) (cast v4)) + (let (v6 u32) (bitcast v4)) (let (v7 u32) (add.checked v6 12)) - (let (v8 u32) (mod.unchecked v7 2)) - (assertz v8) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) (let (v9 (ptr i32)) (inttoptr v7)) (store v9 v0) (let (v10 i32) (const.i32 12)) @@ -170,7 +165,7 @@ (func (export #get_wallet_magic_number) (result felt) (block 0 (let (v1 felt) (const.felt 0)) - (let (v2 felt) (call #miden_tx_kernel_sys::get_id)) + (let (v2 felt) (call #miden_base_sys::bindings::tx::get_id)) (let (v3 i64) (const.i64 42)) (let (v4 felt) (cast v3)) (let (v5 felt) (add.unchecked v4 v2)) @@ -197,36 +192,36 @@ (let (v12 felt) (cast v11)) (let (v13 i64) (const.i64 4)) (let (v14 felt) (cast v13)) - (let (v15 u32) (cast v5)) + (let (v15 u32) (bitcast v5)) (let (v16 u32) (add.checked v15 12)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) (let (v18 (ptr felt)) (inttoptr v16)) (store v18 v14) - (let (v19 u32) (cast v5)) + (let (v19 u32) (bitcast v5)) (let (v20 u32) (add.checked v19 8)) - (let (v21 u32) (mod.unchecked v20 2)) - (assertz v21) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) (let (v22 (ptr felt)) (inttoptr v20)) (store v22 v12) - (let (v23 u32) (cast v5)) + (let (v23 u32) (bitcast v5)) (let (v24 u32) (add.checked v23 4)) - (let (v25 u32) (mod.unchecked v24 2)) - (assertz v25) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) (let (v26 (ptr felt)) (inttoptr v24)) (store v26 v10) - (let (v27 u32) (cast v5)) - (let (v28 u32) (mod.unchecked v27 2)) - (assertz v28) + (let (v27 u32) (bitcast v5)) + (let (v28 u32) (mod.unchecked v27 4)) + (assertz 250 v28) (let (v29 (ptr felt)) (inttoptr v27)) (store v29 v8) (let (v30 i32) (const.i32 16)) (let (v31 i32) (add.wrapping v5 v30)) - (call #miden_tx_kernel_sys::add_asset v31 v5) - (let (v32 u32) (cast v5)) + (call #miden_base_sys::bindings::tx::add_asset v31 v5) + (let (v32 u32) (bitcast v5)) (let (v33 u32) (add.checked v32 16)) - (let (v34 u32) (mod.unchecked v33 2)) - (assertz v34) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) (let (v35 (ptr felt)) (inttoptr v33)) (let (v36 felt) (load v35)) (let (v37 i32) (const.i32 32)) @@ -344,43 +339,43 @@ (store v7 v6) (let (v8 i64) (const.i64 0)) (let (v9 felt) (cast v8)) - (call #miden_tx_kernel_sys::get_inputs v6) - (let (v10 u32) (cast v6)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (call #miden_base_sys::bindings::tx::get_inputs v6) + (let (v10 u32) (bitcast v6)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr i32)) (inttoptr v10)) (let (v13 i32) (load v12)) - (let (v14 u32) (cast v6)) + (let (v14 u32) (bitcast v6)) (let (v15 u32) (add.checked v14 4)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr i32)) (inttoptr v15)) (let (v18 i32) (load v17)) - (let (v19 u32) (cast v6)) + (let (v19 u32) (bitcast v6)) (let (v20 u32) (add.checked v19 8)) - (let (v21 u32) (mod.unchecked v20 2)) - (assertz v21) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) (let (v22 (ptr i32)) (inttoptr v20)) (let (v23 i32) (load v22)) (let (v24 i32) (const.i32 2)) (let (v25 u32) (bitcast v24)) (let (v26 i32) (shl.wrapping v23 v25)) (let (v27 i32) (add.wrapping v18 v26)) - (let (v28 u32) (cast v6)) + (let (v28 u32) (bitcast v6)) (let (v29 u32) (add.checked v28 12)) - (let (v30 u32) (mod.unchecked v29 2)) - (assertz v30) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) (let (v31 (ptr i32)) (inttoptr v29)) (store v31 v27) - (let (v32 u32) (cast v6)) + (let (v32 u32) (bitcast v6)) (let (v33 u32) (add.checked v32 8)) - (let (v34 u32) (mod.unchecked v33 2)) - (assertz v34) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) (let (v35 (ptr i32)) (inttoptr v33)) (store v35 v13) - (let (v36 u32) (cast v6)) - (let (v37 u32) (mod.unchecked v36 2)) - (assertz v37) + (let (v36 u32) (bitcast v6)) + (let (v37 u32) (mod.unchecked v36 4)) + (assertz 250 v37) (let (v38 (ptr i32)) (inttoptr v36)) (store v38 v18) (br (block 2 v26 v6 v27 v9 v18))) @@ -401,9 +396,9 @@ (block 4 (let (v52 i32) (const.i32 -4)) (let (v53 i32) (add.wrapping v40 v52)) - (let (v55 u32) (cast v54)) - (let (v56 u32) (mod.unchecked v55 2)) - (assertz v56) + (let (v55 u32) (bitcast v54)) + (let (v56 u32) (mod.unchecked v55 4)) + (assertz 250 v56) (let (v57 (ptr felt)) (inttoptr v55)) (let (v58 felt) (load v57)) (let (v59 felt) (add.unchecked v51 v58)) @@ -412,10 +407,10 @@ (br (block 2 v53 v42 v43 v59 v61))) (block 5 - (let (v44 u32) (cast v42)) + (let (v44 u32) (bitcast v42)) (let (v45 u32) (add.checked v44 4)) - (let (v46 u32) (mod.unchecked v45 2)) - (assertz v46) + (let (v46 u32) (mod.unchecked v45 4)) + (assertz 250 v46) (let (v47 (ptr i32)) (inttoptr v45)) (store v47 v43) (call # as core::ops::drop::Drop>::drop v42) @@ -428,827 +423,213 @@ (func (export #test_blake3_hash_1to1) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) - (let (v2 i32) (const.i32 0)) - (let (v3 felt) (const.felt 0)) - (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v5 i32) (const.i32 144)) - (let (v6 i32) (sub.wrapping v4 v5)) - (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) - (store v7 v6) - (let (v8 i32) (const.i32 0)) - (let (v9 i64) (const.i64 0)) - (let (v10 felt) (cast v9)) - (br (block 2 v8 v6 v1 v0 v10))) - - (block 1) - - (block 2 - (param v11 i32) - (param v216 i32) - (param v217 i32) - (param v220 i32) - (param v270 felt) - (let (v12 i32) (const.i32 32)) - (let (v13 i1) (neq v11 v12)) - (let (v14 i32) (zext v13)) - (let (v15 i1) (neq v14 0)) - (condbr v15 (block 4) (block 5))) - - (block 3) - - (block 4 - (let (v267 i32) (const.i32 8)) - (let (v268 i32) (add.wrapping v216 v267)) - (let (v269 i32) (add.wrapping v268 v11)) - (let (v271 u32) (cast v269)) - (let (v272 u32) (mod.unchecked v271 2)) - (assertz v272) - (let (v273 (ptr felt)) (inttoptr v271)) - (store v273 v270) - (let (v274 i32) (const.i32 4)) - (let (v275 i32) (add.wrapping v11 v274)) - (br (block 2 v275 v216 v217 v220 v270))) - - (block 5 - (let (v16 i32) (const.i32 0)) - (br (block 7 v16 v216 v217 v220))) + (let (v2 u32) (bitcast v1)) + (let (v3 (ptr i32)) (inttoptr v2)) + (let (v4 i32) (load v3)) + (let (v5 u32) (bitcast v1)) + (let (v6 u32) (add.checked v5 4)) + (let (v7 (ptr i32)) (inttoptr v6)) + (let (v8 i32) (load v7)) + (let (v9 u32) (bitcast v1)) + (let (v10 u32) (add.checked v9 8)) + (let (v11 (ptr i32)) (inttoptr v10)) + (let (v12 i32) (load v11)) + (let (v13 u32) (bitcast v1)) + (let (v14 u32) (add.checked v13 12)) + (let (v15 (ptr i32)) (inttoptr v14)) + (let (v16 i32) (load v15)) + (let (v17 u32) (bitcast v1)) + (let (v18 u32) (add.checked v17 16)) + (let (v19 (ptr i32)) (inttoptr v18)) + (let (v20 i32) (load v19)) + (let (v21 u32) (bitcast v1)) + (let (v22 u32) (add.checked v21 20)) + (let (v23 (ptr i32)) (inttoptr v22)) + (let (v24 i32) (load v23)) + (let (v25 u32) (bitcast v1)) + (let (v26 u32) (add.checked v25 24)) + (let (v27 (ptr i32)) (inttoptr v26)) + (let (v28 i32) (load v27)) + (let (v29 u32) (bitcast v1)) + (let (v30 u32) (add.checked v29 28)) + (let (v31 (ptr i32)) (inttoptr v30)) + (let (v32 i32) (load v31)) + (let [(v33 i32) (v34 i32) (v35 i32) (v36 i32) (v37 i32) (v38 i32) (v39 i32) (v40 i32)] (call (#std::crypto::hashes::blake3 #hash_1to1) v4 v8 v12 v16 v20 v24 v28 v32)) + (let (v41 u32) (cast v0)) + (let (v42 (ptr i32)) (inttoptr v41)) + (store v42 v33) + (let (v43 u32) (add.checked v41 8)) + (let (v44 (ptr i32)) (inttoptr v43)) + (store v44 v34) + (let (v45 u32) (add.checked v41 16)) + (let (v46 (ptr i32)) (inttoptr v45)) + (store v46 v35) + (let (v47 u32) (add.checked v41 24)) + (let (v48 (ptr i32)) (inttoptr v47)) + (store v48 v36) + (let (v49 u32) (add.checked v41 32)) + (let (v50 (ptr i32)) (inttoptr v49)) + (store v50 v37) + (let (v51 u32) (add.checked v41 40)) + (let (v52 (ptr i32)) (inttoptr v51)) + (store v52 v38) + (let (v53 u32) (add.checked v41 48)) + (let (v54 (ptr i32)) (inttoptr v53)) + (store v54 v39) + (let (v55 u32) (add.checked v41 56)) + (let (v56 (ptr i32)) (inttoptr v55)) + (store v56 v40) + (br (block 1))) - (block 6 - (let (v221 u32) (cast v178)) - (let (v222 u32) (add.checked v221 104)) - (let (v223 u32) (mod.unchecked v222 3)) - (assertz v223) - (let (v224 (ptr i64)) (inttoptr v222)) - (let (v225 i64) (load v224)) - (let (v226 u32) (cast v218)) - (let (v227 (ptr i64)) (inttoptr v226)) - (store v227 v225) - (let (v228 i32) (const.i32 24)) - (let (v229 i32) (add.wrapping v218 v228)) - (let (v230 i32) (const.i32 104)) - (let (v231 i32) (add.wrapping v178 v230)) - (let (v232 i32) (const.i32 24)) - (let (v233 i32) (add.wrapping v231 v232)) - (let (v234 u32) (cast v233)) - (let (v235 u32) (mod.unchecked v234 3)) - (assertz v235) - (let (v236 (ptr i64)) (inttoptr v234)) - (let (v237 i64) (load v236)) - (let (v238 u32) (cast v229)) - (let (v239 (ptr i64)) (inttoptr v238)) - (store v239 v237) - (let (v240 i32) (const.i32 16)) - (let (v241 i32) (add.wrapping v218 v240)) - (let (v242 i32) (const.i32 104)) - (let (v243 i32) (add.wrapping v178 v242)) - (let (v244 i32) (const.i32 16)) - (let (v245 i32) (add.wrapping v243 v244)) - (let (v246 u32) (cast v245)) - (let (v247 u32) (mod.unchecked v246 3)) - (assertz v247) - (let (v248 (ptr i64)) (inttoptr v246)) - (let (v249 i64) (load v248)) - (let (v250 u32) (cast v241)) - (let (v251 (ptr i64)) (inttoptr v250)) - (store v251 v249) - (let (v252 i32) (const.i32 8)) - (let (v253 i32) (add.wrapping v218 v252)) - (let (v254 i32) (const.i32 104)) - (let (v255 i32) (add.wrapping v178 v254)) - (let (v256 i32) (const.i32 8)) - (let (v257 i32) (add.wrapping v255 v256)) - (let (v258 u32) (cast v257)) - (let (v259 u32) (mod.unchecked v258 3)) - (assertz v259) - (let (v260 (ptr i64)) (inttoptr v258)) - (let (v261 i64) (load v260)) - (let (v262 u32) (cast v253)) - (let (v263 (ptr i64)) (inttoptr v262)) - (store v263 v261) - (let (v264 i32) (const.i32 144)) - (let (v265 i32) (add.wrapping v178 v264)) - (let (v266 (ptr i32)) (global.symbol #__stack_pointer)) - (store v266 v265) + (block 1 (ret)) + ) - (block 7 - (param v17 i32) - (param v22 i32) - (param v204 i32) - (param v219 i32) - (let (v18 i32) (const.i32 32)) - (let (v19 i1) (neq v17 v18)) - (let (v20 i32) (zext v19)) - (let (v21 i1) (neq v20 0)) - (condbr v21 (block 9) (block 10))) - - (block 8) - - (block 9 - (let (v201 i32) (const.i32 8)) - (let (v202 i32) (add.wrapping v22 v201)) - (let (v203 i32) (add.wrapping v202 v17)) - (let (v205 i32) (add.wrapping v204 v17)) - (let (v206 u32) (cast v205)) - (let (v207 (ptr u32)) (inttoptr v206)) - (let (v208 u32) (load v207)) - (let (v209 i64) (zext v208)) - (let (v210 felt) (cast v209)) - (let (v211 u32) (cast v203)) - (let (v212 u32) (mod.unchecked v211 2)) - (assertz v212) - (let (v213 (ptr felt)) (inttoptr v211)) - (store v213 v210) - (let (v214 i32) (const.i32 4)) - (let (v215 i32) (add.wrapping v17 v214)) - (br (block 7 v215 v22 v204 v219))) - - (block 10 - (let (v23 u32) (cast v22)) - (let (v24 u32) (add.checked v23 8)) - (let (v25 u32) (mod.unchecked v24 2)) - (assertz v25) - (let (v26 (ptr felt)) (inttoptr v24)) - (let (v27 felt) (load v26)) - (let (v28 u32) (cast v22)) - (let (v29 u32) (add.checked v28 12)) - (let (v30 u32) (mod.unchecked v29 2)) - (assertz v30) - (let (v31 (ptr felt)) (inttoptr v29)) - (let (v32 felt) (load v31)) - (let (v33 u32) (cast v22)) - (let (v34 u32) (add.checked v33 16)) - (let (v35 u32) (mod.unchecked v34 2)) - (assertz v35) - (let (v36 (ptr felt)) (inttoptr v34)) - (let (v37 felt) (load v36)) - (let (v38 u32) (cast v22)) - (let (v39 u32) (add.checked v38 20)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) - (let (v41 (ptr felt)) (inttoptr v39)) - (let (v42 felt) (load v41)) - (let (v43 u32) (cast v22)) - (let (v44 u32) (add.checked v43 24)) - (let (v45 u32) (mod.unchecked v44 2)) - (assertz v45) - (let (v46 (ptr felt)) (inttoptr v44)) - (let (v47 felt) (load v46)) - (let (v48 u32) (cast v22)) - (let (v49 u32) (add.checked v48 28)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr felt)) (inttoptr v49)) - (let (v52 felt) (load v51)) - (let (v53 u32) (cast v22)) - (let (v54 u32) (add.checked v53 32)) - (let (v55 u32) (mod.unchecked v54 2)) - (assertz v55) - (let (v56 (ptr felt)) (inttoptr v54)) - (let (v57 felt) (load v56)) - (let (v58 u32) (cast v22)) - (let (v59 u32) (add.checked v58 36)) - (let (v60 u32) (mod.unchecked v59 2)) - (assertz v60) - (let (v61 (ptr felt)) (inttoptr v59)) - (let (v62 felt) (load v61)) - (let (v63 i32) (const.i32 40)) - (let (v64 i32) (add.wrapping v22 v63)) - (let [(v65 felt) (v66 felt) (v67 felt) (v68 felt) (v69 felt) (v70 felt) (v71 felt) (v72 felt)] (call (#std::crypto_hashes #blake3_hash_1to1) v27 v32 v37 v42 v47 v52 v57 v62)) - (let (v73 u32) (cast v64)) - (let (v74 (ptr felt)) (inttoptr v73)) + (func (export #test_blake3_hash_2to1) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v2 u32) (bitcast v1)) + (let (v3 (ptr i32)) (inttoptr v2)) + (let (v4 i32) (load v3)) + (let (v5 u32) (bitcast v1)) + (let (v6 u32) (add.checked v5 4)) + (let (v7 (ptr i32)) (inttoptr v6)) + (let (v8 i32) (load v7)) + (let (v9 u32) (bitcast v1)) + (let (v10 u32) (add.checked v9 8)) + (let (v11 (ptr i32)) (inttoptr v10)) + (let (v12 i32) (load v11)) + (let (v13 u32) (bitcast v1)) + (let (v14 u32) (add.checked v13 12)) + (let (v15 (ptr i32)) (inttoptr v14)) + (let (v16 i32) (load v15)) + (let (v17 u32) (bitcast v1)) + (let (v18 u32) (add.checked v17 16)) + (let (v19 (ptr i32)) (inttoptr v18)) + (let (v20 i32) (load v19)) + (let (v21 u32) (bitcast v1)) + (let (v22 u32) (add.checked v21 20)) + (let (v23 (ptr i32)) (inttoptr v22)) + (let (v24 i32) (load v23)) + (let (v25 u32) (bitcast v1)) + (let (v26 u32) (add.checked v25 24)) + (let (v27 (ptr i32)) (inttoptr v26)) + (let (v28 i32) (load v27)) + (let (v29 u32) (bitcast v1)) + (let (v30 u32) (add.checked v29 28)) + (let (v31 (ptr i32)) (inttoptr v30)) + (let (v32 i32) (load v31)) + (let (v33 u32) (bitcast v1)) + (let (v34 u32) (add.checked v33 32)) + (let (v35 (ptr i32)) (inttoptr v34)) + (let (v36 i32) (load v35)) + (let (v37 u32) (bitcast v1)) + (let (v38 u32) (add.checked v37 36)) + (let (v39 (ptr i32)) (inttoptr v38)) + (let (v40 i32) (load v39)) + (let (v41 u32) (bitcast v1)) + (let (v42 u32) (add.checked v41 40)) + (let (v43 (ptr i32)) (inttoptr v42)) + (let (v44 i32) (load v43)) + (let (v45 u32) (bitcast v1)) + (let (v46 u32) (add.checked v45 44)) + (let (v47 (ptr i32)) (inttoptr v46)) + (let (v48 i32) (load v47)) + (let (v49 u32) (bitcast v1)) + (let (v50 u32) (add.checked v49 48)) + (let (v51 (ptr i32)) (inttoptr v50)) + (let (v52 i32) (load v51)) + (let (v53 u32) (bitcast v1)) + (let (v54 u32) (add.checked v53 52)) + (let (v55 (ptr i32)) (inttoptr v54)) + (let (v56 i32) (load v55)) + (let (v57 u32) (bitcast v1)) + (let (v58 u32) (add.checked v57 56)) + (let (v59 (ptr i32)) (inttoptr v58)) + (let (v60 i32) (load v59)) + (let (v61 u32) (bitcast v1)) + (let (v62 u32) (add.checked v61 60)) + (let (v63 (ptr i32)) (inttoptr v62)) + (let (v64 i32) (load v63)) + (let [(v65 i32) (v66 i32) (v67 i32) (v68 i32) (v69 i32) (v70 i32) (v71 i32) (v72 i32)] (call (#std::crypto::hashes::blake3 #hash_2to1) v4 v8 v12 v16 v20 v24 v28 v32 v36 v40 v44 v48 v52 v56 v60 v64)) + (let (v73 u32) (cast v0)) + (let (v74 (ptr i32)) (inttoptr v73)) (store v74 v65) (let (v75 u32) (add.checked v73 8)) - (let (v76 (ptr felt)) (inttoptr v75)) + (let (v76 (ptr i32)) (inttoptr v75)) (store v76 v66) (let (v77 u32) (add.checked v73 16)) - (let (v78 (ptr felt)) (inttoptr v77)) + (let (v78 (ptr i32)) (inttoptr v77)) (store v78 v67) (let (v79 u32) (add.checked v73 24)) - (let (v80 (ptr felt)) (inttoptr v79)) + (let (v80 (ptr i32)) (inttoptr v79)) (store v80 v68) (let (v81 u32) (add.checked v73 32)) - (let (v82 (ptr felt)) (inttoptr v81)) + (let (v82 (ptr i32)) (inttoptr v81)) (store v82 v69) (let (v83 u32) (add.checked v73 40)) - (let (v84 (ptr felt)) (inttoptr v83)) + (let (v84 (ptr i32)) (inttoptr v83)) (store v84 v70) (let (v85 u32) (add.checked v73 48)) - (let (v86 (ptr felt)) (inttoptr v85)) + (let (v86 (ptr i32)) (inttoptr v85)) (store v86 v71) (let (v87 u32) (add.checked v73 56)) - (let (v88 (ptr felt)) (inttoptr v87)) + (let (v88 (ptr i32)) (inttoptr v87)) (store v88 v72) - (let (v89 i32) (const.i32 72)) - (let (v90 i32) (add.wrapping v22 v89)) - (let (v91 i32) (const.i32 24)) - (let (v92 i32) (add.wrapping v90 v91)) - (let (v93 i32) (const.i32 40)) - (let (v94 i32) (add.wrapping v22 v93)) - (let (v95 i32) (const.i32 24)) - (let (v96 i32) (add.wrapping v94 v95)) - (let (v97 u32) (cast v96)) - (let (v98 u32) (mod.unchecked v97 2)) - (assertz v98) - (let (v99 (ptr i64)) (inttoptr v97)) - (let (v100 i64) (load v99)) - (let (v101 u32) (cast v92)) - (let (v102 u32) (mod.unchecked v101 3)) - (assertz v102) - (let (v103 (ptr i64)) (inttoptr v101)) - (store v103 v100) - (let (v104 i32) (const.i32 72)) - (let (v105 i32) (add.wrapping v22 v104)) - (let (v106 i32) (const.i32 16)) - (let (v107 i32) (add.wrapping v105 v106)) - (let (v108 i32) (const.i32 40)) - (let (v109 i32) (add.wrapping v22 v108)) - (let (v110 i32) (const.i32 16)) - (let (v111 i32) (add.wrapping v109 v110)) - (let (v112 u32) (cast v111)) - (let (v113 u32) (mod.unchecked v112 2)) - (assertz v113) - (let (v114 (ptr i64)) (inttoptr v112)) - (let (v115 i64) (load v114)) - (let (v116 u32) (cast v107)) - (let (v117 u32) (mod.unchecked v116 3)) - (assertz v117) - (let (v118 (ptr i64)) (inttoptr v116)) - (store v118 v115) - (let (v119 i32) (const.i32 72)) - (let (v120 i32) (add.wrapping v22 v119)) - (let (v121 i32) (const.i32 8)) - (let (v122 i32) (add.wrapping v120 v121)) - (let (v123 i32) (const.i32 40)) - (let (v124 i32) (add.wrapping v22 v123)) - (let (v125 i32) (const.i32 8)) - (let (v126 i32) (add.wrapping v124 v125)) - (let (v127 u32) (cast v126)) - (let (v128 u32) (mod.unchecked v127 2)) - (assertz v128) - (let (v129 (ptr i64)) (inttoptr v127)) - (let (v130 i64) (load v129)) - (let (v131 u32) (cast v122)) - (let (v132 u32) (mod.unchecked v131 3)) - (assertz v132) - (let (v133 (ptr i64)) (inttoptr v131)) - (store v133 v130) - (let (v134 u32) (cast v22)) - (let (v135 u32) (add.checked v134 40)) - (let (v136 u32) (mod.unchecked v135 2)) - (assertz v136) - (let (v137 (ptr i64)) (inttoptr v135)) - (let (v138 i64) (load v137)) - (let (v139 u32) (cast v22)) - (let (v140 u32) (add.checked v139 72)) - (let (v141 u32) (mod.unchecked v140 3)) - (assertz v141) - (let (v142 (ptr i64)) (inttoptr v140)) - (store v142 v138) - (let (v143 i32) (const.i32 104)) - (let (v144 i32) (add.wrapping v22 v143)) - (let (v145 i32) (const.i32 24)) - (let (v146 i32) (add.wrapping v144 v145)) - (let (v147 i64) (const.i64 0)) - (let (v148 u32) (cast v146)) - (let (v149 u32) (mod.unchecked v148 3)) - (assertz v149) - (let (v150 (ptr i64)) (inttoptr v148)) - (store v150 v147) - (let (v151 i32) (const.i32 104)) - (let (v152 i32) (add.wrapping v22 v151)) - (let (v153 i32) (const.i32 16)) - (let (v154 i32) (add.wrapping v152 v153)) - (let (v155 i64) (const.i64 0)) - (let (v156 u32) (cast v154)) - (let (v157 u32) (mod.unchecked v156 3)) - (assertz v157) - (let (v158 (ptr i64)) (inttoptr v156)) - (store v158 v155) - (let (v159 i32) (const.i32 104)) - (let (v160 i32) (add.wrapping v22 v159)) - (let (v161 i32) (const.i32 8)) - (let (v162 i32) (add.wrapping v160 v161)) - (let (v163 i64) (const.i64 0)) - (let (v164 u32) (cast v162)) - (let (v165 u32) (mod.unchecked v164 3)) - (assertz v165) - (let (v166 (ptr i64)) (inttoptr v164)) - (store v166 v163) - (let (v167 i64) (const.i64 0)) - (let (v168 u32) (cast v22)) - (let (v169 u32) (add.checked v168 104)) - (let (v170 u32) (mod.unchecked v169 3)) - (assertz v170) - (let (v171 (ptr i64)) (inttoptr v169)) - (store v171 v167) - (let (v172 i32) (const.i32 0)) - (br (block 11 v172 v22 v219))) - - (block 11 (param v173 i32) (param v178 i32) (param v218 i32) - (let (v174 i32) (const.i32 32)) - (let (v175 i1) (eq v173 v174)) - (let (v176 i32) (zext v175)) - (let (v177 i1) (neq v176 0)) - (condbr v177 (block 6) (block 13))) - - (block 12) - - (block 13 - (let (v179 i32) (const.i32 72)) - (let (v180 i32) (add.wrapping v178 v179)) - (let (v181 i32) (add.wrapping v180 v173)) - (let (v182 u32) (cast v181)) - (let (v183 u32) (mod.unchecked v182 2)) - (assertz v183) - (let (v184 (ptr felt)) (inttoptr v182)) - (let (v185 felt) (load v184)) - (let (v186 i64) (cast v185)) - (let (v187 u32) (cast v178)) - (let (v188 u32) (add.checked v187 136)) - (let (v189 u32) (mod.unchecked v188 3)) - (assertz v189) - (let (v190 (ptr i64)) (inttoptr v188)) - (store v190 v186) - (let (v191 i32) (const.i32 104)) - (let (v192 i32) (add.wrapping v178 v191)) - (let (v193 i32) (add.wrapping v192 v173)) - (let (v194 i32) (const.i32 4)) - (let (v195 i32) (const.i32 136)) - (let (v196 i32) (add.wrapping v178 v195)) - (let (v197 i32) (const.i32 4)) - (let (v198 i32) (const.i32 1048620)) - (call #core::slice::::copy_from_slice v193 v194 v196 v197 v198) - (let (v199 i32) (const.i32 4)) - (let (v200 i32) (add.wrapping v173 v199)) - (br (block 11 v200 v178 v218))) - ) - - (func (export #test_blake3_hash_2to1) - (param i32) (param i32) (param i32) - (block 0 (param v0 i32) (param v1 i32) (param v2 i32) - (let (v3 i32) (const.i32 0)) - (let (v4 felt) (const.felt 0)) - (let (v5 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v6 i32) (const.i32 240)) - (let (v7 i32) (sub.wrapping v5 v6)) - (let (v8 (ptr i32)) (global.symbol #__stack_pointer)) - (store v8 v7) - (let (v9 i32) (const.i32 0)) - (let (v10 i64) (const.i64 0)) - (let (v11 felt) (cast v10)) - (br (block 2 v9 v7 v2 v0 v1 v11))) - - (block 1) - - (block 2 - (param v12 i32) - (param v298 i32) - (param v299 i32) - (param v300 i32) - (param v301 i32) - (param v305 felt) - (let (v13 i32) (const.i32 32)) - (let (v14 i1) (neq v12 v13)) - (let (v15 i32) (zext v14)) - (let (v16 i1) (neq v15 0)) - (condbr v16 (block 4) (block 5))) - - (block 3) - - (block 4 - (let (v302 i32) (const.i32 8)) - (let (v303 i32) (add.wrapping v298 v302)) - (let (v304 i32) (add.wrapping v303 v12)) - (let (v306 u32) (cast v304)) - (let (v307 u32) (mod.unchecked v306 2)) - (assertz v307) - (let (v308 (ptr felt)) (inttoptr v306)) - (store v308 v305) - (let (v309 i32) (const.i32 4)) - (let (v310 i32) (add.wrapping v12 v309)) - (br (block 2 v310 v298 v299 v300 v301 v305))) - - (block 5 - (let (v17 i32) (const.i32 0)) - (br (block 6 v17 v298 v299 v300 v301))) - - (block 6 - (param v18 i32) - (param v280 i32) - (param v281 i32) - (param v282 i32) - (param v286 i32) - (let (v19 i32) (const.i32 32)) - (let (v20 i1) (neq v18 v19)) - (let (v21 i32) (zext v20)) - (let (v22 i1) (neq v21 0)) - (condbr v22 (block 8) (block 9))) - - (block 7) - - (block 8 - (let (v283 i32) (const.i32 8)) - (let (v284 i32) (add.wrapping v280 v283)) - (let (v285 i32) (add.wrapping v284 v18)) - (let (v287 i32) (add.wrapping v286 v18)) - (let (v288 u32) (cast v287)) - (let (v289 (ptr u32)) (inttoptr v288)) - (let (v290 u32) (load v289)) - (let (v291 i64) (zext v290)) - (let (v292 felt) (cast v291)) - (let (v293 u32) (cast v285)) - (let (v294 u32) (mod.unchecked v293 2)) - (assertz v294) - (let (v295 (ptr felt)) (inttoptr v293)) - (store v295 v292) - (let (v296 i32) (const.i32 4)) - (let (v297 i32) (add.wrapping v18 v296)) - (br (block 6 v297 v280 v281 v282 v286))) - - (block 9 - (let (v23 i32) (const.i32 0)) - (let (v24 i64) (const.i64 0)) - (let (v25 felt) (cast v24)) - (br (block 10 v23 v280 v281 v282 v25))) - - (block 10 - (param v26 i32) - (param v220 i32) - (param v221 i32) - (param v224 i32) - (param v274 felt) - (let (v27 i32) (const.i32 32)) - (let (v28 i1) (neq v26 v27)) - (let (v29 i32) (zext v28)) - (let (v30 i1) (neq v29 0)) - (condbr v30 (block 12) (block 13))) - - (block 11) - - (block 12 - (let (v271 i32) (const.i32 40)) - (let (v272 i32) (add.wrapping v220 v271)) - (let (v273 i32) (add.wrapping v272 v26)) - (let (v275 u32) (cast v273)) - (let (v276 u32) (mod.unchecked v275 2)) - (assertz v276) - (let (v277 (ptr felt)) (inttoptr v275)) - (store v277 v274) - (let (v278 i32) (const.i32 4)) - (let (v279 i32) (add.wrapping v26 v278)) - (br (block 10 v279 v220 v221 v224 v274))) - - (block 13 - (let (v31 i32) (const.i32 0)) - (br (block 15 v31 v220 v221 v224))) + (br (block 1))) - (block 14 - (let (v225 u32) (cast v182)) - (let (v226 u32) (add.checked v225 200)) - (let (v227 u32) (mod.unchecked v226 3)) - (assertz v227) - (let (v228 (ptr i64)) (inttoptr v226)) - (let (v229 i64) (load v228)) - (let (v230 u32) (cast v222)) - (let (v231 (ptr i64)) (inttoptr v230)) - (store v231 v229) - (let (v232 i32) (const.i32 24)) - (let (v233 i32) (add.wrapping v222 v232)) - (let (v234 i32) (const.i32 200)) - (let (v235 i32) (add.wrapping v182 v234)) - (let (v236 i32) (const.i32 24)) - (let (v237 i32) (add.wrapping v235 v236)) - (let (v238 u32) (cast v237)) - (let (v239 u32) (mod.unchecked v238 3)) - (assertz v239) - (let (v240 (ptr i64)) (inttoptr v238)) - (let (v241 i64) (load v240)) - (let (v242 u32) (cast v233)) - (let (v243 (ptr i64)) (inttoptr v242)) - (store v243 v241) - (let (v244 i32) (const.i32 16)) - (let (v245 i32) (add.wrapping v222 v244)) - (let (v246 i32) (const.i32 200)) - (let (v247 i32) (add.wrapping v182 v246)) - (let (v248 i32) (const.i32 16)) - (let (v249 i32) (add.wrapping v247 v248)) - (let (v250 u32) (cast v249)) - (let (v251 u32) (mod.unchecked v250 3)) - (assertz v251) - (let (v252 (ptr i64)) (inttoptr v250)) - (let (v253 i64) (load v252)) - (let (v254 u32) (cast v245)) - (let (v255 (ptr i64)) (inttoptr v254)) - (store v255 v253) - (let (v256 i32) (const.i32 8)) - (let (v257 i32) (add.wrapping v222 v256)) - (let (v258 i32) (const.i32 200)) - (let (v259 i32) (add.wrapping v182 v258)) - (let (v260 i32) (const.i32 8)) - (let (v261 i32) (add.wrapping v259 v260)) - (let (v262 u32) (cast v261)) - (let (v263 u32) (mod.unchecked v262 3)) - (assertz v263) - (let (v264 (ptr i64)) (inttoptr v262)) - (let (v265 i64) (load v264)) - (let (v266 u32) (cast v257)) - (let (v267 (ptr i64)) (inttoptr v266)) - (store v267 v265) - (let (v268 i32) (const.i32 240)) - (let (v269 i32) (add.wrapping v182 v268)) - (let (v270 (ptr i32)) (global.symbol #__stack_pointer)) - (store v270 v269) + (block 1 (ret)) - - (block 15 - (param v32 i32) - (param v37 i32) - (param v208 i32) - (param v223 i32) - (let (v33 i32) (const.i32 32)) - (let (v34 i1) (neq v32 v33)) - (let (v35 i32) (zext v34)) - (let (v36 i1) (neq v35 0)) - (condbr v36 (block 17) (block 18))) - - (block 16) - - (block 17 - (let (v205 i32) (const.i32 40)) - (let (v206 i32) (add.wrapping v37 v205)) - (let (v207 i32) (add.wrapping v206 v32)) - (let (v209 i32) (add.wrapping v208 v32)) - (let (v210 u32) (cast v209)) - (let (v211 (ptr u32)) (inttoptr v210)) - (let (v212 u32) (load v211)) - (let (v213 i64) (zext v212)) - (let (v214 felt) (cast v213)) - (let (v215 u32) (cast v207)) - (let (v216 u32) (mod.unchecked v215 2)) - (assertz v216) - (let (v217 (ptr felt)) (inttoptr v215)) - (store v217 v214) - (let (v218 i32) (const.i32 4)) - (let (v219 i32) (add.wrapping v32 v218)) - (br (block 15 v219 v37 v208 v223))) - - (block 18 - (let (v38 u32) (cast v37)) - (let (v39 u32) (add.checked v38 8)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) - (let (v41 (ptr felt)) (inttoptr v39)) - (let (v42 felt) (load v41)) - (let (v43 u32) (cast v37)) - (let (v44 u32) (add.checked v43 12)) - (let (v45 u32) (mod.unchecked v44 2)) - (assertz v45) - (let (v46 (ptr felt)) (inttoptr v44)) - (let (v47 felt) (load v46)) - (let (v48 u32) (cast v37)) - (let (v49 u32) (add.checked v48 16)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr felt)) (inttoptr v49)) - (let (v52 felt) (load v51)) - (let (v53 u32) (cast v37)) - (let (v54 u32) (add.checked v53 20)) - (let (v55 u32) (mod.unchecked v54 2)) - (assertz v55) - (let (v56 (ptr felt)) (inttoptr v54)) - (let (v57 felt) (load v56)) - (let (v58 u32) (cast v37)) - (let (v59 u32) (add.checked v58 24)) - (let (v60 u32) (mod.unchecked v59 2)) - (assertz v60) - (let (v61 (ptr felt)) (inttoptr v59)) - (let (v62 felt) (load v61)) - (let (v63 u32) (cast v37)) - (let (v64 u32) (add.checked v63 28)) - (let (v65 u32) (mod.unchecked v64 2)) - (assertz v65) - (let (v66 (ptr felt)) (inttoptr v64)) - (let (v67 felt) (load v66)) - (let (v68 u32) (cast v37)) - (let (v69 u32) (add.checked v68 32)) - (let (v70 u32) (mod.unchecked v69 2)) - (assertz v70) - (let (v71 (ptr felt)) (inttoptr v69)) - (let (v72 felt) (load v71)) - (let (v73 u32) (cast v37)) - (let (v74 u32) (add.checked v73 36)) - (let (v75 u32) (mod.unchecked v74 2)) - (assertz v75) - (let (v76 (ptr felt)) (inttoptr v74)) - (let (v77 felt) (load v76)) - (let (v78 u32) (cast v37)) - (let (v79 u32) (add.checked v78 40)) - (let (v80 u32) (mod.unchecked v79 2)) - (assertz v80) - (let (v81 (ptr felt)) (inttoptr v79)) - (let (v82 felt) (load v81)) - (let (v83 u32) (cast v37)) - (let (v84 u32) (add.checked v83 44)) - (let (v85 u32) (mod.unchecked v84 2)) - (assertz v85) - (let (v86 (ptr felt)) (inttoptr v84)) - (let (v87 felt) (load v86)) - (let (v88 u32) (cast v37)) - (let (v89 u32) (add.checked v88 48)) - (let (v90 u32) (mod.unchecked v89 2)) - (assertz v90) - (let (v91 (ptr felt)) (inttoptr v89)) - (let (v92 felt) (load v91)) - (let (v93 u32) (cast v37)) - (let (v94 u32) (add.checked v93 52)) - (let (v95 u32) (mod.unchecked v94 2)) - (assertz v95) - (let (v96 (ptr felt)) (inttoptr v94)) - (let (v97 felt) (load v96)) - (let (v98 u32) (cast v37)) - (let (v99 u32) (add.checked v98 56)) - (let (v100 u32) (mod.unchecked v99 2)) - (assertz v100) - (let (v101 (ptr felt)) (inttoptr v99)) - (let (v102 felt) (load v101)) - (let (v103 u32) (cast v37)) - (let (v104 u32) (add.checked v103 60)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) - (let (v106 (ptr felt)) (inttoptr v104)) - (let (v107 felt) (load v106)) - (let (v108 u32) (cast v37)) - (let (v109 u32) (add.checked v108 64)) - (let (v110 u32) (mod.unchecked v109 2)) - (assertz v110) - (let (v111 (ptr felt)) (inttoptr v109)) - (let (v112 felt) (load v111)) - (let (v113 u32) (cast v37)) - (let (v114 u32) (add.checked v113 68)) - (let (v115 u32) (mod.unchecked v114 2)) - (assertz v115) - (let (v116 (ptr felt)) (inttoptr v114)) - (let (v117 felt) (load v116)) - (let (v118 i32) (const.i32 72)) - (let (v119 i32) (add.wrapping v37 v118)) - (let [(v120 felt) (v121 felt) (v122 felt) (v123 felt) (v124 felt) (v125 felt) (v126 felt) (v127 felt)] (call (#std::crypto_hashes #blake3_hash_2to1) v42 v47 v52 v57 v62 v67 v72 v77 v82 v87 v92 v97 v102 v107 v112 v117)) - (let (v128 u32) (cast v119)) - (let (v129 (ptr felt)) (inttoptr v128)) - (store v129 v120) - (let (v130 u32) (add.checked v128 8)) - (let (v131 (ptr felt)) (inttoptr v130)) - (store v131 v121) - (let (v132 u32) (add.checked v128 16)) - (let (v133 (ptr felt)) (inttoptr v132)) - (store v133 v122) - (let (v134 u32) (add.checked v128 24)) - (let (v135 (ptr felt)) (inttoptr v134)) - (store v135 v123) - (let (v136 u32) (add.checked v128 32)) - (let (v137 (ptr felt)) (inttoptr v136)) - (store v137 v124) - (let (v138 u32) (add.checked v128 40)) - (let (v139 (ptr felt)) (inttoptr v138)) - (store v139 v125) - (let (v140 u32) (add.checked v128 48)) - (let (v141 (ptr felt)) (inttoptr v140)) - (store v141 v126) - (let (v142 u32) (add.checked v128 56)) - (let (v143 (ptr felt)) (inttoptr v142)) - (store v143 v127) - (let (v144 i32) (const.i32 136)) - (let (v145 i32) (add.wrapping v37 v144)) - (let (v146 i32) (const.i32 72)) - (let (v147 i32) (add.wrapping v37 v146)) - (let (v148 i32) (const.i32 64)) - (let (v149 u32) (cast v145)) - (let (v150 (ptr u8)) (inttoptr v149)) - (let (v151 u32) (cast v147)) - (let (v152 (ptr u8)) (inttoptr v151)) - (memcpy v152 v150 v148) - (let (v153 i32) (const.i32 224)) - (let (v154 i32) (add.wrapping v37 v153)) - (let (v155 i64) (const.i64 0)) - (let (v156 u32) (cast v154)) - (let (v157 u32) (mod.unchecked v156 3)) - (assertz v157) - (let (v158 (ptr i64)) (inttoptr v156)) - (store v158 v155) - (let (v159 i32) (const.i32 216)) - (let (v160 i32) (add.wrapping v37 v159)) - (let (v161 i64) (const.i64 0)) - (let (v162 u32) (cast v160)) - (let (v163 u32) (mod.unchecked v162 3)) - (assertz v163) - (let (v164 (ptr i64)) (inttoptr v162)) - (store v164 v161) - (let (v165 i32) (const.i32 208)) - (let (v166 i32) (add.wrapping v37 v165)) - (let (v167 i64) (const.i64 0)) - (let (v168 u32) (cast v166)) - (let (v169 u32) (mod.unchecked v168 3)) - (assertz v169) - (let (v170 (ptr i64)) (inttoptr v168)) - (store v170 v167) - (let (v171 i64) (const.i64 0)) - (let (v172 u32) (cast v37)) - (let (v173 u32) (add.checked v172 200)) - (let (v174 u32) (mod.unchecked v173 3)) - (assertz v174) - (let (v175 (ptr i64)) (inttoptr v173)) - (store v175 v171) - (let (v176 i32) (const.i32 0)) - (br (block 19 v176 v37 v223))) - - (block 19 (param v177 i32) (param v182 i32) (param v222 i32) - (let (v178 i32) (const.i32 32)) - (let (v179 i1) (eq v177 v178)) - (let (v180 i32) (zext v179)) - (let (v181 i1) (neq v180 0)) - (condbr v181 (block 14) (block 21))) - - (block 20) - - (block 21 - (let (v183 i32) (const.i32 136)) - (let (v184 i32) (add.wrapping v182 v183)) - (let (v185 i32) (add.wrapping v184 v177)) - (let (v186 u32) (cast v185)) - (let (v187 u32) (mod.unchecked v186 2)) - (assertz v187) - (let (v188 (ptr felt)) (inttoptr v186)) - (let (v189 felt) (load v188)) - (let (v190 i64) (cast v189)) - (let (v191 u32) (cast v182)) - (let (v192 u32) (add.checked v191 232)) - (let (v193 u32) (mod.unchecked v192 3)) - (assertz v193) - (let (v194 (ptr i64)) (inttoptr v192)) - (store v194 v190) - (let (v195 i32) (const.i32 200)) - (let (v196 i32) (add.wrapping v182 v195)) - (let (v197 i32) (add.wrapping v196 v177)) - (let (v198 i32) (const.i32 4)) - (let (v199 i32) (const.i32 232)) - (let (v200 i32) (add.wrapping v182 v199)) - (let (v201 i32) (const.i32 4)) - (let (v202 i32) (const.i32 1048636)) - (call #core::slice::::copy_from_slice v197 v198 v200 v201 v202) - (let (v203 i32) (const.i32 4)) - (let (v204 i32) (add.wrapping v177 v203)) - (br (block 19 v204 v182 v222))) ) (func (export #test_rpo_falcon512_verify) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) - (let (v2 u32) (cast v0)) - (let (v3 u32) (mod.unchecked v2 2)) - (assertz v3) + (let (v2 u32) (bitcast v0)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) (let (v4 (ptr felt)) (inttoptr v2)) (let (v5 felt) (load v4)) - (let (v6 u32) (cast v0)) + (let (v6 u32) (bitcast v0)) (let (v7 u32) (add.checked v6 4)) - (let (v8 u32) (mod.unchecked v7 2)) - (assertz v8) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) (let (v9 (ptr felt)) (inttoptr v7)) (let (v10 felt) (load v9)) - (let (v11 u32) (cast v0)) + (let (v11 u32) (bitcast v0)) (let (v12 u32) (add.checked v11 8)) - (let (v13 u32) (mod.unchecked v12 2)) - (assertz v13) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) (let (v14 (ptr felt)) (inttoptr v12)) (let (v15 felt) (load v14)) - (let (v16 u32) (cast v0)) + (let (v16 u32) (bitcast v0)) (let (v17 u32) (add.checked v16 12)) - (let (v18 u32) (mod.unchecked v17 2)) - (assertz v18) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) (let (v19 (ptr felt)) (inttoptr v17)) (let (v20 felt) (load v19)) - (let (v21 u32) (cast v1)) - (let (v22 u32) (mod.unchecked v21 2)) - (assertz v22) + (let (v21 u32) (bitcast v1)) + (let (v22 u32) (mod.unchecked v21 4)) + (assertz 250 v22) (let (v23 (ptr felt)) (inttoptr v21)) (let (v24 felt) (load v23)) - (let (v25 u32) (cast v1)) + (let (v25 u32) (bitcast v1)) (let (v26 u32) (add.checked v25 4)) - (let (v27 u32) (mod.unchecked v26 2)) - (assertz v27) + (let (v27 u32) (mod.unchecked v26 4)) + (assertz 250 v27) (let (v28 (ptr felt)) (inttoptr v26)) (let (v29 felt) (load v28)) - (let (v30 u32) (cast v1)) + (let (v30 u32) (bitcast v1)) (let (v31 u32) (add.checked v30 8)) - (let (v32 u32) (mod.unchecked v31 2)) - (assertz v32) + (let (v32 u32) (mod.unchecked v31 4)) + (assertz 250 v32) (let (v33 (ptr felt)) (inttoptr v31)) (let (v34 felt) (load v33)) - (let (v35 u32) (cast v1)) + (let (v35 u32) (bitcast v1)) (let (v36 u32) (add.checked v35 12)) - (let (v37 u32) (mod.unchecked v36 2)) - (assertz v37) + (let (v37 u32) (mod.unchecked v36 4)) + (assertz 250 v37) (let (v38 (ptr felt)) (inttoptr v36)) (let (v39 felt) (load v38)) - (call (#miden:stdlib/std_crypto_dsa #rpo_falcon512_verify) v5 v10 v15 v20 v24 v29 v34 v39) + (call (#std::crypto::dsa::rpo_falcon512 #rpo_falcon512_verify) v5 v10 v15 v20 v24 v29 v34 v39) (br (block 1))) (block 1 @@ -1283,10 +664,10 @@ (let (v6 i32) (sub.wrapping v4 v5)) (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) (store v7 v6) - (call #miden_tx_kernel_sys::remove_asset v6 v0) - (let (v8 u32) (cast v6)) - (let (v9 u32) (mod.unchecked v8 2)) - (assertz v9) + (call #miden_base_sys::bindings::tx::remove_asset v6 v0) + (let (v8 u32) (bitcast v6)) + (let (v9 u32) (mod.unchecked v8 4)) + (assertz 250 v9) (let (v10 (ptr felt)) (inttoptr v8)) (let (v11 felt) (load v10)) (let (v12 i32) (const.i32 16)) @@ -1306,7 +687,7 @@ (param v1 felt) (param v2 felt) (param v3 i32) - (let (v5 felt) (call #miden_tx_kernel_sys::create_note v0 v1 v2 v3)) + (let (v5 felt) (call #miden_base_sys::bindings::tx::create_note v0 v1 v2 v3)) (br (block 1 v5))) (block 1 (param v4 felt) @@ -1315,7 +696,7 @@ (func (export #__rust_alloc) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) - (let (v3 i32) (const.i32 1048652)) + (let (v3 i32) (const.i32 1048576)) (let (v4 i32) (call #::alloc v3 v1 v0)) (br (block 1 v4))) @@ -1325,7 +706,7 @@ (func (export #__rust_alloc_zeroed) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) - (let (v3 i32) (const.i32 1048652)) + (let (v3 i32) (const.i32 1048576)) (let (v4 i32) (call #core::alloc::global::GlobalAlloc::alloc_zeroed v3 v1 v0)) (br (block 1 v4))) @@ -1337,9 +718,9 @@ (param i32) (block 0 (param v0 i32) (let (v1 i32) (const.i32 0)) - (let (v2 u32) (cast v0)) - (let (v3 u32) (mod.unchecked v2 2)) - (assertz v3) + (let (v2 u32) (bitcast v0)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) (let (v4 (ptr i32)) (inttoptr v2)) (let (v5 i32) (load v4)) (let (v6 i32) (const.i32 2)) @@ -1351,10 +732,10 @@ (ret)) (block 2 (param v37 i32) (param v54 i32) - (let (v38 u32) (cast v37)) + (let (v38 u32) (bitcast v37)) (let (v39 u32) (add.checked v38 4)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) + (let (v40 u32) (mod.unchecked v39 4)) + (assertz 250 v40) (let (v41 (ptr i32)) (inttoptr v39)) (let (v42 i32) (load v41)) (let (v43 i32) (const.i32 -4)) @@ -1373,32 +754,32 @@ (condbr v13 (block 2 v0 v5) (block 4))) (block 4 - (let (v14 u32) (cast v10)) + (let (v14 u32) (bitcast v10)) (let (v15 u32) (add.checked v14 4)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr i32)) (inttoptr v15)) (let (v18 i32) (load v17)) (let (v19 i32) (const.i32 3)) (let (v20 i32) (band v18 v19)) - (let (v21 u32) (cast v0)) + (let (v21 u32) (bitcast v0)) (let (v22 u32) (add.checked v21 4)) - (let (v23 u32) (mod.unchecked v22 2)) - (assertz v23) + (let (v23 u32) (mod.unchecked v22 4)) + (assertz 250 v23) (let (v24 (ptr i32)) (inttoptr v22)) (let (v25 i32) (load v24)) (let (v26 i32) (const.i32 -4)) (let (v27 i32) (band v25 v26)) (let (v28 i32) (bor v20 v27)) - (let (v29 u32) (cast v10)) + (let (v29 u32) (bitcast v10)) (let (v30 u32) (add.checked v29 4)) - (let (v31 u32) (mod.unchecked v30 2)) - (assertz v31) + (let (v31 u32) (mod.unchecked v30 4)) + (assertz 250 v31) (let (v32 (ptr i32)) (inttoptr v30)) (store v32 v28) - (let (v33 u32) (cast v0)) - (let (v34 u32) (mod.unchecked v33 2)) - (assertz v34) + (let (v33 u32) (bitcast v0)) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) (let (v35 (ptr i32)) (inttoptr v33)) (let (v36 i32) (load v35)) (br (block 2 v0 v36))) @@ -1406,25 +787,25 @@ (block 5 (param v70 i32) (param v71 i32) (param v78 i32) (let (v72 i32) (const.i32 3)) (let (v73 i32) (band v71 v72)) - (let (v74 u32) (cast v70)) + (let (v74 u32) (bitcast v70)) (let (v75 u32) (add.checked v74 4)) - (let (v76 u32) (mod.unchecked v75 2)) - (assertz v76) + (let (v76 u32) (mod.unchecked v75 4)) + (assertz 250 v76) (let (v77 (ptr i32)) (inttoptr v75)) (store v77 v73) (let (v79 i32) (const.i32 3)) (let (v80 i32) (band v78 v79)) - (let (v81 u32) (cast v70)) - (let (v82 u32) (mod.unchecked v81 2)) - (assertz v82) + (let (v81 u32) (bitcast v70)) + (let (v82 u32) (mod.unchecked v81 4)) + (assertz 250 v82) (let (v83 (ptr i32)) (inttoptr v81)) (store v83 v80) (br (block 1))) (block 6 - (let (v48 u32) (cast v44)) - (let (v49 u32) (mod.unchecked v48 2)) - (assertz v49) + (let (v48 u32) (bitcast v44)) + (let (v49 u32) (mod.unchecked v48 4)) + (assertz 250 v49) (let (v50 (ptr i32)) (inttoptr v48)) (let (v51 i32) (load v50)) (let (v52 i32) (const.i32 3)) @@ -1432,20 +813,20 @@ (let (v55 i32) (const.i32 -4)) (let (v56 i32) (band v54 v55)) (let (v57 i32) (bor v53 v56)) - (let (v58 u32) (cast v44)) - (let (v59 u32) (mod.unchecked v58 2)) - (assertz v59) + (let (v58 u32) (bitcast v44)) + (let (v59 u32) (mod.unchecked v58 4)) + (assertz 250 v59) (let (v60 (ptr i32)) (inttoptr v58)) (store v60 v57) - (let (v61 u32) (cast v37)) + (let (v61 u32) (bitcast v37)) (let (v62 u32) (add.checked v61 4)) - (let (v63 u32) (mod.unchecked v62 2)) - (assertz v63) + (let (v63 u32) (mod.unchecked v62 4)) + (assertz 250 v63) (let (v64 (ptr i32)) (inttoptr v62)) (let (v65 i32) (load v64)) - (let (v66 u32) (cast v37)) - (let (v67 u32) (mod.unchecked v66 2)) - (assertz v67) + (let (v66 u32) (bitcast v37)) + (let (v67 u32) (mod.unchecked v66 4)) + (assertz 250 v67) (let (v68 (ptr i32)) (inttoptr v66)) (let (v69 i32) (load v68)) (br (block 5 v37 v65 v69))) @@ -1475,7 +856,7 @@ (let (v22 u32) (bitcast v20)) (let (v23 u32) (shr.wrapping v21 v22)) (let (v24 i32) (bitcast v23)) - (let (v25 u32) (cast v24)) + (let (v25 u32) (bitcast v24)) (let (v26 i32) (memory.grow v25)) (let (v27 i32) (const.i32 -1)) (let (v28 i1) (neq v26 v27)) @@ -1487,15 +868,15 @@ (ret)) (block 2 (param v50 i32) (param v51 i32) (param v56 i32) - (let (v52 u32) (cast v50)) + (let (v52 u32) (bitcast v50)) (let (v53 u32) (add.checked v52 4)) - (let (v54 u32) (mod.unchecked v53 2)) - (assertz v54) + (let (v54 u32) (mod.unchecked v53 4)) + (assertz 250 v54) (let (v55 (ptr i32)) (inttoptr v53)) (store v55 v51) - (let (v57 u32) (cast v50)) - (let (v58 u32) (mod.unchecked v57 2)) - (assertz v58) + (let (v57 u32) (bitcast v50)) + (let (v58 u32) (mod.unchecked v57 4)) + (assertz 250 v58) (let (v59 (ptr i32)) (inttoptr v57)) (store v59 v56) (br (block 1))) @@ -1505,10 +886,10 @@ (let (v34 u32) (bitcast v33)) (let (v35 i32) (shl.wrapping v26 v34)) (let (v36 i64) (const.i64 0)) - (let (v37 u32) (cast v35)) + (let (v37 u32) (bitcast v35)) (let (v38 u32) (add.checked v37 4)) - (let (v39 u32) (mod.unchecked v38 2)) - (assertz v39) + (let (v39 u32) (mod.unchecked v38 4)) + (assertz 250 v39) (let (v40 (ptr i64)) (inttoptr v38)) (store v40 v36) (let (v41 i32) (const.i32 -65536)) @@ -1516,9 +897,9 @@ (let (v43 i32) (add.wrapping v35 v42)) (let (v44 i32) (const.i32 2)) (let (v45 i32) (bor v43 v44)) - (let (v46 u32) (cast v35)) - (let (v47 u32) (mod.unchecked v46 2)) - (assertz v47) + (let (v46 u32) (bitcast v35)) + (let (v47 u32) (mod.unchecked v46 4)) + (assertz 250 v47) (let (v48 (ptr i32)) (inttoptr v46)) (store v48 v45) (let (v49 i32) (const.i32 0)) @@ -1542,9 +923,9 @@ (let (v10 i32) (const.i32 2)) (let (v11 u32) (bitcast v10)) (let (v12 i32) (shl.wrapping v0 v11)) - (let (v13 u32) (cast v2)) - (let (v14 u32) (mod.unchecked v13 2)) - (assertz v14) + (let (v13 u32) (bitcast v2)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) (let (v15 (ptr i32)) (inttoptr v13)) (let (v16 i32) (load v15)) (br (block 2 v16 v12 v9 v6 v2 v7))) @@ -1572,9 +953,9 @@ (param v244 i32) (param v245 i32) (param v246 i32) - (let (v240 u32) (cast v238)) - (let (v241 u32) (mod.unchecked v240 2)) - (assertz v241) + (let (v240 u32) (bitcast v238)) + (let (v241 u32) (mod.unchecked v240 4)) + (assertz 250 v241) (let (v242 (ptr i32)) (inttoptr v240)) (store v242 v239) (br (block 2 v239 v243 v244 v245 v238 v246))) @@ -1588,9 +969,9 @@ (block 7 (param v227 i32) (param v228 i32) (let (v229 i32) (const.i32 1)) (let (v230 i32) (bor v228 v229)) - (let (v231 u32) (cast v227)) - (let (v232 u32) (mod.unchecked v231 2)) - (assertz v232) + (let (v231 u32) (bitcast v227)) + (let (v232 u32) (mod.unchecked v231 4)) + (assertz 250 v232) (let (v233 (ptr i32)) (inttoptr v231)) (store v233 v230) (let (v234 i32) (const.i32 8)) @@ -1600,14 +981,14 @@ (block 8 (let (v216 i32) (const.i32 -3)) (let (v217 i32) (band v145 v216)) - (let (v218 u32) (cast v122)) - (let (v219 u32) (mod.unchecked v218 2)) - (assertz v219) + (let (v218 u32) (bitcast v122)) + (let (v219 u32) (mod.unchecked v218 4)) + (assertz 250 v219) (let (v220 (ptr i32)) (inttoptr v218)) (store v220 v217) - (let (v221 u32) (cast v120)) - (let (v222 u32) (mod.unchecked v221 2)) - (assertz v222) + (let (v221 u32) (bitcast v120)) + (let (v222 u32) (mod.unchecked v221 4)) + (assertz 250 v222) (let (v223 (ptr i32)) (inttoptr v221)) (let (v224 i32) (load v223)) (let (v225 i32) (const.i32 2)) @@ -1621,10 +1002,10 @@ (param v56 i32) (param v59 i32) (param v247 i32) - (let (v23 u32) (cast v22)) + (let (v23 u32) (bitcast v22)) (let (v24 u32) (add.checked v23 8)) - (let (v25 u32) (mod.unchecked v24 2)) - (assertz v25) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) (let (v26 (ptr i32)) (inttoptr v24)) (let (v27 i32) (load v26)) (let (v28 i32) (const.i32 1)) @@ -1637,16 +1018,16 @@ (block 11 (let (v156 i32) (const.i32 -2)) (let (v157 i32) (band v27 v156)) - (let (v158 u32) (cast v22)) + (let (v158 u32) (bitcast v22)) (let (v159 u32) (add.checked v158 8)) - (let (v160 u32) (mod.unchecked v159 2)) - (assertz v160) + (let (v160 u32) (mod.unchecked v159 4)) + (assertz 250 v160) (let (v161 (ptr i32)) (inttoptr v159)) (store v161 v157) - (let (v162 u32) (cast v22)) + (let (v162 u32) (bitcast v22)) (let (v163 u32) (add.checked v162 4)) - (let (v164 u32) (mod.unchecked v163 2)) - (assertz v164) + (let (v164 u32) (mod.unchecked v163 4)) + (assertz 250 v164) (let (v165 (ptr i32)) (inttoptr v163)) (let (v166 i32) (load v165)) (let (v167 i32) (const.i32 -4)) @@ -1655,9 +1036,9 @@ (condbr v169 (block 22) (block 23))) (block 12 - (let (v31 u32) (cast v22)) - (let (v32 u32) (mod.unchecked v31 2)) - (assertz v32) + (let (v31 u32) (bitcast v22)) + (let (v32 u32) (mod.unchecked v31 4)) + (assertz 250 v32) (let (v33 (ptr i32)) (inttoptr v31)) (let (v34 i32) (load v33)) (let (v35 i32) (const.i32 -4)) @@ -1687,34 +1068,34 @@ (block 14 (let (v69 i32) (const.i32 0)) (let (v70 i32) (const.i32 0)) - (let (v71 u32) (cast v50)) - (let (v72 u32) (mod.unchecked v71 2)) - (assertz v72) + (let (v71 u32) (bitcast v50)) + (let (v72 u32) (mod.unchecked v71 4)) + (assertz 250 v72) (let (v73 (ptr i32)) (inttoptr v71)) (store v73 v70) (let (v74 i32) (const.i32 -8)) (let (v75 i32) (add.wrapping v50 v74)) (let (v76 i64) (const.i64 0)) - (let (v77 u32) (cast v75)) - (let (v78 u32) (mod.unchecked v77 2)) - (assertz v78) + (let (v77 u32) (bitcast v75)) + (let (v78 u32) (mod.unchecked v77 4)) + (assertz 250 v78) (let (v79 (ptr i64)) (inttoptr v77)) (store v79 v76) - (let (v80 u32) (cast v22)) - (let (v81 u32) (mod.unchecked v80 2)) - (assertz v81) + (let (v80 u32) (bitcast v22)) + (let (v81 u32) (mod.unchecked v80 4)) + (assertz 250 v81) (let (v82 (ptr i32)) (inttoptr v80)) (let (v83 i32) (load v82)) (let (v84 i32) (const.i32 -4)) (let (v85 i32) (band v83 v84)) - (let (v86 u32) (cast v75)) - (let (v87 u32) (mod.unchecked v86 2)) - (assertz v87) + (let (v86 u32) (bitcast v75)) + (let (v87 u32) (mod.unchecked v86 4)) + (assertz 250 v87) (let (v88 (ptr i32)) (inttoptr v86)) (store v88 v85) - (let (v89 u32) (cast v22)) - (let (v90 u32) (mod.unchecked v89 2)) - (assertz v90) + (let (v89 u32) (bitcast v22)) + (let (v90 u32) (mod.unchecked v89 4)) + (assertz 250 v90) (let (v91 (ptr i32)) (inttoptr v89)) (let (v92 i32) (load v91)) (let (v93 i32) (const.i32 2)) @@ -1730,51 +1111,51 @@ (block 16 (let (v60 i32) (const.i32 -4)) (let (v61 i32) (band v27 v60)) - (let (v62 u32) (cast v59)) - (let (v63 u32) (mod.unchecked v62 2)) - (assertz v63) + (let (v62 u32) (bitcast v59)) + (let (v63 u32) (mod.unchecked v62 4)) + (assertz 250 v63) (let (v64 (ptr i32)) (inttoptr v62)) (store v64 v61) - (let (v65 u32) (cast v22)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v65 u32) (bitcast v22)) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (let (v68 i32) (load v67)) (br (block 7 v22 v68))) (block 17 (param v120 i32) (param v121 i32) (param v122 i32) (let (v123 i32) (bor v121 v122)) - (let (v124 u32) (cast v120)) + (let (v124 u32) (bitcast v120)) (let (v125 u32) (add.checked v124 4)) - (let (v126 u32) (mod.unchecked v125 2)) - (assertz v126) + (let (v126 u32) (mod.unchecked v125 4)) + (assertz 250 v126) (let (v127 (ptr i32)) (inttoptr v125)) (store v127 v123) - (let (v128 u32) (cast v122)) + (let (v128 u32) (bitcast v122)) (let (v129 u32) (add.checked v128 8)) - (let (v130 u32) (mod.unchecked v129 2)) - (assertz v130) + (let (v130 u32) (mod.unchecked v129 4)) + (assertz 250 v130) (let (v131 (ptr i32)) (inttoptr v129)) (let (v132 i32) (load v131)) (let (v133 i32) (const.i32 -2)) (let (v134 i32) (band v132 v133)) - (let (v135 u32) (cast v122)) + (let (v135 u32) (bitcast v122)) (let (v136 u32) (add.checked v135 8)) - (let (v137 u32) (mod.unchecked v136 2)) - (assertz v137) + (let (v137 u32) (mod.unchecked v136 4)) + (assertz 250 v137) (let (v138 (ptr i32)) (inttoptr v136)) (store v138 v134) - (let (v139 u32) (cast v122)) - (let (v140 u32) (mod.unchecked v139 2)) - (assertz v140) + (let (v139 u32) (bitcast v122)) + (let (v140 u32) (mod.unchecked v139 4)) + (assertz 250 v140) (let (v141 (ptr i32)) (inttoptr v139)) (let (v142 i32) (load v141)) (let (v143 i32) (const.i32 3)) (let (v144 i32) (band v142 v143)) (let (v145 i32) (bor v144 v120)) - (let (v146 u32) (cast v122)) - (let (v147 u32) (mod.unchecked v146 2)) - (assertz v147) + (let (v146 u32) (bitcast v122)) + (let (v147 u32) (mod.unchecked v146 4)) + (assertz 250 v147) (let (v148 (ptr i32)) (inttoptr v146)) (store v148 v145) (let (v149 i32) (const.i32 2)) @@ -1791,25 +1172,25 @@ (condbr v100 (block 17 v75 v69 v22) (block 19))) (block 19 - (let (v101 u32) (cast v97)) + (let (v101 u32) (bitcast v97)) (let (v102 u32) (add.checked v101 4)) - (let (v103 u32) (mod.unchecked v102 2)) - (assertz v103) + (let (v103 u32) (mod.unchecked v102 4)) + (assertz 250 v103) (let (v104 (ptr i32)) (inttoptr v102)) (let (v105 i32) (load v104)) (let (v106 i32) (const.i32 3)) (let (v107 i32) (band v105 v106)) (let (v108 i32) (bor v107 v75)) - (let (v109 u32) (cast v97)) + (let (v109 u32) (bitcast v97)) (let (v110 u32) (add.checked v109 4)) - (let (v111 u32) (mod.unchecked v110 2)) - (assertz v111) + (let (v111 u32) (mod.unchecked v110 4)) + (assertz 250 v111) (let (v112 (ptr i32)) (inttoptr v110)) (store v112 v108) - (let (v113 u32) (cast v75)) + (let (v113 u32) (bitcast v75)) (let (v114 u32) (add.checked v113 4)) - (let (v115 u32) (mod.unchecked v114 2)) - (assertz v115) + (let (v115 u32) (mod.unchecked v114 4)) + (assertz 250 v115) (let (v116 (ptr i32)) (inttoptr v114)) (let (v117 i32) (load v116)) (let (v118 i32) (const.i32 3)) @@ -1817,9 +1198,9 @@ (br (block 17 v75 v119 v22))) (block 20 - (let (v152 u32) (cast v120)) - (let (v153 u32) (mod.unchecked v152 2)) - (assertz v153) + (let (v152 u32) (bitcast v120)) + (let (v153 u32) (mod.unchecked v152 4)) + (assertz 250 v153) (let (v154 (ptr i32)) (inttoptr v152)) (let (v155 i32) (load v154)) (br (block 7 v120 v155))) @@ -1833,7 +1214,7 @@ (param v214 i32) (param v249 i32) (call #wee_alloc::neighbors::Neighbors::remove v180) - (let (v181 u32) (cast v180)) + (let (v181 u32) (bitcast v180)) (let (v182 (ptr u8)) (inttoptr v181)) (let (v183 u8) (load v182)) (let (v184 i32) (zext v183)) @@ -1846,7 +1227,7 @@ (block 22 (let (v171 i32) (const.i32 0)) - (let (v172 u32) (cast v168)) + (let (v172 u32) (bitcast v168)) (let (v173 (ptr u8)) (inttoptr v172)) (let (v174 u8) (load v173)) (let (v175 i32) (zext v174)) @@ -1867,24 +1248,24 @@ (param v210 i32) (param v213 i32) (param v248 i32) - (let (v203 u32) (cast v200)) - (let (v204 u32) (mod.unchecked v203 2)) - (assertz v204) + (let (v203 u32) (bitcast v200)) + (let (v204 u32) (mod.unchecked v203 4)) + (assertz 250 v204) (let (v205 (ptr i32)) (inttoptr v203)) (store v205 v202) (br (block 9 v202 v207 v210 v213 v200 v248))) (block 25 - (let (v191 u32) (cast v190)) - (let (v192 u32) (mod.unchecked v191 2)) - (assertz v192) + (let (v191 u32) (bitcast v190)) + (let (v192 u32) (mod.unchecked v191 4)) + (assertz 250 v192) (let (v193 (ptr i32)) (inttoptr v191)) (let (v194 i32) (load v193)) (let (v195 i32) (const.i32 2)) (let (v196 i32) (bor v194 v195)) - (let (v197 u32) (cast v190)) - (let (v198 u32) (mod.unchecked v197 2)) - (assertz v198) + (let (v197 u32) (bitcast v190)) + (let (v198 u32) (mod.unchecked v197 4)) + (assertz 250 v198) (let (v199 (ptr i32)) (inttoptr v197)) (store v199 v196) (br (block 24 v201 v190 v208 v211 v214 v249))) @@ -1923,15 +1304,15 @@ (br (block 1 v100))) (block 3 - (let (v20 u32) (cast v0)) - (let (v21 u32) (mod.unchecked v20 2)) - (assertz v21) + (let (v20 u32) (bitcast v0)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) (let (v22 (ptr i32)) (inttoptr v20)) (let (v23 i32) (load v22)) - (let (v24 u32) (cast v7)) + (let (v24 u32) (bitcast v7)) (let (v25 u32) (add.checked v24 12)) - (let (v26 u32) (mod.unchecked v25 2)) - (assertz v26) + (let (v26 u32) (mod.unchecked v25 4)) + (assertz 250 v26) (let (v27 (ptr i32)) (inttoptr v25)) (store v27 v23) (let (v28 i32) (const.i32 3)) @@ -1951,9 +1332,9 @@ (block 4 (call #::new_cell_for_free_list v7 v7 v34 v16) - (let (v49 u32) (cast v7)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) + (let (v49 u32) (bitcast v7)) + (let (v50 u32) (mod.unchecked v49 4)) + (assertz 250 v50) (let (v51 (ptr i32)) (inttoptr v49)) (let (v52 i32) (load v51)) (let (v53 i1) (eq v52 0)) @@ -1962,15 +1343,15 @@ (condbr v55 (block 7) (block 8))) (block 5 - (let (v41 u32) (cast v7)) + (let (v41 u32) (bitcast v7)) (let (v42 u32) (add.checked v41 12)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) + (let (v43 u32) (mod.unchecked v42 4)) + (assertz 250 v43) (let (v44 (ptr i32)) (inttoptr v42)) (let (v45 i32) (load v44)) - (let (v46 u32) (cast v0)) - (let (v47 u32) (mod.unchecked v46 2)) - (assertz v47) + (let (v46 u32) (bitcast v0)) + (let (v47 u32) (mod.unchecked v46 4)) + (assertz 250 v47) (let (v48 (ptr i32)) (inttoptr v46)) (store v48 v45) (br (block 2 v7 v37))) @@ -1980,57 +1361,57 @@ (br (block 2 v96 v94))) (block 7 - (let (v64 u32) (cast v7)) + (let (v64 u32) (bitcast v7)) (let (v65 u32) (add.checked v64 4)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (let (v68 i32) (load v67)) - (let (v69 u32) (cast v7)) + (let (v69 u32) (bitcast v7)) (let (v70 u32) (add.checked v69 12)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) (let (v72 (ptr i32)) (inttoptr v70)) (let (v73 i32) (load v72)) - (let (v74 u32) (cast v68)) + (let (v74 u32) (bitcast v68)) (let (v75 u32) (add.checked v74 8)) - (let (v76 u32) (mod.unchecked v75 2)) - (assertz v76) + (let (v76 u32) (mod.unchecked v75 4)) + (assertz 250 v76) (let (v77 (ptr i32)) (inttoptr v75)) (store v77 v73) - (let (v78 u32) (cast v7)) + (let (v78 u32) (bitcast v7)) (let (v79 u32) (add.checked v78 12)) - (let (v80 u32) (mod.unchecked v79 2)) - (assertz v80) + (let (v80 u32) (mod.unchecked v79 4)) + (assertz 250 v80) (let (v81 (ptr i32)) (inttoptr v79)) (store v81 v68) (let (v82 i32) (const.i32 12)) (let (v83 i32) (add.wrapping v7 v82)) (let (v84 i32) (call #wee_alloc::alloc_first_fit v34 v16 v83)) - (let (v85 u32) (cast v7)) + (let (v85 u32) (bitcast v7)) (let (v86 u32) (add.checked v85 12)) - (let (v87 u32) (mod.unchecked v86 2)) - (assertz v87) + (let (v87 u32) (mod.unchecked v86 4)) + (assertz 250 v87) (let (v88 (ptr i32)) (inttoptr v86)) (let (v89 i32) (load v88)) - (let (v90 u32) (cast v0)) - (let (v91 u32) (mod.unchecked v90 2)) - (assertz v91) + (let (v90 u32) (bitcast v0)) + (let (v91 u32) (mod.unchecked v90 4)) + (assertz 250 v91) (let (v92 (ptr i32)) (inttoptr v90)) (store v92 v89) (let (v93 i1) (neq v84 0)) (condbr v93 (block 2 v7 v84) (block 9))) (block 8 - (let (v56 u32) (cast v7)) + (let (v56 u32) (bitcast v7)) (let (v57 u32) (add.checked v56 12)) - (let (v58 u32) (mod.unchecked v57 2)) - (assertz v58) + (let (v58 u32) (mod.unchecked v57 4)) + (assertz 250 v58) (let (v59 (ptr i32)) (inttoptr v57)) (let (v60 i32) (load v59)) - (let (v61 u32) (cast v0)) - (let (v62 u32) (mod.unchecked v61 2)) - (assertz v62) + (let (v61 u32) (bitcast v0)) + (let (v62 u32) (mod.unchecked v61 4)) + (assertz 250 v62) (let (v63 (ptr i32)) (inttoptr v61)) (store v63 v60) (br (block 6 v7))) @@ -2062,35 +1443,35 @@ (block 4 (let (v11 i32) (const.i32 0)) - (let (v12 u32) (cast v1)) - (let (v13 u32) (mod.unchecked v12 2)) - (assertz v13) + (let (v12 u32) (bitcast v1)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) (let (v14 (ptr i32)) (inttoptr v12)) (store v14 v11) (let (v15 i32) (const.i32 -8)) (let (v16 i32) (add.wrapping v1 v15)) - (let (v17 u32) (cast v16)) - (let (v18 u32) (mod.unchecked v17 2)) - (assertz v18) + (let (v17 u32) (bitcast v16)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) (let (v19 (ptr i32)) (inttoptr v17)) (let (v20 i32) (load v19)) (let (v21 i32) (const.i32 -2)) (let (v22 i32) (band v20 v21)) - (let (v23 u32) (cast v16)) - (let (v24 u32) (mod.unchecked v23 2)) - (assertz v24) + (let (v23 u32) (bitcast v16)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) (let (v25 (ptr i32)) (inttoptr v23)) (store v25 v22) - (let (v26 u32) (cast v0)) - (let (v27 u32) (mod.unchecked v26 2)) - (assertz v27) + (let (v26 u32) (bitcast v0)) + (let (v27 u32) (mod.unchecked v26 4)) + (assertz 250 v27) (let (v28 (ptr i32)) (inttoptr v26)) (let (v29 i32) (load v28)) (let (v30 i32) (const.i32 4)) (let (v31 i32) (add.wrapping v16 v30)) - (let (v32 u32) (cast v31)) - (let (v33 u32) (mod.unchecked v32 2)) - (assertz v33) + (let (v32 u32) (bitcast v31)) + (let (v33 u32) (mod.unchecked v32 4)) + (assertz 250 v33) (let (v34 (ptr i32)) (inttoptr v32)) (let (v35 i32) (load v34)) (let (v36 i32) (const.i32 -4)) @@ -2101,9 +1482,9 @@ (condbr v40 (block 7 v20 v1 v29 v16 v0) (block 8))) (block 5 (param v109 i32) (param v113 i32) - (let (v115 u32) (cast v109)) - (let (v116 u32) (mod.unchecked v115 2)) - (assertz v116) + (let (v115 u32) (bitcast v109)) + (let (v116 u32) (mod.unchecked v115 4)) + (assertz 250 v116) (let (v117 (ptr i32)) (inttoptr v115)) (store v117 v113) (br (block 2))) @@ -2123,7 +1504,7 @@ (condbr v69 (block 12 v85 v87 v111 v101) (block 13))) (block 8 - (let (v41 u32) (cast v37)) + (let (v41 u32) (bitcast v37)) (let (v42 (ptr u8)) (inttoptr v41)) (let (v43 u8) (load v42)) (let (v44 i32) (zext v43)) @@ -2134,7 +1515,7 @@ (block 9 (call #wee_alloc::neighbors::Neighbors::remove v16) - (let (v48 u32) (cast v16)) + (let (v48 u32) (bitcast v16)) (let (v49 (ptr u8)) (inttoptr v48)) (let (v50 u8) (load v49)) (let (v51 i32) (zext v50)) @@ -2146,40 +1527,40 @@ (condbr v56 (block 6 v29 v0) (block 10))) (block 10 - (let (v57 u32) (cast v37)) - (let (v58 u32) (mod.unchecked v57 2)) - (assertz v58) + (let (v57 u32) (bitcast v37)) + (let (v58 u32) (mod.unchecked v57 4)) + (assertz 250 v58) (let (v59 (ptr i32)) (inttoptr v57)) (let (v60 i32) (load v59)) (let (v61 i32) (const.i32 2)) (let (v62 i32) (bor v60 v61)) - (let (v63 u32) (cast v37)) - (let (v64 u32) (mod.unchecked v63 2)) - (assertz v64) + (let (v63 u32) (bitcast v37)) + (let (v64 u32) (mod.unchecked v63 4)) + (assertz 250 v64) (let (v65 (ptr i32)) (inttoptr v63)) (store v65 v62) (br (block 6 v29 v0))) (block 11 - (let (v91 u32) (cast v71)) + (let (v91 u32) (bitcast v71)) (let (v92 u32) (add.checked v91 8)) - (let (v93 u32) (mod.unchecked v92 2)) - (assertz v93) + (let (v93 u32) (mod.unchecked v92 4)) + (assertz 250 v93) (let (v94 (ptr i32)) (inttoptr v92)) (let (v95 i32) (load v94)) (let (v96 i32) (const.i32 -4)) (let (v97 i32) (band v95 v96)) - (let (v98 u32) (cast v85)) - (let (v99 u32) (mod.unchecked v98 2)) - (assertz v99) + (let (v98 u32) (bitcast v85)) + (let (v99 u32) (mod.unchecked v98 4)) + (assertz 250 v99) (let (v100 (ptr i32)) (inttoptr v98)) (store v100 v97) (let (v102 i32) (const.i32 1)) (let (v103 i32) (bor v101 v102)) - (let (v104 u32) (cast v71)) + (let (v104 u32) (bitcast v71)) (let (v105 u32) (add.checked v104 8)) - (let (v106 u32) (mod.unchecked v105 2)) - (assertz v106) + (let (v106 u32) (mod.unchecked v105 4)) + (assertz 250 v106) (let (v107 (ptr i32)) (inttoptr v105)) (store v107 v103) (br (block 6 v87 v111))) @@ -2189,9 +1570,9 @@ (param v86 i32) (param v110 i32) (param v114 i32) - (let (v88 u32) (cast v84)) - (let (v89 u32) (mod.unchecked v88 2)) - (assertz v89) + (let (v88 u32) (bitcast v84)) + (let (v89 u32) (mod.unchecked v88 4)) + (assertz 250 v89) (let (v90 (ptr i32)) (inttoptr v88)) (store v90 v86) (br (block 5 v110 v114))) @@ -2205,7 +1586,7 @@ (condbr v74 (block 12 v85 v87 v111 v101) (block 14))) (block 14 - (let (v75 u32) (cast v71)) + (let (v75 u32) (bitcast v71)) (let (v76 (ptr u8)) (inttoptr v75)) (let (v77 u8) (load v76)) (let (v78 i32) (zext v77)) @@ -2220,7 +1601,7 @@ (br (block 12 v85 v87 v111 v101))) ) - (func (export #miden_tx_kernel_sys::get_id) + (func (export #miden_base_sys::bindings::tx::get_id) (result felt) (block 0 (let (v1 felt) (call (#miden::account #get_id))) @@ -2230,7 +1611,7 @@ (ret v0)) ) - (func (export #miden_tx_kernel_sys::get_inputs) + (func (export #miden_base_sys::bindings::tx::get_inputs) (param i32) (block 0 (param v0 i32) (let (v1 i32) (const.i32 0)) @@ -2244,281 +1625,210 @@ (let (v8 i32) (const.i32 256)) (let (v9 i32) (const.i32 0)) (call #alloc::raw_vec::RawVec::try_allocate_in v7 v8 v9) - (let (v10 u32) (cast v4)) - (let (v11 u32) (add.checked v10 12)) - (let (v12 u32) (mod.unchecked v11 2)) - (assertz v12) + (let (v10 u32) (bitcast v4)) + (let (v11 u32) (add.checked v10 8)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) (let (v13 (ptr i32)) (inttoptr v11)) (let (v14 i32) (load v13)) - (let (v15 u32) (cast v4)) - (let (v16 u32) (add.checked v15 8)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) + (let (v15 u32) (bitcast v4)) + (let (v16 u32) (add.checked v15 4)) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) (let (v18 (ptr i32)) (inttoptr v16)) (let (v19 i32) (load v18)) - (let (v20 u32) (cast v4)) - (let (v21 u32) (add.checked v20 4)) - (let (v22 u32) (mod.unchecked v21 2)) - (assertz v22) - (let (v23 (ptr i32)) (inttoptr v21)) - (let (v24 i32) (load v23)) - (let (v25 i1) (eq v24 0)) - (let (v26 i32) (zext v25)) - (let (v27 i1) (neq v26 0)) - (condbr v27 (block 3) (block 4))) + (let (v20 i1) (eq v19 0)) + (let (v21 i32) (zext v20)) + (let (v22 i1) (neq v21 0)) + (condbr v22 (block 2) (block 3))) - (block 1) + (block 1 + (ret)) (block 2 - (call #alloc::raw_vec::capacity_overflow) - (unreachable)) + (let (v28 u32) (bitcast v4)) + (let (v29 u32) (add.checked v28 12)) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) + (let (v31 (ptr i32)) (inttoptr v29)) + (let (v32 i32) (load v31)) + (let [(v33 i32) (v34 felt)] (call (#miden::note #get_inputs) v32)) + (let (v35 i32) (const.i32 0)) + (let (v36 u32) (bitcast v0)) + (let (v37 u32) (add.checked v36 8)) + (let (v38 u32) (mod.unchecked v37 4)) + (assertz 250 v38) + (let (v39 (ptr i32)) (inttoptr v37)) + (store v39 v35) + (let (v40 u32) (bitcast v0)) + (let (v41 u32) (add.checked v40 4)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) + (let (v43 (ptr i32)) (inttoptr v41)) + (store v43 v32) + (let (v44 u32) (bitcast v0)) + (let (v45 u32) (mod.unchecked v44 4)) + (assertz 250 v45) + (let (v46 (ptr i32)) (inttoptr v44)) + (store v46 v14) + (let (v47 i32) (const.i32 16)) + (let (v48 i32) (add.wrapping v4 v47)) + (let (v49 (ptr i32)) (global.symbol #__stack_pointer)) + (store v49 v48) + (br (block 1))) (block 3 - (let [(v31 i32) (v32 felt)] (call (#miden::note #get_inputs) v14)) - (let (v33 i32) (const.i32 0)) - (let (v34 u32) (cast v0)) - (let (v35 u32) (add.checked v34 8)) - (let (v36 u32) (mod.unchecked v35 2)) - (assertz v36) - (let (v37 (ptr i32)) (inttoptr v35)) - (store v37 v33) - (let (v38 u32) (cast v0)) - (let (v39 u32) (add.checked v38 4)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) - (let (v41 (ptr i32)) (inttoptr v39)) - (store v41 v14) - (let (v42 u32) (cast v0)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) - (let (v44 (ptr i32)) (inttoptr v42)) - (store v44 v19) - (let (v45 i32) (const.i32 16)) - (let (v46 i32) (add.wrapping v4 v45)) - (let (v47 (ptr i32)) (global.symbol #__stack_pointer)) - (store v47 v46) - (ret)) - - (block 4 - (let (v28 i1) (eq v19 0)) - (let (v29 i32) (zext v28)) - (let (v30 i1) (neq v29 0)) - (condbr v30 (block 2) (block 5))) - - (block 5 - (call #alloc::alloc::handle_alloc_error v19 v14) + (let (v23 u32) (bitcast v4)) + (let (v24 u32) (add.checked v23 12)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) + (let (v26 (ptr i32)) (inttoptr v24)) + (let (v27 i32) (load v26)) + (call #alloc::raw_vec::handle_error v14 v27) (unreachable)) ) - (func (export #miden_tx_kernel_sys::add_asset) + (func (export #miden_base_sys::bindings::tx::add_asset) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) - (let (v2 i32) (const.i32 0)) - (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v4 i32) (const.i32 16)) - (let (v5 i32) (sub.wrapping v3 v4)) - (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) - (store v6 v5) - (let (v7 u32) (cast v1)) - (let (v8 u32) (mod.unchecked v7 2)) - (assertz v8) + (let (v2 u32) (bitcast v1)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) + (let (v4 (ptr felt)) (inttoptr v2)) + (let (v5 felt) (load v4)) + (let (v6 u32) (bitcast v1)) + (let (v7 u32) (add.checked v6 4)) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) (let (v9 (ptr felt)) (inttoptr v7)) (let (v10 felt) (load v9)) - (let (v11 u32) (cast v1)) - (let (v12 u32) (add.checked v11 4)) - (let (v13 u32) (mod.unchecked v12 2)) - (assertz v13) + (let (v11 u32) (bitcast v1)) + (let (v12 u32) (add.checked v11 8)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) (let (v14 (ptr felt)) (inttoptr v12)) (let (v15 felt) (load v14)) - (let (v16 u32) (cast v1)) - (let (v17 u32) (add.checked v16 8)) - (let (v18 u32) (mod.unchecked v17 2)) - (assertz v18) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (add.checked v16 12)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) (let (v19 (ptr felt)) (inttoptr v17)) (let (v20 felt) (load v19)) - (let (v21 u32) (cast v1)) - (let (v22 u32) (add.checked v21 12)) - (let (v23 u32) (mod.unchecked v22 2)) - (assertz v23) - (let (v24 (ptr felt)) (inttoptr v22)) - (let (v25 felt) (load v24)) - (let [(v26 felt) (v27 felt) (v28 felt) (v29 felt)] (call (#miden::account #add_asset) v10 v15 v20 v25)) - (let (v30 u32) (cast v5)) - (let (v31 (ptr felt)) (inttoptr v30)) - (store v31 v26) - (let (v32 u32) (add.checked v30 8)) - (let (v33 (ptr felt)) (inttoptr v32)) - (store v33 v27) - (let (v34 u32) (add.checked v30 16)) - (let (v35 (ptr felt)) (inttoptr v34)) - (store v35 v28) - (let (v36 u32) (add.checked v30 24)) - (let (v37 (ptr felt)) (inttoptr v36)) - (store v37 v29) - (let (v38 i32) (const.i32 8)) - (let (v39 i32) (add.wrapping v0 v38)) - (let (v40 i32) (const.i32 8)) - (let (v41 i32) (add.wrapping v5 v40)) - (let (v42 u32) (cast v41)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) - (let (v44 (ptr i64)) (inttoptr v42)) - (let (v45 i64) (load v44)) - (let (v46 u32) (cast v39)) - (let (v47 u32) (mod.unchecked v46 2)) - (assertz v47) - (let (v48 (ptr i64)) (inttoptr v46)) - (store v48 v45) - (let (v49 u32) (cast v5)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr i64)) (inttoptr v49)) - (let (v52 i64) (load v51)) - (let (v53 u32) (cast v0)) - (let (v54 u32) (mod.unchecked v53 2)) - (assertz v54) - (let (v55 (ptr i64)) (inttoptr v53)) - (store v55 v52) - (let (v56 i32) (const.i32 16)) - (let (v57 i32) (add.wrapping v5 v56)) - (let (v58 (ptr i32)) (global.symbol #__stack_pointer)) - (store v58 v57) + (let [(v21 felt) (v22 felt) (v23 felt) (v24 felt)] (call (#miden::account #add_asset) v5 v10 v15 v20)) + (let (v25 u32) (cast v0)) + (let (v26 (ptr felt)) (inttoptr v25)) + (store v26 v21) + (let (v27 u32) (add.checked v25 8)) + (let (v28 (ptr felt)) (inttoptr v27)) + (store v28 v22) + (let (v29 u32) (add.checked v25 16)) + (let (v30 (ptr felt)) (inttoptr v29)) + (store v30 v23) + (let (v31 u32) (add.checked v25 24)) + (let (v32 (ptr felt)) (inttoptr v31)) + (store v32 v24) (br (block 1))) (block 1 (ret)) ) - (func (export #miden_tx_kernel_sys::remove_asset) + (func (export #miden_base_sys::bindings::tx::remove_asset) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) - (let (v2 i32) (const.i32 0)) - (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v4 i32) (const.i32 16)) - (let (v5 i32) (sub.wrapping v3 v4)) - (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) - (store v6 v5) - (let (v7 u32) (cast v1)) - (let (v8 u32) (mod.unchecked v7 2)) - (assertz v8) + (let (v2 u32) (bitcast v1)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) + (let (v4 (ptr felt)) (inttoptr v2)) + (let (v5 felt) (load v4)) + (let (v6 u32) (bitcast v1)) + (let (v7 u32) (add.checked v6 4)) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) (let (v9 (ptr felt)) (inttoptr v7)) (let (v10 felt) (load v9)) - (let (v11 u32) (cast v1)) - (let (v12 u32) (add.checked v11 4)) - (let (v13 u32) (mod.unchecked v12 2)) - (assertz v13) + (let (v11 u32) (bitcast v1)) + (let (v12 u32) (add.checked v11 8)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) (let (v14 (ptr felt)) (inttoptr v12)) (let (v15 felt) (load v14)) - (let (v16 u32) (cast v1)) - (let (v17 u32) (add.checked v16 8)) - (let (v18 u32) (mod.unchecked v17 2)) - (assertz v18) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (add.checked v16 12)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) (let (v19 (ptr felt)) (inttoptr v17)) (let (v20 felt) (load v19)) - (let (v21 u32) (cast v1)) - (let (v22 u32) (add.checked v21 12)) - (let (v23 u32) (mod.unchecked v22 2)) - (assertz v23) - (let (v24 (ptr felt)) (inttoptr v22)) - (let (v25 felt) (load v24)) - (let [(v26 felt) (v27 felt) (v28 felt) (v29 felt)] (call (#miden::account #remove_asset) v10 v15 v20 v25)) - (let (v30 u32) (cast v5)) - (let (v31 (ptr felt)) (inttoptr v30)) - (store v31 v26) - (let (v32 u32) (add.checked v30 8)) - (let (v33 (ptr felt)) (inttoptr v32)) - (store v33 v27) - (let (v34 u32) (add.checked v30 16)) - (let (v35 (ptr felt)) (inttoptr v34)) - (store v35 v28) - (let (v36 u32) (add.checked v30 24)) - (let (v37 (ptr felt)) (inttoptr v36)) - (store v37 v29) - (let (v38 i32) (const.i32 8)) - (let (v39 i32) (add.wrapping v0 v38)) - (let (v40 i32) (const.i32 8)) - (let (v41 i32) (add.wrapping v5 v40)) - (let (v42 u32) (cast v41)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) - (let (v44 (ptr i64)) (inttoptr v42)) - (let (v45 i64) (load v44)) - (let (v46 u32) (cast v39)) - (let (v47 u32) (mod.unchecked v46 2)) - (assertz v47) - (let (v48 (ptr i64)) (inttoptr v46)) - (store v48 v45) - (let (v49 u32) (cast v5)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr i64)) (inttoptr v49)) - (let (v52 i64) (load v51)) - (let (v53 u32) (cast v0)) - (let (v54 u32) (mod.unchecked v53 2)) - (assertz v54) - (let (v55 (ptr i64)) (inttoptr v53)) - (store v55 v52) - (let (v56 i32) (const.i32 16)) - (let (v57 i32) (add.wrapping v5 v56)) - (let (v58 (ptr i32)) (global.symbol #__stack_pointer)) - (store v58 v57) + (let [(v21 felt) (v22 felt) (v23 felt) (v24 felt)] (call (#miden::account #remove_asset) v5 v10 v15 v20)) + (let (v25 u32) (cast v0)) + (let (v26 (ptr felt)) (inttoptr v25)) + (store v26 v21) + (let (v27 u32) (add.checked v25 8)) + (let (v28 (ptr felt)) (inttoptr v27)) + (store v28 v22) + (let (v29 u32) (add.checked v25 16)) + (let (v30 (ptr felt)) (inttoptr v29)) + (store v30 v23) + (let (v31 u32) (add.checked v25 24)) + (let (v32 (ptr felt)) (inttoptr v31)) + (store v32 v24) (br (block 1))) (block 1 (ret)) ) - (func (export #miden_tx_kernel_sys::create_note) + (func (export #miden_base_sys::bindings::tx::create_note) (param i32) (param felt) (param felt) (param i32) (result felt) (block 0 (param v0 i32) (param v1 felt) (param v2 felt) (param v3 i32) - (let (v5 u32) (cast v0)) - (let (v6 u32) (mod.unchecked v5 2)) - (assertz v6) + (let (v5 u32) (bitcast v0)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) (let (v7 (ptr felt)) (inttoptr v5)) (let (v8 felt) (load v7)) - (let (v9 u32) (cast v0)) + (let (v9 u32) (bitcast v0)) (let (v10 u32) (add.checked v9 4)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr felt)) (inttoptr v10)) (let (v13 felt) (load v12)) - (let (v14 u32) (cast v0)) + (let (v14 u32) (bitcast v0)) (let (v15 u32) (add.checked v14 8)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr felt)) (inttoptr v15)) (let (v18 felt) (load v17)) - (let (v19 u32) (cast v0)) + (let (v19 u32) (bitcast v0)) (let (v20 u32) (add.checked v19 12)) - (let (v21 u32) (mod.unchecked v20 2)) - (assertz v21) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) (let (v22 (ptr felt)) (inttoptr v20)) (let (v23 felt) (load v22)) - (let (v24 u32) (cast v3)) - (let (v25 u32) (mod.unchecked v24 2)) - (assertz v25) + (let (v24 u32) (bitcast v3)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) (let (v26 (ptr felt)) (inttoptr v24)) (let (v27 felt) (load v26)) - (let (v28 u32) (cast v3)) + (let (v28 u32) (bitcast v3)) (let (v29 u32) (add.checked v28 4)) - (let (v30 u32) (mod.unchecked v29 2)) - (assertz v30) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) (let (v31 (ptr felt)) (inttoptr v29)) (let (v32 felt) (load v31)) - (let (v33 u32) (cast v3)) + (let (v33 u32) (bitcast v3)) (let (v34 u32) (add.checked v33 8)) - (let (v35 u32) (mod.unchecked v34 2)) - (assertz v35) + (let (v35 u32) (mod.unchecked v34 4)) + (assertz 250 v35) (let (v36 (ptr felt)) (inttoptr v34)) (let (v37 felt) (load v36)) - (let (v38 u32) (cast v3)) + (let (v38 u32) (bitcast v3)) (let (v39 u32) (add.checked v38 12)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) + (let (v40 u32) (mod.unchecked v39 4)) + (assertz 250 v40) (let (v41 (ptr felt)) (inttoptr v39)) (let (v42 felt) (load v41)) (let (v43 felt) (call (#miden::tx #create_note) v8 v13 v18 v23 v1 v2 v27 v32 v37 v42)) @@ -2541,68 +1851,65 @@ (let (v8 i32) (add.wrapping v5 v7)) (let (v9 i32) (const.i32 0)) (call #alloc::raw_vec::RawVec::try_allocate_in v8 v1 v9) - (let (v10 u32) (cast v5)) - (let (v11 u32) (add.checked v10 12)) - (let (v12 u32) (mod.unchecked v11 2)) - (assertz v12) + (let (v10 u32) (bitcast v5)) + (let (v11 u32) (add.checked v10 8)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) (let (v13 (ptr i32)) (inttoptr v11)) (let (v14 i32) (load v13)) - (let (v15 u32) (cast v5)) - (let (v16 u32) (add.checked v15 8)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) + (let (v15 u32) (bitcast v5)) + (let (v16 u32) (add.checked v15 4)) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) (let (v18 (ptr i32)) (inttoptr v16)) (let (v19 i32) (load v18)) - (let (v20 u32) (cast v5)) - (let (v21 u32) (add.checked v20 4)) - (let (v22 u32) (mod.unchecked v21 2)) - (assertz v22) - (let (v23 (ptr i32)) (inttoptr v21)) - (let (v24 i32) (load v23)) - (let (v25 i1) (eq v24 0)) - (let (v26 i32) (zext v25)) - (let (v27 i1) (neq v26 0)) - (condbr v27 (block 3) (block 4))) + (let (v20 i1) (eq v19 0)) + (let (v21 i32) (zext v20)) + (let (v22 i1) (neq v21 0)) + (condbr v22 (block 2) (block 3))) - (block 1) + (block 1 + (ret)) (block 2 - (call #alloc::raw_vec::capacity_overflow) - (unreachable)) + (let (v28 u32) (bitcast v5)) + (let (v29 u32) (add.checked v28 12)) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) + (let (v31 (ptr i32)) (inttoptr v29)) + (let (v32 i32) (load v31)) + (let (v33 i32) (const.i32 0)) + (let (v34 u32) (bitcast v0)) + (let (v35 u32) (add.checked v34 8)) + (let (v36 u32) (mod.unchecked v35 4)) + (assertz 250 v36) + (let (v37 (ptr i32)) (inttoptr v35)) + (store v37 v33) + (let (v38 u32) (bitcast v0)) + (let (v39 u32) (add.checked v38 4)) + (let (v40 u32) (mod.unchecked v39 4)) + (assertz 250 v40) + (let (v41 (ptr i32)) (inttoptr v39)) + (store v41 v32) + (let (v42 u32) (bitcast v0)) + (let (v43 u32) (mod.unchecked v42 4)) + (assertz 250 v43) + (let (v44 (ptr i32)) (inttoptr v42)) + (store v44 v14) + (let (v45 i32) (const.i32 16)) + (let (v46 i32) (add.wrapping v5 v45)) + (let (v47 (ptr i32)) (global.symbol #__stack_pointer)) + (store v47 v46) + (br (block 1))) (block 3 - (let (v31 i32) (const.i32 0)) - (let (v32 u32) (cast v0)) - (let (v33 u32) (add.checked v32 8)) - (let (v34 u32) (mod.unchecked v33 2)) - (assertz v34) - (let (v35 (ptr i32)) (inttoptr v33)) - (store v35 v31) - (let (v36 u32) (cast v0)) - (let (v37 u32) (add.checked v36 4)) - (let (v38 u32) (mod.unchecked v37 2)) - (assertz v38) - (let (v39 (ptr i32)) (inttoptr v37)) - (store v39 v14) - (let (v40 u32) (cast v0)) - (let (v41 u32) (mod.unchecked v40 2)) - (assertz v41) - (let (v42 (ptr i32)) (inttoptr v40)) - (store v42 v19) - (let (v43 i32) (const.i32 16)) - (let (v44 i32) (add.wrapping v5 v43)) - (let (v45 (ptr i32)) (global.symbol #__stack_pointer)) - (store v45 v44) - (ret)) - - (block 4 - (let (v28 i1) (eq v19 0)) - (let (v29 i32) (zext v28)) - (let (v30 i1) (neq v29 0)) - (condbr v30 (block 2) (block 5))) - - (block 5 - (call #alloc::alloc::handle_alloc_error v19 v14) + (let (v23 u32) (bitcast v5)) + (let (v24 u32) (add.checked v23 12)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) + (let (v26 (ptr i32)) (inttoptr v24)) + (let (v27 i32) (load v26)) + (call #alloc::raw_vec::handle_error v14 v27) (unreachable)) ) @@ -2617,9 +1924,9 @@ (ret)) (block 2 (param v62 i32) (param v64 i32) - (let (v65 u32) (cast v62)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v65 u32) (bitcast v62)) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (store v67 v64) (br (block 1))) @@ -2635,10 +1942,10 @@ (block 4 (let (v5 i64) (const.i64 17179869184)) - (let (v6 u32) (cast v0)) + (let (v6 u32) (bitcast v0)) (let (v7 u32) (add.checked v6 4)) - (let (v8 u32) (mod.unchecked v7 2)) - (assertz v8) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) (let (v9 (ptr i64)) (inttoptr v7)) (store v9 v5) (let (v10 i32) (const.i32 0)) @@ -2657,10 +1964,10 @@ (block 7 (let (v17 i32) (const.i32 0)) - (let (v18 u32) (cast v0)) + (let (v18 u32) (bitcast v0)) (let (v19 u32) (add.checked v18 4)) - (let (v20 u32) (mod.unchecked v19 2)) - (assertz v20) + (let (v20 u32) (mod.unchecked v19 4)) + (assertz 250 v20) (let (v21 (ptr i32)) (inttoptr v19)) (store v21 v17) (br (block 5 v0))) @@ -2682,8 +1989,8 @@ (block 10 (let (v26 i32) (const.i32 0)) - (let (v27 u32) (cast v26)) - (let (v28 u32) (add.checked v27 1048656)) + (let (v27 u32) (bitcast v26)) + (let (v28 u32) (add.checked v27 1048580)) (let (v29 (ptr u8)) (inttoptr v28)) (let (v30 u8) (load v29)) (let (v31 i32) (zext v30)) @@ -2692,32 +1999,32 @@ (br (block 8 v33 v0 v1 v24))) (block 11 - (let (v52 u32) (cast v40)) + (let (v52 u32) (bitcast v40)) (let (v53 u32) (add.checked v52 8)) - (let (v54 u32) (mod.unchecked v53 2)) - (assertz v54) + (let (v54 u32) (mod.unchecked v53 4)) + (assertz 250 v54) (let (v55 (ptr i32)) (inttoptr v53)) (store v55 v51) (let (v56 i32) (const.i32 4)) - (let (v57 u32) (cast v40)) + (let (v57 u32) (bitcast v40)) (let (v58 u32) (add.checked v57 4)) - (let (v59 u32) (mod.unchecked v58 2)) - (assertz v59) + (let (v59 u32) (mod.unchecked v58 4)) + (assertz 250 v59) (let (v60 (ptr i32)) (inttoptr v58)) (store v60 v56) (br (block 5 v40))) (block 12 - (let (v41 u32) (cast v40)) + (let (v41 u32) (bitcast v40)) (let (v42 u32) (add.checked v41 8)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) + (let (v43 u32) (mod.unchecked v42 4)) + (assertz 250 v43) (let (v44 (ptr i32)) (inttoptr v42)) (store v44 v36) - (let (v46 u32) (cast v40)) + (let (v46 u32) (bitcast v40)) (let (v47 u32) (add.checked v46 4)) - (let (v48 u32) (mod.unchecked v47 2)) - (assertz v48) + (let (v48 u32) (mod.unchecked v47 4)) + (assertz 250 v48) (let (v49 (ptr i32)) (inttoptr v47)) (store v49 v45) (let (v50 i32) (const.i32 0)) @@ -2728,118 +2035,97 @@ (param i32) (param felt) (block 0 (param v0 i32) (param v1 felt) (let (v2 i32) (const.i32 0)) - (let (v3 i64) (const.i64 0)) - (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v5 i32) (const.i32 64)) - (let (v6 i32) (sub.wrapping v4 v5)) - (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) - (store v7 v6) - (let (v8 i32) (const.i32 12)) - (let (v9 i32) (add.wrapping v6 v8)) - (let (v10 i64) (cast v1)) - (let (v11 i32) (trunc v10)) - (let (v12 i32) (const.i32 2)) - (let (v13 u32) (bitcast v12)) - (let (v14 i32) (shl.wrapping v11 v13)) - (call #alloc::vec::Vec::with_capacity v9 v14) - (let (v15 u32) (cast v6)) - (let (v16 u32) (add.checked v15 16)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) - (let (v18 (ptr i32)) (inttoptr v16)) - (let (v19 i32) (load v18)) - (let (v20 i32) (const.i32 40)) - (let (v21 i32) (add.wrapping v6 v20)) - (let [(v22 felt) (v23 felt) (v24 felt) (v25 felt) (v26 i32)] (call (#miden:stdlib/std_mem #pipe_words_to_memory) v1 v19)) - (let (v27 u32) (cast v21)) - (let (v28 (ptr felt)) (inttoptr v27)) - (store v28 v22) - (let (v29 u32) (add.checked v27 8)) - (let (v30 (ptr felt)) (inttoptr v29)) - (store v30 v23) - (let (v31 u32) (add.checked v27 16)) - (let (v32 (ptr felt)) (inttoptr v31)) - (store v32 v24) - (let (v33 u32) (add.checked v27 24)) - (let (v34 (ptr felt)) (inttoptr v33)) - (store v34 v25) - (let (v35 u32) (add.checked v27 32)) - (let (v36 (ptr i32)) (inttoptr v35)) - (store v36 v26) - (let (v37 i32) (const.i32 24)) - (let (v38 i32) (add.wrapping v6 v37)) - (let (v39 i32) (const.i32 8)) - (let (v40 i32) (add.wrapping v38 v39)) - (let (v41 i32) (const.i32 40)) - (let (v42 i32) (add.wrapping v6 v41)) - (let (v43 i32) (const.i32 8)) - (let (v44 i32) (add.wrapping v42 v43)) - (let (v45 u32) (cast v44)) - (let (v46 u32) (mod.unchecked v45 3)) - (assertz v46) - (let (v47 (ptr i64)) (inttoptr v45)) - (let (v48 i64) (load v47)) - (let (v49 u32) (cast v40)) - (let (v50 u32) (mod.unchecked v49 3)) - (assertz v50) - (let (v51 (ptr i64)) (inttoptr v49)) - (store v51 v48) - (let (v52 u32) (cast v6)) - (let (v53 u32) (add.checked v52 40)) - (let (v54 u32) (mod.unchecked v53 3)) - (assertz v54) - (let (v55 (ptr i64)) (inttoptr v53)) - (let (v56 i64) (load v55)) - (let (v57 u32) (cast v6)) - (let (v58 u32) (add.checked v57 24)) - (let (v59 u32) (mod.unchecked v58 3)) - (assertz v59) - (let (v60 (ptr i64)) (inttoptr v58)) - (store v60 v56) - (let (v61 i32) (const.i32 8)) - (let (v62 i32) (add.wrapping v0 v61)) - (let (v63 u32) (cast v62)) - (let (v64 u32) (mod.unchecked v63 2)) - (assertz v64) - (let (v65 (ptr i64)) (inttoptr v63)) - (store v65 v48) - (let (v66 u32) (cast v0)) - (let (v67 u32) (mod.unchecked v66 2)) - (assertz v67) + (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v4 i32) (const.i32 32)) + (let (v5 i32) (sub.wrapping v3 v4)) + (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) + (store v6 v5) + (let (v7 i64) (cast v1)) + (let (v8 i32) (trunc v7)) + (let (v9 i32) (const.i32 2)) + (let (v10 u32) (bitcast v9)) + (let (v11 i32) (shl.wrapping v8 v10)) + (call #alloc::vec::Vec::with_capacity v5 v11) + (let (v12 u32) (bitcast v5)) + (let (v13 u32) (add.checked v12 4)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) + (let (v15 (ptr i32)) (inttoptr v13)) + (let (v16 i32) (load v15)) + (let (v17 i32) (const.i32 12)) + (let (v18 i32) (add.wrapping v5 v17)) + (let [(v19 felt) (v20 felt) (v21 felt) (v22 felt) (v23 i32)] (call (#std::mem #pipe_words_to_memory) v1 v16)) + (let (v24 u32) (cast v18)) + (let (v25 (ptr felt)) (inttoptr v24)) + (store v25 v19) + (let (v26 u32) (add.checked v24 8)) + (let (v27 (ptr felt)) (inttoptr v26)) + (store v27 v20) + (let (v28 u32) (add.checked v24 16)) + (let (v29 (ptr felt)) (inttoptr v28)) + (store v29 v21) + (let (v30 u32) (add.checked v24 24)) + (let (v31 (ptr felt)) (inttoptr v30)) + (store v31 v22) + (let (v32 u32) (add.checked v24 32)) + (let (v33 (ptr i32)) (inttoptr v32)) + (store v33 v23) + (let (v34 i32) (const.i32 8)) + (let (v35 i32) (add.wrapping v0 v34)) + (let (v36 i32) (const.i32 12)) + (let (v37 i32) (add.wrapping v5 v36)) + (let (v38 i32) (const.i32 8)) + (let (v39 i32) (add.wrapping v37 v38)) + (let (v40 u32) (bitcast v39)) + (let (v41 u32) (mod.unchecked v40 4)) + (assertz 250 v41) + (let (v42 (ptr i64)) (inttoptr v40)) + (let (v43 i64) (load v42)) + (let (v44 u32) (bitcast v35)) + (let (v45 u32) (mod.unchecked v44 4)) + (assertz 250 v45) + (let (v46 (ptr i64)) (inttoptr v44)) + (store v46 v43) + (let (v47 u32) (bitcast v5)) + (let (v48 u32) (add.checked v47 12)) + (let (v49 u32) (mod.unchecked v48 4)) + (assertz 250 v49) + (let (v50 (ptr i64)) (inttoptr v48)) + (let (v51 i64) (load v50)) + (let (v52 u32) (bitcast v0)) + (let (v53 u32) (mod.unchecked v52 4)) + (assertz 250 v53) + (let (v54 (ptr i64)) (inttoptr v52)) + (store v54 v51) + (let (v55 i32) (const.i32 24)) + (let (v56 i32) (add.wrapping v0 v55)) + (let (v57 i32) (const.i32 8)) + (let (v58 i32) (add.wrapping v5 v57)) + (let (v59 u32) (bitcast v58)) + (let (v60 u32) (mod.unchecked v59 4)) + (assertz 250 v60) + (let (v61 (ptr i32)) (inttoptr v59)) + (let (v62 i32) (load v61)) + (let (v63 u32) (bitcast v56)) + (let (v64 u32) (mod.unchecked v63 4)) + (assertz 250 v64) + (let (v65 (ptr i32)) (inttoptr v63)) + (store v65 v62) + (let (v66 u32) (bitcast v5)) + (let (v67 u32) (mod.unchecked v66 4)) + (assertz 250 v67) (let (v68 (ptr i64)) (inttoptr v66)) - (store v68 v56) - (let (v69 u32) (cast v6)) - (let (v70 u32) (add.checked v69 12)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) - (let (v72 (ptr i64)) (inttoptr v70)) - (let (v73 i64) (load v72)) - (let (v74 u32) (cast v0)) - (let (v75 u32) (add.checked v74 16)) - (let (v76 u32) (mod.unchecked v75 2)) - (assertz v76) - (let (v77 (ptr i64)) (inttoptr v75)) - (store v77 v73) - (let (v78 i32) (const.i32 24)) - (let (v79 i32) (add.wrapping v0 v78)) - (let (v80 i32) (const.i32 12)) - (let (v81 i32) (add.wrapping v6 v80)) - (let (v82 i32) (const.i32 8)) - (let (v83 i32) (add.wrapping v81 v82)) - (let (v84 u32) (cast v83)) - (let (v85 u32) (mod.unchecked v84 2)) - (assertz v85) - (let (v86 (ptr i32)) (inttoptr v84)) - (let (v87 i32) (load v86)) - (let (v88 u32) (cast v79)) - (let (v89 u32) (mod.unchecked v88 2)) - (assertz v89) - (let (v90 (ptr i32)) (inttoptr v88)) - (store v90 v87) - (let (v91 i32) (const.i32 64)) - (let (v92 i32) (add.wrapping v6 v91)) - (let (v93 (ptr i32)) (global.symbol #__stack_pointer)) - (store v93 v92) + (let (v69 i64) (load v68)) + (let (v70 u32) (bitcast v0)) + (let (v71 u32) (add.checked v70 16)) + (let (v72 u32) (mod.unchecked v71 4)) + (assertz 250 v72) + (let (v73 (ptr i64)) (inttoptr v71)) + (store v73 v69) + (let (v74 i32) (const.i32 32)) + (let (v75 i32) (add.wrapping v5 v74)) + (let (v76 (ptr i32)) (global.symbol #__stack_pointer)) + (store v76 v75) (br (block 1))) (block 1 @@ -2850,148 +2136,127 @@ (param i32) (param felt) (block 0 (param v0 i32) (param v1 felt) (let (v2 i32) (const.i32 0)) - (let (v3 i64) (const.i64 0)) - (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v5 i32) (const.i32 96)) - (let (v6 i32) (sub.wrapping v4 v5)) - (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) - (store v7 v6) - (let (v8 i32) (const.i32 12)) - (let (v9 i32) (add.wrapping v6 v8)) - (let (v10 i64) (cast v1)) - (let (v11 i32) (trunc v10)) - (let (v12 i32) (const.i32 2)) - (let (v13 u32) (bitcast v12)) - (let (v14 i32) (shl.wrapping v11 v13)) - (call #alloc::vec::Vec::with_capacity v9 v14) - (let (v15 u32) (cast v6)) - (let (v16 u32) (add.checked v15 16)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) - (let (v18 (ptr i32)) (inttoptr v16)) - (let (v19 i32) (load v18)) - (let (v20 i64) (const.i64 0)) - (let (v21 felt) (cast v20)) - (let (v22 i32) (const.i32 4)) - (let (v23 u32) (bitcast v22)) - (let (v24 i32) (shl.wrapping v11 v23)) - (let (v25 i32) (add.wrapping v19 v24)) - (let (v26 i32) (const.i32 40)) - (let (v27 i32) (add.wrapping v6 v26)) - (let [(v28 felt) (v29 felt) (v30 felt) (v31 felt) (v32 felt) (v33 felt) (v34 felt) (v35 felt) (v36 felt) (v37 felt) (v38 felt) (v39 felt) (v40 i32)] (call (#miden:stdlib/std_mem #pipe_double_words_to_memory) v21 v21 v21 v21 v21 v21 v21 v21 v21 v21 v21 v21 v19 v25)) - (let (v41 u32) (cast v27)) - (let (v42 (ptr felt)) (inttoptr v41)) - (store v42 v28) - (let (v43 u32) (add.checked v41 8)) - (let (v44 (ptr felt)) (inttoptr v43)) - (store v44 v29) - (let (v45 u32) (add.checked v41 16)) - (let (v46 (ptr felt)) (inttoptr v45)) - (store v46 v30) - (let (v47 u32) (add.checked v41 24)) - (let (v48 (ptr felt)) (inttoptr v47)) - (store v48 v31) - (let (v49 u32) (add.checked v41 32)) - (let (v50 (ptr felt)) (inttoptr v49)) - (store v50 v32) - (let (v51 u32) (add.checked v41 40)) - (let (v52 (ptr felt)) (inttoptr v51)) - (store v52 v33) - (let (v53 u32) (add.checked v41 48)) - (let (v54 (ptr felt)) (inttoptr v53)) - (store v54 v34) - (let (v55 u32) (add.checked v41 56)) - (let (v56 (ptr felt)) (inttoptr v55)) - (store v56 v35) - (let (v57 u32) (add.checked v41 64)) - (let (v58 (ptr felt)) (inttoptr v57)) - (store v58 v36) - (let (v59 u32) (add.checked v41 72)) - (let (v60 (ptr felt)) (inttoptr v59)) - (store v60 v37) - (let (v61 u32) (add.checked v41 80)) - (let (v62 (ptr felt)) (inttoptr v61)) - (store v62 v38) - (let (v63 u32) (add.checked v41 88)) - (let (v64 (ptr felt)) (inttoptr v63)) - (store v64 v39) - (let (v65 u32) (add.checked v41 96)) - (let (v66 (ptr i32)) (inttoptr v65)) - (store v66 v40) - (let (v67 i32) (const.i32 24)) - (let (v68 i32) (add.wrapping v6 v67)) - (let (v69 i32) (const.i32 8)) - (let (v70 i32) (add.wrapping v68 v69)) - (let (v71 i32) (const.i32 40)) - (let (v72 i32) (add.wrapping v6 v71)) - (let (v73 i32) (const.i32 24)) - (let (v74 i32) (add.wrapping v72 v73)) - (let (v75 u32) (cast v74)) - (let (v76 u32) (mod.unchecked v75 3)) - (assertz v76) - (let (v77 (ptr i64)) (inttoptr v75)) - (let (v78 i64) (load v77)) - (let (v79 u32) (cast v70)) - (let (v80 u32) (mod.unchecked v79 3)) - (assertz v80) - (let (v81 (ptr i64)) (inttoptr v79)) - (store v81 v78) - (let (v82 u32) (cast v6)) - (let (v83 u32) (add.checked v82 56)) - (let (v84 u32) (mod.unchecked v83 3)) - (assertz v84) - (let (v85 (ptr i64)) (inttoptr v83)) - (let (v86 i64) (load v85)) - (let (v87 u32) (cast v6)) - (let (v88 u32) (add.checked v87 24)) - (let (v89 u32) (mod.unchecked v88 3)) - (assertz v89) - (let (v90 (ptr i64)) (inttoptr v88)) - (store v90 v86) - (let (v91 i32) (const.i32 8)) - (let (v92 i32) (add.wrapping v0 v91)) - (let (v93 u32) (cast v92)) - (let (v94 u32) (mod.unchecked v93 2)) - (assertz v94) - (let (v95 (ptr i64)) (inttoptr v93)) - (store v95 v78) - (let (v96 u32) (cast v0)) - (let (v97 u32) (mod.unchecked v96 2)) - (assertz v97) + (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v4 i32) (const.i32 64)) + (let (v5 i32) (sub.wrapping v3 v4)) + (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) + (store v6 v5) + (let (v7 i64) (cast v1)) + (let (v8 i32) (trunc v7)) + (let (v9 i32) (const.i32 2)) + (let (v10 u32) (bitcast v9)) + (let (v11 i32) (shl.wrapping v8 v10)) + (call #alloc::vec::Vec::with_capacity v5 v11) + (let (v12 u32) (bitcast v5)) + (let (v13 u32) (add.checked v12 4)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) + (let (v15 (ptr i32)) (inttoptr v13)) + (let (v16 i32) (load v15)) + (let (v17 i64) (const.i64 0)) + (let (v18 felt) (cast v17)) + (let (v19 i32) (const.i32 4)) + (let (v20 u32) (bitcast v19)) + (let (v21 i32) (shl.wrapping v8 v20)) + (let (v22 i32) (add.wrapping v16 v21)) + (let (v23 i32) (const.i32 12)) + (let (v24 i32) (add.wrapping v5 v23)) + (let [(v25 felt) (v26 felt) (v27 felt) (v28 felt) (v29 felt) (v30 felt) (v31 felt) (v32 felt) (v33 felt) (v34 felt) (v35 felt) (v36 felt) (v37 i32)] (call (#std::mem #pipe_double_words_to_memory) v18 v18 v18 v18 v18 v18 v18 v18 v18 v18 v18 v18 v16 v22)) + (let (v38 u32) (cast v24)) + (let (v39 (ptr felt)) (inttoptr v38)) + (store v39 v25) + (let (v40 u32) (add.checked v38 8)) + (let (v41 (ptr felt)) (inttoptr v40)) + (store v41 v26) + (let (v42 u32) (add.checked v38 16)) + (let (v43 (ptr felt)) (inttoptr v42)) + (store v43 v27) + (let (v44 u32) (add.checked v38 24)) + (let (v45 (ptr felt)) (inttoptr v44)) + (store v45 v28) + (let (v46 u32) (add.checked v38 32)) + (let (v47 (ptr felt)) (inttoptr v46)) + (store v47 v29) + (let (v48 u32) (add.checked v38 40)) + (let (v49 (ptr felt)) (inttoptr v48)) + (store v49 v30) + (let (v50 u32) (add.checked v38 48)) + (let (v51 (ptr felt)) (inttoptr v50)) + (store v51 v31) + (let (v52 u32) (add.checked v38 56)) + (let (v53 (ptr felt)) (inttoptr v52)) + (store v53 v32) + (let (v54 u32) (add.checked v38 64)) + (let (v55 (ptr felt)) (inttoptr v54)) + (store v55 v33) + (let (v56 u32) (add.checked v38 72)) + (let (v57 (ptr felt)) (inttoptr v56)) + (store v57 v34) + (let (v58 u32) (add.checked v38 80)) + (let (v59 (ptr felt)) (inttoptr v58)) + (store v59 v35) + (let (v60 u32) (add.checked v38 88)) + (let (v61 (ptr felt)) (inttoptr v60)) + (store v61 v36) + (let (v62 u32) (add.checked v38 96)) + (let (v63 (ptr i32)) (inttoptr v62)) + (store v63 v37) + (let (v64 i32) (const.i32 8)) + (let (v65 i32) (add.wrapping v0 v64)) + (let (v66 i32) (const.i32 12)) + (let (v67 i32) (add.wrapping v5 v66)) + (let (v68 i32) (const.i32 24)) + (let (v69 i32) (add.wrapping v67 v68)) + (let (v70 u32) (bitcast v69)) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) + (let (v72 (ptr i64)) (inttoptr v70)) + (let (v73 i64) (load v72)) + (let (v74 u32) (bitcast v65)) + (let (v75 u32) (mod.unchecked v74 4)) + (assertz 250 v75) + (let (v76 (ptr i64)) (inttoptr v74)) + (store v76 v73) + (let (v77 u32) (bitcast v5)) + (let (v78 u32) (add.checked v77 28)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) + (let (v80 (ptr i64)) (inttoptr v78)) + (let (v81 i64) (load v80)) + (let (v82 u32) (bitcast v0)) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) + (let (v84 (ptr i64)) (inttoptr v82)) + (store v84 v81) + (let (v85 i32) (const.i32 24)) + (let (v86 i32) (add.wrapping v0 v85)) + (let (v87 i32) (const.i32 8)) + (let (v88 i32) (add.wrapping v5 v87)) + (let (v89 u32) (bitcast v88)) + (let (v90 u32) (mod.unchecked v89 4)) + (assertz 250 v90) + (let (v91 (ptr i32)) (inttoptr v89)) + (let (v92 i32) (load v91)) + (let (v93 u32) (bitcast v86)) + (let (v94 u32) (mod.unchecked v93 4)) + (assertz 250 v94) + (let (v95 (ptr i32)) (inttoptr v93)) + (store v95 v92) + (let (v96 u32) (bitcast v5)) + (let (v97 u32) (mod.unchecked v96 4)) + (assertz 250 v97) (let (v98 (ptr i64)) (inttoptr v96)) - (store v98 v86) - (let (v99 u32) (cast v6)) - (let (v100 u32) (add.checked v99 12)) - (let (v101 u32) (mod.unchecked v100 2)) - (assertz v101) - (let (v102 (ptr i64)) (inttoptr v100)) - (let (v103 i64) (load v102)) - (let (v104 u32) (cast v0)) - (let (v105 u32) (add.checked v104 16)) - (let (v106 u32) (mod.unchecked v105 2)) - (assertz v106) - (let (v107 (ptr i64)) (inttoptr v105)) - (store v107 v103) - (let (v108 i32) (const.i32 24)) - (let (v109 i32) (add.wrapping v0 v108)) - (let (v110 i32) (const.i32 12)) - (let (v111 i32) (add.wrapping v6 v110)) - (let (v112 i32) (const.i32 8)) - (let (v113 i32) (add.wrapping v111 v112)) - (let (v114 u32) (cast v113)) - (let (v115 u32) (mod.unchecked v114 2)) - (assertz v115) - (let (v116 (ptr i32)) (inttoptr v114)) - (let (v117 i32) (load v116)) - (let (v118 u32) (cast v109)) - (let (v119 u32) (mod.unchecked v118 2)) - (assertz v119) - (let (v120 (ptr i32)) (inttoptr v118)) - (store v120 v117) - (let (v121 i32) (const.i32 96)) - (let (v122 i32) (add.wrapping v6 v121)) - (let (v123 (ptr i32)) (global.symbol #__stack_pointer)) - (store v123 v122) + (let (v99 i64) (load v98)) + (let (v100 u32) (bitcast v0)) + (let (v101 u32) (add.checked v100 16)) + (let (v102 u32) (mod.unchecked v101 4)) + (assertz 250 v102) + (let (v103 (ptr i64)) (inttoptr v101)) + (store v103 v99) + (let (v104 i32) (const.i32 64)) + (let (v105 i32) (add.wrapping v5 v104)) + (let (v106 (ptr i32)) (global.symbol #__stack_pointer)) + (store v106 v105) (br (block 1))) (block 1 @@ -3016,7 +2281,7 @@ (ret)) ) - (func (export #alloc::alloc::handle_alloc_error) + (func (export #alloc::raw_vec::handle_error) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) (unreachable)) @@ -3024,50 +2289,6 @@ (block 1) ) - (func (export #alloc::raw_vec::capacity_overflow) - - (block 0 - (unreachable)) - - (block 1) - ) - - (func (export #core::slice::::copy_from_slice::len_mismatch_fail) - (param i32) (param i32) (param i32) - (block 0 (param v0 i32) (param v1 i32) (param v2 i32) - (unreachable)) - - (block 1) - ) - - (func (export #core::slice::::copy_from_slice) - (param i32) (param i32) (param i32) (param i32) (param i32) - (block 0 - (param v0 i32) - (param v1 i32) - (param v2 i32) - (param v3 i32) - (param v4 i32) - (let (v5 i1) (neq v1 v3)) - (let (v6 i32) (zext v5)) - (let (v7 i1) (neq v6 0)) - (condbr v7 (block 2) (block 3))) - - (block 1) - - (block 2 - (call #core::slice::::copy_from_slice::len_mismatch_fail v1 v1 v1) - (unreachable)) - - (block 3 - (let (v8 u32) (cast v0)) - (let (v9 (ptr u8)) (inttoptr v8)) - (let (v10 u32) (cast v2)) - (let (v11 (ptr u8)) (inttoptr v10)) - (memcpy v11 v9 v1) - (ret)) - ) - (func (export #get_wallet_magic_number.command_export) (result felt) (block 0 (let (v1 felt) (call #get_wallet_magic_number)) @@ -3121,9 +2342,9 @@ ) (func (export #test_blake3_hash_2to1.command_export) - (param i32) (param i32) (param i32) - (block 0 (param v0 i32) (param v1 i32) (param v2 i32) - (call #test_blake3_hash_2to1 v0 v1 v2) + (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (call #test_blake3_hash_2to1 v0 v1) (call #__wasm_call_dtors) (br (block 1))) @@ -3199,16 +2420,16 @@ (func (import #miden::note #get_inputs) (param i32) (result i32 felt)) (func (import #miden::tx #create_note) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (result felt)) - (func (import #miden:stdlib/std_crypto_dsa #rpo_falcon512_verify) + (func (import #std::crypto::dsa::rpo_falcon512 #rpo_falcon512_verify) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt)) - (func (import #miden:stdlib/std_mem #pipe_double_words_to_memory) + (func (import #std::crypto::hashes::blake3 #hash_1to1) + (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32 i32 i32 i32 i32 i32 i32 i32)) + (func (import #std::crypto::hashes::blake3 #hash_2to1) + (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32 i32 i32 i32 i32 i32 i32 i32)) + (func (import #std::mem #pipe_double_words_to_memory) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param i32) (param i32) (result felt felt felt felt felt felt felt felt felt felt felt felt i32)) - (func (import #miden:stdlib/std_mem #pipe_words_to_memory) + (func (import #std::mem #pipe_words_to_memory) (param felt) (param i32) (result felt felt felt felt i32)) - (func (import #std::crypto_hashes #blake3_hash_1to1) - (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (result felt felt felt felt felt felt felt felt)) - (func (import #std::crypto_hashes #blake3_hash_2to1) - (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (result felt felt felt felt felt felt felt felt)) ) ) diff --git a/tests/integration/expected/rust_sdk_account_test/miden_sdk_account_test.wat b/tests/integration/expected/rust_sdk_account_test/miden_sdk_account_test.wat index 41bf1019..05b2ea36 100644 --- a/tests/integration/expected/rust_sdk_account_test/miden_sdk_account_test.wat +++ b/tests/integration/expected/rust_sdk_account_test/miden_sdk_account_test.wat @@ -7,8 +7,8 @@ (type (;5;) (func (param f32))) (type (;6;) (func (param f32) (result f32))) (type (;7;) (func (param f32 f32))) - (type (;8;) (func (param f32 f32 f32 f32 f32 f32 f32 f32 i32))) - (type (;9;) (func (param f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 i32))) + (type (;8;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32))) + (type (;9;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32))) (type (;10;) (func (param f32 f32 f32 f32 f32 f32 f32 f32))) (type (;11;) (func (result f32))) (type (;12;) (func (param i32) (result i32))) @@ -26,7 +26,6 @@ (type (;24;) (func (param i32 i32) (result i32))) (type (;25;) (func (param i32 i32 i32 i32))) (type (;26;) (func)) - (type (;27;) (func (param i32 i32 i32 i32 i32))) (import "miden:stdlib/intrinsics_felt" "from_u64_unchecked" (func $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked (;0;) (type 0))) (import "miden:stdlib/intrinsics_felt" "add" (func $miden_stdlib_sys::intrinsics::felt::extern_add (;1;) (type 1))) (import "miden:stdlib/intrinsics_felt" "as_u64" (func $miden_stdlib_sys::intrinsics::felt::extern_as_u64 (;2;) (type 2))) @@ -46,16 +45,16 @@ (import "miden:stdlib/intrinsics_felt" "div" (func $miden_stdlib_sys::intrinsics::felt::extern_div (;16;) (type 1))) (import "miden:stdlib/intrinsics_felt" "assert_eq" (func $miden_stdlib_sys::intrinsics::felt::extern_assert_eq (;17;) (type 7))) (import "miden:stdlib/intrinsics_felt" "neg" (func $miden_stdlib_sys::intrinsics::felt::extern_neg (;18;) (type 6))) - (import "std::crypto_hashes" "blake3_hash_1to1<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 (;19;) (type 8))) - (import "std::crypto_hashes" "blake3_hash_2to1<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_2to1 (;20;) (type 9))) - (import "miden:stdlib/std_crypto_dsa" "rpo_falcon512_verify<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::crypto::dsa::extern_rpo_falcon512_verify (;21;) (type 10))) - (import "miden::account" "get_id<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_account_get_id (;22;) (type 11))) - (import "miden::note" "get_inputs<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_note_get_inputs (;23;) (type 12))) - (import "miden::account" "add_asset<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_account_add_asset (;24;) (type 13))) - (import "miden::account" "remove_asset<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_account_remove_asset (;25;) (type 13))) - (import "miden::tx" "create_note<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_tx_create_note (;26;) (type 14))) - (import "miden:stdlib/std_mem" "pipe_words_to_memory<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::mem::extern_pipe_words_to_memory (;27;) (type 15))) - (import "miden:stdlib/std_mem" "pipe_double_words_to_memory<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::mem::extern_pipe_double_words_to_memory (;28;) (type 16))) + (import "std::crypto::hashes::blake3" "hash_1to1<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 (;19;) (type 8))) + (import "std::crypto::hashes::blake3" "hash_2to1<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_2to1 (;20;) (type 9))) + (import "std::crypto::dsa::rpo_falcon512" "rpo_falcon512_verify<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::crypto::dsa::extern_rpo_falcon512_verify (;21;) (type 10))) + (import "miden::account" "get_id<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_account_get_id (;22;) (type 11))) + (import "miden::note" "get_inputs<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_note_get_inputs (;23;) (type 12))) + (import "miden::account" "add_asset<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_account_add_asset (;24;) (type 13))) + (import "miden::account" "remove_asset<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_account_remove_asset (;25;) (type 13))) + (import "miden::tx" "create_note<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_tx_create_note (;26;) (type 14))) + (import "std::mem" "pipe_words_to_memory<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::mem::extern_pipe_words_to_memory (;27;) (type 15))) + (import "std::mem" "pipe_double_words_to_memory<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::mem::extern_pipe_double_words_to_memory (;28;) (type 16))) (func $< as core::ops::drop::Drop>::drop::DropGuard as core::ops::drop::Drop>::drop (;29;) (type 17) (param i32) (local i32) global.get $__stack_pointer @@ -116,7 +115,7 @@ local.get 1 ) (func $__rust_dealloc (;32;) (type 19) (param i32 i32 i32) - i32.const 1048652 + i32.const 1048576 local.get 0 local.get 2 local.get 1 @@ -143,7 +142,7 @@ ) (func $get_wallet_magic_number (;34;) (type 11) (result f32) (local f32) - call $miden_tx_kernel_sys::get_id + call $miden_base_sys::bindings::tx::get_id local.set 0 i64.const 42 call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked @@ -183,7 +182,7 @@ i32.const 16 i32.add local.get 0 - call $miden_tx_kernel_sys::add_asset + call $miden_base_sys::bindings::tx::add_asset local.get 0 f32.load offset=16 local.set 1 @@ -293,7 +292,7 @@ call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked local.set 1 local.get 0 - call $miden_tx_kernel_sys::get_inputs + call $miden_base_sys::bindings::tx::get_inputs local.get 0 i32.load local.set 2 @@ -348,469 +347,60 @@ end ) (func $test_blake3_hash_1to1 (;38;) (type 20) (param i32 i32) - (local i32 i32 f32) - global.get $__stack_pointer - i32.const 144 - i32.sub - local.tee 2 - global.set $__stack_pointer - i32.const 0 - local.set 3 - i64.const 0 - call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked - local.set 4 - loop ;; label = @1 - block ;; label = @2 - local.get 3 - i32.const 32 - i32.ne - br_if 0 (;@2;) - i32.const 0 - local.set 3 - block ;; label = @3 - loop ;; label = @4 - block ;; label = @5 - local.get 3 - i32.const 32 - i32.ne - br_if 0 (;@5;) - local.get 2 - f32.load offset=8 - local.get 2 - f32.load offset=12 - local.get 2 - f32.load offset=16 - local.get 2 - f32.load offset=20 - local.get 2 - f32.load offset=24 - local.get 2 - f32.load offset=28 - local.get 2 - f32.load offset=32 - local.get 2 - f32.load offset=36 - local.get 2 - i32.const 40 - i32.add - call $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 - local.get 2 - i32.const 72 - i32.add - i32.const 24 - i32.add - local.get 2 - i32.const 40 - i32.add - i32.const 24 - i32.add - i64.load align=4 - i64.store - local.get 2 - i32.const 72 - i32.add - i32.const 16 - i32.add - local.get 2 - i32.const 40 - i32.add - i32.const 16 - i32.add - i64.load align=4 - i64.store - local.get 2 - i32.const 72 - i32.add - i32.const 8 - i32.add - local.get 2 - i32.const 40 - i32.add - i32.const 8 - i32.add - i64.load align=4 - i64.store - local.get 2 - local.get 2 - i64.load offset=40 align=4 - i64.store offset=72 - local.get 2 - i32.const 104 - i32.add - i32.const 24 - i32.add - i64.const 0 - i64.store - local.get 2 - i32.const 104 - i32.add - i32.const 16 - i32.add - i64.const 0 - i64.store - local.get 2 - i32.const 104 - i32.add - i32.const 8 - i32.add - i64.const 0 - i64.store - local.get 2 - i64.const 0 - i64.store offset=104 - i32.const 0 - local.set 3 - loop ;; label = @6 - local.get 3 - i32.const 32 - i32.eq - br_if 3 (;@3;) - local.get 2 - local.get 2 - i32.const 72 - i32.add - local.get 3 - i32.add - f32.load - call $miden_stdlib_sys::intrinsics::felt::extern_as_u64 - i64.store offset=136 - local.get 2 - i32.const 104 - i32.add - local.get 3 - i32.add - i32.const 4 - local.get 2 - i32.const 136 - i32.add - i32.const 4 - i32.const 1048620 - call $core::slice::::copy_from_slice - local.get 3 - i32.const 4 - i32.add - local.set 3 - br 0 (;@6;) - end - end - local.get 2 - i32.const 8 - i32.add - local.get 3 - i32.add - local.get 1 - local.get 3 - i32.add - i64.load32_u align=1 - call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked - f32.store - local.get 3 - i32.const 4 - i32.add - local.set 3 - br 0 (;@4;) - end - end - local.get 0 - local.get 2 - i64.load offset=104 - i64.store align=1 - local.get 0 - i32.const 24 - i32.add - local.get 2 - i32.const 104 - i32.add - i32.const 24 - i32.add - i64.load - i64.store align=1 - local.get 0 - i32.const 16 - i32.add - local.get 2 - i32.const 104 - i32.add - i32.const 16 - i32.add - i64.load - i64.store align=1 - local.get 0 - i32.const 8 - i32.add - local.get 2 - i32.const 104 - i32.add - i32.const 8 - i32.add - i64.load - i64.store align=1 - local.get 2 - i32.const 144 - i32.add - global.set $__stack_pointer - return - end - local.get 2 - i32.const 8 - i32.add - local.get 3 - i32.add - local.get 4 - f32.store - local.get 3 - i32.const 4 - i32.add - local.set 3 - br 0 (;@1;) - end + local.get 1 + i32.load align=1 + local.get 1 + i32.load offset=4 align=1 + local.get 1 + i32.load offset=8 align=1 + local.get 1 + i32.load offset=12 align=1 + local.get 1 + i32.load offset=16 align=1 + local.get 1 + i32.load offset=20 align=1 + local.get 1 + i32.load offset=24 align=1 + local.get 1 + i32.load offset=28 align=1 + local.get 0 + call $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 ) - (func $test_blake3_hash_2to1 (;39;) (type 19) (param i32 i32 i32) - (local i32 i32 f32) - global.get $__stack_pointer - i32.const 240 - i32.sub - local.tee 3 - global.set $__stack_pointer - i32.const 0 - local.set 4 - i64.const 0 - call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked - local.set 5 - loop ;; label = @1 - block ;; label = @2 - local.get 4 - i32.const 32 - i32.ne - br_if 0 (;@2;) - i32.const 0 - local.set 4 - loop ;; label = @3 - block ;; label = @4 - local.get 4 - i32.const 32 - i32.ne - br_if 0 (;@4;) - i32.const 0 - local.set 4 - i64.const 0 - call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked - local.set 5 - loop ;; label = @5 - block ;; label = @6 - local.get 4 - i32.const 32 - i32.ne - br_if 0 (;@6;) - i32.const 0 - local.set 4 - block ;; label = @7 - loop ;; label = @8 - block ;; label = @9 - local.get 4 - i32.const 32 - i32.ne - br_if 0 (;@9;) - local.get 3 - f32.load offset=8 - local.get 3 - f32.load offset=12 - local.get 3 - f32.load offset=16 - local.get 3 - f32.load offset=20 - local.get 3 - f32.load offset=24 - local.get 3 - f32.load offset=28 - local.get 3 - f32.load offset=32 - local.get 3 - f32.load offset=36 - local.get 3 - f32.load offset=40 - local.get 3 - f32.load offset=44 - local.get 3 - f32.load offset=48 - local.get 3 - f32.load offset=52 - local.get 3 - f32.load offset=56 - local.get 3 - f32.load offset=60 - local.get 3 - f32.load offset=64 - local.get 3 - f32.load offset=68 - local.get 3 - i32.const 72 - i32.add - call $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_2to1 - local.get 3 - i32.const 136 - i32.add - local.get 3 - i32.const 72 - i32.add - i32.const 64 - memory.copy - local.get 3 - i32.const 224 - i32.add - i64.const 0 - i64.store - local.get 3 - i32.const 216 - i32.add - i64.const 0 - i64.store - local.get 3 - i32.const 208 - i32.add - i64.const 0 - i64.store - local.get 3 - i64.const 0 - i64.store offset=200 - i32.const 0 - local.set 4 - loop ;; label = @10 - local.get 4 - i32.const 32 - i32.eq - br_if 3 (;@7;) - local.get 3 - local.get 3 - i32.const 136 - i32.add - local.get 4 - i32.add - f32.load - call $miden_stdlib_sys::intrinsics::felt::extern_as_u64 - i64.store offset=232 - local.get 3 - i32.const 200 - i32.add - local.get 4 - i32.add - i32.const 4 - local.get 3 - i32.const 232 - i32.add - i32.const 4 - i32.const 1048636 - call $core::slice::::copy_from_slice - local.get 4 - i32.const 4 - i32.add - local.set 4 - br 0 (;@10;) - end - end - local.get 3 - i32.const 40 - i32.add - local.get 4 - i32.add - local.get 2 - local.get 4 - i32.add - i64.load32_u align=1 - call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked - f32.store - local.get 4 - i32.const 4 - i32.add - local.set 4 - br 0 (;@8;) - end - end - local.get 0 - local.get 3 - i64.load offset=200 - i64.store align=1 - local.get 0 - i32.const 24 - i32.add - local.get 3 - i32.const 200 - i32.add - i32.const 24 - i32.add - i64.load - i64.store align=1 - local.get 0 - i32.const 16 - i32.add - local.get 3 - i32.const 200 - i32.add - i32.const 16 - i32.add - i64.load - i64.store align=1 - local.get 0 - i32.const 8 - i32.add - local.get 3 - i32.const 200 - i32.add - i32.const 8 - i32.add - i64.load - i64.store align=1 - local.get 3 - i32.const 240 - i32.add - global.set $__stack_pointer - return - end - local.get 3 - i32.const 40 - i32.add - local.get 4 - i32.add - local.get 5 - f32.store - local.get 4 - i32.const 4 - i32.add - local.set 4 - br 0 (;@5;) - end - end - local.get 3 - i32.const 8 - i32.add - local.get 4 - i32.add - local.get 1 - local.get 4 - i32.add - i64.load32_u align=1 - call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked - f32.store - local.get 4 - i32.const 4 - i32.add - local.set 4 - br 0 (;@3;) - end - end - local.get 3 - i32.const 8 - i32.add - local.get 4 - i32.add - local.get 5 - f32.store - local.get 4 - i32.const 4 - i32.add - local.set 4 - br 0 (;@1;) - end + (func $test_blake3_hash_2to1 (;39;) (type 20) (param i32 i32) + local.get 1 + i32.load align=1 + local.get 1 + i32.load offset=4 align=1 + local.get 1 + i32.load offset=8 align=1 + local.get 1 + i32.load offset=12 align=1 + local.get 1 + i32.load offset=16 align=1 + local.get 1 + i32.load offset=20 align=1 + local.get 1 + i32.load offset=24 align=1 + local.get 1 + i32.load offset=28 align=1 + local.get 1 + i32.load offset=32 align=1 + local.get 1 + i32.load offset=36 align=1 + local.get 1 + i32.load offset=40 align=1 + local.get 1 + i32.load offset=44 align=1 + local.get 1 + i32.load offset=48 align=1 + local.get 1 + i32.load offset=52 align=1 + local.get 1 + i32.load offset=56 align=1 + local.get 1 + i32.load offset=60 align=1 + local.get 0 + call $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_2to1 ) (func $test_rpo_falcon512_verify (;40;) (type 20) (param i32 i32) local.get 0 @@ -850,7 +440,7 @@ global.set $__stack_pointer local.get 1 local.get 0 - call $miden_tx_kernel_sys::remove_asset + call $miden_base_sys::bindings::tx::remove_asset local.get 1 f32.load local.set 2 @@ -865,16 +455,16 @@ local.get 1 local.get 2 local.get 3 - call $miden_tx_kernel_sys::create_note + call $miden_base_sys::bindings::tx::create_note ) (func $__rust_alloc (;45;) (type 24) (param i32 i32) (result i32) - i32.const 1048652 + i32.const 1048576 local.get 1 local.get 0 call $::alloc ) (func $__rust_alloc_zeroed (;46;) (type 24) (param i32 i32) (result i32) - i32.const 1048652 + i32.const 1048576 local.get 1 local.get 0 call $core::alloc::global::GlobalAlloc::alloc_zeroed @@ -1432,10 +1022,10 @@ i32.store end ) - (func $miden_tx_kernel_sys::get_id (;52;) (type 11) (result f32) - call $miden_tx_kernel_sys::externs::extern_account_get_id + (func $miden_base_sys::bindings::tx::get_id (;52;) (type 11) (result f32) + call $miden_base_sys::bindings::tx::externs::extern_account_get_id ) - (func $miden_tx_kernel_sys::get_inputs (;53;) (type 17) (param i32) + (func $miden_base_sys::bindings::tx::get_inputs (;53;) (type 17) (param i32) (local i32 i32 i32) global.get $__stack_pointer i32.const 16 @@ -1449,53 +1039,39 @@ i32.const 0 call $alloc::raw_vec::RawVec::try_allocate_in local.get 1 - i32.load offset=12 - local.set 2 - local.get 1 i32.load offset=8 - local.set 3 + local.set 2 block ;; label = @1 - block ;; label = @2 - local.get 1 - i32.load offset=4 - i32.eqz - br_if 0 (;@2;) - local.get 3 - i32.eqz - br_if 1 (;@1;) - local.get 3 - local.get 2 - call $alloc::alloc::handle_alloc_error - unreachable - end - local.get 2 - call $miden_tx_kernel_sys::externs::extern_note_get_inputs - drop - local.get 0 - i32.const 0 - i32.store offset=8 - local.get 0 + local.get 1 + i32.load offset=4 + i32.eqz + br_if 0 (;@1;) local.get 2 - i32.store offset=4 - local.get 0 - local.get 3 - i32.store local.get 1 - i32.const 16 - i32.add - global.set $__stack_pointer - return + i32.load offset=12 + call $alloc::raw_vec::handle_error + unreachable end - call $alloc::raw_vec::capacity_overflow - unreachable - ) - (func $miden_tx_kernel_sys::add_asset (;54;) (type 20) (param i32 i32) - (local i32) - global.get $__stack_pointer + local.get 1 + i32.load offset=12 + local.tee 3 + call $miden_base_sys::bindings::tx::externs::extern_note_get_inputs + drop + local.get 0 + i32.const 0 + i32.store offset=8 + local.get 0 + local.get 3 + i32.store offset=4 + local.get 0 + local.get 2 + i32.store + local.get 1 i32.const 16 - i32.sub - local.tee 2 + i32.add global.set $__stack_pointer + ) + (func $miden_base_sys::bindings::tx::add_asset (;54;) (type 20) (param i32 i32) local.get 1 f32.load local.get 1 @@ -1504,32 +1080,10 @@ f32.load offset=8 local.get 1 f32.load offset=12 - local.get 2 - call $miden_tx_kernel_sys::externs::extern_account_add_asset - local.get 0 - i32.const 8 - i32.add - local.get 2 - i32.const 8 - i32.add - i64.load align=4 - i64.store align=4 local.get 0 - local.get 2 - i64.load align=4 - i64.store align=4 - local.get 2 - i32.const 16 - i32.add - global.set $__stack_pointer + call $miden_base_sys::bindings::tx::externs::extern_account_add_asset ) - (func $miden_tx_kernel_sys::remove_asset (;55;) (type 20) (param i32 i32) - (local i32) - global.get $__stack_pointer - i32.const 16 - i32.sub - local.tee 2 - global.set $__stack_pointer + (func $miden_base_sys::bindings::tx::remove_asset (;55;) (type 20) (param i32 i32) local.get 1 f32.load local.get 1 @@ -1538,26 +1092,10 @@ f32.load offset=8 local.get 1 f32.load offset=12 - local.get 2 - call $miden_tx_kernel_sys::externs::extern_account_remove_asset - local.get 0 - i32.const 8 - i32.add - local.get 2 - i32.const 8 - i32.add - i64.load align=4 - i64.store align=4 local.get 0 - local.get 2 - i64.load align=4 - i64.store align=4 - local.get 2 - i32.const 16 - i32.add - global.set $__stack_pointer + call $miden_base_sys::bindings::tx::externs::extern_account_remove_asset ) - (func $miden_tx_kernel_sys::create_note (;56;) (type 23) (param i32 f32 f32 i32) (result f32) + (func $miden_base_sys::bindings::tx::create_note (;56;) (type 23) (param i32 f32 f32 i32) (result f32) local.get 0 f32.load local.get 0 @@ -1576,7 +1114,7 @@ f32.load offset=8 local.get 3 f32.load offset=12 - call $miden_tx_kernel_sys::externs::extern_tx_create_note + call $miden_base_sys::bindings::tx::externs::extern_tx_create_note ) (func $alloc::vec::Vec::with_capacity (;57;) (type 20) (param i32 i32) (local i32 i32) @@ -1592,42 +1130,35 @@ i32.const 0 call $alloc::raw_vec::RawVec::try_allocate_in local.get 2 - i32.load offset=12 - local.set 3 - local.get 2 i32.load offset=8 local.set 1 block ;; label = @1 - block ;; label = @2 - local.get 2 - i32.load offset=4 - i32.eqz - br_if 0 (;@2;) - local.get 1 - i32.eqz - br_if 1 (;@1;) - local.get 1 - local.get 3 - call $alloc::alloc::handle_alloc_error - unreachable - end - local.get 0 - i32.const 0 - i32.store offset=8 - local.get 0 - local.get 3 - i32.store offset=4 - local.get 0 + local.get 2 + i32.load offset=4 + i32.eqz + br_if 0 (;@1;) local.get 1 - i32.store local.get 2 - i32.const 16 - i32.add - global.set $__stack_pointer - return + i32.load offset=12 + call $alloc::raw_vec::handle_error + unreachable end - call $alloc::raw_vec::capacity_overflow - unreachable + local.get 2 + i32.load offset=12 + local.set 3 + local.get 0 + i32.const 0 + i32.store offset=8 + local.get 0 + local.get 3 + i32.store offset=4 + local.get 0 + local.get 1 + i32.store + local.get 2 + i32.const 16 + i32.add + global.set $__stack_pointer ) (func $alloc::raw_vec::RawVec::try_allocate_in (;58;) (type 19) (param i32 i32 i32) (local i32) @@ -1662,7 +1193,7 @@ local.get 2 br_if 0 (;@4;) i32.const 0 - i32.load8_u offset=1048656 + i32.load8_u offset=1048580 drop local.get 3 i32.const 4 @@ -1704,15 +1235,13 @@ i32.store ) (func $miden_stdlib_sys::stdlib::mem::pipe_words_to_memory (;59;) (type 21) (param i32 f32) - (local i32 i64 i64) + (local i32) global.get $__stack_pointer - i32.const 64 + i32.const 32 i32.sub local.tee 2 global.set $__stack_pointer local.get 2 - i32.const 12 - i32.add local.get 1 call $miden_stdlib_sys::intrinsics::felt::extern_as_u64 i32.wrap_i64 @@ -1721,66 +1250,50 @@ call $alloc::vec::Vec::with_capacity local.get 1 local.get 2 - i32.load offset=16 + i32.load offset=4 local.get 2 - i32.const 40 + i32.const 12 i32.add call $miden_stdlib_sys::stdlib::mem::extern_pipe_words_to_memory - local.get 2 - i32.const 24 - i32.add + local.get 0 i32.const 8 i32.add local.get 2 - i32.const 40 - i32.add - i32.const 8 + i32.const 12 i32.add - i64.load - local.tee 3 - i64.store - local.get 2 - local.get 2 - i64.load offset=40 - local.tee 4 - i64.store offset=24 - local.get 0 i32.const 8 i32.add - local.get 3 - i64.store align=4 - local.get 0 - local.get 4 + i64.load align=4 i64.store align=4 local.get 0 local.get 2 i64.load offset=12 align=4 - i64.store offset=16 align=4 + i64.store align=4 local.get 0 i32.const 24 i32.add local.get 2 - i32.const 12 - i32.add i32.const 8 i32.add i32.load i32.store + local.get 0 local.get 2 - i32.const 64 + i64.load align=4 + i64.store offset=16 align=4 + local.get 2 + i32.const 32 i32.add global.set $__stack_pointer ) (func $miden_stdlib_sys::stdlib::mem::pipe_double_words_to_memory (;60;) (type 21) (param i32 f32) - (local i32 i32 i32 i64 i64) + (local i32 i32 i32) global.get $__stack_pointer - i32.const 96 + i32.const 64 i32.sub local.tee 2 global.set $__stack_pointer local.get 2 - i32.const 12 - i32.add local.get 1 call $miden_stdlib_sys::intrinsics::felt::extern_as_u64 i32.wrap_i64 @@ -1789,7 +1302,7 @@ i32.shl call $alloc::vec::Vec::with_capacity local.get 2 - i32.load offset=16 + i32.load offset=4 local.set 4 i64.const 0 call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked @@ -1812,51 +1325,37 @@ i32.shl i32.add local.get 2 - i32.const 40 + i32.const 12 i32.add call $miden_stdlib_sys::stdlib::mem::extern_pipe_double_words_to_memory - local.get 2 - i32.const 24 - i32.add + local.get 0 i32.const 8 i32.add local.get 2 - i32.const 40 + i32.const 12 i32.add i32.const 24 i32.add - i64.load - local.tee 5 - i64.store - local.get 2 - local.get 2 - i64.load offset=56 - local.tee 6 - i64.store offset=24 - local.get 0 - i32.const 8 - i32.add - local.get 5 - i64.store align=4 - local.get 0 - local.get 6 + i64.load align=4 i64.store align=4 local.get 0 local.get 2 - i64.load offset=12 align=4 - i64.store offset=16 align=4 + i64.load offset=28 align=4 + i64.store align=4 local.get 0 i32.const 24 i32.add local.get 2 - i32.const 12 - i32.add i32.const 8 i32.add i32.load i32.store + local.get 0 + local.get 2 + i64.load align=4 + i64.store offset=16 align=4 local.get 2 - i32.const 96 + i32.const 64 i32.add global.set $__stack_pointer ) @@ -1865,91 +1364,64 @@ call $dummy call $dummy ) - (func $alloc::alloc::handle_alloc_error (;63;) (type 20) (param i32 i32) - unreachable - unreachable - ) - (func $alloc::raw_vec::capacity_overflow (;64;) (type 26) + (func $alloc::raw_vec::handle_error (;63;) (type 20) (param i32 i32) unreachable unreachable ) - (func $core::slice::::copy_from_slice::len_mismatch_fail (;65;) (type 19) (param i32 i32 i32) - unreachable - unreachable - ) - (func $core::slice::::copy_from_slice (;66;) (type 27) (param i32 i32 i32 i32 i32) - block ;; label = @1 - local.get 1 - local.get 3 - i32.ne - br_if 0 (;@1;) - local.get 0 - local.get 2 - local.get 1 - memory.copy - return - end - local.get 1 - local.get 1 - local.get 1 - call $core::slice::::copy_from_slice::len_mismatch_fail - unreachable - ) - (func $get_wallet_magic_number.command_export (;67;) (type 11) (result f32) + (func $get_wallet_magic_number.command_export (;64;) (type 11) (result f32) call $get_wallet_magic_number call $__wasm_call_dtors ) - (func $test_add_asset.command_export (;68;) (type 11) (result f32) + (func $test_add_asset.command_export (;65;) (type 11) (result f32) call $test_add_asset call $__wasm_call_dtors ) - (func $test_felt_ops_smoke.command_export (;69;) (type 1) (param f32 f32) (result f32) + (func $test_felt_ops_smoke.command_export (;66;) (type 1) (param f32 f32) (result f32) local.get 0 local.get 1 call $test_felt_ops_smoke call $__wasm_call_dtors ) - (func $note_script.command_export (;70;) (type 11) (result f32) + (func $note_script.command_export (;67;) (type 11) (result f32) call $note_script call $__wasm_call_dtors ) - (func $test_blake3_hash_1to1.command_export (;71;) (type 20) (param i32 i32) + (func $test_blake3_hash_1to1.command_export (;68;) (type 20) (param i32 i32) local.get 0 local.get 1 call $test_blake3_hash_1to1 call $__wasm_call_dtors ) - (func $test_blake3_hash_2to1.command_export (;72;) (type 19) (param i32 i32 i32) + (func $test_blake3_hash_2to1.command_export (;69;) (type 20) (param i32 i32) local.get 0 local.get 1 - local.get 2 call $test_blake3_hash_2to1 call $__wasm_call_dtors ) - (func $test_rpo_falcon512_verify.command_export (;73;) (type 20) (param i32 i32) + (func $test_rpo_falcon512_verify.command_export (;70;) (type 20) (param i32 i32) local.get 0 local.get 1 call $test_rpo_falcon512_verify call $__wasm_call_dtors ) - (func $test_pipe_words_to_memory.command_export (;74;) (type 21) (param i32 f32) + (func $test_pipe_words_to_memory.command_export (;71;) (type 21) (param i32 f32) local.get 0 local.get 1 call $test_pipe_words_to_memory call $__wasm_call_dtors ) - (func $test_pipe_double_words_to_memory.command_export (;75;) (type 21) (param i32 f32) + (func $test_pipe_double_words_to_memory.command_export (;72;) (type 21) (param i32 f32) local.get 0 local.get 1 call $test_pipe_double_words_to_memory call $__wasm_call_dtors ) - (func $test_remove_asset.command_export (;76;) (type 22) (param i32) (result f32) + (func $test_remove_asset.command_export (;73;) (type 22) (param i32) (result f32) local.get 0 call $test_remove_asset call $__wasm_call_dtors ) - (func $test_create_note.command_export (;77;) (type 23) (param i32 f32 f32 i32) (result f32) + (func $test_create_note.command_export (;74;) (type 23) (param i32 f32 f32 i32) (result f32) local.get 0 local.get 1 local.get 2 @@ -1972,5 +1444,4 @@ (export "test_pipe_double_words_to_memory" (func $test_pipe_double_words_to_memory.command_export)) (export "test_remove_asset" (func $test_remove_asset.command_export)) (export "test_create_note" (func $test_create_note.command_export)) - (data $.rodata (;0;) (i32.const 1048576) "~/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs\00\00\10\00,\00\00\00\8a\00\00\00(\00\00\00\00\00\10\00,\00\00\00\d0\00\00\00(\00\00\00") ) \ No newline at end of file diff --git a/tests/integration/expected/rust_sdk_basic_wallet/rust_sdk_basic_wallet.hir b/tests/integration/expected/rust_sdk_basic_wallet/rust_sdk_basic_wallet.hir index 216a4183..dd994dc2 100644 --- a/tests/integration/expected/rust_sdk_basic_wallet/rust_sdk_basic_wallet.hir +++ b/tests/integration/expected/rust_sdk_basic_wallet/rust_sdk_basic_wallet.hir @@ -19,7 +19,7 @@ (let (v4 i32) (sub.wrapping v2 v3)) (let (v5 (ptr i32)) (global.symbol #__stack_pointer)) (store v5 v4) - (call #miden_tx_kernel_sys::add_asset v4 v0) + (call #miden_base_sys::bindings::tx::add_asset v4 v0) (let (v6 i32) (const.i32 16)) (let (v7 i32) (add.wrapping v4 v6)) (let (v8 (ptr i32)) (global.symbol #__stack_pointer)) @@ -43,8 +43,8 @@ (let (v7 i32) (sub.wrapping v5 v6)) (let (v8 (ptr i32)) (global.symbol #__stack_pointer)) (store v8 v7) - (call #miden_tx_kernel_sys::remove_asset v7 v0) - (let (v9 felt) (call #miden_tx_kernel_sys::create_note v7 v1 v2 v3)) + (call #miden_base_sys::bindings::tx::remove_asset v7 v0) + (let (v9 felt) (call #miden_base_sys::bindings::tx::create_note v7 v1 v2 v3)) (let (v10 i32) (const.i32 16)) (let (v11 i32) (add.wrapping v7 v10)) (let (v12 (ptr i32)) (global.symbol #__stack_pointer)) @@ -55,215 +55,147 @@ (ret)) ) - (func (export #miden_tx_kernel_sys::add_asset) + (func (export #miden_base_sys::bindings::tx::add_asset) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) - (let (v2 i32) (const.i32 0)) - (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v4 i32) (const.i32 16)) - (let (v5 i32) (sub.wrapping v3 v4)) - (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) - (store v6 v5) - (let (v7 u32) (cast v1)) - (let (v8 u32) (mod.unchecked v7 2)) - (assertz v8) + (let (v2 u32) (bitcast v1)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) + (let (v4 (ptr felt)) (inttoptr v2)) + (let (v5 felt) (load v4)) + (let (v6 u32) (bitcast v1)) + (let (v7 u32) (add.checked v6 4)) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) (let (v9 (ptr felt)) (inttoptr v7)) (let (v10 felt) (load v9)) - (let (v11 u32) (cast v1)) - (let (v12 u32) (add.checked v11 4)) - (let (v13 u32) (mod.unchecked v12 2)) - (assertz v13) + (let (v11 u32) (bitcast v1)) + (let (v12 u32) (add.checked v11 8)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) (let (v14 (ptr felt)) (inttoptr v12)) (let (v15 felt) (load v14)) - (let (v16 u32) (cast v1)) - (let (v17 u32) (add.checked v16 8)) - (let (v18 u32) (mod.unchecked v17 2)) - (assertz v18) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (add.checked v16 12)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) (let (v19 (ptr felt)) (inttoptr v17)) (let (v20 felt) (load v19)) - (let (v21 u32) (cast v1)) - (let (v22 u32) (add.checked v21 12)) - (let (v23 u32) (mod.unchecked v22 2)) - (assertz v23) - (let (v24 (ptr felt)) (inttoptr v22)) - (let (v25 felt) (load v24)) - (let [(v26 felt) (v27 felt) (v28 felt) (v29 felt)] (call (#miden::account #add_asset) v10 v15 v20 v25)) - (let (v30 u32) (cast v5)) - (let (v31 (ptr felt)) (inttoptr v30)) - (store v31 v26) - (let (v32 u32) (add.checked v30 8)) - (let (v33 (ptr felt)) (inttoptr v32)) - (store v33 v27) - (let (v34 u32) (add.checked v30 16)) - (let (v35 (ptr felt)) (inttoptr v34)) - (store v35 v28) - (let (v36 u32) (add.checked v30 24)) - (let (v37 (ptr felt)) (inttoptr v36)) - (store v37 v29) - (let (v38 i32) (const.i32 8)) - (let (v39 i32) (add.wrapping v0 v38)) - (let (v40 i32) (const.i32 8)) - (let (v41 i32) (add.wrapping v5 v40)) - (let (v42 u32) (cast v41)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) - (let (v44 (ptr i64)) (inttoptr v42)) - (let (v45 i64) (load v44)) - (let (v46 u32) (cast v39)) - (let (v47 u32) (mod.unchecked v46 2)) - (assertz v47) - (let (v48 (ptr i64)) (inttoptr v46)) - (store v48 v45) - (let (v49 u32) (cast v5)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr i64)) (inttoptr v49)) - (let (v52 i64) (load v51)) - (let (v53 u32) (cast v0)) - (let (v54 u32) (mod.unchecked v53 2)) - (assertz v54) - (let (v55 (ptr i64)) (inttoptr v53)) - (store v55 v52) - (let (v56 i32) (const.i32 16)) - (let (v57 i32) (add.wrapping v5 v56)) - (let (v58 (ptr i32)) (global.symbol #__stack_pointer)) - (store v58 v57) + (let [(v21 felt) (v22 felt) (v23 felt) (v24 felt)] (call (#miden::account #add_asset) v5 v10 v15 v20)) + (let (v25 u32) (cast v0)) + (let (v26 (ptr felt)) (inttoptr v25)) + (store v26 v21) + (let (v27 u32) (add.checked v25 8)) + (let (v28 (ptr felt)) (inttoptr v27)) + (store v28 v22) + (let (v29 u32) (add.checked v25 16)) + (let (v30 (ptr felt)) (inttoptr v29)) + (store v30 v23) + (let (v31 u32) (add.checked v25 24)) + (let (v32 (ptr felt)) (inttoptr v31)) + (store v32 v24) (br (block 1))) (block 1 (ret)) ) - (func (export #miden_tx_kernel_sys::remove_asset) + (func (export #miden_base_sys::bindings::tx::remove_asset) (param i32) (param i32) (block 0 (param v0 i32) (param v1 i32) - (let (v2 i32) (const.i32 0)) - (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v4 i32) (const.i32 16)) - (let (v5 i32) (sub.wrapping v3 v4)) - (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) - (store v6 v5) - (let (v7 u32) (cast v1)) - (let (v8 u32) (mod.unchecked v7 2)) - (assertz v8) + (let (v2 u32) (bitcast v1)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) + (let (v4 (ptr felt)) (inttoptr v2)) + (let (v5 felt) (load v4)) + (let (v6 u32) (bitcast v1)) + (let (v7 u32) (add.checked v6 4)) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) (let (v9 (ptr felt)) (inttoptr v7)) (let (v10 felt) (load v9)) - (let (v11 u32) (cast v1)) - (let (v12 u32) (add.checked v11 4)) - (let (v13 u32) (mod.unchecked v12 2)) - (assertz v13) + (let (v11 u32) (bitcast v1)) + (let (v12 u32) (add.checked v11 8)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) (let (v14 (ptr felt)) (inttoptr v12)) (let (v15 felt) (load v14)) - (let (v16 u32) (cast v1)) - (let (v17 u32) (add.checked v16 8)) - (let (v18 u32) (mod.unchecked v17 2)) - (assertz v18) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (add.checked v16 12)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) (let (v19 (ptr felt)) (inttoptr v17)) (let (v20 felt) (load v19)) - (let (v21 u32) (cast v1)) - (let (v22 u32) (add.checked v21 12)) - (let (v23 u32) (mod.unchecked v22 2)) - (assertz v23) - (let (v24 (ptr felt)) (inttoptr v22)) - (let (v25 felt) (load v24)) - (let [(v26 felt) (v27 felt) (v28 felt) (v29 felt)] (call (#miden::account #remove_asset) v10 v15 v20 v25)) - (let (v30 u32) (cast v5)) - (let (v31 (ptr felt)) (inttoptr v30)) - (store v31 v26) - (let (v32 u32) (add.checked v30 8)) - (let (v33 (ptr felt)) (inttoptr v32)) - (store v33 v27) - (let (v34 u32) (add.checked v30 16)) - (let (v35 (ptr felt)) (inttoptr v34)) - (store v35 v28) - (let (v36 u32) (add.checked v30 24)) - (let (v37 (ptr felt)) (inttoptr v36)) - (store v37 v29) - (let (v38 i32) (const.i32 8)) - (let (v39 i32) (add.wrapping v0 v38)) - (let (v40 i32) (const.i32 8)) - (let (v41 i32) (add.wrapping v5 v40)) - (let (v42 u32) (cast v41)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) - (let (v44 (ptr i64)) (inttoptr v42)) - (let (v45 i64) (load v44)) - (let (v46 u32) (cast v39)) - (let (v47 u32) (mod.unchecked v46 2)) - (assertz v47) - (let (v48 (ptr i64)) (inttoptr v46)) - (store v48 v45) - (let (v49 u32) (cast v5)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr i64)) (inttoptr v49)) - (let (v52 i64) (load v51)) - (let (v53 u32) (cast v0)) - (let (v54 u32) (mod.unchecked v53 2)) - (assertz v54) - (let (v55 (ptr i64)) (inttoptr v53)) - (store v55 v52) - (let (v56 i32) (const.i32 16)) - (let (v57 i32) (add.wrapping v5 v56)) - (let (v58 (ptr i32)) (global.symbol #__stack_pointer)) - (store v58 v57) + (let [(v21 felt) (v22 felt) (v23 felt) (v24 felt)] (call (#miden::account #remove_asset) v5 v10 v15 v20)) + (let (v25 u32) (cast v0)) + (let (v26 (ptr felt)) (inttoptr v25)) + (store v26 v21) + (let (v27 u32) (add.checked v25 8)) + (let (v28 (ptr felt)) (inttoptr v27)) + (store v28 v22) + (let (v29 u32) (add.checked v25 16)) + (let (v30 (ptr felt)) (inttoptr v29)) + (store v30 v23) + (let (v31 u32) (add.checked v25 24)) + (let (v32 (ptr felt)) (inttoptr v31)) + (store v32 v24) (br (block 1))) (block 1 (ret)) ) - (func (export #miden_tx_kernel_sys::create_note) + (func (export #miden_base_sys::bindings::tx::create_note) (param i32) (param felt) (param felt) (param i32) (result felt) (block 0 (param v0 i32) (param v1 felt) (param v2 felt) (param v3 i32) - (let (v5 u32) (cast v0)) - (let (v6 u32) (mod.unchecked v5 2)) - (assertz v6) + (let (v5 u32) (bitcast v0)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) (let (v7 (ptr felt)) (inttoptr v5)) (let (v8 felt) (load v7)) - (let (v9 u32) (cast v0)) + (let (v9 u32) (bitcast v0)) (let (v10 u32) (add.checked v9 4)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr felt)) (inttoptr v10)) (let (v13 felt) (load v12)) - (let (v14 u32) (cast v0)) + (let (v14 u32) (bitcast v0)) (let (v15 u32) (add.checked v14 8)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr felt)) (inttoptr v15)) (let (v18 felt) (load v17)) - (let (v19 u32) (cast v0)) + (let (v19 u32) (bitcast v0)) (let (v20 u32) (add.checked v19 12)) - (let (v21 u32) (mod.unchecked v20 2)) - (assertz v21) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) (let (v22 (ptr felt)) (inttoptr v20)) (let (v23 felt) (load v22)) - (let (v24 u32) (cast v3)) - (let (v25 u32) (mod.unchecked v24 2)) - (assertz v25) + (let (v24 u32) (bitcast v3)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) (let (v26 (ptr felt)) (inttoptr v24)) (let (v27 felt) (load v26)) - (let (v28 u32) (cast v3)) + (let (v28 u32) (bitcast v3)) (let (v29 u32) (add.checked v28 4)) - (let (v30 u32) (mod.unchecked v29 2)) - (assertz v30) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) (let (v31 (ptr felt)) (inttoptr v29)) (let (v32 felt) (load v31)) - (let (v33 u32) (cast v3)) + (let (v33 u32) (bitcast v3)) (let (v34 u32) (add.checked v33 8)) - (let (v35 u32) (mod.unchecked v34 2)) - (assertz v35) + (let (v35 u32) (mod.unchecked v34 4)) + (assertz 250 v35) (let (v36 (ptr felt)) (inttoptr v34)) (let (v37 felt) (load v36)) - (let (v38 u32) (cast v3)) + (let (v38 u32) (bitcast v3)) (let (v39 u32) (add.checked v38 12)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) + (let (v40 u32) (mod.unchecked v39 4)) + (assertz 250 v40) (let (v41 (ptr felt)) (inttoptr v39)) (let (v42 felt) (load v41)) (let (v43 felt) (call (#miden::tx #create_note) v8 v13 v18 v23 v1 v2 v27 v32 v37 v42)) diff --git a/tests/integration/expected/rust_sdk_basic_wallet/rust_sdk_basic_wallet.wat b/tests/integration/expected/rust_sdk_basic_wallet/rust_sdk_basic_wallet.wat index e936efde..2fa63c39 100644 --- a/tests/integration/expected/rust_sdk_basic_wallet/rust_sdk_basic_wallet.wat +++ b/tests/integration/expected/rust_sdk_basic_wallet/rust_sdk_basic_wallet.wat @@ -5,9 +5,9 @@ (type (;3;) (func (param i32 f32 f32 i32))) (type (;4;) (func (param i32 i32))) (type (;5;) (func (param i32 f32 f32 i32) (result f32))) - (import "miden::account" "add_asset<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_account_add_asset (;0;) (type 0))) - (import "miden::account" "remove_asset<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_account_remove_asset (;1;) (type 0))) - (import "miden::tx" "create_note<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_tx_kernel_sys::externs::extern_tx_create_note (;2;) (type 1))) + (import "miden::account" "add_asset<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_account_add_asset (;0;) (type 0))) + (import "miden::account" "remove_asset<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_account_remove_asset (;1;) (type 0))) + (import "miden::tx" "create_note<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_tx_create_note (;2;) (type 1))) (func $receive_asset (;3;) (type 2) (param i32) (local i32) global.get $__stack_pointer @@ -17,7 +17,7 @@ global.set $__stack_pointer local.get 1 local.get 0 - call $miden_tx_kernel_sys::add_asset + call $miden_base_sys::bindings::tx::add_asset local.get 1 i32.const 16 i32.add @@ -32,25 +32,19 @@ global.set $__stack_pointer local.get 4 local.get 0 - call $miden_tx_kernel_sys::remove_asset + call $miden_base_sys::bindings::tx::remove_asset local.get 4 local.get 1 local.get 2 local.get 3 - call $miden_tx_kernel_sys::create_note + call $miden_base_sys::bindings::tx::create_note drop local.get 4 i32.const 16 i32.add global.set $__stack_pointer ) - (func $miden_tx_kernel_sys::add_asset (;5;) (type 4) (param i32 i32) - (local i32) - global.get $__stack_pointer - i32.const 16 - i32.sub - local.tee 2 - global.set $__stack_pointer + (func $miden_base_sys::bindings::tx::add_asset (;5;) (type 4) (param i32 i32) local.get 1 f32.load local.get 1 @@ -59,32 +53,10 @@ f32.load offset=8 local.get 1 f32.load offset=12 - local.get 2 - call $miden_tx_kernel_sys::externs::extern_account_add_asset local.get 0 - i32.const 8 - i32.add - local.get 2 - i32.const 8 - i32.add - i64.load align=4 - i64.store align=4 - local.get 0 - local.get 2 - i64.load align=4 - i64.store align=4 - local.get 2 - i32.const 16 - i32.add - global.set $__stack_pointer + call $miden_base_sys::bindings::tx::externs::extern_account_add_asset ) - (func $miden_tx_kernel_sys::remove_asset (;6;) (type 4) (param i32 i32) - (local i32) - global.get $__stack_pointer - i32.const 16 - i32.sub - local.tee 2 - global.set $__stack_pointer + (func $miden_base_sys::bindings::tx::remove_asset (;6;) (type 4) (param i32 i32) local.get 1 f32.load local.get 1 @@ -93,26 +65,10 @@ f32.load offset=8 local.get 1 f32.load offset=12 - local.get 2 - call $miden_tx_kernel_sys::externs::extern_account_remove_asset local.get 0 - i32.const 8 - i32.add - local.get 2 - i32.const 8 - i32.add - i64.load align=4 - i64.store align=4 - local.get 0 - local.get 2 - i64.load align=4 - i64.store align=4 - local.get 2 - i32.const 16 - i32.add - global.set $__stack_pointer + call $miden_base_sys::bindings::tx::externs::extern_account_remove_asset ) - (func $miden_tx_kernel_sys::create_note (;7;) (type 5) (param i32 f32 f32 i32) (result f32) + (func $miden_base_sys::bindings::tx::create_note (;7;) (type 5) (param i32 f32 f32 i32) (result f32) local.get 0 f32.load local.get 0 @@ -131,7 +87,7 @@ f32.load offset=8 local.get 3 f32.load offset=12 - call $miden_tx_kernel_sys::externs::extern_tx_create_note + call $miden_base_sys::bindings::tx::externs::extern_tx_create_note ) (table (;0;) 1 1 funcref) (memory (;0;) 16) diff --git a/tests/integration/expected/shl_i16.hir b/tests/integration/expected/shl_i16.hir index d5428b2e..fe8d73cb 100644 --- a/tests/integration/expected/shl_i16.hir +++ b/tests/integration/expected/shl_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_0321dd193a3848fd9694d83145f19dfd509077216649a5c8574ca9ef1fad1279 + (module #test_rust_947b1fd0c78559d180609e8a959684c5090a8ac458193ed6a1103a863d3c8bd0 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shl_i16.masm b/tests/integration/expected/shl_i16.masm index a979c58d..567a2ab8 100644 --- a/tests/integration/expected/shl_i16.masm +++ b/tests/integration/expected/shl_i16.masm @@ -1,4 +1,4 @@ -# mod test_rust_0321dd193a3848fd9694d83145f19dfd509077216649a5c8574ca9ef1fad1279 +# mod test_rust_947b1fd0c78559d180609e8a959684c5090a8ac458193ed6a1103a863d3c8bd0 export.entrypoint push.15 @@ -9,6 +9,3 @@ export.entrypoint end -begin - exec.::test_rust_0321dd193a3848fd9694d83145f19dfd509077216649a5c8574ca9ef1fad1279::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shl_i16.wat b/tests/integration/expected/shl_i16.wat index 80991a03..65f7ea5c 100644 --- a/tests/integration/expected/shl_i16.wat +++ b/tests/integration/expected/shl_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_0321dd193a3848fd9694d83145f19dfd509077216649a5c8574ca9ef1fad1279.wasm +(module $test_rust_947b1fd0c78559d180609e8a959684c5090a8ac458193ed6a1103a863d3c8bd0.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/shl_i32.hir b/tests/integration/expected/shl_i32.hir index 8eb34c0f..362242a7 100644 --- a/tests/integration/expected/shl_i32.hir +++ b/tests/integration/expected/shl_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_77347ac38c4f68c555c0f6c6fd4af8c580cac21fd98baf7c8bd8e0249991b718 + (module #test_rust_b1a7a85321f9f6b080f6e9a0676c7398d86d5c2a5214aa2a59f442c8152d33f8 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shl_i32.masm b/tests/integration/expected/shl_i32.masm index 3c041645..9219851b 100644 --- a/tests/integration/expected/shl_i32.masm +++ b/tests/integration/expected/shl_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_77347ac38c4f68c555c0f6c6fd4af8c580cac21fd98baf7c8bd8e0249991b718 +# mod test_rust_b1a7a85321f9f6b080f6e9a0676c7398d86d5c2a5214aa2a59f442c8152d33f8 export.entrypoint swap.1 u32shl end -begin - exec.::test_rust_77347ac38c4f68c555c0f6c6fd4af8c580cac21fd98baf7c8bd8e0249991b718::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shl_i32.wat b/tests/integration/expected/shl_i32.wat index a2228e3d..ffa6e89a 100644 --- a/tests/integration/expected/shl_i32.wat +++ b/tests/integration/expected/shl_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_77347ac38c4f68c555c0f6c6fd4af8c580cac21fd98baf7c8bd8e0249991b718.wasm +(module $test_rust_b1a7a85321f9f6b080f6e9a0676c7398d86d5c2a5214aa2a59f442c8152d33f8.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/shl_i64.hir b/tests/integration/expected/shl_i64.hir index 6a4639d7..a52be75f 100644 --- a/tests/integration/expected/shl_i64.hir +++ b/tests/integration/expected/shl_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_5daeb206dcf172633a3952fa7cdfecf35c6015e5d0a99a46308f39387d96320e + (module #test_rust_25e2507052972928b154ff844858eb75529a3497622ee9ca52b471d8a099e59f ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shl_i64.masm b/tests/integration/expected/shl_i64.masm index b9562976..6ce2a7c5 100644 --- a/tests/integration/expected/shl_i64.masm +++ b/tests/integration/expected/shl_i64.masm @@ -1,4 +1,4 @@ -# mod test_rust_5daeb206dcf172633a3952fa7cdfecf35c6015e5d0a99a46308f39387d96320e +# mod test_rust_25e2507052972928b154ff844858eb75529a3497622ee9ca52b471d8a099e59f export.entrypoint movdn.3 @@ -17,6 +17,3 @@ export.entrypoint end -begin - exec.::test_rust_5daeb206dcf172633a3952fa7cdfecf35c6015e5d0a99a46308f39387d96320e::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shl_i64.wat b/tests/integration/expected/shl_i64.wat index 50194a3e..cb9076a1 100644 --- a/tests/integration/expected/shl_i64.wat +++ b/tests/integration/expected/shl_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_5daeb206dcf172633a3952fa7cdfecf35c6015e5d0a99a46308f39387d96320e.wasm +(module $test_rust_25e2507052972928b154ff844858eb75529a3497622ee9ca52b471d8a099e59f.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 0 diff --git a/tests/integration/expected/shl_i8.hir b/tests/integration/expected/shl_i8.hir index 19282d73..577fdc6a 100644 --- a/tests/integration/expected/shl_i8.hir +++ b/tests/integration/expected/shl_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_5c39989232aaeaed99257c5c5dd56de3164cb62fe893b1c4752946d9a8035626 + (module #test_rust_5f1b43480ab6707fd5d599fff30d72a40baf9972173edc344c239f0c3b48da64 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shl_i8.masm b/tests/integration/expected/shl_i8.masm index 9e21fa23..c461e25d 100644 --- a/tests/integration/expected/shl_i8.masm +++ b/tests/integration/expected/shl_i8.masm @@ -1,4 +1,4 @@ -# mod test_rust_5c39989232aaeaed99257c5c5dd56de3164cb62fe893b1c4752946d9a8035626 +# mod test_rust_5f1b43480ab6707fd5d599fff30d72a40baf9972173edc344c239f0c3b48da64 export.entrypoint push.7 @@ -9,6 +9,3 @@ export.entrypoint end -begin - exec.::test_rust_5c39989232aaeaed99257c5c5dd56de3164cb62fe893b1c4752946d9a8035626::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shl_i8.wat b/tests/integration/expected/shl_i8.wat index 2f213c25..5632f948 100644 --- a/tests/integration/expected/shl_i8.wat +++ b/tests/integration/expected/shl_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_5c39989232aaeaed99257c5c5dd56de3164cb62fe893b1c4752946d9a8035626.wasm +(module $test_rust_5f1b43480ab6707fd5d599fff30d72a40baf9972173edc344c239f0c3b48da64.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/shl_u16.hir b/tests/integration/expected/shl_u16.hir index e77cda52..7ee28126 100644 --- a/tests/integration/expected/shl_u16.hir +++ b/tests/integration/expected/shl_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_12e1569e41153e52fb7cb3781dcfca47ee0548f6160a9e8e38b7734ffd45cb7e + (module #test_rust_0ab094171adf5f867d5a41b825b648320b4a7b9662828d177cacb8db3f7de5ef ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shl_u16.masm b/tests/integration/expected/shl_u16.masm index 509d5ccd..c9d986e2 100644 --- a/tests/integration/expected/shl_u16.masm +++ b/tests/integration/expected/shl_u16.masm @@ -1,4 +1,4 @@ -# mod test_rust_12e1569e41153e52fb7cb3781dcfca47ee0548f6160a9e8e38b7734ffd45cb7e +# mod test_rust_0ab094171adf5f867d5a41b825b648320b4a7b9662828d177cacb8db3f7de5ef export.entrypoint push.15 @@ -11,6 +11,3 @@ export.entrypoint end -begin - exec.::test_rust_12e1569e41153e52fb7cb3781dcfca47ee0548f6160a9e8e38b7734ffd45cb7e::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shl_u16.wat b/tests/integration/expected/shl_u16.wat index f0de324e..2eee5243 100644 --- a/tests/integration/expected/shl_u16.wat +++ b/tests/integration/expected/shl_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_12e1569e41153e52fb7cb3781dcfca47ee0548f6160a9e8e38b7734ffd45cb7e.wasm +(module $test_rust_0ab094171adf5f867d5a41b825b648320b4a7b9662828d177cacb8db3f7de5ef.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/shl_u32.hir b/tests/integration/expected/shl_u32.hir index b9e6daef..8dacc68d 100644 --- a/tests/integration/expected/shl_u32.hir +++ b/tests/integration/expected/shl_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c3626bb8d040702290734d36fd1995f9bd099bbd60fea362c6a50e3386dab95b + (module #test_rust_7e6c842b77a3cb1324eb4149ea3db75e8175bb301dd8d842a28fa5eb165bc64c ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shl_u32.masm b/tests/integration/expected/shl_u32.masm index 3a71024c..ca5370bf 100644 --- a/tests/integration/expected/shl_u32.masm +++ b/tests/integration/expected/shl_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_c3626bb8d040702290734d36fd1995f9bd099bbd60fea362c6a50e3386dab95b +# mod test_rust_7e6c842b77a3cb1324eb4149ea3db75e8175bb301dd8d842a28fa5eb165bc64c export.entrypoint swap.1 u32shl end -begin - exec.::test_rust_c3626bb8d040702290734d36fd1995f9bd099bbd60fea362c6a50e3386dab95b::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shl_u32.wat b/tests/integration/expected/shl_u32.wat index 74358d45..3e60a40c 100644 --- a/tests/integration/expected/shl_u32.wat +++ b/tests/integration/expected/shl_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_c3626bb8d040702290734d36fd1995f9bd099bbd60fea362c6a50e3386dab95b.wasm +(module $test_rust_7e6c842b77a3cb1324eb4149ea3db75e8175bb301dd8d842a28fa5eb165bc64c.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/shl_u64.hir b/tests/integration/expected/shl_u64.hir index 7a1de7f6..9fcd32ba 100644 --- a/tests/integration/expected/shl_u64.hir +++ b/tests/integration/expected/shl_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_21d1812ea2f884845a2cfbe3e06081f8da3b99f4431337b3e405dda690a969f6 + (module #test_rust_2a329af439c3fda4a420516309900eb5dee52a3d62676c5dfee856e4056b3fa5 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shl_u64.masm b/tests/integration/expected/shl_u64.masm index 72739468..329c9bb4 100644 --- a/tests/integration/expected/shl_u64.masm +++ b/tests/integration/expected/shl_u64.masm @@ -1,4 +1,4 @@ -# mod test_rust_21d1812ea2f884845a2cfbe3e06081f8da3b99f4431337b3e405dda690a969f6 +# mod test_rust_2a329af439c3fda4a420516309900eb5dee52a3d62676c5dfee856e4056b3fa5 export.entrypoint movdn.3 @@ -17,6 +17,3 @@ export.entrypoint end -begin - exec.::test_rust_21d1812ea2f884845a2cfbe3e06081f8da3b99f4431337b3e405dda690a969f6::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shl_u64.wat b/tests/integration/expected/shl_u64.wat index 0864d871..c91d4044 100644 --- a/tests/integration/expected/shl_u64.wat +++ b/tests/integration/expected/shl_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_21d1812ea2f884845a2cfbe3e06081f8da3b99f4431337b3e405dda690a969f6.wasm +(module $test_rust_2a329af439c3fda4a420516309900eb5dee52a3d62676c5dfee856e4056b3fa5.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 0 diff --git a/tests/integration/expected/shl_u8.hir b/tests/integration/expected/shl_u8.hir index b2984e40..6c204c7f 100644 --- a/tests/integration/expected/shl_u8.hir +++ b/tests/integration/expected/shl_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_11ed47f38055f9bb6c854e44680e18c81be5e7220524472414d55982c663892d + (module #test_rust_c41b1b7ac309f4bb3497653978e4c903a0185e0b268c2fca135833d9389bacc9 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shl_u8.masm b/tests/integration/expected/shl_u8.masm index 7c56a795..d8614105 100644 --- a/tests/integration/expected/shl_u8.masm +++ b/tests/integration/expected/shl_u8.masm @@ -1,4 +1,4 @@ -# mod test_rust_11ed47f38055f9bb6c854e44680e18c81be5e7220524472414d55982c663892d +# mod test_rust_c41b1b7ac309f4bb3497653978e4c903a0185e0b268c2fca135833d9389bacc9 export.entrypoint push.7 @@ -11,6 +11,3 @@ export.entrypoint end -begin - exec.::test_rust_11ed47f38055f9bb6c854e44680e18c81be5e7220524472414d55982c663892d::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shl_u8.wat b/tests/integration/expected/shl_u8.wat index 6c862d57..43c46886 100644 --- a/tests/integration/expected/shl_u8.wat +++ b/tests/integration/expected/shl_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_11ed47f38055f9bb6c854e44680e18c81be5e7220524472414d55982c663892d.wasm +(module $test_rust_c41b1b7ac309f4bb3497653978e4c903a0185e0b268c2fca135833d9389bacc9.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/shr_i64.hir b/tests/integration/expected/shr_i64.hir index 91da4feb..5c854f3d 100644 --- a/tests/integration/expected/shr_i64.hir +++ b/tests/integration/expected/shr_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_087594a87838a1cc38b5a90fd9df794436bb2f9a756e5f08d05946a400c9e019 + (module #test_rust_9e782fbd0f39c9f1f4f8c1623ec32ad4d1666e9dfad0fc58c43a8ade8dfcb60c ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shr_i64.masm b/tests/integration/expected/shr_i64.masm index 2911dbf0..8ff8b76a 100644 --- a/tests/integration/expected/shr_i64.masm +++ b/tests/integration/expected/shr_i64.masm @@ -1,4 +1,4 @@ -# mod test_rust_087594a87838a1cc38b5a90fd9df794436bb2f9a756e5f08d05946a400c9e019 +# mod test_rust_9e782fbd0f39c9f1f4f8c1623ec32ad4d1666e9dfad0fc58c43a8ade8dfcb60c export.entrypoint movdn.3 @@ -17,6 +17,3 @@ export.entrypoint end -begin - exec.::test_rust_087594a87838a1cc38b5a90fd9df794436bb2f9a756e5f08d05946a400c9e019::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shr_i64.wat b/tests/integration/expected/shr_i64.wat index 47fd7f43..1727fc11 100644 --- a/tests/integration/expected/shr_i64.wat +++ b/tests/integration/expected/shr_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_087594a87838a1cc38b5a90fd9df794436bb2f9a756e5f08d05946a400c9e019.wasm +(module $test_rust_9e782fbd0f39c9f1f4f8c1623ec32ad4d1666e9dfad0fc58c43a8ade8dfcb60c.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 0 diff --git a/tests/integration/expected/shr_u16.hir b/tests/integration/expected/shr_u16.hir index ecd64ff8..6b537084 100644 --- a/tests/integration/expected/shr_u16.hir +++ b/tests/integration/expected/shr_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_0b3b019a1f9ca0666eeeeff0b69793030831994482d8a03491ea3289d29dd83b + (module #test_rust_044d9f6f5bf1c98609cfe5f9496ee9e517cb2900d43714636541400c34d5fb03 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shr_u16.masm b/tests/integration/expected/shr_u16.masm index 90367f0b..25e00a36 100644 --- a/tests/integration/expected/shr_u16.masm +++ b/tests/integration/expected/shr_u16.masm @@ -1,4 +1,4 @@ -# mod test_rust_0b3b019a1f9ca0666eeeeff0b69793030831994482d8a03491ea3289d29dd83b +# mod test_rust_044d9f6f5bf1c98609cfe5f9496ee9e517cb2900d43714636541400c34d5fb03 export.entrypoint push.15 @@ -9,6 +9,3 @@ export.entrypoint end -begin - exec.::test_rust_0b3b019a1f9ca0666eeeeff0b69793030831994482d8a03491ea3289d29dd83b::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shr_u16.wat b/tests/integration/expected/shr_u16.wat index 058375c0..baef8b15 100644 --- a/tests/integration/expected/shr_u16.wat +++ b/tests/integration/expected/shr_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_0b3b019a1f9ca0666eeeeff0b69793030831994482d8a03491ea3289d29dd83b.wasm +(module $test_rust_044d9f6f5bf1c98609cfe5f9496ee9e517cb2900d43714636541400c34d5fb03.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/shr_u32.hir b/tests/integration/expected/shr_u32.hir index afae847a..9a777df7 100644 --- a/tests/integration/expected/shr_u32.hir +++ b/tests/integration/expected/shr_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_29e2b0618aa3bc24d39d545f8e7f4ef75a53efc331745cc813a80714b87c4f85 + (module #test_rust_8ce82de7c4fb77fe54a97d76d270876e6dc8484997171b1a52821c97bc67dbba ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shr_u32.masm b/tests/integration/expected/shr_u32.masm index d17f1de7..1eec3a1f 100644 --- a/tests/integration/expected/shr_u32.masm +++ b/tests/integration/expected/shr_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_29e2b0618aa3bc24d39d545f8e7f4ef75a53efc331745cc813a80714b87c4f85 +# mod test_rust_8ce82de7c4fb77fe54a97d76d270876e6dc8484997171b1a52821c97bc67dbba export.entrypoint swap.1 u32shr end -begin - exec.::test_rust_29e2b0618aa3bc24d39d545f8e7f4ef75a53efc331745cc813a80714b87c4f85::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shr_u32.wat b/tests/integration/expected/shr_u32.wat index 16cd04ec..226f94e0 100644 --- a/tests/integration/expected/shr_u32.wat +++ b/tests/integration/expected/shr_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_29e2b0618aa3bc24d39d545f8e7f4ef75a53efc331745cc813a80714b87c4f85.wasm +(module $test_rust_8ce82de7c4fb77fe54a97d76d270876e6dc8484997171b1a52821c97bc67dbba.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/shr_u64.hir b/tests/integration/expected/shr_u64.hir index c2545d67..3f35e6cb 100644 --- a/tests/integration/expected/shr_u64.hir +++ b/tests/integration/expected/shr_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_340914f962f8e04df64caa8f22202f6738c696c9f8ddd7bcb057642c319d2de0 + (module #test_rust_06af793a34a89f72818a0d65a5b5ac2526e0731e32c76ae951f9d05d12b6d4e4 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shr_u64.masm b/tests/integration/expected/shr_u64.masm index 5e8cdda8..9995090c 100644 --- a/tests/integration/expected/shr_u64.masm +++ b/tests/integration/expected/shr_u64.masm @@ -1,4 +1,4 @@ -# mod test_rust_340914f962f8e04df64caa8f22202f6738c696c9f8ddd7bcb057642c319d2de0 +# mod test_rust_06af793a34a89f72818a0d65a5b5ac2526e0731e32c76ae951f9d05d12b6d4e4 export.entrypoint movdn.3 @@ -17,6 +17,3 @@ export.entrypoint end -begin - exec.::test_rust_340914f962f8e04df64caa8f22202f6738c696c9f8ddd7bcb057642c319d2de0::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shr_u64.wat b/tests/integration/expected/shr_u64.wat index 8b9ef969..9bbfb32e 100644 --- a/tests/integration/expected/shr_u64.wat +++ b/tests/integration/expected/shr_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_340914f962f8e04df64caa8f22202f6738c696c9f8ddd7bcb057642c319d2de0.wasm +(module $test_rust_06af793a34a89f72818a0d65a5b5ac2526e0731e32c76ae951f9d05d12b6d4e4.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 0 diff --git a/tests/integration/expected/shr_u8.hir b/tests/integration/expected/shr_u8.hir index 1a27c1f8..af08be0a 100644 --- a/tests/integration/expected/shr_u8.hir +++ b/tests/integration/expected/shr_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_0c960295b036bf3739ebef1e3e9ee68b7d941715927c576e8625d987a31dbbfe + (module #test_rust_5e6fba59478d938d56559a1d9ca7b9fe13244e2b0714fdfc42042b83af78612f ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/shr_u8.masm b/tests/integration/expected/shr_u8.masm index 35e24db3..e0c17239 100644 --- a/tests/integration/expected/shr_u8.masm +++ b/tests/integration/expected/shr_u8.masm @@ -1,4 +1,4 @@ -# mod test_rust_0c960295b036bf3739ebef1e3e9ee68b7d941715927c576e8625d987a31dbbfe +# mod test_rust_5e6fba59478d938d56559a1d9ca7b9fe13244e2b0714fdfc42042b83af78612f export.entrypoint push.7 @@ -9,6 +9,3 @@ export.entrypoint end -begin - exec.::test_rust_0c960295b036bf3739ebef1e3e9ee68b7d941715927c576e8625d987a31dbbfe::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/shr_u8.wat b/tests/integration/expected/shr_u8.wat index 35265009..84a0704b 100644 --- a/tests/integration/expected/shr_u8.wat +++ b/tests/integration/expected/shr_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_0c960295b036bf3739ebef1e3e9ee68b7d941715927c576e8625d987a31dbbfe.wasm +(module $test_rust_5e6fba59478d938d56559a1d9ca7b9fe13244e2b0714fdfc42042b83af78612f.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/sub_felt.masm b/tests/integration/expected/sub_felt.masm index f21267dd..6ea35947 100644 --- a/tests/integration/expected/sub_felt.masm +++ b/tests/integration/expected/sub_felt.masm @@ -5,6 +5,3 @@ export.entrypoint end -begin - exec.::sub_felt::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_i16.hir b/tests/integration/expected/sub_i16.hir index 51ee3f62..928a7069 100644 --- a/tests/integration/expected/sub_i16.hir +++ b/tests/integration/expected/sub_i16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_0bd9d85b7ff8d3866d324cd6d4ca05c25e67a2304dcd772858e426a99ba6ac7a + (module #test_rust_6fb192cd8f45d09bfbce4dc3824f4ab50385e70882ac508535654ca25af2ff66 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/sub_i16.masm b/tests/integration/expected/sub_i16.masm index eb40ef0c..a477c6a8 100644 --- a/tests/integration/expected/sub_i16.masm +++ b/tests/integration/expected/sub_i16.masm @@ -1,10 +1,7 @@ -# mod test_rust_0bd9d85b7ff8d3866d324cd6d4ca05c25e67a2304dcd772858e426a99ba6ac7a +# mod test_rust_6fb192cd8f45d09bfbce4dc3824f4ab50385e70882ac508535654ca25af2ff66 export.entrypoint swap.1 u32wrapping_sub end -begin - exec.::test_rust_0bd9d85b7ff8d3866d324cd6d4ca05c25e67a2304dcd772858e426a99ba6ac7a::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_i16.wat b/tests/integration/expected/sub_i16.wat index cbfb9ec5..b544978a 100644 --- a/tests/integration/expected/sub_i16.wat +++ b/tests/integration/expected/sub_i16.wat @@ -1,4 +1,4 @@ -(module $test_rust_0bd9d85b7ff8d3866d324cd6d4ca05c25e67a2304dcd772858e426a99ba6ac7a.wasm +(module $test_rust_6fb192cd8f45d09bfbce4dc3824f4ab50385e70882ac508535654ca25af2ff66.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/sub_i32.hir b/tests/integration/expected/sub_i32.hir index fa26294c..839cc8d4 100644 --- a/tests/integration/expected/sub_i32.hir +++ b/tests/integration/expected/sub_i32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_6c95bc4ac3c970051b695c8b0d81ce4e464588966d9047a4db06a19a2885319c + (module #test_rust_698d995f2c0b88d2812071d204a744bc080ce741c0da79a5c54d851946837d51 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/sub_i32.masm b/tests/integration/expected/sub_i32.masm index 756d5865..03d8c48d 100644 --- a/tests/integration/expected/sub_i32.masm +++ b/tests/integration/expected/sub_i32.masm @@ -1,10 +1,7 @@ -# mod test_rust_6c95bc4ac3c970051b695c8b0d81ce4e464588966d9047a4db06a19a2885319c +# mod test_rust_698d995f2c0b88d2812071d204a744bc080ce741c0da79a5c54d851946837d51 export.entrypoint swap.1 u32wrapping_sub end -begin - exec.::test_rust_6c95bc4ac3c970051b695c8b0d81ce4e464588966d9047a4db06a19a2885319c::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_i32.wat b/tests/integration/expected/sub_i32.wat index de0c4440..b49aef1d 100644 --- a/tests/integration/expected/sub_i32.wat +++ b/tests/integration/expected/sub_i32.wat @@ -1,4 +1,4 @@ -(module $test_rust_6c95bc4ac3c970051b695c8b0d81ce4e464588966d9047a4db06a19a2885319c.wasm +(module $test_rust_698d995f2c0b88d2812071d204a744bc080ce741c0da79a5c54d851946837d51.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/sub_i64.hir b/tests/integration/expected/sub_i64.hir index 23be5e36..8357f11c 100644 --- a/tests/integration/expected/sub_i64.hir +++ b/tests/integration/expected/sub_i64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_0f85748dfab4d3d35b9d3f85e947a3028671242e03ef7bc6e26194fbbf566570 + (module #test_rust_52c69166bf1f3ac3df7337dc12e7ba379d9ff44d7d8a8eb36c6c73182238ea88 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/sub_i64.masm b/tests/integration/expected/sub_i64.masm index a7f8df89..fd61d56c 100644 --- a/tests/integration/expected/sub_i64.masm +++ b/tests/integration/expected/sub_i64.masm @@ -1,10 +1,7 @@ -# mod test_rust_0f85748dfab4d3d35b9d3f85e947a3028671242e03ef7bc6e26194fbbf566570 +# mod test_rust_52c69166bf1f3ac3df7337dc12e7ba379d9ff44d7d8a8eb36c6c73182238ea88 export.entrypoint movdn.3 movdn.3 exec.::std::math::u64::wrapping_sub end -begin - exec.::test_rust_0f85748dfab4d3d35b9d3f85e947a3028671242e03ef7bc6e26194fbbf566570::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_i64.wat b/tests/integration/expected/sub_i64.wat index 08f01294..f1d27dbd 100644 --- a/tests/integration/expected/sub_i64.wat +++ b/tests/integration/expected/sub_i64.wat @@ -1,4 +1,4 @@ -(module $test_rust_0f85748dfab4d3d35b9d3f85e947a3028671242e03ef7bc6e26194fbbf566570.wasm +(module $test_rust_52c69166bf1f3ac3df7337dc12e7ba379d9ff44d7d8a8eb36c6c73182238ea88.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 0 diff --git a/tests/integration/expected/sub_i8.hir b/tests/integration/expected/sub_i8.hir index 726e4728..6c48a97a 100644 --- a/tests/integration/expected/sub_i8.hir +++ b/tests/integration/expected/sub_i8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_47672a27266673dae49801c73b4791b5dd218b4cbca4677e7e9390d3988f3484 + (module #test_rust_ad1749dbdf86cbb2d7af210b3181b5a21a0a457d8a76cf3261cf21a9902c3de0 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/sub_i8.masm b/tests/integration/expected/sub_i8.masm index 9c5667ac..dcb12c60 100644 --- a/tests/integration/expected/sub_i8.masm +++ b/tests/integration/expected/sub_i8.masm @@ -1,10 +1,7 @@ -# mod test_rust_47672a27266673dae49801c73b4791b5dd218b4cbca4677e7e9390d3988f3484 +# mod test_rust_ad1749dbdf86cbb2d7af210b3181b5a21a0a457d8a76cf3261cf21a9902c3de0 export.entrypoint swap.1 u32wrapping_sub end -begin - exec.::test_rust_47672a27266673dae49801c73b4791b5dd218b4cbca4677e7e9390d3988f3484::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_i8.wat b/tests/integration/expected/sub_i8.wat index 6b202ca9..ea7fbf0f 100644 --- a/tests/integration/expected/sub_i8.wat +++ b/tests/integration/expected/sub_i8.wat @@ -1,4 +1,4 @@ -(module $test_rust_47672a27266673dae49801c73b4791b5dd218b4cbca4677e7e9390d3988f3484.wasm +(module $test_rust_ad1749dbdf86cbb2d7af210b3181b5a21a0a457d8a76cf3261cf21a9902c3de0.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/sub_u16.hir b/tests/integration/expected/sub_u16.hir index b3f7694d..bfebe4a7 100644 --- a/tests/integration/expected/sub_u16.hir +++ b/tests/integration/expected/sub_u16.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c0e8cc698fc282804a294a7ee5f65d91b6c6b89556c58494b84b1b928da26ac7 + (module #test_rust_f938d50f6700b001e6e4fa342fa235de0b28c5e79d3c4837b142860d9d8b8e6f ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/sub_u16.masm b/tests/integration/expected/sub_u16.masm index a05d1f27..c90196aa 100644 --- a/tests/integration/expected/sub_u16.masm +++ b/tests/integration/expected/sub_u16.masm @@ -1,10 +1,7 @@ -# mod test_rust_c0e8cc698fc282804a294a7ee5f65d91b6c6b89556c58494b84b1b928da26ac7 +# mod test_rust_f938d50f6700b001e6e4fa342fa235de0b28c5e79d3c4837b142860d9d8b8e6f export.entrypoint swap.1 u32wrapping_sub push.65535 u32and end -begin - exec.::test_rust_c0e8cc698fc282804a294a7ee5f65d91b6c6b89556c58494b84b1b928da26ac7::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_u16.wat b/tests/integration/expected/sub_u16.wat index 964f5b07..1090e301 100644 --- a/tests/integration/expected/sub_u16.wat +++ b/tests/integration/expected/sub_u16.wat @@ -1,4 +1,4 @@ -(module $test_rust_c0e8cc698fc282804a294a7ee5f65d91b6c6b89556c58494b84b1b928da26ac7.wasm +(module $test_rust_f938d50f6700b001e6e4fa342fa235de0b28c5e79d3c4837b142860d9d8b8e6f.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/sub_u32.hir b/tests/integration/expected/sub_u32.hir index 03e553c4..77f7c3f0 100644 --- a/tests/integration/expected/sub_u32.hir +++ b/tests/integration/expected/sub_u32.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_caa1ad606ef14599034dee42dfda3f3b0e116720e1d8e83f024cc9fd2113e4b0 + (module #test_rust_a27a86095ba52da4bcd985229e6b3275c1a4a8354c4b119cef358f6ec3ac98c4 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/sub_u32.masm b/tests/integration/expected/sub_u32.masm index 32905f04..a435830d 100644 --- a/tests/integration/expected/sub_u32.masm +++ b/tests/integration/expected/sub_u32.masm @@ -1,10 +1,7 @@ -# mod test_rust_caa1ad606ef14599034dee42dfda3f3b0e116720e1d8e83f024cc9fd2113e4b0 +# mod test_rust_a27a86095ba52da4bcd985229e6b3275c1a4a8354c4b119cef358f6ec3ac98c4 export.entrypoint swap.1 u32wrapping_sub end -begin - exec.::test_rust_caa1ad606ef14599034dee42dfda3f3b0e116720e1d8e83f024cc9fd2113e4b0::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_u32.wat b/tests/integration/expected/sub_u32.wat index c619c7fb..ee25bf19 100644 --- a/tests/integration/expected/sub_u32.wat +++ b/tests/integration/expected/sub_u32.wat @@ -1,4 +1,4 @@ -(module $test_rust_caa1ad606ef14599034dee42dfda3f3b0e116720e1d8e83f024cc9fd2113e4b0.wasm +(module $test_rust_a27a86095ba52da4bcd985229e6b3275c1a4a8354c4b119cef358f6ec3ac98c4.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/sub_u64.hir b/tests/integration/expected/sub_u64.hir index e8336d23..c3a35057 100644 --- a/tests/integration/expected/sub_u64.hir +++ b/tests/integration/expected/sub_u64.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_c41269e28d824a670ab81604f68197c58597e1d3d436ce5573ca0f7437aad0ba + (module #test_rust_5574a62019b06e2b235711c006fa92058c6184438940dab99ef3bc7024353803 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/sub_u64.masm b/tests/integration/expected/sub_u64.masm index c7cf5284..c7fddefe 100644 --- a/tests/integration/expected/sub_u64.masm +++ b/tests/integration/expected/sub_u64.masm @@ -1,10 +1,7 @@ -# mod test_rust_c41269e28d824a670ab81604f68197c58597e1d3d436ce5573ca0f7437aad0ba +# mod test_rust_5574a62019b06e2b235711c006fa92058c6184438940dab99ef3bc7024353803 export.entrypoint movdn.3 movdn.3 exec.::std::math::u64::wrapping_sub end -begin - exec.::test_rust_c41269e28d824a670ab81604f68197c58597e1d3d436ce5573ca0f7437aad0ba::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_u64.wat b/tests/integration/expected/sub_u64.wat index 85e7f39d..3e65c8d3 100644 --- a/tests/integration/expected/sub_u64.wat +++ b/tests/integration/expected/sub_u64.wat @@ -1,4 +1,4 @@ -(module $test_rust_c41269e28d824a670ab81604f68197c58597e1d3d436ce5573ca0f7437aad0ba.wasm +(module $test_rust_5574a62019b06e2b235711c006fa92058c6184438940dab99ef3bc7024353803.wasm (type (;0;) (func (param i64 i64) (result i64))) (func $entrypoint (;0;) (type 0) (param i64 i64) (result i64) local.get 0 diff --git a/tests/integration/expected/sub_u8.hir b/tests/integration/expected/sub_u8.hir index 92e32b08..45679df9 100644 --- a/tests/integration/expected/sub_u8.hir +++ b/tests/integration/expected/sub_u8.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_199edd7a9771d7f0d34a9bbc05730a9c8345e263f0285d6a3d4f49a010be4661 + (module #test_rust_35c4da632353887f7b18847780ef2124ea854f0ed6df12437e5a3eaa8f8aacc6 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/sub_u8.masm b/tests/integration/expected/sub_u8.masm index 6fdd31eb..cf22c681 100644 --- a/tests/integration/expected/sub_u8.masm +++ b/tests/integration/expected/sub_u8.masm @@ -1,10 +1,7 @@ -# mod test_rust_199edd7a9771d7f0d34a9bbc05730a9c8345e263f0285d6a3d4f49a010be4661 +# mod test_rust_35c4da632353887f7b18847780ef2124ea854f0ed6df12437e5a3eaa8f8aacc6 export.entrypoint swap.1 u32wrapping_sub push.255 u32and end -begin - exec.::test_rust_199edd7a9771d7f0d34a9bbc05730a9c8345e263f0285d6a3d4f49a010be4661::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/sub_u8.wat b/tests/integration/expected/sub_u8.wat index 5230bd64..270880f8 100644 --- a/tests/integration/expected/sub_u8.wat +++ b/tests/integration/expected/sub_u8.wat @@ -1,4 +1,4 @@ -(module $test_rust_199edd7a9771d7f0d34a9bbc05730a9c8345e263f0285d6a3d4f49a010be4661.wasm +(module $test_rust_35c4da632353887f7b18847780ef2124ea854f0ed6df12437e5a3eaa8f8aacc6.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet.hir b/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet.hir index 60487219..31f31e27 100644 --- a/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet.hir +++ b/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet.hir @@ -39,6 +39,9 @@ ) (module #basic_wallet + ;; Data Segments + (data (mut) (offset 1048576) 0x01000000) + ;; Constants (const (id 0) 0x00100000) @@ -54,6 +57,50 @@ (ret)) ) + (func (export #__rust_alloc) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 1048580)) + (let (v4 i32) (call #::alloc v3 v1 v0)) + (br (block 1 v4))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #__rust_realloc) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i32) (const.i32 0)) + (let (v6 i32) (const.i32 1048580)) + (let (v7 i32) (call #::alloc v6 v2 v3)) + (let (v8 i1) (eq v7 0)) + (let (v9 i32) (zext v8)) + (let (v10 i1) (neq v9 0)) + (condbr v10 (block 2 v7) (block 3))) + + (block 1 (param v4 i32) + (ret v4)) + + (block 2 (param v22 i32) + (br (block 1 v22))) + + (block 3 + (let (v11 u32) (bitcast v1)) + (let (v12 u32) (bitcast v3)) + (let (v13 i1) (lt v11 v12)) + (let (v14 i32) (sext v13)) + (let (v15 i1) (neq v14 0)) + (let (v16 i32) (select v15 v1 v3)) + (let (v17 u32) (bitcast v7)) + (let (v18 (ptr u8)) (inttoptr v17)) + (let (v19 u32) (bitcast v0)) + (let (v20 (ptr u8)) (inttoptr v19)) + (memcpy v20 v18 v16) + (let (v21 i32) (const.i32 1048580)) + (call #::dealloc v21 v0 v2 v1) + (br (block 2 v7))) + ) + (func (export #miden:basic-wallet/basic-wallet@1.0.0#receive-asset) (param i64) (param i64) (param i64) (param i64) (block 0 (param v0 i64) (param v1 i64) (param v2 i64) (param v3 i64) @@ -63,7 +110,7 @@ (let (v7 i32) (sub.wrapping v5 v6)) (let (v8 (ptr i32)) (global.symbol #__stack_pointer)) (store v8 v7) - (call #wit_bindgen::rt::run_ctors_once) + (call #wit_bindgen_rt::run_ctors_once) (call (#wit-component:shim #indirect-miden:base/account@1.0.0-add-asset) v0 v1 v2 v3 v7) (let (v9 i32) (const.i32 32)) (let (v10 i32) (add.wrapping v7 v9)) @@ -93,572 +140,615 @@ (let (v12 i32) (sub.wrapping v10 v11)) (let (v13 (ptr i32)) (global.symbol #__stack_pointer)) (store v13 v12) - (call #wit_bindgen::rt::run_ctors_once) + (call #wit_bindgen_rt::run_ctors_once) (call (#wit-component:shim #indirect-miden:base/account@1.0.0-remove-asset) v0 v1 v2 v3 v12) - (let (v14 u32) (cast v12)) - (let (v15 u32) (mod.unchecked v14 3)) - (assertz v15) + (let (v14 u32) (bitcast v12)) + (let (v15 u32) (mod.unchecked v14 8)) + (assertz 250 v15) (let (v16 (ptr i64)) (inttoptr v14)) (let (v17 i64) (load v16)) - (let (v18 i32) (const.i32 8)) - (let (v19 i32) (add.wrapping v12 v18)) - (let (v20 u32) (cast v19)) - (let (v21 u32) (mod.unchecked v20 3)) - (assertz v21) - (let (v22 (ptr i64)) (inttoptr v20)) - (let (v23 i64) (load v22)) - (let (v24 i32) (const.i32 16)) - (let (v25 i32) (add.wrapping v12 v24)) - (let (v26 u32) (cast v25)) - (let (v27 u32) (mod.unchecked v26 3)) - (assertz v27) - (let (v28 (ptr i64)) (inttoptr v26)) - (let (v29 i64) (load v28)) - (let (v30 i32) (const.i32 24)) - (let (v31 i32) (add.wrapping v12 v30)) - (let (v32 u32) (cast v31)) - (let (v33 u32) (mod.unchecked v32 3)) - (assertz v33) - (let (v34 (ptr i64)) (inttoptr v32)) - (let (v35 i64) (load v34)) - (let (v36 i64) (call (#miden:base/tx@1.0.0 #create-note) v17 v23 v29 v35 v4 v5 v6 v7 v8)) - (let (v37 i32) (const.i32 32)) - (let (v38 i32) (add.wrapping v12 v37)) - (let (v39 (ptr i32)) (global.symbol #__stack_pointer)) - (store v39 v38) + (let (v18 u32) (bitcast v12)) + (let (v19 u32) (add.checked v18 8)) + (let (v20 u32) (mod.unchecked v19 8)) + (assertz 250 v20) + (let (v21 (ptr i64)) (inttoptr v19)) + (let (v22 i64) (load v21)) + (let (v23 u32) (bitcast v12)) + (let (v24 u32) (add.checked v23 16)) + (let (v25 u32) (mod.unchecked v24 8)) + (assertz 250 v25) + (let (v26 (ptr i64)) (inttoptr v24)) + (let (v27 i64) (load v26)) + (let (v28 u32) (bitcast v12)) + (let (v29 u32) (add.checked v28 24)) + (let (v30 u32) (mod.unchecked v29 8)) + (assertz 250 v30) + (let (v31 (ptr i64)) (inttoptr v29)) + (let (v32 i64) (load v31)) + (let (v33 i64) (call (#miden:base/tx@1.0.0 #create-note) v17 v22 v27 v32 v4 v5 v6 v7 v8)) + (let (v34 i32) (const.i32 32)) + (let (v35 i32) (add.wrapping v12 v34)) + (let (v36 (ptr i32)) (global.symbol #__stack_pointer)) + (store v36 v35) (br (block 1))) (block 1 (ret)) ) - (func (export #__rust_alloc) (param i32) (param i32) (result i32) - (block 0 (param v0 i32) (param v1 i32) - (let (v3 i32) (const.i32 1048576)) - (let (v4 i32) (call #::alloc v3 v1 v0)) - (br (block 1 v4))) + (func (export #cabi_realloc_wit_bindgen_0_28_0) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i1) (neq v1 0)) + (condbr v5 (block 5) (block 6))) - (block 1 (param v2 i32) - (ret v2)) + (block 1 (param v4 i32)) + + (block 2 + (unreachable)) + + (block 3 (param v21 i32) + (ret v21)) + + (block 4 (param v17 i32) + (let (v18 i1) (eq v17 0)) + (let (v19 i32) (zext v18)) + (let (v20 i1) (neq v19 0)) + (condbr v20 (block 2) (block 8))) + + (block 5 + (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) + (br (block 4 v16))) + + (block 6 + (let (v6 i1) (eq v3 0)) + (let (v7 i32) (zext v6)) + (let (v8 i1) (neq v7 0)) + (condbr v8 (block 3 v2) (block 7))) + + (block 7 + (let (v9 i32) (const.i32 0)) + (let (v10 u32) (bitcast v9)) + (let (v11 u32) (add.checked v10 1048584)) + (let (v12 (ptr u8)) (inttoptr v11)) + (let (v13 u8) (load v12)) + (let (v14 i32) (zext v13)) + (let (v15 i32) (call #__rust_alloc v3 v2)) + (br (block 4 v15))) + + (block 8 + (br (block 3 v17))) ) - (func (export #__rust_realloc) - (param i32) (param i32) (param i32) (param i32) (result i32) - (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) - (let (v5 i32) (const.i32 0)) - (let (v6 i32) (const.i32 1048576)) - (let (v7 i32) (call #::alloc v6 v2 v3)) - (let (v8 i1) (eq v7 0)) - (let (v9 i32) (zext v8)) - (let (v10 i1) (neq v9 0)) - (condbr v10 (block 2 v7) (block 3))) + (func (export #wit_bindgen_rt::run_ctors_once) + (block 0 + (let (v0 i32) (const.i32 0)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (add.checked v1 1048585)) + (let (v3 (ptr u8)) (inttoptr v2)) + (let (v4 u8) (load v3)) + (let (v5 i32) (zext v4)) + (let (v6 i1) (neq v5 0)) + (condbr v6 (block 2) (block 3))) - (block 1 (param v4 i32) - (ret v4)) + (block 1 + (ret)) - (block 2 (param v22 i32) - (br (block 1 v22))) + (block 2 + (br (block 1))) (block 3 - (let (v11 u32) (bitcast v1)) - (let (v12 u32) (bitcast v3)) - (let (v13 i1) (lt v11 v12)) - (let (v14 i32) (sext v13)) - (let (v15 i1) (neq v14 0)) - (let (v16 i32) (select v15 v1 v3)) - (let (v17 u32) (cast v7)) - (let (v18 (ptr u8)) (inttoptr v17)) - (let (v19 u32) (cast v0)) - (let (v20 (ptr u8)) (inttoptr v19)) - (memcpy v20 v18 v16) - (let (v21 i32) (const.i32 1048576)) - (call #::dealloc v21 v0 v2 v1) - (br (block 2 v7))) + (call #__wasm_call_ctors) + (let (v7 i32) (const.i32 0)) + (let (v8 i32) (const.i32 1)) + (let (v9 u32) (bitcast v8)) + (let (v10 u8) (trunc v9)) + (let (v11 u32) (bitcast v7)) + (let (v12 u32) (add.checked v11 1048585)) + (let (v13 (ptr u8)) (inttoptr v12)) + (store v13 v10) + (br (block 2))) ) (func (export #wee_alloc::alloc_first_fit) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (let (v4 i32) (const.i32 0)) - (let (v5 u32) (cast v2)) - (let (v6 u32) (mod.unchecked v5 2)) - (assertz v6) + (let (v5 u32) (bitcast v2)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) (let (v7 (ptr i32)) (inttoptr v5)) (let (v8 i32) (load v7)) - (let (v9 i1) (eq v8 0)) - (let (v10 i32) (zext v9)) - (let (v11 i1) (neq v10 0)) - (condbr v11 (block 2) (block 3))) + (let (v9 i1) (neq v8 0)) + (condbr v9 (block 2) (block 3))) (block 1 (param v3 i32) (ret v3)) (block 2 - (let (v330 i32) (const.i32 0)) - (br (block 1 v330))) + (let (v11 i32) (const.i32 -1)) + (let (v12 i32) (add.wrapping v1 v11)) + (let (v13 i32) (const.i32 0)) + (let (v14 i32) (sub.wrapping v13 v1)) + (let (v15 i32) (const.i32 2)) + (let (v16 u32) (bitcast v15)) + (let (v17 i32) (shl.wrapping v0 v16)) + (br (block 4 v8 v2 v17 v14 v12))) (block 3 - (let (v12 i32) (const.i32 -1)) - (let (v13 i32) (add.wrapping v1 v12)) - (let (v14 i32) (const.i32 0)) - (let (v15 i32) (sub.wrapping v14 v1)) - (let (v16 i32) (const.i32 2)) - (let (v17 u32) (bitcast v16)) - (let (v18 i32) (shl.wrapping v0 v17)) - (br (block 4 v8 v2 v18 v15 v13))) + (let (v10 i32) (const.i32 0)) + (ret v10)) (block 4 - (param v19 i32) - (param v160 i32) - (param v171 i32) - (param v185 i32) + (param v18 i32) + (param v169 i32) + (param v182 i32) (param v197 i32) - (let (v20 i32) (const.i32 8)) - (let (v21 i32) (add.wrapping v19 v20)) - (let (v22 u32) (cast v19)) - (let (v23 u32) (add.checked v22 8)) - (let (v24 u32) (mod.unchecked v23 2)) - (assertz v24) - (let (v25 (ptr i32)) (inttoptr v23)) - (let (v26 i32) (load v25)) - (let (v27 i32) (const.i32 1)) - (let (v28 i32) (band v26 v27)) - (let (v29 i1) (neq v28 0)) - (condbr v29 (block 7) (block 8))) + (param v210 i32) + (let (v19 u32) (bitcast v18)) + (let (v20 u32) (add.checked v19 8)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) + (let (v22 (ptr i32)) (inttoptr v20)) + (let (v23 i32) (load v22)) + (let (v24 i32) (const.i32 1)) + (let (v25 i32) (band v23 v24)) + (let (v26 i1) (neq v25 0)) + (condbr v26 (block 7) (block 8))) (block 5 - (br (block 2))) + (let (v344 i32) (const.i32 0)) + (br (block 1 v344))) (block 6 - (param v161 i32) - (param v168 i32) - (param v170 i32) - (param v184 i32) + (param v172 i32) + (param v179 i32) + (param v181 i32) (param v196 i32) - (param v204 i32) - (param v205 i32) - (let (v162 u32) (cast v161)) - (let (v163 u32) (mod.unchecked v162 2)) - (assertz v163) - (let (v164 (ptr i32)) (inttoptr v162)) - (let (v165 i32) (load v164)) - (let (v166 i32) (const.i32 -4)) - (let (v167 i32) (band v165 v166)) - (let (v169 i32) (sub.wrapping v167 v168)) - (let (v176 u32) (bitcast v169)) - (let (v177 u32) (bitcast v170)) - (let (v178 i1) (lt v176 v177)) - (let (v179 i32) (sext v178)) - (let (v180 i1) (neq v179 0)) - (condbr v180 (block 21 v204 v205 v170 v184 v196) (block 22))) + (param v209 i32) + (param v218 i32) + (param v219 i32) + (let (v173 u32) (bitcast v172)) + (let (v174 u32) (mod.unchecked v173 4)) + (assertz 250 v174) + (let (v175 (ptr i32)) (inttoptr v173)) + (let (v176 i32) (load v175)) + (let (v177 i32) (const.i32 -4)) + (let (v178 i32) (band v176 v177)) + (let (v180 i32) (sub.wrapping v178 v179)) + (let (v188 u32) (bitcast v180)) + (let (v189 u32) (bitcast v181)) + (let (v190 i1) (lt v188 v189)) + (let (v191 i32) (sext v190)) + (let (v192 i1) (neq v191 0)) + (condbr v192 (block 22 v218 v219 v181 v196 v209) (block 23))) (block 7 - (br (block 9 v21 v26 v19 v160 v171 v185 v197))) + (br (block 9 v18 v23 v169 v182 v197 v210))) (block 8 - (br (block 6 v19 v21 v171 v185 v197 v160 v26))) + (let (v27 i32) (const.i32 8)) + (let (v28 i32) (add.wrapping v18 v27)) + (br (block 6 v18 v28 v182 v197 v210 v169 v23))) (block 9 + (param v29 i32) (param v30 i32) - (param v31 i32) - (param v37 i32) - (param v144 i32) - (param v174 i32) - (param v188 i32) - (param v200 i32) - (let (v32 i32) (const.i32 -2)) - (let (v33 i32) (band v31 v32)) - (let (v34 u32) (cast v30)) - (let (v35 u32) (mod.unchecked v34 2)) - (assertz v35) + (param v156 i32) + (param v187 i32) + (param v202 i32) + (param v215 i32) + (let (v31 i32) (const.i32 -2)) + (let (v32 i32) (band v30 v31)) + (let (v33 u32) (bitcast v29)) + (let (v34 u32) (add.checked v33 8)) + (let (v35 u32) (mod.unchecked v34 4)) + (assertz 250 v35) (let (v36 (ptr i32)) (inttoptr v34)) - (store v36 v33) - (let (v38 u32) (cast v37)) - (let (v39 u32) (add.checked v38 4)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) - (let (v41 (ptr i32)) (inttoptr v39)) - (let (v42 i32) (load v41)) - (let (v43 i32) (const.i32 -4)) - (let (v44 i32) (band v42 v43)) - (let (v45 u32) (cast v44)) - (let (v46 u32) (mod.unchecked v45 2)) - (assertz v46) - (let (v47 (ptr i32)) (inttoptr v45)) - (let (v48 i32) (load v47)) - (let (v49 u32) (cast v37)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr i32)) (inttoptr v49)) - (let (v52 i32) (load v51)) - (let (v53 i32) (const.i32 -4)) - (let (v54 i32) (band v52 v53)) - (let (v55 i1) (neq v54 0)) - (condbr v55 (block 13) (block 14))) + (store v36 v32) + (let (v37 u32) (bitcast v29)) + (let (v38 u32) (add.checked v37 4)) + (let (v39 u32) (mod.unchecked v38 4)) + (assertz 250 v39) + (let (v40 (ptr i32)) (inttoptr v38)) + (let (v41 i32) (load v40)) + (let (v42 i32) (const.i32 -4)) + (let (v43 i32) (band v41 v42)) + (let (v44 i1) (neq v43 0)) + (condbr v44 (block 12) (block 13))) (block 10 - (br (block 6 v146 v151 v172 v186 v198 v142 v156))) + (let (v170 i32) (const.i32 8)) + (let (v171 i32) (add.wrapping v157 v170)) + (br (block 6 v157 v171 v183 v198 v211 v152 v165))) (block 11 - (param v112 i32) - (param v113 i32) - (param v120 i32) - (param v131 i32) - (param v143 i32) - (param v173 i32) - (param v187 i32) - (param v199 i32) - (let (v114 i32) (const.i32 3)) - (let (v115 i32) (band v113 v114)) - (let (v116 u32) (cast v112)) - (let (v117 u32) (add.checked v116 4)) - (let (v118 u32) (mod.unchecked v117 2)) - (assertz v118) - (let (v119 (ptr i32)) (inttoptr v117)) - (store v119 v115) - (let (v121 i32) (const.i32 3)) - (let (v122 i32) (band v120 v121)) - (let (v123 u32) (cast v112)) - (let (v124 u32) (mod.unchecked v123 2)) - (assertz v124) - (let (v125 (ptr i32)) (inttoptr v123)) - (store v125 v122) - (let (v126 i32) (const.i32 2)) - (let (v127 i32) (band v120 v126)) - (let (v128 i1) (eq v127 0)) - (let (v129 i32) (zext v128)) - (let (v130 i1) (neq v129 0)) - (condbr v130 (block 18 v143 v131 v173 v187 v199) (block 19))) + (param v55 i32) + (param v75 i32) + (param v122 i32) + (param v142 i32) + (param v155 i32) + (param v186 i32) + (param v201 i32) + (param v214 i32) + (let (v56 u32) (bitcast v55)) + (let (v57 u32) (mod.unchecked v56 4)) + (assertz 250 v57) + (let (v58 (ptr i32)) (inttoptr v56)) + (let (v59 i32) (load v58)) + (let (v60 i32) (const.i32 -4)) + (let (v61 i32) (band v59 v60)) + (let (v62 i1) (eq v61 0)) + (let (v63 i32) (zext v62)) + (let (v64 i1) (neq v63 0)) + (condbr v64 (block 14 v75 v59 v55 v122 v142 v155 v186 v201 v214) (block 15))) (block 12 - (param v93 i32) - (param v94 i32) - (param v97 i32) - (param v102 i32) - (param v132 i32) - (param v145 i32) - (param v175 i32) - (param v189 i32) - (param v201 i32) - (let (v95 i32) (const.i32 3)) - (let (v96 i32) (band v94 v95)) - (let (v98 i32) (bor v96 v97)) - (let (v99 u32) (cast v93)) - (let (v100 u32) (mod.unchecked v99 2)) - (assertz v100) - (let (v101 (ptr i32)) (inttoptr v99)) - (store v101 v98) - (let (v103 u32) (cast v102)) - (let (v104 u32) (add.checked v103 4)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) - (let (v106 (ptr i32)) (inttoptr v104)) - (let (v107 i32) (load v106)) - (let (v108 u32) (cast v102)) - (let (v109 u32) (mod.unchecked v108 2)) - (assertz v109) - (let (v110 (ptr i32)) (inttoptr v108)) - (let (v111 i32) (load v110)) - (br (block 11 v102 v107 v111 v132 v145 v175 v189 v201))) + (let (v46 i32) (const.i32 0)) + (let (v47 u32) (bitcast v43)) + (let (v48 (ptr u8)) (inttoptr v47)) + (let (v49 u8) (load v48)) + (let (v50 i32) (zext v49)) + (let (v51 i32) (const.i32 1)) + (let (v52 i32) (band v50 v51)) + (let (v53 i1) (neq v52 0)) + (let (v54 i32) (select v53 v46 v43)) + (br (block 11 v29 v43 v41 v54 v156 v187 v202 v215))) (block 13 - (let (v56 i32) (const.i32 2)) - (let (v57 i32) (band v52 v56)) - (let (v58 i1) (eq v57 0)) - (let (v59 i32) (zext v58)) - (let (v60 i1) (neq v59 0)) - (condbr v60 (block 15) (block 16))) + (let (v45 i32) (const.i32 0)) + (br (block 11 v29 v43 v41 v45 v156 v187 v202 v215))) (block 14 - (br (block 12 v44 v48 v54 v37 v44 v144 v174 v188 v200))) + (param v92 i32) + (param v102 i32) + (param v109 i32) + (param v121 i32) + (param v141 i32) + (param v154 i32) + (param v185 i32) + (param v200 i32) + (param v213 i32) + (let (v93 i1) (eq v92 0)) + (let (v94 i32) (zext v93)) + (let (v95 i1) (neq v94 0)) + (condbr v95 (block 17 v109 v121 v102 v141 v154 v185 v200 v213) (block 18))) (block 15 - (let (v61 u32) (cast v54)) - (let (v62 u32) (add.checked v61 4)) - (let (v63 u32) (mod.unchecked v62 2)) - (assertz v63) - (let (v64 (ptr i32)) (inttoptr v62)) - (let (v65 i32) (load v64)) - (let (v66 i32) (const.i32 3)) - (let (v67 i32) (band v65 v66)) - (let (v68 i32) (bor v67 v44)) - (let (v69 u32) (cast v54)) - (let (v70 u32) (add.checked v69 4)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) - (let (v72 (ptr i32)) (inttoptr v70)) - (store v72 v68) - (let (v73 u32) (cast v37)) - (let (v74 u32) (mod.unchecked v73 2)) - (assertz v74) - (let (v75 (ptr i32)) (inttoptr v73)) - (let (v76 i32) (load v75)) - (let (v77 u32) (cast v37)) - (let (v78 u32) (add.checked v77 4)) - (let (v79 u32) (mod.unchecked v78 2)) - (assertz v79) - (let (v80 (ptr i32)) (inttoptr v78)) - (let (v81 i32) (load v80)) - (let (v82 i32) (const.i32 -4)) - (let (v83 i32) (band v81 v82)) - (let (v84 i1) (eq v83 0)) - (let (v85 i32) (zext v84)) - (let (v86 i1) (neq v85 0)) - (condbr v86 (block 11 v37 v81 v76 v44 v144 v174 v188 v200) (block 17))) + (let (v65 i32) (const.i32 2)) + (let (v66 i32) (band v59 v65)) + (let (v67 i1) (neq v66 0)) + (condbr v67 (block 14 v75 v59 v55 v122 v142 v155 v186 v201 v214) (block 16))) (block 16 - (br (block 12 v44 v48 v54 v37 v44 v144 v174 v188 v200))) + (let (v68 u32) (bitcast v61)) + (let (v69 u32) (add.checked v68 4)) + (let (v70 u32) (mod.unchecked v69 4)) + (assertz 250 v70) + (let (v71 (ptr i32)) (inttoptr v69)) + (let (v72 i32) (load v71)) + (let (v73 i32) (const.i32 3)) + (let (v74 i32) (band v72 v73)) + (let (v76 i32) (bor v74 v75)) + (let (v77 u32) (bitcast v61)) + (let (v78 u32) (add.checked v77 4)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) + (let (v80 (ptr i32)) (inttoptr v78)) + (store v80 v76) + (let (v81 u32) (bitcast v55)) + (let (v82 u32) (add.checked v81 4)) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) + (let (v84 (ptr i32)) (inttoptr v82)) + (let (v85 i32) (load v84)) + (let (v86 i32) (const.i32 -4)) + (let (v87 i32) (band v85 v86)) + (let (v88 u32) (bitcast v55)) + (let (v89 u32) (mod.unchecked v88 4)) + (assertz 250 v89) + (let (v90 (ptr i32)) (inttoptr v88)) + (let (v91 i32) (load v90)) + (br (block 14 v87 v91 v55 v85 v142 v155 v186 v201 v214))) (block 17 - (let (v87 i32) (const.i32 -4)) - (let (v88 i32) (band v76 v87)) - (let (v89 u32) (cast v83)) - (let (v90 u32) (mod.unchecked v89 2)) - (assertz v90) - (let (v91 (ptr i32)) (inttoptr v89)) - (let (v92 i32) (load v91)) - (br (block 12 v83 v92 v88 v37 v44 v144 v174 v188 v200))) + (param v119 i32) + (param v120 i32) + (param v129 i32) + (param v140 i32) + (param v153 i32) + (param v184 i32) + (param v199 i32) + (param v212 i32) + (let (v123 i32) (const.i32 3)) + (let (v124 i32) (band v120 v123)) + (let (v125 u32) (bitcast v119)) + (let (v126 u32) (add.checked v125 4)) + (let (v127 u32) (mod.unchecked v126 4)) + (assertz 250 v127) + (let (v128 (ptr i32)) (inttoptr v126)) + (store v128 v124) + (let (v130 i32) (const.i32 3)) + (let (v131 i32) (band v129 v130)) + (let (v132 u32) (bitcast v119)) + (let (v133 u32) (mod.unchecked v132 4)) + (assertz 250 v133) + (let (v134 (ptr i32)) (inttoptr v132)) + (store v134 v131) + (let (v135 i32) (const.i32 2)) + (let (v136 i32) (band v129 v135)) + (let (v137 i1) (eq v136 0)) + (let (v138 i32) (zext v137)) + (let (v139 i1) (neq v138 0)) + (condbr v139 (block 19 v153 v140 v184 v199 v212) (block 20))) (block 18 - (param v142 i32) - (param v146 i32) - (param v172 i32) - (param v186 i32) - (param v198 i32) - (let (v147 u32) (cast v142)) - (let (v148 u32) (mod.unchecked v147 2)) - (assertz v148) - (let (v149 (ptr i32)) (inttoptr v147)) - (store v149 v146) - (let (v150 i32) (const.i32 8)) - (let (v151 i32) (add.wrapping v146 v150)) - (let (v152 u32) (cast v146)) - (let (v153 u32) (add.checked v152 8)) - (let (v154 u32) (mod.unchecked v153 2)) - (assertz v154) - (let (v155 (ptr i32)) (inttoptr v153)) - (let (v156 i32) (load v155)) - (let (v157 i32) (const.i32 1)) - (let (v158 i32) (band v156 v157)) - (let (v159 i1) (neq v158 0)) - (condbr v159 (block 9 v151 v156 v146 v142 v172 v186 v198) (block 20))) + (let (v96 u32) (bitcast v92)) + (let (v97 u32) (mod.unchecked v96 4)) + (assertz 250 v97) + (let (v98 (ptr i32)) (inttoptr v96)) + (let (v99 i32) (load v98)) + (let (v100 i32) (const.i32 3)) + (let (v101 i32) (band v99 v100)) + (let (v103 i32) (const.i32 -4)) + (let (v104 i32) (band v102 v103)) + (let (v105 i32) (bor v101 v104)) + (let (v106 u32) (bitcast v92)) + (let (v107 u32) (mod.unchecked v106 4)) + (assertz 250 v107) + (let (v108 (ptr i32)) (inttoptr v106)) + (store v108 v105) + (let (v110 u32) (bitcast v109)) + (let (v111 u32) (add.checked v110 4)) + (let (v112 u32) (mod.unchecked v111 4)) + (assertz 250 v112) + (let (v113 (ptr i32)) (inttoptr v111)) + (let (v114 i32) (load v113)) + (let (v115 u32) (bitcast v109)) + (let (v116 u32) (mod.unchecked v115 4)) + (assertz 250 v116) + (let (v117 (ptr i32)) (inttoptr v115)) + (let (v118 i32) (load v117)) + (br (block 17 v109 v114 v118 v141 v154 v185 v200 v213))) (block 19 - (let (v133 u32) (cast v131)) - (let (v134 u32) (mod.unchecked v133 2)) - (assertz v134) - (let (v135 (ptr i32)) (inttoptr v133)) - (let (v136 i32) (load v135)) - (let (v137 i32) (const.i32 2)) - (let (v138 i32) (bor v136 v137)) - (let (v139 u32) (cast v131)) - (let (v140 u32) (mod.unchecked v139 2)) - (assertz v140) - (let (v141 (ptr i32)) (inttoptr v139)) - (store v141 v138) - (br (block 18 v143 v131 v173 v187 v199))) + (param v152 i32) + (param v157 i32) + (param v183 i32) + (param v198 i32) + (param v211 i32) + (let (v158 u32) (bitcast v152)) + (let (v159 u32) (mod.unchecked v158 4)) + (assertz 250 v159) + (let (v160 (ptr i32)) (inttoptr v158)) + (store v160 v157) + (let (v161 u32) (bitcast v157)) + (let (v162 u32) (add.checked v161 8)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) + (let (v164 (ptr i32)) (inttoptr v162)) + (let (v165 i32) (load v164)) + (let (v166 i32) (const.i32 1)) + (let (v167 i32) (band v165 v166)) + (let (v168 i1) (neq v167 0)) + (condbr v168 (block 9 v157 v165 v152 v183 v198 v211) (block 21))) (block 20 - (br (block 10))) + (let (v143 u32) (bitcast v140)) + (let (v144 u32) (mod.unchecked v143 4)) + (assertz 250 v144) + (let (v145 (ptr i32)) (inttoptr v143)) + (let (v146 i32) (load v145)) + (let (v147 i32) (const.i32 2)) + (let (v148 i32) (bor v146 v147)) + (let (v149 u32) (bitcast v140)) + (let (v150 u32) (mod.unchecked v149 4)) + (assertz 250 v150) + (let (v151 (ptr i32)) (inttoptr v149)) + (store v151 v148) + (br (block 19 v153 v140 v184 v199 v212))) (block 21 - (param v321 i32) - (param v322 i32) - (param v327 i32) - (param v328 i32) - (param v329 i32) - (let (v323 u32) (cast v321)) - (let (v324 u32) (mod.unchecked v323 2)) - (assertz v324) - (let (v325 (ptr i32)) (inttoptr v323)) - (store v325 v322) - (let (v326 i1) (neq v322 0)) - (condbr v326 (block 4 v322 v321 v327 v328 v329) (block 32))) + (br (block 10))) (block 22 - (let (v181 i32) (const.i32 72)) - (let (v182 i32) (add.wrapping v168 v181)) - (let (v183 i32) (sub.wrapping v167 v170)) - (let (v190 i32) (band v183 v184)) - (let (v191 u32) (bitcast v182)) - (let (v192 u32) (bitcast v190)) - (let (v193 i1) (lte v191 v192)) - (let (v194 i32) (sext v193)) - (let (v195 i1) (neq v194 0)) - (condbr v195 (block 24) (block 25))) - - (block 23 (param v312 i32) (param v313 i32) - (let (v314 i32) (const.i32 1)) - (let (v315 i32) (bor v313 v314)) - (let (v316 u32) (cast v312)) - (let (v317 u32) (mod.unchecked v316 2)) - (assertz v317) - (let (v318 (ptr i32)) (inttoptr v316)) - (store v318 v315) - (let (v319 i32) (const.i32 8)) - (let (v320 i32) (add.wrapping v312 v319)) - (ret v320)) - - (block 24 - (let (v215 i32) (const.i32 0)) - (let (v216 i32) (const.i32 0)) - (let (v217 u32) (cast v190)) - (let (v218 u32) (mod.unchecked v217 2)) - (assertz v218) - (let (v219 (ptr i32)) (inttoptr v217)) - (store v219 v216) - (let (v220 i32) (const.i32 -8)) - (let (v221 i32) (add.wrapping v190 v220)) - (let (v222 i64) (const.i64 0)) - (let (v223 u32) (cast v221)) - (let (v224 u32) (mod.unchecked v223 2)) - (assertz v224) - (let (v225 (ptr i64)) (inttoptr v223)) - (store v225 v222) - (let (v226 u32) (cast v161)) - (let (v227 u32) (mod.unchecked v226 2)) - (assertz v227) - (let (v228 (ptr i32)) (inttoptr v226)) - (let (v229 i32) (load v228)) - (let (v230 i32) (const.i32 -4)) - (let (v231 i32) (band v229 v230)) - (let (v232 u32) (cast v221)) - (let (v233 u32) (mod.unchecked v232 2)) - (assertz v233) - (let (v234 (ptr i32)) (inttoptr v232)) - (store v234 v231) - (let (v235 u32) (cast v161)) - (let (v236 u32) (mod.unchecked v235 2)) - (assertz v236) - (let (v237 (ptr i32)) (inttoptr v235)) - (let (v238 i32) (load v237)) - (let (v239 i32) (const.i32 -4)) - (let (v240 i32) (band v238 v239)) - (let (v241 i1) (eq v240 0)) - (let (v242 i32) (zext v241)) - (let (v243 i1) (neq v242 0)) - (condbr v243 (block 27 v221 v215 v161 v168) (block 28))) + (param v335 i32) + (param v336 i32) + (param v341 i32) + (param v342 i32) + (param v343 i32) + (let (v337 u32) (bitcast v335)) + (let (v338 u32) (mod.unchecked v337 4)) + (assertz 250 v338) + (let (v339 (ptr i32)) (inttoptr v337)) + (store v339 v336) + (let (v340 i1) (neq v336 0)) + (condbr v340 (block 4 v336 v335 v341 v342 v343) (block 33))) + + (block 23 + (let (v193 i32) (const.i32 72)) + (let (v194 i32) (add.wrapping v179 v193)) + (let (v195 i32) (sub.wrapping v178 v181)) + (let (v203 i32) (band v195 v196)) + (let (v204 u32) (bitcast v194)) + (let (v205 u32) (bitcast v203)) + (let (v206 i1) (lte v204 v205)) + (let (v207 i32) (sext v206)) + (let (v208 i1) (neq v207 0)) + (condbr v208 (block 25) (block 26))) + + (block 24 (param v326 i32) (param v327 i32) + (let (v328 i32) (const.i32 1)) + (let (v329 i32) (bor v327 v328)) + (let (v330 u32) (bitcast v326)) + (let (v331 u32) (mod.unchecked v330 4)) + (assertz 250 v331) + (let (v332 (ptr i32)) (inttoptr v330)) + (store v332 v329) + (let (v333 i32) (const.i32 8)) + (let (v334 i32) (add.wrapping v326 v333)) + (ret v334)) (block 25 - (let (v202 i32) (band v196 v168)) - (let (v203 i1) (neq v202 0)) - (condbr v203 (block 21 v204 v205 v170 v184 v196) (block 26))) + (let (v229 i32) (const.i32 0)) + (let (v230 i32) (const.i32 0)) + (let (v231 u32) (bitcast v203)) + (let (v232 u32) (mod.unchecked v231 4)) + (assertz 250 v232) + (let (v233 (ptr i32)) (inttoptr v231)) + (store v233 v230) + (let (v234 i32) (const.i32 -8)) + (let (v235 i32) (add.wrapping v203 v234)) + (let (v236 i64) (const.i64 0)) + (let (v237 u32) (bitcast v235)) + (let (v238 u32) (mod.unchecked v237 4)) + (assertz 250 v238) + (let (v239 (ptr i64)) (inttoptr v237)) + (store v239 v236) + (let (v240 u32) (bitcast v172)) + (let (v241 u32) (mod.unchecked v240 4)) + (assertz 250 v241) + (let (v242 (ptr i32)) (inttoptr v240)) + (let (v243 i32) (load v242)) + (let (v244 i32) (const.i32 -4)) + (let (v245 i32) (band v243 v244)) + (let (v246 u32) (bitcast v235)) + (let (v247 u32) (mod.unchecked v246 4)) + (assertz 250 v247) + (let (v248 (ptr i32)) (inttoptr v246)) + (store v248 v245) + (let (v249 u32) (bitcast v172)) + (let (v250 u32) (mod.unchecked v249 4)) + (assertz 250 v250) + (let (v251 (ptr i32)) (inttoptr v249)) + (let (v252 i32) (load v251)) + (let (v253 i32) (const.i32 -4)) + (let (v254 i32) (band v252 v253)) + (let (v255 i1) (eq v254 0)) + (let (v256 i32) (zext v255)) + (let (v257 i1) (neq v256 0)) + (condbr v257 (block 28 v235 v229 v172 v179) (block 29))) (block 26 - (let (v206 i32) (const.i32 -4)) - (let (v207 i32) (band v205 v206)) - (let (v208 u32) (cast v204)) - (let (v209 u32) (mod.unchecked v208 2)) - (assertz v209) - (let (v210 (ptr i32)) (inttoptr v208)) - (store v210 v207) - (let (v211 u32) (cast v161)) - (let (v212 u32) (mod.unchecked v211 2)) - (assertz v212) - (let (v213 (ptr i32)) (inttoptr v211)) - (let (v214 i32) (load v213)) - (br (block 23 v161 v214))) + (let (v216 i32) (band v209 v179)) + (let (v217 i1) (neq v216 0)) + (condbr v217 (block 22 v218 v219 v181 v196 v209) (block 27))) (block 27 - (param v266 i32) - (param v267 i32) - (param v268 i32) - (param v274 i32) - (let (v269 i32) (bor v267 v268)) - (let (v270 u32) (cast v266)) - (let (v271 u32) (add.checked v270 4)) - (let (v272 u32) (mod.unchecked v271 2)) - (assertz v272) - (let (v273 (ptr i32)) (inttoptr v271)) - (store v273 v269) - (let (v275 u32) (cast v274)) - (let (v276 u32) (mod.unchecked v275 2)) - (assertz v276) - (let (v277 (ptr i32)) (inttoptr v275)) - (let (v278 i32) (load v277)) - (let (v279 i32) (const.i32 -2)) - (let (v280 i32) (band v278 v279)) - (let (v281 u32) (cast v274)) - (let (v282 u32) (mod.unchecked v281 2)) - (assertz v282) - (let (v283 (ptr i32)) (inttoptr v281)) - (store v283 v280) - (let (v284 u32) (cast v268)) - (let (v285 u32) (mod.unchecked v284 2)) - (assertz v285) - (let (v286 (ptr i32)) (inttoptr v284)) - (let (v287 i32) (load v286)) - (let (v288 i32) (const.i32 3)) - (let (v289 i32) (band v287 v288)) - (let (v290 i32) (bor v289 v266)) - (let (v291 u32) (cast v268)) - (let (v292 u32) (mod.unchecked v291 2)) - (assertz v292) - (let (v293 (ptr i32)) (inttoptr v291)) - (store v293 v290) - (let (v294 i32) (const.i32 2)) - (let (v295 i32) (band v287 v294)) - (let (v296 i1) (neq v295 0)) - (condbr v296 (block 30) (block 31))) + (let (v220 i32) (const.i32 -4)) + (let (v221 i32) (band v219 v220)) + (let (v222 u32) (bitcast v218)) + (let (v223 u32) (mod.unchecked v222 4)) + (assertz 250 v223) + (let (v224 (ptr i32)) (inttoptr v222)) + (store v224 v221) + (let (v225 u32) (bitcast v172)) + (let (v226 u32) (mod.unchecked v225 4)) + (assertz 250 v226) + (let (v227 (ptr i32)) (inttoptr v225)) + (let (v228 i32) (load v227)) + (br (block 24 v172 v228))) (block 28 - (let (v244 i32) (const.i32 2)) - (let (v245 i32) (band v238 v244)) - (let (v246 i1) (neq v245 0)) - (condbr v246 (block 27 v221 v215 v161 v168) (block 29))) + (param v280 i32) + (param v281 i32) + (param v282 i32) + (param v288 i32) + (let (v283 i32) (bor v281 v282)) + (let (v284 u32) (bitcast v280)) + (let (v285 u32) (add.checked v284 4)) + (let (v286 u32) (mod.unchecked v285 4)) + (assertz 250 v286) + (let (v287 (ptr i32)) (inttoptr v285)) + (store v287 v283) + (let (v289 u32) (bitcast v288)) + (let (v290 u32) (mod.unchecked v289 4)) + (assertz 250 v290) + (let (v291 (ptr i32)) (inttoptr v289)) + (let (v292 i32) (load v291)) + (let (v293 i32) (const.i32 -2)) + (let (v294 i32) (band v292 v293)) + (let (v295 u32) (bitcast v288)) + (let (v296 u32) (mod.unchecked v295 4)) + (assertz 250 v296) + (let (v297 (ptr i32)) (inttoptr v295)) + (store v297 v294) + (let (v298 u32) (bitcast v282)) + (let (v299 u32) (mod.unchecked v298 4)) + (assertz 250 v299) + (let (v300 (ptr i32)) (inttoptr v298)) + (let (v301 i32) (load v300)) + (let (v302 i32) (const.i32 3)) + (let (v303 i32) (band v301 v302)) + (let (v304 i32) (bor v303 v280)) + (let (v305 u32) (bitcast v282)) + (let (v306 u32) (mod.unchecked v305 4)) + (assertz 250 v306) + (let (v307 (ptr i32)) (inttoptr v305)) + (store v307 v304) + (let (v308 i32) (const.i32 2)) + (let (v309 i32) (band v301 v308)) + (let (v310 i1) (neq v309 0)) + (condbr v310 (block 31) (block 32))) (block 29 - (let (v247 u32) (cast v240)) - (let (v248 u32) (add.checked v247 4)) - (let (v249 u32) (mod.unchecked v248 2)) - (assertz v249) - (let (v250 (ptr i32)) (inttoptr v248)) - (let (v251 i32) (load v250)) - (let (v252 i32) (const.i32 3)) - (let (v253 i32) (band v251 v252)) - (let (v254 i32) (bor v253 v221)) - (let (v255 u32) (cast v240)) - (let (v256 u32) (add.checked v255 4)) - (let (v257 u32) (mod.unchecked v256 2)) - (assertz v257) - (let (v258 (ptr i32)) (inttoptr v256)) - (store v258 v254) - (let (v259 u32) (cast v221)) - (let (v260 u32) (add.checked v259 4)) - (let (v261 u32) (mod.unchecked v260 2)) - (assertz v261) - (let (v262 (ptr i32)) (inttoptr v260)) - (let (v263 i32) (load v262)) - (let (v264 i32) (const.i32 3)) - (let (v265 i32) (band v263 v264)) - (br (block 27 v221 v265 v161 v168))) + (let (v258 i32) (const.i32 2)) + (let (v259 i32) (band v252 v258)) + (let (v260 i1) (neq v259 0)) + (condbr v260 (block 28 v235 v229 v172 v179) (block 30))) (block 30 - (let (v301 i32) (const.i32 -3)) - (let (v302 i32) (band v290 v301)) - (let (v303 u32) (cast v268)) - (let (v304 u32) (mod.unchecked v303 2)) - (assertz v304) - (let (v305 (ptr i32)) (inttoptr v303)) - (store v305 v302) - (let (v306 u32) (cast v266)) - (let (v307 u32) (mod.unchecked v306 2)) - (assertz v307) - (let (v308 (ptr i32)) (inttoptr v306)) - (let (v309 i32) (load v308)) - (let (v310 i32) (const.i32 2)) - (let (v311 i32) (bor v309 v310)) - (br (block 23 v266 v311))) + (let (v261 u32) (bitcast v254)) + (let (v262 u32) (add.checked v261 4)) + (let (v263 u32) (mod.unchecked v262 4)) + (assertz 250 v263) + (let (v264 (ptr i32)) (inttoptr v262)) + (let (v265 i32) (load v264)) + (let (v266 i32) (const.i32 3)) + (let (v267 i32) (band v265 v266)) + (let (v268 i32) (bor v267 v235)) + (let (v269 u32) (bitcast v254)) + (let (v270 u32) (add.checked v269 4)) + (let (v271 u32) (mod.unchecked v270 4)) + (assertz 250 v271) + (let (v272 (ptr i32)) (inttoptr v270)) + (store v272 v268) + (let (v273 u32) (bitcast v235)) + (let (v274 u32) (add.checked v273 4)) + (let (v275 u32) (mod.unchecked v274 4)) + (assertz 250 v275) + (let (v276 (ptr i32)) (inttoptr v274)) + (let (v277 i32) (load v276)) + (let (v278 i32) (const.i32 3)) + (let (v279 i32) (band v277 v278)) + (br (block 28 v235 v279 v172 v179))) (block 31 - (let (v297 u32) (cast v266)) - (let (v298 u32) (mod.unchecked v297 2)) - (assertz v298) - (let (v299 (ptr i32)) (inttoptr v297)) - (let (v300 i32) (load v299)) - (br (block 23 v266 v300))) + (let (v315 i32) (const.i32 -3)) + (let (v316 i32) (band v304 v315)) + (let (v317 u32) (bitcast v282)) + (let (v318 u32) (mod.unchecked v317 4)) + (assertz 250 v318) + (let (v319 (ptr i32)) (inttoptr v317)) + (store v319 v316) + (let (v320 u32) (bitcast v280)) + (let (v321 u32) (mod.unchecked v320 4)) + (assertz 250 v321) + (let (v322 (ptr i32)) (inttoptr v320)) + (let (v323 i32) (load v322)) + (let (v324 i32) (const.i32 2)) + (let (v325 i32) (bor v323 v324)) + (br (block 24 v280 v325))) (block 32 + (let (v311 u32) (bitcast v280)) + (let (v312 u32) (mod.unchecked v311 4)) + (assertz 250 v312) + (let (v313 (ptr i32)) (inttoptr v311)) + (let (v314 i32) (load v313)) + (br (block 24 v280 v314))) + + (block 33 (br (block 5))) ) @@ -685,15 +775,15 @@ (br (block 1 v102))) (block 3 - (let (v10 u32) (cast v0)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (let (v10 u32) (bitcast v0)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr i32)) (inttoptr v10)) (let (v13 i32) (load v12)) - (let (v14 u32) (cast v7)) + (let (v14 u32) (bitcast v7)) (let (v15 u32) (add.checked v14 12)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr i32)) (inttoptr v15)) (store v17 v13) (let (v18 i32) (const.i32 3)) @@ -713,15 +803,15 @@ (br (block 2 v7 v1))) (block 5 (param v88 i32) (param v89 i32) (param v103 i32) - (let (v90 u32) (cast v89)) + (let (v90 u32) (bitcast v89)) (let (v91 u32) (add.checked v90 12)) - (let (v92 u32) (mod.unchecked v91 2)) - (assertz v92) + (let (v92 u32) (mod.unchecked v91 4)) + (assertz 250 v92) (let (v93 (ptr i32)) (inttoptr v91)) (let (v94 i32) (load v93)) - (let (v95 u32) (cast v88)) - (let (v96 u32) (mod.unchecked v95 2)) - (assertz v96) + (let (v95 u32) (bitcast v88)) + (let (v96 u32) (mod.unchecked v95 4)) + (assertz 250 v96) (let (v97 (ptr i32)) (inttoptr v95)) (store v97 v94) (br (block 2 v89 v103))) @@ -747,7 +837,7 @@ (let (v46 u32) (bitcast v44)) (let (v47 u32) (shr.wrapping v45 v46)) (let (v48 i32) (bitcast v47)) - (let (v49 u32) (cast v48)) + (let (v49 u32) (bitcast v48)) (let (v50 i32) (memory.grow v49)) (let (v51 i32) (const.i32 -1)) (let (v52 i1) (neq v50 v51)) @@ -760,22 +850,22 @@ (let (v57 u32) (bitcast v56)) (let (v58 i32) (shl.wrapping v50 v57)) (let (v59 i32) (const.i32 0)) - (let (v60 u32) (cast v58)) + (let (v60 u32) (bitcast v58)) (let (v61 u32) (add.checked v60 4)) - (let (v62 u32) (mod.unchecked v61 2)) - (assertz v62) + (let (v62 u32) (mod.unchecked v61 4)) + (assertz 250 v62) (let (v63 (ptr i32)) (inttoptr v61)) (store v63 v59) - (let (v64 u32) (cast v7)) + (let (v64 u32) (bitcast v7)) (let (v65 u32) (add.checked v64 12)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (let (v68 i32) (load v67)) - (let (v69 u32) (cast v58)) + (let (v69 u32) (bitcast v58)) (let (v70 u32) (add.checked v69 8)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) (let (v72 (ptr i32)) (inttoptr v70)) (store v72 v68) (let (v73 i32) (const.i32 -65536)) @@ -783,15 +873,15 @@ (let (v75 i32) (add.wrapping v58 v74)) (let (v76 i32) (const.i32 2)) (let (v77 i32) (bor v75 v76)) - (let (v78 u32) (cast v58)) - (let (v79 u32) (mod.unchecked v78 2)) - (assertz v79) + (let (v78 u32) (bitcast v58)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) (let (v80 (ptr i32)) (inttoptr v78)) (store v80 v77) - (let (v81 u32) (cast v7)) + (let (v81 u32) (bitcast v7)) (let (v82 u32) (add.checked v81 12)) - (let (v83 u32) (mod.unchecked v82 2)) - (assertz v83) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) (let (v84 (ptr i32)) (inttoptr v82)) (store v84 v58) (let (v85 i32) (const.i32 12)) @@ -826,36 +916,36 @@ (condbr v10 (block 2) (block 4))) (block 4 - (let (v11 u32) (cast v0)) - (let (v12 u32) (mod.unchecked v11 2)) - (assertz v12) + (let (v11 u32) (bitcast v0)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) (let (v13 (ptr i32)) (inttoptr v11)) (let (v14 i32) (load v13)) (let (v15 i32) (const.i32 0)) - (let (v16 u32) (cast v1)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) (let (v18 (ptr i32)) (inttoptr v16)) (store v18 v15) (let (v19 i32) (const.i32 -8)) (let (v20 i32) (add.wrapping v1 v19)) - (let (v21 u32) (cast v20)) - (let (v22 u32) (mod.unchecked v21 2)) - (assertz v22) + (let (v21 u32) (bitcast v20)) + (let (v22 u32) (mod.unchecked v21 4)) + (assertz 250 v22) (let (v23 (ptr i32)) (inttoptr v21)) (let (v24 i32) (load v23)) (let (v25 i32) (const.i32 -2)) (let (v26 i32) (band v24 v25)) - (let (v27 u32) (cast v20)) - (let (v28 u32) (mod.unchecked v27 2)) - (assertz v28) + (let (v27 u32) (bitcast v20)) + (let (v28 u32) (mod.unchecked v27 4)) + (assertz 250 v28) (let (v29 (ptr i32)) (inttoptr v27)) (store v29 v26) (let (v30 i32) (const.i32 4)) (let (v31 i32) (add.wrapping v20 v30)) - (let (v32 u32) (cast v31)) - (let (v33 u32) (mod.unchecked v32 2)) - (assertz v33) + (let (v32 u32) (bitcast v31)) + (let (v33 u32) (mod.unchecked v32 4)) + (assertz 250 v33) (let (v34 (ptr i32)) (inttoptr v32)) (let (v35 i32) (load v34)) (let (v36 i32) (const.i32 -4)) @@ -866,9 +956,9 @@ (condbr v40 (block 10 v24 v1 v20 v14 v0) (block 11))) (block 5 (param v181 i32) (param v187 i32) - (let (v189 u32) (cast v181)) - (let (v190 u32) (mod.unchecked v189 2)) - (assertz v190) + (let (v189 u32) (bitcast v181)) + (let (v190 u32) (mod.unchecked v189 4)) + (assertz 250 v190) (let (v191 (ptr i32)) (inttoptr v189)) (store v191 v187) (br (block 2))) @@ -878,9 +968,9 @@ (param v177 i32) (param v186 i32) (param v188 i32) - (let (v178 u32) (cast v176)) - (let (v179 u32) (mod.unchecked v178 2)) - (assertz v179) + (let (v178 u32) (bitcast v176)) + (let (v179 u32) (mod.unchecked v178 4)) + (assertz 250 v179) (let (v180 (ptr i32)) (inttoptr v178)) (store v180 v177) (br (block 5 v186 v188))) @@ -889,7 +979,7 @@ (br (block 5 v182 v172))) (block 8 - (let (v147 u32) (cast v52)) + (let (v147 u32) (bitcast v52)) (let (v148 (ptr u8)) (inttoptr v147)) (let (v149 u8) (load v148)) (let (v150 i32) (zext v149)) @@ -918,9 +1008,9 @@ (condbr v55 (block 6 v154 v175 v185 v165) (block 13))) (block 11 - (let (v41 u32) (cast v37)) - (let (v42 u32) (mod.unchecked v41 2)) - (assertz v42) + (let (v41 u32) (bitcast v37)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) (let (v43 (ptr i32)) (inttoptr v41)) (let (v44 i32) (load v43)) (let (v45 i32) (const.i32 1)) @@ -954,16 +1044,16 @@ (param v183 i32) (let (v119 i32) (const.i32 3)) (let (v120 i32) (band v118 v119)) - (let (v121 u32) (cast v117)) - (let (v122 u32) (mod.unchecked v121 2)) - (assertz v122) + (let (v121 u32) (bitcast v117)) + (let (v122 u32) (mod.unchecked v121 4)) + (assertz 250 v122) (let (v123 (ptr i32)) (inttoptr v121)) (store v123 v120) (let (v126 i32) (const.i32 3)) (let (v127 i32) (band v125 v126)) - (let (v128 u32) (cast v124)) - (let (v129 u32) (mod.unchecked v128 2)) - (assertz v129) + (let (v128 u32) (bitcast v124)) + (let (v129 u32) (mod.unchecked v128 4)) + (assertz 250 v129) (let (v130 (ptr i32)) (inttoptr v128)) (store v130 v127) (let (v131 i32) (const.i32 2)) @@ -987,19 +1077,19 @@ (let (v101 i32) (const.i32 3)) (let (v102 i32) (band v100 v101)) (let (v103 i32) (bor v99 v102)) - (let (v104 u32) (cast v96)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) + (let (v104 u32) (bitcast v96)) + (let (v105 u32) (mod.unchecked v104 4)) + (assertz 250 v105) (let (v106 (ptr i32)) (inttoptr v104)) (store v106 v103) - (let (v108 u32) (cast v107)) - (let (v109 u32) (mod.unchecked v108 2)) - (assertz v109) + (let (v108 u32) (bitcast v107)) + (let (v109 u32) (mod.unchecked v108 4)) + (assertz 250 v109) (let (v110 (ptr i32)) (inttoptr v108)) (let (v111 i32) (load v110)) - (let (v113 u32) (cast v112)) - (let (v114 u32) (mod.unchecked v113 2)) - (assertz v114) + (let (v113 u32) (bitcast v112)) + (let (v114 u32) (mod.unchecked v113 4)) + (assertz 250 v114) (let (v115 (ptr i32)) (inttoptr v113)) (let (v116 i32) (load v115)) (br (block 15 v107 v111 v112 v116 v137 v174 v184))) @@ -1014,29 +1104,29 @@ (br (block 16 v37 v26 v44 v31 v20 v37 v14 v0))) (block 19 - (let (v67 u32) (cast v62)) + (let (v67 u32) (bitcast v62)) (let (v68 u32) (add.checked v67 4)) - (let (v69 u32) (mod.unchecked v68 2)) - (assertz v69) + (let (v69 u32) (mod.unchecked v68 4)) + (assertz 250 v69) (let (v70 (ptr i32)) (inttoptr v68)) (let (v71 i32) (load v70)) (let (v72 i32) (const.i32 3)) (let (v73 i32) (band v71 v72)) (let (v74 i32) (bor v73 v37)) - (let (v75 u32) (cast v62)) + (let (v75 u32) (bitcast v62)) (let (v76 u32) (add.checked v75 4)) - (let (v77 u32) (mod.unchecked v76 2)) - (assertz v77) + (let (v77 u32) (mod.unchecked v76 4)) + (assertz 250 v77) (let (v78 (ptr i32)) (inttoptr v76)) (store v78 v74) - (let (v79 u32) (cast v20)) - (let (v80 u32) (mod.unchecked v79 2)) - (assertz v80) + (let (v79 u32) (bitcast v20)) + (let (v80 u32) (mod.unchecked v79 4)) + (assertz 250 v80) (let (v81 (ptr i32)) (inttoptr v79)) (let (v82 i32) (load v81)) - (let (v83 u32) (cast v31)) - (let (v84 u32) (mod.unchecked v83 2)) - (assertz v84) + (let (v83 u32) (bitcast v31)) + (let (v84 u32) (mod.unchecked v83 4)) + (assertz 250 v84) (let (v85 (ptr i32)) (inttoptr v83)) (let (v86 i32) (load v85)) (let (v87 i32) (const.i32 -4)) @@ -1047,120 +1137,61 @@ (condbr v91 (block 15 v31 v86 v20 v82 v37 v14 v0) (block 20))) (block 20 - (let (v92 u32) (cast v88)) - (let (v93 u32) (mod.unchecked v92 2)) - (assertz v93) + (let (v92 u32) (bitcast v88)) + (let (v93 u32) (mod.unchecked v92 4)) + (assertz 250 v93) (let (v94 (ptr i32)) (inttoptr v92)) (let (v95 i32) (load v94)) (br (block 16 v88 v82 v95 v31 v20 v37 v14 v0))) (block 21 - (let (v138 u32) (cast v136)) - (let (v139 u32) (mod.unchecked v138 2)) - (assertz v139) + (let (v138 u32) (bitcast v136)) + (let (v139 u32) (mod.unchecked v138 4)) + (assertz 250 v139) (let (v140 (ptr i32)) (inttoptr v138)) (let (v141 i32) (load v140)) (let (v142 i32) (const.i32 2)) (let (v143 i32) (bor v141 v142)) - (let (v144 u32) (cast v136)) - (let (v145 u32) (mod.unchecked v144 2)) - (assertz v145) + (let (v144 u32) (bitcast v136)) + (let (v145 u32) (mod.unchecked v144 4)) + (assertz 250 v145) (let (v146 (ptr i32)) (inttoptr v144)) (store v146 v143) (br (block 7 v173 v183))) (block 22 - (let (v155 u32) (cast v52)) + (let (v155 u32) (bitcast v52)) (let (v156 u32) (add.checked v155 8)) - (let (v157 u32) (mod.unchecked v156 2)) - (assertz v157) + (let (v157 u32) (mod.unchecked v156 4)) + (assertz 250 v157) (let (v158 (ptr i32)) (inttoptr v156)) (let (v159 i32) (load v158)) (let (v160 i32) (const.i32 -4)) (let (v161 i32) (band v159 v160)) - (let (v162 u32) (cast v154)) - (let (v163 u32) (mod.unchecked v162 2)) - (assertz v163) + (let (v162 u32) (bitcast v154)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) (let (v164 (ptr i32)) (inttoptr v162)) (store v164 v161) (let (v166 i32) (const.i32 1)) (let (v167 i32) (bor v165 v166)) - (let (v168 u32) (cast v52)) + (let (v168 u32) (bitcast v52)) (let (v169 u32) (add.checked v168 8)) - (let (v170 u32) (mod.unchecked v169 2)) - (assertz v170) + (let (v170 u32) (mod.unchecked v169 4)) + (assertz 250 v170) (let (v171 (ptr i32)) (inttoptr v169)) (store v171 v167) (br (block 7 v175 v185))) ) - (func (export #wit_bindgen::rt::run_ctors_once) - (block 0 - (let (v0 i32) (const.i32 0)) - (let (v1 u32) (cast v0)) - (let (v2 u32) (add.checked v1 1048581)) - (let (v3 (ptr u8)) (inttoptr v2)) - (let (v4 u8) (load v3)) - (let (v5 i32) (zext v4)) - (let (v6 i1) (neq v5 0)) - (condbr v6 (block 2) (block 3))) - - (block 1 - (ret)) - - (block 2 - (br (block 1))) - - (block 3 - (call #__wasm_call_ctors) - (let (v7 i32) (const.i32 0)) - (let (v8 i32) (const.i32 1)) - (let (v9 u8) (trunc v8)) - (let (v10 u32) (cast v7)) - (let (v11 u32) (add.checked v10 1048581)) - (let (v12 (ptr u8)) (inttoptr v11)) - (store v12 v9) - (br (block 2))) - ) - (func (export #cabi_realloc) (param i32) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) - (let (v5 i1) (neq v1 0)) - (condbr v5 (block 4) (block 5))) + (let (v5 i32) (call #cabi_realloc_wit_bindgen_0_28_0 v0 v1 v2 v3)) + (br (block 1 v5))) (block 1 (param v4 i32) (ret v4)) - - (block 2 (param v19 i32) - (br (block 1 v19))) - - (block 3 (param v17 i32) - (let (v18 i1) (neq v17 0)) - (condbr v18 (block 2 v17) (block 7))) - - (block 4 - (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) - (br (block 3 v16))) - - (block 5 - (let (v6 i1) (eq v3 0)) - (let (v7 i32) (zext v6)) - (let (v8 i1) (neq v7 0)) - (condbr v8 (block 2 v2) (block 6))) - - (block 6 - (let (v9 i32) (const.i32 0)) - (let (v10 u32) (cast v9)) - (let (v11 u32) (add.checked v10 1048580)) - (let (v12 (ptr u8)) (inttoptr v11)) - (let (v13 u8) (load v12)) - (let (v14 i32) (zext v13)) - (let (v15 i32) (call #__rust_alloc v3 v2)) - (br (block 3 v15))) - - (block 7 - (unreachable)) ) ;; Imports diff --git a/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet.wat b/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet.wat index 1c47e648..db91242a 100644 --- a/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet.wat +++ b/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet.wat @@ -50,24 +50,57 @@ (type (;0;) (func (param i64 i64 i64 i64 i32))) (type (;1;) (func (param i64 i64 i64 i64 i64 i64 i64 i64 i64) (result i64))) (type (;2;) (func)) - (type (;3;) (func (param i64 i64 i64 i64))) - (type (;4;) (func (param i64 i64 i64 i64 i64 i64 i64 i64 i64))) - (type (;5;) (func (param i32 i32) (result i32))) - (type (;6;) (func (param i32 i32 i32 i32) (result i32))) + (type (;3;) (func (param i32 i32) (result i32))) + (type (;4;) (func (param i32 i32 i32 i32) (result i32))) + (type (;5;) (func (param i64 i64 i64 i64))) + (type (;6;) (func (param i64 i64 i64 i64 i64 i64 i64 i64 i64))) (type (;7;) (func (param i32 i32 i32) (result i32))) (type (;8;) (func (param i32 i32 i32 i32))) (import "miden:base/account@1.0.0" "add-asset" (func $basic_wallet::bindings::miden::base::account::add_asset::wit_import (;0;) (type 0))) (import "miden:base/account@1.0.0" "remove-asset" (func $basic_wallet::bindings::miden::base::account::remove_asset::wit_import (;1;) (type 0))) (import "miden:base/tx@1.0.0" "create-note" (func $basic_wallet::bindings::miden::base::tx::create_note::wit_import (;2;) (type 1))) (func $__wasm_call_ctors (;3;) (type 2)) - (func $miden:basic-wallet/basic-wallet@1.0.0#receive-asset (;4;) (type 3) (param i64 i64 i64 i64) + (func $__rust_alloc (;4;) (type 3) (param i32 i32) (result i32) + i32.const 1048580 + local.get 1 + local.get 0 + call $::alloc + ) + (func $__rust_realloc (;5;) (type 4) (param i32 i32 i32 i32) (result i32) + (local i32) + block ;; label = @1 + i32.const 1048580 + local.get 2 + local.get 3 + call $::alloc + local.tee 4 + i32.eqz + br_if 0 (;@1;) + local.get 4 + local.get 0 + local.get 1 + local.get 3 + local.get 1 + local.get 3 + i32.lt_u + select + memory.copy + i32.const 1048580 + local.get 0 + local.get 2 + local.get 1 + call $::dealloc + end + local.get 4 + ) + (func $miden:basic-wallet/basic-wallet@1.0.0#receive-asset (;6;) (type 5) (param i64 i64 i64 i64) (local i32) global.get $__stack_pointer i32.const 32 i32.sub local.tee 4 global.set $__stack_pointer - call $wit_bindgen::rt::run_ctors_once + call $wit_bindgen_rt::run_ctors_once local.get 0 local.get 1 local.get 2 @@ -79,14 +112,14 @@ i32.add global.set $__stack_pointer ) - (func $miden:basic-wallet/basic-wallet@1.0.0#send-asset (;5;) (type 4) (param i64 i64 i64 i64 i64 i64 i64 i64 i64) + (func $miden:basic-wallet/basic-wallet@1.0.0#send-asset (;7;) (type 6) (param i64 i64 i64 i64 i64 i64 i64 i64 i64) (local i32) global.get $__stack_pointer i32.const 32 i32.sub local.tee 9 global.set $__stack_pointer - call $wit_bindgen::rt::run_ctors_once + call $wit_bindgen_rt::run_ctors_once local.get 0 local.get 1 local.get 2 @@ -96,17 +129,11 @@ local.get 9 i64.load local.get 9 - i32.const 8 - i32.add - i64.load + i64.load offset=8 local.get 9 - i32.const 16 - i32.add - i64.load + i64.load offset=16 local.get 9 - i32.const 24 - i32.add - i64.load + i64.load offset=24 local.get 4 local.get 5 local.get 6 @@ -119,342 +146,359 @@ i32.add global.set $__stack_pointer ) - (func $__rust_alloc (;6;) (type 5) (param i32 i32) (result i32) - i32.const 1048576 - local.get 1 - local.get 0 - call $::alloc - ) - (func $__rust_realloc (;7;) (type 6) (param i32 i32 i32 i32) (result i32) - (local i32) + (func $cabi_realloc_wit_bindgen_0_28_0 (;8;) (type 4) (param i32 i32 i32 i32) (result i32) block ;; label = @1 - i32.const 1048576 + block ;; label = @2 + block ;; label = @3 + block ;; label = @4 + local.get 1 + br_if 0 (;@4;) + local.get 3 + i32.eqz + br_if 2 (;@2;) + i32.const 0 + i32.load8_u offset=1048584 + drop + local.get 3 + local.get 2 + call $__rust_alloc + local.set 2 + br 1 (;@3;) + end + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $__rust_realloc + local.set 2 + end + local.get 2 + i32.eqz + br_if 1 (;@1;) + end local.get 2 - local.get 3 - call $::alloc - local.tee 4 - i32.eqz + return + end + unreachable + unreachable + ) + (func $wit_bindgen_rt::run_ctors_once (;9;) (type 2) + block ;; label = @1 + i32.const 0 + i32.load8_u offset=1048585 br_if 0 (;@1;) - local.get 4 - local.get 0 - local.get 1 - local.get 3 - local.get 1 - local.get 3 - i32.lt_u - select - memory.copy - i32.const 1048576 - local.get 0 - local.get 2 - local.get 1 - call $::dealloc + call $__wasm_call_ctors + i32.const 0 + i32.const 1 + i32.store8 offset=1048585 end - local.get 4 ) - (func $wee_alloc::alloc_first_fit (;8;) (type 7) (param i32 i32 i32) (result i32) - (local i32 i32 i32 i32 i32 i32) + (func $wee_alloc::alloc_first_fit (;10;) (type 7) (param i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 2 i32.load local.tee 3 - i32.eqz br_if 0 (;@1;) - local.get 1 - i32.const -1 - i32.add - local.set 4 i32.const 0 - local.get 1 - i32.sub - local.set 5 - local.get 0 - i32.const 2 - i32.shl - local.set 6 - loop ;; label = @2 - local.get 3 - i32.const 8 - i32.add - local.set 7 + return + end + local.get 1 + i32.const -1 + i32.add + local.set 4 + i32.const 0 + local.get 1 + i32.sub + local.set 5 + local.get 0 + i32.const 2 + i32.shl + local.set 6 + loop ;; label = @1 + block ;; label = @2 block ;; label = @3 + local.get 3 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) + local.get 3 + i32.const 8 + i32.add + local.set 0 + br 1 (;@2;) + end + loop ;; label = @3 + local.get 3 + local.get 1 + i32.const -2 + i32.and + i32.store offset=8 block ;; label = @4 - local.get 3 - i32.load offset=8 - local.tee 0 + block ;; label = @5 + local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 + i32.and + local.tee 0 + br_if 0 (;@5;) + i32.const 0 + local.set 8 + br 1 (;@4;) + end + i32.const 0 + local.get 0 + local.get 0 + i32.load8_u i32.const 1 i32.and - br_if 0 (;@4;) - local.get 3 - local.set 1 - br 1 (;@3;) + select + local.set 8 end - loop ;; label = @4 - local.get 7 - local.get 0 - i32.const -2 - i32.and - i32.store + block ;; label = @4 local.get 3 - i32.load offset=4 + i32.load + local.tee 1 i32.const -4 i32.and - local.tee 1 - i32.load - local.set 7 - block ;; label = @5 - block ;; label = @6 - block ;; label = @7 - local.get 3 - i32.load - local.tee 8 - i32.const -4 - i32.and - local.tee 0 - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - block ;; label = @7 - local.get 8 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - local.get 0 - local.get 0 - i32.load offset=4 - i32.const 3 - i32.and - local.get 1 - i32.or - i32.store offset=4 - local.get 3 - i32.load - local.set 0 - local.get 3 - i32.load offset=4 - local.tee 7 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 1 (;@5;) - local.get 0 - i32.const -4 - i32.and - local.set 0 - local.get 8 - i32.load - local.set 7 - end - local.get 8 - local.get 7 - i32.const 3 - i32.and - local.get 0 - i32.or - i32.store - local.get 3 - i32.load offset=4 - local.set 7 - local.get 3 - i32.load - local.set 0 - end - local.get 3 - local.get 7 + local.tee 9 + i32.eqz + br_if 0 (;@4;) + local.get 1 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 9 + local.get 9 + i32.load offset=4 i32.const 3 i32.and + local.get 0 + i32.or i32.store offset=4 local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 + i32.and + local.set 0 + local.get 3 + i32.load + local.set 1 + end + block ;; label = @4 + local.get 0 + i32.eqz + br_if 0 (;@4;) local.get 0 + local.get 0 + i32.load i32.const 3 i32.and - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@5;) - local.get 1 - local.get 1 - i32.load - i32.const 2 - i32.or - i32.store - end - local.get 2 local.get 1 + i32.const -4 + i32.and + i32.or i32.store - local.get 1 - i32.const 8 - i32.add + local.get 3 + i32.load offset=4 local.set 7 + local.get 3 + i32.load + local.set 1 + end + local.get 3 + local.get 7 + i32.const 3 + i32.and + i32.store offset=4 + local.get 3 + local.get 1 + i32.const 3 + i32.and + i32.store + block ;; label = @4 local.get 1 - local.set 3 - local.get 1 - i32.load offset=8 - local.tee 0 - i32.const 1 + i32.const 2 i32.and + i32.eqz br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load + i32.const 2 + i32.or + i32.store end + local.get 2 + local.get 8 + i32.store + local.get 8 + local.set 3 + local.get 8 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) end + local.get 8 + i32.const 8 + i32.add + local.set 0 + local.get 8 + local.set 3 + end + block ;; label = @2 + local.get 3 + i32.load + i32.const -4 + i32.and + local.tee 8 + local.get 0 + i32.sub + local.get 6 + i32.lt_u + br_if 0 (;@2;) block ;; label = @3 + block ;; label = @4 + local.get 0 + i32.const 72 + i32.add + local.get 8 + local.get 6 + i32.sub + local.get 5 + i32.and + local.tee 8 + i32.le_u + br_if 0 (;@4;) + local.get 4 + local.get 0 + i32.and + br_if 2 (;@2;) + local.get 2 + local.get 1 + i32.const -4 + i32.and + i32.store + local.get 3 + i32.load + local.set 0 + local.get 3 + local.set 1 + br 1 (;@3;) + end + i32.const 0 + local.set 7 + local.get 8 + i32.const 0 + i32.store + local.get 8 + i32.const -8 + i32.add + local.tee 1 + i64.const 0 + i64.store align=4 local.get 1 + local.get 3 i32.load i32.const -4 i32.and - local.tee 3 - local.get 7 - i32.sub - local.get 6 - i32.lt_u - br_if 0 (;@3;) + i32.store block ;; label = @4 - block ;; label = @5 - local.get 7 - i32.const 72 - i32.add - local.get 3 - local.get 6 - i32.sub - local.get 5 - i32.and - local.tee 3 - i32.le_u - br_if 0 (;@5;) - local.get 4 - local.get 7 - i32.and - br_if 2 (;@3;) - local.get 2 - local.get 0 - i32.const -4 - i32.and - i32.store - local.get 1 - i32.load - local.set 0 - local.get 1 - local.set 3 - br 1 (;@4;) - end - i32.const 0 - local.set 0 - local.get 3 - i32.const 0 - i32.store local.get 3 - i32.const -8 - i32.add - local.tee 3 - i64.const 0 - i64.store align=4 - local.get 3 - local.get 1 i32.load + local.tee 9 i32.const -4 i32.and - i32.store - block ;; label = @5 - local.get 1 - i32.load - local.tee 2 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 0 (;@5;) - local.get 2 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 8 - local.get 8 - i32.load offset=4 - i32.const 3 - i32.and - local.get 3 - i32.or - i32.store offset=4 - local.get 3 - i32.load offset=4 - i32.const 3 - i32.and - local.set 0 - end - local.get 3 - local.get 0 - local.get 1 - i32.or - i32.store offset=4 - local.get 7 - local.get 7 - i32.load - i32.const -2 + local.tee 8 + i32.eqz + br_if 0 (;@4;) + local.get 9 + i32.const 2 i32.and - i32.store - local.get 1 - local.get 1 - i32.load - local.tee 0 + br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load offset=4 i32.const 3 i32.and - local.get 3 + local.get 1 i32.or - local.tee 7 - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 3 - i32.load - local.set 0 - br 1 (;@4;) - end + i32.store offset=4 local.get 1 - local.get 7 - i32.const -3 + i32.load offset=4 + i32.const 3 i32.and - i32.store - local.get 3 - i32.load - i32.const 2 - i32.or - local.set 0 + local.set 7 end + local.get 1 + local.get 7 local.get 3 + i32.or + i32.store offset=4 local.get 0 - i32.const 1 + local.get 0 + i32.load + i32.const -2 + i32.and + i32.store + local.get 3 + local.get 3 + i32.load + local.tee 0 + i32.const 3 + i32.and + local.get 1 i32.or + local.tee 8 i32.store + block ;; label = @4 + local.get 0 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 1 + i32.load + local.set 0 + br 1 (;@3;) + end local.get 3 - i32.const 8 - i32.add - return + local.get 8 + i32.const -3 + i32.and + i32.store + local.get 1 + i32.load + i32.const 2 + i32.or + local.set 0 end - local.get 2 + local.get 1 local.get 0 + i32.const 1 + i32.or i32.store - local.get 0 - local.set 3 - local.get 0 - br_if 0 (;@2;) + local.get 1 + i32.const 8 + i32.add + return end + local.get 2 + local.get 1 + i32.store + local.get 1 + local.set 3 + local.get 1 + br_if 0 (;@1;) end i32.const 0 ) - (func $::alloc (;9;) (type 7) (param i32 i32 i32) (result i32) + (func $::alloc (;11;) (type 7) (param i32 i32 i32) (result i32) (local i32 i32 i32) global.get $__stack_pointer i32.const 16 @@ -558,7 +602,7 @@ global.set $__stack_pointer local.get 2 ) - (func $::dealloc (;10;) (type 8) (param i32 i32 i32 i32) + (func $::dealloc (;12;) (type 8) (param i32 i32 i32 i32) (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 1 @@ -731,56 +775,23 @@ i32.store end ) - (func $wit_bindgen::rt::run_ctors_once (;11;) (type 2) - block ;; label = @1 - i32.const 0 - i32.load8_u offset=1048581 - br_if 0 (;@1;) - call $__wasm_call_ctors - i32.const 0 - i32.const 1 - i32.store8 offset=1048581 - end - ) - (func $cabi_realloc (;12;) (type 6) (param i32 i32 i32 i32) (result i32) - block ;; label = @1 - block ;; label = @2 - block ;; label = @3 - local.get 1 - br_if 0 (;@3;) - local.get 3 - i32.eqz - br_if 2 (;@1;) - i32.const 0 - i32.load8_u offset=1048580 - drop - local.get 3 - local.get 2 - call $__rust_alloc - local.set 2 - br 1 (;@2;) - end - local.get 0 - local.get 1 - local.get 2 - local.get 3 - call $__rust_realloc - local.set 2 - end - local.get 2 - br_if 0 (;@1;) - unreachable - unreachable - end + (func $cabi_realloc (;13;) (type 4) (param i32 i32 i32 i32) (result i32) + local.get 0 + local.get 1 local.get 2 + local.get 3 + call $cabi_realloc_wit_bindgen_0_28_0 ) - (table (;0;) 1 1 funcref) + (table (;0;) 2 2 funcref) (memory (;0;) 17) (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) (export "memory" (memory 0)) (export "miden:basic-wallet/basic-wallet@1.0.0#receive-asset" (func $miden:basic-wallet/basic-wallet@1.0.0#receive-asset)) (export "miden:basic-wallet/basic-wallet@1.0.0#send-asset" (func $miden:basic-wallet/basic-wallet@1.0.0#send-asset)) + (export "cabi_realloc_wit_bindgen_0_28_0" (func $cabi_realloc_wit_bindgen_0_28_0)) (export "cabi_realloc" (func $cabi_realloc)) + (elem (;0;) (i32.const 1) func $cabi_realloc) + (data $.rodata (;0;) (i32.const 1048576) "\01\00\00\00") ) (core module (;1;) (type (;0;) (func (param i64 i64 i64 i64 i32))) diff --git a/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet_p2id_note.hir b/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet_p2id_note.hir index a1e9496c..fbc1fef5 100644 --- a/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet_p2id_note.hir +++ b/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet_p2id_note.hir @@ -29,6 +29,9 @@ ) (module #basic_wallet_p2id_note + ;; Data Segments + (data (mut) (offset 1048576) 0x0100000004000000040000000200000046656c74696e6e6572000000030000000800000008000000040000004163636f756e744964000000030000000800000008000000050000007372632f6c69622e72730000480010000a000000210000002c000000480010000a0000002400000009000000060000000b00000000000000010000000c000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e6465782069732000008800100020000000a8001000120000003d3d213d6d617463686573617373657274696f6e20606c6566742020726967687460206661696c65640a20206c6566743a200a2072696768743a2000d700100010000000e700100017000000fe0010000900000020726967687460206661696c65643a200a20206c6566743a20000000d70010001000000020011000100000003001100009000000fe001000090000003a2000000d0000000c000000040000000e0000000f0000001000000020202020207b202c20207b0a2c0a7d207d6c6962726172792f636f72652f7372632f666d742f6e756d2e7273890110001b00000069000000170000003078303030313032303330343035303630373038303931303131313231333134313531363137313831393230323132323233323432353236323732383239333033313332333333343335333633373338333934303431343234333434343534363437343834393530353135323533353435353536353735383539363036313632363336343635363636373638363937303731373237333734373537363737373837393830383138323833383438353836383738383839393039313932393339343935393639373938393972616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e6774682000007e021000120000009002100022000000) + ;; Constants (const (id 0) 0x00100000) @@ -44,151 +47,178 @@ (ret)) ) - (func (export #miden:base/note-script@1.0.0#note-script) - (block 0 - (let (v0 i32) (const.i32 0)) - (let (v1 i32) (global.load i32 (global.symbol #__stack_pointer))) - (let (v2 i32) (const.i32 16)) - (let (v3 i32) (sub.wrapping v1 v2)) - (let (v4 (ptr i32)) (global.symbol #__stack_pointer)) - (store v4 v3) - (call #wit_bindgen::rt::run_ctors_once) - (let (v5 i32) (const.i32 8)) - (let (v6 i32) (add.wrapping v3 v5)) - (call (#wit-component:shim #indirect-miden:base/note@1.0.0-get-inputs) v6) - (let (v7 i32) (const.i32 12)) - (let (v8 i32) (add.wrapping v3 v7)) - (let (v9 u32) (cast v8)) - (let (v10 u32) (mod.unchecked v9 2)) - (assertz v10) - (let (v11 (ptr i32)) (inttoptr v9)) - (let (v12 i32) (load v11)) - (let (v13 i1) (eq v12 0)) - (let (v14 i32) (zext v13)) - (let (v15 i1) (neq v14 0)) - (condbr v15 (block 2) (block 3))) + (func (export #<&T as core::fmt::Debug>::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v5 i32) (const.i32 16)) + (let (v6 i32) (sub.wrapping v4 v5)) + (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) + (store v7 v6) + (let (v8 u32) (bitcast v0)) + (let (v9 u32) (mod.unchecked v8 4)) + (assertz 250 v9) + (let (v10 (ptr i32)) (inttoptr v8)) + (let (v11 i32) (load v10)) + (let (v12 i32) (const.i32 8)) + (let (v13 i32) (add.wrapping v6 v12)) + (let (v14 i32) (const.i32 1048620)) + (let (v15 i32) (const.i32 9)) + (call #core::fmt::Formatter::debug_struct v13 v1 v14 v15) + (let (v16 i32) (const.i32 8)) + (let (v17 i32) (add.wrapping v6 v16)) + (let (v18 i32) (const.i32 1048596)) + (let (v19 i32) (const.i32 5)) + (let (v20 i32) (const.i32 1048632)) + (let (v21 i32) (call #core::fmt::builders::DebugStruct::field v17 v18 v19 v11 v20)) + (let (v22 i32) (call #core::fmt::builders::DebugStruct::finish v21)) + (let (v23 i32) (const.i32 16)) + (let (v24 i32) (add.wrapping v6 v23)) + (let (v25 (ptr i32)) (global.symbol #__stack_pointer)) + (store v25 v24) + (br (block 1 v22))) - (block 1) + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #core::fmt::num::::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 u32) (bitcast v1)) + (let (v5 u32) (add.checked v4 28)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) + (let (v7 (ptr i32)) (inttoptr v5)) + (let (v8 i32) (load v7)) + (let (v9 i32) (const.i32 16)) + (let (v10 i32) (band v8 v9)) + (let (v11 i1) (neq v10 0)) + (condbr v11 (block 2) (block 3))) + + (block 1 (param v2 i32) + (ret v2)) (block 2 - (unreachable)) + (let (v17 i32) (call #core::fmt::num::::fmt v0 v1)) + (br (block 1 v17))) (block 3 - (let (v16 u32) (cast v3)) - (let (v17 u32) (add.checked v16 8)) - (let (v18 u32) (mod.unchecked v17 2)) - (assertz v18) - (let (v19 (ptr i32)) (inttoptr v17)) - (let (v20 i32) (load v19)) - (let (v21 u32) (cast v20)) - (let (v22 u32) (mod.unchecked v21 3)) - (assertz v22) - (let (v23 (ptr i64)) (inttoptr v21)) - (let (v24 i64) (load v23)) - (let (v25 i64) (call (#miden:base/core-types@1.0.0 #account-id-from-felt) v24)) - (let (v26 i64) (call (#miden:base/account@1.0.0 #get-id))) - (let (v27 i1) (neq v25 v26)) - (let (v28 i32) (zext v27)) - (let (v29 i1) (neq v28 0)) - (condbr v29 (block 2) (block 4))) + (let (v12 i32) (const.i32 32)) + (let (v13 i32) (band v8 v12)) + (let (v14 i1) (neq v13 0)) + (condbr v14 (block 4) (block 5))) (block 4 - (let (v30 i32) (const.i32 8)) - (let (v31 i32) (add.wrapping v3 v30)) - (call (#wit-component:shim #indirect-miden:base/note@1.0.0-get-assets) v31) - (let (v32 i32) (const.i32 12)) - (let (v33 i32) (add.wrapping v3 v32)) - (let (v34 u32) (cast v33)) - (let (v35 u32) (mod.unchecked v34 2)) - (assertz v35) - (let (v36 (ptr i32)) (inttoptr v34)) - (let (v37 i32) (load v36)) - (let (v38 i1) (eq v37 0)) - (let (v39 i32) (zext v38)) - (let (v40 i1) (neq v39 0)) - (condbr v40 (block 5 v20 v12 v3) (block 6))) + (let (v16 i32) (call #core::fmt::num::::fmt v0 v1)) + (ret v16)) - (block 5 (param v84 i32) (param v87 i32) (param v92 i32) - (let (v83 i32) (const.i32 1048576)) - (let (v86 i32) (const.i32 8)) - (let (v89 i32) (const.i32 3)) - (let (v90 u32) (bitcast v89)) - (let (v91 i32) (shl.wrapping v87 v90)) - (call #::dealloc v83 v84 v86 v91) - (let (v94 i32) (const.i32 16)) - (let (v95 i32) (add.wrapping v92 v94)) - (let (v96 (ptr i32)) (global.symbol #__stack_pointer)) - (store v96 v95) + (block 5 + (let (v15 i32) (call #core::fmt::num::imp::::fmt v0 v1)) + (ret v15)) + ) + + (func (export #core::ptr::drop_in_place) + (param i32) + (block 0 (param v0 i32) + (br (block 1))) + + (block 1 (ret)) + ) - (block 6 - (let (v41 u32) (cast v3)) - (let (v42 u32) (add.checked v41 8)) - (let (v43 u32) (mod.unchecked v42 2)) - (assertz v43) - (let (v44 (ptr i32)) (inttoptr v42)) - (let (v45 i32) (load v44)) - (let (v46 i32) (const.i32 5)) - (let (v47 u32) (bitcast v46)) - (let (v48 i32) (shl.wrapping v37 v47)) - (let (v49 i32) (add.wrapping v45 v48)) - (br (block 7 v45 v49 v45 v37 v20 v12 v3))) + (func (export #core::ptr::drop_in_place<&basic_wallet_p2id_note::bindings::miden::base::core_types::AccountId>) + (param i32) + (block 0 (param v0 i32) + (br (block 1))) - (block 7 - (param v50 i32) - (param v72 i32) - (param v77 i32) - (param v79 i32) - (param v85 i32) - (param v88 i32) - (param v93 i32) - (let (v51 u32) (cast v50)) - (let (v52 u32) (mod.unchecked v51 3)) - (assertz v52) - (let (v53 (ptr i64)) (inttoptr v51)) - (let (v54 i64) (load v53)) - (let (v55 u32) (cast v50)) - (let (v56 u32) (add.checked v55 8)) - (let (v57 u32) (mod.unchecked v56 3)) - (assertz v57) - (let (v58 (ptr i64)) (inttoptr v56)) - (let (v59 i64) (load v58)) - (let (v60 u32) (cast v50)) - (let (v61 u32) (add.checked v60 16)) - (let (v62 u32) (mod.unchecked v61 3)) - (assertz v62) - (let (v63 (ptr i64)) (inttoptr v61)) - (let (v64 i64) (load v63)) - (let (v65 u32) (cast v50)) - (let (v66 u32) (add.checked v65 24)) - (let (v67 u32) (mod.unchecked v66 3)) - (assertz v67) - (let (v68 (ptr i64)) (inttoptr v66)) - (let (v69 i64) (load v68)) - (call (#miden:basic-wallet/basic-wallet@1.0.0 #receive-asset) v54 v59 v64 v69) - (let (v70 i32) (const.i32 32)) - (let (v71 i32) (add.wrapping v50 v70)) - (let (v73 i1) (neq v71 v72)) - (let (v74 i32) (zext v73)) - (let (v75 i1) (neq v74 0)) - (condbr v75 (block 7 v71 v72 v77 v79 v85 v88 v93) (block 9))) + (block 1 + (ret)) + ) - (block 8 - (let (v76 i32) (const.i32 1048576)) - (let (v78 i32) (const.i32 8)) - (let (v80 i32) (const.i32 5)) - (let (v81 u32) (bitcast v80)) - (let (v82 i32) (shl.wrapping v79 v81)) - (call #::dealloc v76 v77 v78 v82) - (br (block 5 v85 v88 v93))) + (func (export #core::panicking::assert_failed) + (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v5 i32) (const.i32 16)) + (let (v6 i32) (sub.wrapping v4 v5)) + (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) + (store v7 v6) + (let (v8 u32) (bitcast v6)) + (let (v9 u32) (add.checked v8 12)) + (let (v10 u32) (mod.unchecked v9 4)) + (assertz 250 v10) + (let (v11 (ptr i32)) (inttoptr v9)) + (store v11 v1) + (let (v12 u32) (bitcast v6)) + (let (v13 u32) (add.checked v12 8)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) + (let (v15 (ptr i32)) (inttoptr v13)) + (store v15 v0) + (let (v16 i32) (const.i32 0)) + (let (v17 i32) (const.i32 8)) + (let (v18 i32) (add.wrapping v6 v17)) + (let (v19 i32) (const.i32 1048576)) + (let (v20 i32) (const.i32 12)) + (let (v21 i32) (add.wrapping v6 v20)) + (let (v22 i32) (const.i32 1048576)) + (let (v23 i32) (const.i32 1048676)) + (call #core::panicking::assert_failed_inner v16 v18 v19 v21 v22 v2 v23) + (unreachable)) - (block 9 - (br (block 8))) + (block 1) + ) + + (func (export #rust_begin_unwind) (param i32) + (block 0 (param v0 i32) + (br (block 2))) + + (block 1) + + (block 2 + (br (block 2))) + + (block 3) + ) + + (func (export #::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v5 i32) (const.i32 16)) + (let (v6 i32) (sub.wrapping v4 v5)) + (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) + (store v7 v6) + (let (v8 i32) (const.i32 8)) + (let (v9 i32) (add.wrapping v6 v8)) + (let (v10 i32) (const.i32 1048592)) + (let (v11 i32) (const.i32 4)) + (call #core::fmt::Formatter::debug_struct v9 v1 v10 v11) + (let (v12 i32) (const.i32 8)) + (let (v13 i32) (add.wrapping v6 v12)) + (let (v14 i32) (const.i32 1048596)) + (let (v15 i32) (const.i32 5)) + (let (v16 i32) (const.i32 1048604)) + (let (v17 i32) (call #core::fmt::builders::DebugStruct::field v13 v14 v15 v0 v16)) + (let (v18 i32) (call #core::fmt::builders::DebugStruct::finish v17)) + (let (v19 i32) (const.i32 16)) + (let (v20 i32) (add.wrapping v6 v19)) + (let (v21 (ptr i32)) (global.symbol #__stack_pointer)) + (store v21 v20) + (br (block 1 v18))) + + (block 1 (param v2 i32) + (ret v2)) ) (func (export #__rust_alloc) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) - (let (v3 i32) (const.i32 1048576)) + (let (v3 i32) (const.i32 1049284)) (let (v4 i32) (call #::alloc v3 v1 v0)) (br (block 1 v4))) @@ -200,7 +230,7 @@ (param i32) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) (let (v5 i32) (const.i32 0)) - (let (v6 i32) (const.i32 1048576)) + (let (v6 i32) (const.i32 1049284)) (let (v7 i32) (call #::alloc v6 v2 v3)) (let (v8 i1) (eq v7 0)) (let (v9 i32) (zext v8)) @@ -220,499 +250,778 @@ (let (v14 i32) (sext v13)) (let (v15 i1) (neq v14 0)) (let (v16 i32) (select v15 v1 v3)) - (let (v17 u32) (cast v7)) + (let (v17 u32) (bitcast v7)) (let (v18 (ptr u8)) (inttoptr v17)) - (let (v19 u32) (cast v0)) + (let (v19 u32) (bitcast v0)) (let (v20 (ptr u8)) (inttoptr v19)) (memcpy v20 v18 v16) - (let (v21 i32) (const.i32 1048576)) + (let (v21 i32) (const.i32 1049284)) (call #::dealloc v21 v0 v2 v1) (br (block 2 v7))) ) + (func (export #miden:base/note-script@1.0.0#note-script) + (block 0 + (let (v0 i32) (const.i32 0)) + (let (v1 i64) (const.i64 0)) + (let (v2 i32) (const.i32 0)) + (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v4 i32) (const.i32 48)) + (let (v5 i32) (sub.wrapping v3 v4)) + (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) + (store v6 v5) + (call #wit_bindgen_rt::run_ctors_once) + (let (v7 i64) (const.i64 0)) + (let (v8 u32) (bitcast v5)) + (let (v9 u32) (add.checked v8 24)) + (let (v10 u32) (mod.unchecked v9 8)) + (assertz 250 v10) + (let (v11 (ptr i64)) (inttoptr v9)) + (store v11 v7) + (let (v12 i32) (const.i32 24)) + (let (v13 i32) (add.wrapping v5 v12)) + (call (#wit-component:shim #indirect-miden:base/note@1.0.0-get-inputs) v13) + (let (v14 u32) (bitcast v5)) + (let (v15 u32) (add.checked v14 28)) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) + (let (v17 (ptr i32)) (inttoptr v15)) + (let (v18 i32) (load v17)) + (let (v19 i1) (eq v18 0)) + (let (v20 i32) (zext v19)) + (let (v21 i1) (neq v20 0)) + (condbr v21 (block 3) (block 4))) + + (block 1) + + (block 2 + (let (v118 i32) (const.i32 0)) + (let (v119 u32) (bitcast v5)) + (let (v120 u32) (add.checked v119 24)) + (let (v121 u32) (mod.unchecked v120 4)) + (assertz 250 v121) + (let (v122 (ptr i32)) (inttoptr v120)) + (store v122 v118) + (let (v123 i32) (const.i32 16)) + (let (v124 i32) (add.wrapping v5 v123)) + (let (v125 i32) (const.i32 8)) + (let (v126 i32) (add.wrapping v5 v125)) + (let (v127 i32) (const.i32 24)) + (let (v128 i32) (add.wrapping v5 v127)) + (call #core::panicking::assert_failed v124 v126 v128) + (unreachable)) + + (block 3 + (let (v115 i32) (const.i32 0)) + (let (v116 i32) (const.i32 0)) + (let (v117 i32) (const.i32 1048660)) + (call #core::panicking::panic_bounds_check v115 v116 v117) + (unreachable)) + + (block 4 + (let (v22 u32) (bitcast v5)) + (let (v23 u32) (add.checked v22 24)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) + (let (v25 (ptr i32)) (inttoptr v23)) + (let (v26 i32) (load v25)) + (let (v27 u32) (bitcast v26)) + (let (v28 u32) (mod.unchecked v27 8)) + (assertz 250 v28) + (let (v29 (ptr i64)) (inttoptr v27)) + (let (v30 i64) (load v29)) + (let (v31 i64) (call (#miden:base/core-types@1.0.0 #account-id-from-felt) v30)) + (let (v32 u32) (bitcast v5)) + (let (v33 u32) (add.checked v32 8)) + (let (v34 u32) (mod.unchecked v33 8)) + (assertz 250 v34) + (let (v35 (ptr i64)) (inttoptr v33)) + (store v35 v31) + (let (v36 i64) (call (#miden:base/account@1.0.0 #get-id))) + (let (v37 u32) (bitcast v5)) + (let (v38 u32) (add.checked v37 16)) + (let (v39 u32) (mod.unchecked v38 8)) + (assertz 250 v39) + (let (v40 (ptr i64)) (inttoptr v38)) + (store v40 v36) + (let (v41 i1) (neq v36 v31)) + (let (v42 i32) (zext v41)) + (let (v43 i1) (neq v42 0)) + (condbr v43 (block 2) (block 5))) + + (block 5 + (let (v44 i64) (const.i64 0)) + (let (v45 u32) (bitcast v5)) + (let (v46 u32) (add.checked v45 24)) + (let (v47 u32) (mod.unchecked v46 8)) + (assertz 250 v47) + (let (v48 (ptr i64)) (inttoptr v46)) + (store v48 v44) + (let (v49 i32) (const.i32 24)) + (let (v50 i32) (add.wrapping v5 v49)) + (call (#wit-component:shim #indirect-miden:base/note@1.0.0-get-assets) v50) + (let (v51 u32) (bitcast v5)) + (let (v52 u32) (add.checked v51 28)) + (let (v53 u32) (mod.unchecked v52 4)) + (assertz 250 v53) + (let (v54 (ptr i32)) (inttoptr v52)) + (let (v55 i32) (load v54)) + (let (v56 i1) (eq v55 0)) + (let (v57 i32) (zext v56)) + (let (v58 i1) (neq v57 0)) + (condbr v58 (block 6 v26 v18 v5) (block 7))) + + (block 6 (param v102 i32) (param v105 i32) (param v110 i32) + (let (v101 i32) (const.i32 1049284)) + (let (v104 i32) (const.i32 8)) + (let (v107 i32) (const.i32 3)) + (let (v108 u32) (bitcast v107)) + (let (v109 i32) (shl.wrapping v105 v108)) + (call #::dealloc v101 v102 v104 v109) + (let (v112 i32) (const.i32 48)) + (let (v113 i32) (add.wrapping v110 v112)) + (let (v114 (ptr i32)) (global.symbol #__stack_pointer)) + (store v114 v113) + (ret)) + + (block 7 + (let (v59 u32) (bitcast v5)) + (let (v60 u32) (add.checked v59 24)) + (let (v61 u32) (mod.unchecked v60 4)) + (assertz 250 v61) + (let (v62 (ptr i32)) (inttoptr v60)) + (let (v63 i32) (load v62)) + (let (v64 i32) (const.i32 5)) + (let (v65 u32) (bitcast v64)) + (let (v66 i32) (shl.wrapping v55 v65)) + (let (v67 i32) (add.wrapping v63 v66)) + (br (block 8 v63 v67 v63 v55 v26 v18 v5))) + + (block 8 + (param v68 i32) + (param v90 i32) + (param v95 i32) + (param v97 i32) + (param v103 i32) + (param v106 i32) + (param v111 i32) + (let (v69 u32) (bitcast v68)) + (let (v70 u32) (mod.unchecked v69 8)) + (assertz 250 v70) + (let (v71 (ptr i64)) (inttoptr v69)) + (let (v72 i64) (load v71)) + (let (v73 u32) (bitcast v68)) + (let (v74 u32) (add.checked v73 8)) + (let (v75 u32) (mod.unchecked v74 8)) + (assertz 250 v75) + (let (v76 (ptr i64)) (inttoptr v74)) + (let (v77 i64) (load v76)) + (let (v78 u32) (bitcast v68)) + (let (v79 u32) (add.checked v78 16)) + (let (v80 u32) (mod.unchecked v79 8)) + (assertz 250 v80) + (let (v81 (ptr i64)) (inttoptr v79)) + (let (v82 i64) (load v81)) + (let (v83 u32) (bitcast v68)) + (let (v84 u32) (add.checked v83 24)) + (let (v85 u32) (mod.unchecked v84 8)) + (assertz 250 v85) + (let (v86 (ptr i64)) (inttoptr v84)) + (let (v87 i64) (load v86)) + (call (#miden:basic-wallet/basic-wallet@1.0.0 #receive-asset) v72 v77 v82 v87) + (let (v88 i32) (const.i32 32)) + (let (v89 i32) (add.wrapping v68 v88)) + (let (v91 i1) (neq v89 v90)) + (let (v92 i32) (zext v91)) + (let (v93 i1) (neq v92 0)) + (condbr v93 (block 8 v89 v90 v95 v97 v103 v106 v111) (block 10))) + + (block 9 + (let (v94 i32) (const.i32 1049284)) + (let (v96 i32) (const.i32 8)) + (let (v98 i32) (const.i32 5)) + (let (v99 u32) (bitcast v98)) + (let (v100 i32) (shl.wrapping v97 v99)) + (call #::dealloc v94 v95 v96 v100) + (br (block 6 v103 v106 v111))) + + (block 10 + (br (block 9))) + ) + + (func (export #cabi_realloc_wit_bindgen_0_28_0) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i1) (neq v1 0)) + (condbr v5 (block 5) (block 6))) + + (block 1 (param v4 i32)) + + (block 2 + (unreachable)) + + (block 3 (param v21 i32) + (ret v21)) + + (block 4 (param v17 i32) + (let (v18 i1) (eq v17 0)) + (let (v19 i32) (zext v18)) + (let (v20 i1) (neq v19 0)) + (condbr v20 (block 2) (block 8))) + + (block 5 + (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) + (br (block 4 v16))) + + (block 6 + (let (v6 i1) (eq v3 0)) + (let (v7 i32) (zext v6)) + (let (v8 i1) (neq v7 0)) + (condbr v8 (block 3 v2) (block 7))) + + (block 7 + (let (v9 i32) (const.i32 0)) + (let (v10 u32) (bitcast v9)) + (let (v11 u32) (add.checked v10 1049288)) + (let (v12 (ptr u8)) (inttoptr v11)) + (let (v13 u8) (load v12)) + (let (v14 i32) (zext v13)) + (let (v15 i32) (call #__rust_alloc v3 v2)) + (br (block 4 v15))) + + (block 8 + (br (block 3 v17))) + ) + + (func (export #wit_bindgen_rt::run_ctors_once) + (block 0 + (let (v0 i32) (const.i32 0)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (add.checked v1 1049289)) + (let (v3 (ptr u8)) (inttoptr v2)) + (let (v4 u8) (load v3)) + (let (v5 i32) (zext v4)) + (let (v6 i1) (neq v5 0)) + (condbr v6 (block 2) (block 3))) + + (block 1 + (ret)) + + (block 2 + (br (block 1))) + + (block 3 + (call #__wasm_call_ctors) + (let (v7 i32) (const.i32 0)) + (let (v8 i32) (const.i32 1)) + (let (v9 u32) (bitcast v8)) + (let (v10 u8) (trunc v9)) + (let (v11 u32) (bitcast v7)) + (let (v12 u32) (add.checked v11 1049289)) + (let (v13 (ptr u8)) (inttoptr v12)) + (store v13 v10) + (br (block 2))) + ) + (func (export #wee_alloc::alloc_first_fit) (param i32) (param i32) (param i32) (result i32) (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (let (v4 i32) (const.i32 0)) - (let (v5 u32) (cast v2)) - (let (v6 u32) (mod.unchecked v5 2)) - (assertz v6) + (let (v5 u32) (bitcast v2)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) (let (v7 (ptr i32)) (inttoptr v5)) (let (v8 i32) (load v7)) - (let (v9 i1) (eq v8 0)) - (let (v10 i32) (zext v9)) - (let (v11 i1) (neq v10 0)) - (condbr v11 (block 2) (block 3))) + (let (v9 i1) (neq v8 0)) + (condbr v9 (block 2) (block 3))) (block 1 (param v3 i32) (ret v3)) (block 2 - (let (v330 i32) (const.i32 0)) - (br (block 1 v330))) + (let (v11 i32) (const.i32 -1)) + (let (v12 i32) (add.wrapping v1 v11)) + (let (v13 i32) (const.i32 0)) + (let (v14 i32) (sub.wrapping v13 v1)) + (let (v15 i32) (const.i32 2)) + (let (v16 u32) (bitcast v15)) + (let (v17 i32) (shl.wrapping v0 v16)) + (br (block 4 v8 v2 v17 v14 v12))) (block 3 - (let (v12 i32) (const.i32 -1)) - (let (v13 i32) (add.wrapping v1 v12)) - (let (v14 i32) (const.i32 0)) - (let (v15 i32) (sub.wrapping v14 v1)) - (let (v16 i32) (const.i32 2)) - (let (v17 u32) (bitcast v16)) - (let (v18 i32) (shl.wrapping v0 v17)) - (br (block 4 v8 v2 v18 v15 v13))) + (let (v10 i32) (const.i32 0)) + (ret v10)) (block 4 - (param v19 i32) - (param v160 i32) - (param v171 i32) - (param v185 i32) + (param v18 i32) + (param v169 i32) + (param v182 i32) (param v197 i32) - (let (v20 i32) (const.i32 8)) - (let (v21 i32) (add.wrapping v19 v20)) - (let (v22 u32) (cast v19)) - (let (v23 u32) (add.checked v22 8)) - (let (v24 u32) (mod.unchecked v23 2)) - (assertz v24) - (let (v25 (ptr i32)) (inttoptr v23)) - (let (v26 i32) (load v25)) - (let (v27 i32) (const.i32 1)) - (let (v28 i32) (band v26 v27)) - (let (v29 i1) (neq v28 0)) - (condbr v29 (block 7) (block 8))) + (param v210 i32) + (let (v19 u32) (bitcast v18)) + (let (v20 u32) (add.checked v19 8)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) + (let (v22 (ptr i32)) (inttoptr v20)) + (let (v23 i32) (load v22)) + (let (v24 i32) (const.i32 1)) + (let (v25 i32) (band v23 v24)) + (let (v26 i1) (neq v25 0)) + (condbr v26 (block 7) (block 8))) (block 5 - (br (block 2))) + (let (v344 i32) (const.i32 0)) + (br (block 1 v344))) (block 6 - (param v161 i32) - (param v168 i32) - (param v170 i32) - (param v184 i32) + (param v172 i32) + (param v179 i32) + (param v181 i32) (param v196 i32) - (param v204 i32) - (param v205 i32) - (let (v162 u32) (cast v161)) - (let (v163 u32) (mod.unchecked v162 2)) - (assertz v163) - (let (v164 (ptr i32)) (inttoptr v162)) - (let (v165 i32) (load v164)) - (let (v166 i32) (const.i32 -4)) - (let (v167 i32) (band v165 v166)) - (let (v169 i32) (sub.wrapping v167 v168)) - (let (v176 u32) (bitcast v169)) - (let (v177 u32) (bitcast v170)) - (let (v178 i1) (lt v176 v177)) - (let (v179 i32) (sext v178)) - (let (v180 i1) (neq v179 0)) - (condbr v180 (block 21 v204 v205 v170 v184 v196) (block 22))) + (param v209 i32) + (param v218 i32) + (param v219 i32) + (let (v173 u32) (bitcast v172)) + (let (v174 u32) (mod.unchecked v173 4)) + (assertz 250 v174) + (let (v175 (ptr i32)) (inttoptr v173)) + (let (v176 i32) (load v175)) + (let (v177 i32) (const.i32 -4)) + (let (v178 i32) (band v176 v177)) + (let (v180 i32) (sub.wrapping v178 v179)) + (let (v188 u32) (bitcast v180)) + (let (v189 u32) (bitcast v181)) + (let (v190 i1) (lt v188 v189)) + (let (v191 i32) (sext v190)) + (let (v192 i1) (neq v191 0)) + (condbr v192 (block 22 v218 v219 v181 v196 v209) (block 23))) (block 7 - (br (block 9 v21 v26 v19 v160 v171 v185 v197))) + (br (block 9 v18 v23 v169 v182 v197 v210))) (block 8 - (br (block 6 v19 v21 v171 v185 v197 v160 v26))) + (let (v27 i32) (const.i32 8)) + (let (v28 i32) (add.wrapping v18 v27)) + (br (block 6 v18 v28 v182 v197 v210 v169 v23))) (block 9 + (param v29 i32) (param v30 i32) - (param v31 i32) - (param v37 i32) - (param v144 i32) - (param v174 i32) - (param v188 i32) - (param v200 i32) - (let (v32 i32) (const.i32 -2)) - (let (v33 i32) (band v31 v32)) - (let (v34 u32) (cast v30)) - (let (v35 u32) (mod.unchecked v34 2)) - (assertz v35) + (param v156 i32) + (param v187 i32) + (param v202 i32) + (param v215 i32) + (let (v31 i32) (const.i32 -2)) + (let (v32 i32) (band v30 v31)) + (let (v33 u32) (bitcast v29)) + (let (v34 u32) (add.checked v33 8)) + (let (v35 u32) (mod.unchecked v34 4)) + (assertz 250 v35) (let (v36 (ptr i32)) (inttoptr v34)) - (store v36 v33) - (let (v38 u32) (cast v37)) - (let (v39 u32) (add.checked v38 4)) - (let (v40 u32) (mod.unchecked v39 2)) - (assertz v40) - (let (v41 (ptr i32)) (inttoptr v39)) - (let (v42 i32) (load v41)) - (let (v43 i32) (const.i32 -4)) - (let (v44 i32) (band v42 v43)) - (let (v45 u32) (cast v44)) - (let (v46 u32) (mod.unchecked v45 2)) - (assertz v46) - (let (v47 (ptr i32)) (inttoptr v45)) - (let (v48 i32) (load v47)) - (let (v49 u32) (cast v37)) - (let (v50 u32) (mod.unchecked v49 2)) - (assertz v50) - (let (v51 (ptr i32)) (inttoptr v49)) - (let (v52 i32) (load v51)) - (let (v53 i32) (const.i32 -4)) - (let (v54 i32) (band v52 v53)) - (let (v55 i1) (neq v54 0)) - (condbr v55 (block 13) (block 14))) + (store v36 v32) + (let (v37 u32) (bitcast v29)) + (let (v38 u32) (add.checked v37 4)) + (let (v39 u32) (mod.unchecked v38 4)) + (assertz 250 v39) + (let (v40 (ptr i32)) (inttoptr v38)) + (let (v41 i32) (load v40)) + (let (v42 i32) (const.i32 -4)) + (let (v43 i32) (band v41 v42)) + (let (v44 i1) (neq v43 0)) + (condbr v44 (block 12) (block 13))) (block 10 - (br (block 6 v146 v151 v172 v186 v198 v142 v156))) + (let (v170 i32) (const.i32 8)) + (let (v171 i32) (add.wrapping v157 v170)) + (br (block 6 v157 v171 v183 v198 v211 v152 v165))) (block 11 - (param v112 i32) - (param v113 i32) - (param v120 i32) - (param v131 i32) - (param v143 i32) - (param v173 i32) - (param v187 i32) - (param v199 i32) - (let (v114 i32) (const.i32 3)) - (let (v115 i32) (band v113 v114)) - (let (v116 u32) (cast v112)) - (let (v117 u32) (add.checked v116 4)) - (let (v118 u32) (mod.unchecked v117 2)) - (assertz v118) - (let (v119 (ptr i32)) (inttoptr v117)) - (store v119 v115) - (let (v121 i32) (const.i32 3)) - (let (v122 i32) (band v120 v121)) - (let (v123 u32) (cast v112)) - (let (v124 u32) (mod.unchecked v123 2)) - (assertz v124) - (let (v125 (ptr i32)) (inttoptr v123)) - (store v125 v122) - (let (v126 i32) (const.i32 2)) - (let (v127 i32) (band v120 v126)) - (let (v128 i1) (eq v127 0)) - (let (v129 i32) (zext v128)) - (let (v130 i1) (neq v129 0)) - (condbr v130 (block 18 v143 v131 v173 v187 v199) (block 19))) + (param v55 i32) + (param v75 i32) + (param v122 i32) + (param v142 i32) + (param v155 i32) + (param v186 i32) + (param v201 i32) + (param v214 i32) + (let (v56 u32) (bitcast v55)) + (let (v57 u32) (mod.unchecked v56 4)) + (assertz 250 v57) + (let (v58 (ptr i32)) (inttoptr v56)) + (let (v59 i32) (load v58)) + (let (v60 i32) (const.i32 -4)) + (let (v61 i32) (band v59 v60)) + (let (v62 i1) (eq v61 0)) + (let (v63 i32) (zext v62)) + (let (v64 i1) (neq v63 0)) + (condbr v64 (block 14 v75 v59 v55 v122 v142 v155 v186 v201 v214) (block 15))) (block 12 - (param v93 i32) - (param v94 i32) - (param v97 i32) - (param v102 i32) - (param v132 i32) - (param v145 i32) - (param v175 i32) - (param v189 i32) - (param v201 i32) - (let (v95 i32) (const.i32 3)) - (let (v96 i32) (band v94 v95)) - (let (v98 i32) (bor v96 v97)) - (let (v99 u32) (cast v93)) - (let (v100 u32) (mod.unchecked v99 2)) - (assertz v100) - (let (v101 (ptr i32)) (inttoptr v99)) - (store v101 v98) - (let (v103 u32) (cast v102)) - (let (v104 u32) (add.checked v103 4)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) - (let (v106 (ptr i32)) (inttoptr v104)) - (let (v107 i32) (load v106)) - (let (v108 u32) (cast v102)) - (let (v109 u32) (mod.unchecked v108 2)) - (assertz v109) - (let (v110 (ptr i32)) (inttoptr v108)) - (let (v111 i32) (load v110)) - (br (block 11 v102 v107 v111 v132 v145 v175 v189 v201))) + (let (v46 i32) (const.i32 0)) + (let (v47 u32) (bitcast v43)) + (let (v48 (ptr u8)) (inttoptr v47)) + (let (v49 u8) (load v48)) + (let (v50 i32) (zext v49)) + (let (v51 i32) (const.i32 1)) + (let (v52 i32) (band v50 v51)) + (let (v53 i1) (neq v52 0)) + (let (v54 i32) (select v53 v46 v43)) + (br (block 11 v29 v43 v41 v54 v156 v187 v202 v215))) (block 13 - (let (v56 i32) (const.i32 2)) - (let (v57 i32) (band v52 v56)) - (let (v58 i1) (eq v57 0)) - (let (v59 i32) (zext v58)) - (let (v60 i1) (neq v59 0)) - (condbr v60 (block 15) (block 16))) + (let (v45 i32) (const.i32 0)) + (br (block 11 v29 v43 v41 v45 v156 v187 v202 v215))) (block 14 - (br (block 12 v44 v48 v54 v37 v44 v144 v174 v188 v200))) + (param v92 i32) + (param v102 i32) + (param v109 i32) + (param v121 i32) + (param v141 i32) + (param v154 i32) + (param v185 i32) + (param v200 i32) + (param v213 i32) + (let (v93 i1) (eq v92 0)) + (let (v94 i32) (zext v93)) + (let (v95 i1) (neq v94 0)) + (condbr v95 (block 17 v109 v121 v102 v141 v154 v185 v200 v213) (block 18))) (block 15 - (let (v61 u32) (cast v54)) - (let (v62 u32) (add.checked v61 4)) - (let (v63 u32) (mod.unchecked v62 2)) - (assertz v63) - (let (v64 (ptr i32)) (inttoptr v62)) - (let (v65 i32) (load v64)) - (let (v66 i32) (const.i32 3)) - (let (v67 i32) (band v65 v66)) - (let (v68 i32) (bor v67 v44)) - (let (v69 u32) (cast v54)) - (let (v70 u32) (add.checked v69 4)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) - (let (v72 (ptr i32)) (inttoptr v70)) - (store v72 v68) - (let (v73 u32) (cast v37)) - (let (v74 u32) (mod.unchecked v73 2)) - (assertz v74) - (let (v75 (ptr i32)) (inttoptr v73)) - (let (v76 i32) (load v75)) - (let (v77 u32) (cast v37)) - (let (v78 u32) (add.checked v77 4)) - (let (v79 u32) (mod.unchecked v78 2)) - (assertz v79) - (let (v80 (ptr i32)) (inttoptr v78)) - (let (v81 i32) (load v80)) - (let (v82 i32) (const.i32 -4)) - (let (v83 i32) (band v81 v82)) - (let (v84 i1) (eq v83 0)) - (let (v85 i32) (zext v84)) - (let (v86 i1) (neq v85 0)) - (condbr v86 (block 11 v37 v81 v76 v44 v144 v174 v188 v200) (block 17))) + (let (v65 i32) (const.i32 2)) + (let (v66 i32) (band v59 v65)) + (let (v67 i1) (neq v66 0)) + (condbr v67 (block 14 v75 v59 v55 v122 v142 v155 v186 v201 v214) (block 16))) (block 16 - (br (block 12 v44 v48 v54 v37 v44 v144 v174 v188 v200))) + (let (v68 u32) (bitcast v61)) + (let (v69 u32) (add.checked v68 4)) + (let (v70 u32) (mod.unchecked v69 4)) + (assertz 250 v70) + (let (v71 (ptr i32)) (inttoptr v69)) + (let (v72 i32) (load v71)) + (let (v73 i32) (const.i32 3)) + (let (v74 i32) (band v72 v73)) + (let (v76 i32) (bor v74 v75)) + (let (v77 u32) (bitcast v61)) + (let (v78 u32) (add.checked v77 4)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) + (let (v80 (ptr i32)) (inttoptr v78)) + (store v80 v76) + (let (v81 u32) (bitcast v55)) + (let (v82 u32) (add.checked v81 4)) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) + (let (v84 (ptr i32)) (inttoptr v82)) + (let (v85 i32) (load v84)) + (let (v86 i32) (const.i32 -4)) + (let (v87 i32) (band v85 v86)) + (let (v88 u32) (bitcast v55)) + (let (v89 u32) (mod.unchecked v88 4)) + (assertz 250 v89) + (let (v90 (ptr i32)) (inttoptr v88)) + (let (v91 i32) (load v90)) + (br (block 14 v87 v91 v55 v85 v142 v155 v186 v201 v214))) (block 17 - (let (v87 i32) (const.i32 -4)) - (let (v88 i32) (band v76 v87)) - (let (v89 u32) (cast v83)) - (let (v90 u32) (mod.unchecked v89 2)) - (assertz v90) - (let (v91 (ptr i32)) (inttoptr v89)) - (let (v92 i32) (load v91)) - (br (block 12 v83 v92 v88 v37 v44 v144 v174 v188 v200))) + (param v119 i32) + (param v120 i32) + (param v129 i32) + (param v140 i32) + (param v153 i32) + (param v184 i32) + (param v199 i32) + (param v212 i32) + (let (v123 i32) (const.i32 3)) + (let (v124 i32) (band v120 v123)) + (let (v125 u32) (bitcast v119)) + (let (v126 u32) (add.checked v125 4)) + (let (v127 u32) (mod.unchecked v126 4)) + (assertz 250 v127) + (let (v128 (ptr i32)) (inttoptr v126)) + (store v128 v124) + (let (v130 i32) (const.i32 3)) + (let (v131 i32) (band v129 v130)) + (let (v132 u32) (bitcast v119)) + (let (v133 u32) (mod.unchecked v132 4)) + (assertz 250 v133) + (let (v134 (ptr i32)) (inttoptr v132)) + (store v134 v131) + (let (v135 i32) (const.i32 2)) + (let (v136 i32) (band v129 v135)) + (let (v137 i1) (eq v136 0)) + (let (v138 i32) (zext v137)) + (let (v139 i1) (neq v138 0)) + (condbr v139 (block 19 v153 v140 v184 v199 v212) (block 20))) (block 18 - (param v142 i32) - (param v146 i32) - (param v172 i32) - (param v186 i32) - (param v198 i32) - (let (v147 u32) (cast v142)) - (let (v148 u32) (mod.unchecked v147 2)) - (assertz v148) - (let (v149 (ptr i32)) (inttoptr v147)) - (store v149 v146) - (let (v150 i32) (const.i32 8)) - (let (v151 i32) (add.wrapping v146 v150)) - (let (v152 u32) (cast v146)) - (let (v153 u32) (add.checked v152 8)) - (let (v154 u32) (mod.unchecked v153 2)) - (assertz v154) - (let (v155 (ptr i32)) (inttoptr v153)) - (let (v156 i32) (load v155)) - (let (v157 i32) (const.i32 1)) - (let (v158 i32) (band v156 v157)) - (let (v159 i1) (neq v158 0)) - (condbr v159 (block 9 v151 v156 v146 v142 v172 v186 v198) (block 20))) + (let (v96 u32) (bitcast v92)) + (let (v97 u32) (mod.unchecked v96 4)) + (assertz 250 v97) + (let (v98 (ptr i32)) (inttoptr v96)) + (let (v99 i32) (load v98)) + (let (v100 i32) (const.i32 3)) + (let (v101 i32) (band v99 v100)) + (let (v103 i32) (const.i32 -4)) + (let (v104 i32) (band v102 v103)) + (let (v105 i32) (bor v101 v104)) + (let (v106 u32) (bitcast v92)) + (let (v107 u32) (mod.unchecked v106 4)) + (assertz 250 v107) + (let (v108 (ptr i32)) (inttoptr v106)) + (store v108 v105) + (let (v110 u32) (bitcast v109)) + (let (v111 u32) (add.checked v110 4)) + (let (v112 u32) (mod.unchecked v111 4)) + (assertz 250 v112) + (let (v113 (ptr i32)) (inttoptr v111)) + (let (v114 i32) (load v113)) + (let (v115 u32) (bitcast v109)) + (let (v116 u32) (mod.unchecked v115 4)) + (assertz 250 v116) + (let (v117 (ptr i32)) (inttoptr v115)) + (let (v118 i32) (load v117)) + (br (block 17 v109 v114 v118 v141 v154 v185 v200 v213))) (block 19 - (let (v133 u32) (cast v131)) - (let (v134 u32) (mod.unchecked v133 2)) - (assertz v134) - (let (v135 (ptr i32)) (inttoptr v133)) - (let (v136 i32) (load v135)) - (let (v137 i32) (const.i32 2)) - (let (v138 i32) (bor v136 v137)) - (let (v139 u32) (cast v131)) - (let (v140 u32) (mod.unchecked v139 2)) - (assertz v140) - (let (v141 (ptr i32)) (inttoptr v139)) - (store v141 v138) - (br (block 18 v143 v131 v173 v187 v199))) + (param v152 i32) + (param v157 i32) + (param v183 i32) + (param v198 i32) + (param v211 i32) + (let (v158 u32) (bitcast v152)) + (let (v159 u32) (mod.unchecked v158 4)) + (assertz 250 v159) + (let (v160 (ptr i32)) (inttoptr v158)) + (store v160 v157) + (let (v161 u32) (bitcast v157)) + (let (v162 u32) (add.checked v161 8)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) + (let (v164 (ptr i32)) (inttoptr v162)) + (let (v165 i32) (load v164)) + (let (v166 i32) (const.i32 1)) + (let (v167 i32) (band v165 v166)) + (let (v168 i1) (neq v167 0)) + (condbr v168 (block 9 v157 v165 v152 v183 v198 v211) (block 21))) (block 20 - (br (block 10))) + (let (v143 u32) (bitcast v140)) + (let (v144 u32) (mod.unchecked v143 4)) + (assertz 250 v144) + (let (v145 (ptr i32)) (inttoptr v143)) + (let (v146 i32) (load v145)) + (let (v147 i32) (const.i32 2)) + (let (v148 i32) (bor v146 v147)) + (let (v149 u32) (bitcast v140)) + (let (v150 u32) (mod.unchecked v149 4)) + (assertz 250 v150) + (let (v151 (ptr i32)) (inttoptr v149)) + (store v151 v148) + (br (block 19 v153 v140 v184 v199 v212))) (block 21 - (param v321 i32) - (param v322 i32) - (param v327 i32) - (param v328 i32) - (param v329 i32) - (let (v323 u32) (cast v321)) - (let (v324 u32) (mod.unchecked v323 2)) - (assertz v324) - (let (v325 (ptr i32)) (inttoptr v323)) - (store v325 v322) - (let (v326 i1) (neq v322 0)) - (condbr v326 (block 4 v322 v321 v327 v328 v329) (block 32))) + (br (block 10))) (block 22 - (let (v181 i32) (const.i32 72)) - (let (v182 i32) (add.wrapping v168 v181)) - (let (v183 i32) (sub.wrapping v167 v170)) - (let (v190 i32) (band v183 v184)) - (let (v191 u32) (bitcast v182)) - (let (v192 u32) (bitcast v190)) - (let (v193 i1) (lte v191 v192)) - (let (v194 i32) (sext v193)) - (let (v195 i1) (neq v194 0)) - (condbr v195 (block 24) (block 25))) - - (block 23 (param v312 i32) (param v313 i32) - (let (v314 i32) (const.i32 1)) - (let (v315 i32) (bor v313 v314)) - (let (v316 u32) (cast v312)) - (let (v317 u32) (mod.unchecked v316 2)) - (assertz v317) - (let (v318 (ptr i32)) (inttoptr v316)) - (store v318 v315) - (let (v319 i32) (const.i32 8)) - (let (v320 i32) (add.wrapping v312 v319)) - (ret v320)) + (param v335 i32) + (param v336 i32) + (param v341 i32) + (param v342 i32) + (param v343 i32) + (let (v337 u32) (bitcast v335)) + (let (v338 u32) (mod.unchecked v337 4)) + (assertz 250 v338) + (let (v339 (ptr i32)) (inttoptr v337)) + (store v339 v336) + (let (v340 i1) (neq v336 0)) + (condbr v340 (block 4 v336 v335 v341 v342 v343) (block 33))) - (block 24 - (let (v215 i32) (const.i32 0)) - (let (v216 i32) (const.i32 0)) - (let (v217 u32) (cast v190)) - (let (v218 u32) (mod.unchecked v217 2)) - (assertz v218) - (let (v219 (ptr i32)) (inttoptr v217)) - (store v219 v216) - (let (v220 i32) (const.i32 -8)) - (let (v221 i32) (add.wrapping v190 v220)) - (let (v222 i64) (const.i64 0)) - (let (v223 u32) (cast v221)) - (let (v224 u32) (mod.unchecked v223 2)) - (assertz v224) - (let (v225 (ptr i64)) (inttoptr v223)) - (store v225 v222) - (let (v226 u32) (cast v161)) - (let (v227 u32) (mod.unchecked v226 2)) - (assertz v227) - (let (v228 (ptr i32)) (inttoptr v226)) - (let (v229 i32) (load v228)) - (let (v230 i32) (const.i32 -4)) - (let (v231 i32) (band v229 v230)) - (let (v232 u32) (cast v221)) - (let (v233 u32) (mod.unchecked v232 2)) - (assertz v233) - (let (v234 (ptr i32)) (inttoptr v232)) - (store v234 v231) - (let (v235 u32) (cast v161)) - (let (v236 u32) (mod.unchecked v235 2)) - (assertz v236) - (let (v237 (ptr i32)) (inttoptr v235)) - (let (v238 i32) (load v237)) - (let (v239 i32) (const.i32 -4)) - (let (v240 i32) (band v238 v239)) - (let (v241 i1) (eq v240 0)) - (let (v242 i32) (zext v241)) - (let (v243 i1) (neq v242 0)) - (condbr v243 (block 27 v221 v215 v161 v168) (block 28))) + (block 23 + (let (v193 i32) (const.i32 72)) + (let (v194 i32) (add.wrapping v179 v193)) + (let (v195 i32) (sub.wrapping v178 v181)) + (let (v203 i32) (band v195 v196)) + (let (v204 u32) (bitcast v194)) + (let (v205 u32) (bitcast v203)) + (let (v206 i1) (lte v204 v205)) + (let (v207 i32) (sext v206)) + (let (v208 i1) (neq v207 0)) + (condbr v208 (block 25) (block 26))) + + (block 24 (param v326 i32) (param v327 i32) + (let (v328 i32) (const.i32 1)) + (let (v329 i32) (bor v327 v328)) + (let (v330 u32) (bitcast v326)) + (let (v331 u32) (mod.unchecked v330 4)) + (assertz 250 v331) + (let (v332 (ptr i32)) (inttoptr v330)) + (store v332 v329) + (let (v333 i32) (const.i32 8)) + (let (v334 i32) (add.wrapping v326 v333)) + (ret v334)) (block 25 - (let (v202 i32) (band v196 v168)) - (let (v203 i1) (neq v202 0)) - (condbr v203 (block 21 v204 v205 v170 v184 v196) (block 26))) + (let (v229 i32) (const.i32 0)) + (let (v230 i32) (const.i32 0)) + (let (v231 u32) (bitcast v203)) + (let (v232 u32) (mod.unchecked v231 4)) + (assertz 250 v232) + (let (v233 (ptr i32)) (inttoptr v231)) + (store v233 v230) + (let (v234 i32) (const.i32 -8)) + (let (v235 i32) (add.wrapping v203 v234)) + (let (v236 i64) (const.i64 0)) + (let (v237 u32) (bitcast v235)) + (let (v238 u32) (mod.unchecked v237 4)) + (assertz 250 v238) + (let (v239 (ptr i64)) (inttoptr v237)) + (store v239 v236) + (let (v240 u32) (bitcast v172)) + (let (v241 u32) (mod.unchecked v240 4)) + (assertz 250 v241) + (let (v242 (ptr i32)) (inttoptr v240)) + (let (v243 i32) (load v242)) + (let (v244 i32) (const.i32 -4)) + (let (v245 i32) (band v243 v244)) + (let (v246 u32) (bitcast v235)) + (let (v247 u32) (mod.unchecked v246 4)) + (assertz 250 v247) + (let (v248 (ptr i32)) (inttoptr v246)) + (store v248 v245) + (let (v249 u32) (bitcast v172)) + (let (v250 u32) (mod.unchecked v249 4)) + (assertz 250 v250) + (let (v251 (ptr i32)) (inttoptr v249)) + (let (v252 i32) (load v251)) + (let (v253 i32) (const.i32 -4)) + (let (v254 i32) (band v252 v253)) + (let (v255 i1) (eq v254 0)) + (let (v256 i32) (zext v255)) + (let (v257 i1) (neq v256 0)) + (condbr v257 (block 28 v235 v229 v172 v179) (block 29))) (block 26 - (let (v206 i32) (const.i32 -4)) - (let (v207 i32) (band v205 v206)) - (let (v208 u32) (cast v204)) - (let (v209 u32) (mod.unchecked v208 2)) - (assertz v209) - (let (v210 (ptr i32)) (inttoptr v208)) - (store v210 v207) - (let (v211 u32) (cast v161)) - (let (v212 u32) (mod.unchecked v211 2)) - (assertz v212) - (let (v213 (ptr i32)) (inttoptr v211)) - (let (v214 i32) (load v213)) - (br (block 23 v161 v214))) + (let (v216 i32) (band v209 v179)) + (let (v217 i1) (neq v216 0)) + (condbr v217 (block 22 v218 v219 v181 v196 v209) (block 27))) (block 27 - (param v266 i32) - (param v267 i32) - (param v268 i32) - (param v274 i32) - (let (v269 i32) (bor v267 v268)) - (let (v270 u32) (cast v266)) - (let (v271 u32) (add.checked v270 4)) - (let (v272 u32) (mod.unchecked v271 2)) - (assertz v272) - (let (v273 (ptr i32)) (inttoptr v271)) - (store v273 v269) - (let (v275 u32) (cast v274)) - (let (v276 u32) (mod.unchecked v275 2)) - (assertz v276) - (let (v277 (ptr i32)) (inttoptr v275)) - (let (v278 i32) (load v277)) - (let (v279 i32) (const.i32 -2)) - (let (v280 i32) (band v278 v279)) - (let (v281 u32) (cast v274)) - (let (v282 u32) (mod.unchecked v281 2)) - (assertz v282) - (let (v283 (ptr i32)) (inttoptr v281)) - (store v283 v280) - (let (v284 u32) (cast v268)) - (let (v285 u32) (mod.unchecked v284 2)) - (assertz v285) - (let (v286 (ptr i32)) (inttoptr v284)) - (let (v287 i32) (load v286)) - (let (v288 i32) (const.i32 3)) - (let (v289 i32) (band v287 v288)) - (let (v290 i32) (bor v289 v266)) - (let (v291 u32) (cast v268)) - (let (v292 u32) (mod.unchecked v291 2)) - (assertz v292) - (let (v293 (ptr i32)) (inttoptr v291)) - (store v293 v290) - (let (v294 i32) (const.i32 2)) - (let (v295 i32) (band v287 v294)) - (let (v296 i1) (neq v295 0)) - (condbr v296 (block 30) (block 31))) + (let (v220 i32) (const.i32 -4)) + (let (v221 i32) (band v219 v220)) + (let (v222 u32) (bitcast v218)) + (let (v223 u32) (mod.unchecked v222 4)) + (assertz 250 v223) + (let (v224 (ptr i32)) (inttoptr v222)) + (store v224 v221) + (let (v225 u32) (bitcast v172)) + (let (v226 u32) (mod.unchecked v225 4)) + (assertz 250 v226) + (let (v227 (ptr i32)) (inttoptr v225)) + (let (v228 i32) (load v227)) + (br (block 24 v172 v228))) (block 28 - (let (v244 i32) (const.i32 2)) - (let (v245 i32) (band v238 v244)) - (let (v246 i1) (neq v245 0)) - (condbr v246 (block 27 v221 v215 v161 v168) (block 29))) + (param v280 i32) + (param v281 i32) + (param v282 i32) + (param v288 i32) + (let (v283 i32) (bor v281 v282)) + (let (v284 u32) (bitcast v280)) + (let (v285 u32) (add.checked v284 4)) + (let (v286 u32) (mod.unchecked v285 4)) + (assertz 250 v286) + (let (v287 (ptr i32)) (inttoptr v285)) + (store v287 v283) + (let (v289 u32) (bitcast v288)) + (let (v290 u32) (mod.unchecked v289 4)) + (assertz 250 v290) + (let (v291 (ptr i32)) (inttoptr v289)) + (let (v292 i32) (load v291)) + (let (v293 i32) (const.i32 -2)) + (let (v294 i32) (band v292 v293)) + (let (v295 u32) (bitcast v288)) + (let (v296 u32) (mod.unchecked v295 4)) + (assertz 250 v296) + (let (v297 (ptr i32)) (inttoptr v295)) + (store v297 v294) + (let (v298 u32) (bitcast v282)) + (let (v299 u32) (mod.unchecked v298 4)) + (assertz 250 v299) + (let (v300 (ptr i32)) (inttoptr v298)) + (let (v301 i32) (load v300)) + (let (v302 i32) (const.i32 3)) + (let (v303 i32) (band v301 v302)) + (let (v304 i32) (bor v303 v280)) + (let (v305 u32) (bitcast v282)) + (let (v306 u32) (mod.unchecked v305 4)) + (assertz 250 v306) + (let (v307 (ptr i32)) (inttoptr v305)) + (store v307 v304) + (let (v308 i32) (const.i32 2)) + (let (v309 i32) (band v301 v308)) + (let (v310 i1) (neq v309 0)) + (condbr v310 (block 31) (block 32))) (block 29 - (let (v247 u32) (cast v240)) - (let (v248 u32) (add.checked v247 4)) - (let (v249 u32) (mod.unchecked v248 2)) - (assertz v249) - (let (v250 (ptr i32)) (inttoptr v248)) - (let (v251 i32) (load v250)) - (let (v252 i32) (const.i32 3)) - (let (v253 i32) (band v251 v252)) - (let (v254 i32) (bor v253 v221)) - (let (v255 u32) (cast v240)) - (let (v256 u32) (add.checked v255 4)) - (let (v257 u32) (mod.unchecked v256 2)) - (assertz v257) - (let (v258 (ptr i32)) (inttoptr v256)) - (store v258 v254) - (let (v259 u32) (cast v221)) - (let (v260 u32) (add.checked v259 4)) - (let (v261 u32) (mod.unchecked v260 2)) - (assertz v261) - (let (v262 (ptr i32)) (inttoptr v260)) - (let (v263 i32) (load v262)) - (let (v264 i32) (const.i32 3)) - (let (v265 i32) (band v263 v264)) - (br (block 27 v221 v265 v161 v168))) + (let (v258 i32) (const.i32 2)) + (let (v259 i32) (band v252 v258)) + (let (v260 i1) (neq v259 0)) + (condbr v260 (block 28 v235 v229 v172 v179) (block 30))) (block 30 - (let (v301 i32) (const.i32 -3)) - (let (v302 i32) (band v290 v301)) - (let (v303 u32) (cast v268)) - (let (v304 u32) (mod.unchecked v303 2)) - (assertz v304) - (let (v305 (ptr i32)) (inttoptr v303)) - (store v305 v302) - (let (v306 u32) (cast v266)) - (let (v307 u32) (mod.unchecked v306 2)) - (assertz v307) - (let (v308 (ptr i32)) (inttoptr v306)) - (let (v309 i32) (load v308)) - (let (v310 i32) (const.i32 2)) - (let (v311 i32) (bor v309 v310)) - (br (block 23 v266 v311))) + (let (v261 u32) (bitcast v254)) + (let (v262 u32) (add.checked v261 4)) + (let (v263 u32) (mod.unchecked v262 4)) + (assertz 250 v263) + (let (v264 (ptr i32)) (inttoptr v262)) + (let (v265 i32) (load v264)) + (let (v266 i32) (const.i32 3)) + (let (v267 i32) (band v265 v266)) + (let (v268 i32) (bor v267 v235)) + (let (v269 u32) (bitcast v254)) + (let (v270 u32) (add.checked v269 4)) + (let (v271 u32) (mod.unchecked v270 4)) + (assertz 250 v271) + (let (v272 (ptr i32)) (inttoptr v270)) + (store v272 v268) + (let (v273 u32) (bitcast v235)) + (let (v274 u32) (add.checked v273 4)) + (let (v275 u32) (mod.unchecked v274 4)) + (assertz 250 v275) + (let (v276 (ptr i32)) (inttoptr v274)) + (let (v277 i32) (load v276)) + (let (v278 i32) (const.i32 3)) + (let (v279 i32) (band v277 v278)) + (br (block 28 v235 v279 v172 v179))) (block 31 - (let (v297 u32) (cast v266)) - (let (v298 u32) (mod.unchecked v297 2)) - (assertz v298) - (let (v299 (ptr i32)) (inttoptr v297)) - (let (v300 i32) (load v299)) - (br (block 23 v266 v300))) + (let (v315 i32) (const.i32 -3)) + (let (v316 i32) (band v304 v315)) + (let (v317 u32) (bitcast v282)) + (let (v318 u32) (mod.unchecked v317 4)) + (assertz 250 v318) + (let (v319 (ptr i32)) (inttoptr v317)) + (store v319 v316) + (let (v320 u32) (bitcast v280)) + (let (v321 u32) (mod.unchecked v320 4)) + (assertz 250 v321) + (let (v322 (ptr i32)) (inttoptr v320)) + (let (v323 i32) (load v322)) + (let (v324 i32) (const.i32 2)) + (let (v325 i32) (bor v323 v324)) + (br (block 24 v280 v325))) (block 32 + (let (v311 u32) (bitcast v280)) + (let (v312 u32) (mod.unchecked v311 4)) + (assertz 250 v312) + (let (v313 (ptr i32)) (inttoptr v311)) + (let (v314 i32) (load v313)) + (br (block 24 v280 v314))) + + (block 33 (br (block 5))) ) @@ -739,15 +1048,15 @@ (br (block 1 v102))) (block 3 - (let (v10 u32) (cast v0)) - (let (v11 u32) (mod.unchecked v10 2)) - (assertz v11) + (let (v10 u32) (bitcast v0)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) (let (v12 (ptr i32)) (inttoptr v10)) (let (v13 i32) (load v12)) - (let (v14 u32) (cast v7)) + (let (v14 u32) (bitcast v7)) (let (v15 u32) (add.checked v14 12)) - (let (v16 u32) (mod.unchecked v15 2)) - (assertz v16) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) (let (v17 (ptr i32)) (inttoptr v15)) (store v17 v13) (let (v18 i32) (const.i32 3)) @@ -767,15 +1076,15 @@ (br (block 2 v7 v1))) (block 5 (param v88 i32) (param v89 i32) (param v103 i32) - (let (v90 u32) (cast v89)) + (let (v90 u32) (bitcast v89)) (let (v91 u32) (add.checked v90 12)) - (let (v92 u32) (mod.unchecked v91 2)) - (assertz v92) + (let (v92 u32) (mod.unchecked v91 4)) + (assertz 250 v92) (let (v93 (ptr i32)) (inttoptr v91)) (let (v94 i32) (load v93)) - (let (v95 u32) (cast v88)) - (let (v96 u32) (mod.unchecked v95 2)) - (assertz v96) + (let (v95 u32) (bitcast v88)) + (let (v96 u32) (mod.unchecked v95 4)) + (assertz 250 v96) (let (v97 (ptr i32)) (inttoptr v95)) (store v97 v94) (br (block 2 v89 v103))) @@ -801,7 +1110,7 @@ (let (v46 u32) (bitcast v44)) (let (v47 u32) (shr.wrapping v45 v46)) (let (v48 i32) (bitcast v47)) - (let (v49 u32) (cast v48)) + (let (v49 u32) (bitcast v48)) (let (v50 i32) (memory.grow v49)) (let (v51 i32) (const.i32 -1)) (let (v52 i1) (neq v50 v51)) @@ -814,22 +1123,22 @@ (let (v57 u32) (bitcast v56)) (let (v58 i32) (shl.wrapping v50 v57)) (let (v59 i32) (const.i32 0)) - (let (v60 u32) (cast v58)) + (let (v60 u32) (bitcast v58)) (let (v61 u32) (add.checked v60 4)) - (let (v62 u32) (mod.unchecked v61 2)) - (assertz v62) + (let (v62 u32) (mod.unchecked v61 4)) + (assertz 250 v62) (let (v63 (ptr i32)) (inttoptr v61)) (store v63 v59) - (let (v64 u32) (cast v7)) + (let (v64 u32) (bitcast v7)) (let (v65 u32) (add.checked v64 12)) - (let (v66 u32) (mod.unchecked v65 2)) - (assertz v66) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) (let (v67 (ptr i32)) (inttoptr v65)) (let (v68 i32) (load v67)) - (let (v69 u32) (cast v58)) + (let (v69 u32) (bitcast v58)) (let (v70 u32) (add.checked v69 8)) - (let (v71 u32) (mod.unchecked v70 2)) - (assertz v71) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) (let (v72 (ptr i32)) (inttoptr v70)) (store v72 v68) (let (v73 i32) (const.i32 -65536)) @@ -837,15 +1146,15 @@ (let (v75 i32) (add.wrapping v58 v74)) (let (v76 i32) (const.i32 2)) (let (v77 i32) (bor v75 v76)) - (let (v78 u32) (cast v58)) - (let (v79 u32) (mod.unchecked v78 2)) - (assertz v79) + (let (v78 u32) (bitcast v58)) + (let (v79 u32) (mod.unchecked v78 4)) + (assertz 250 v79) (let (v80 (ptr i32)) (inttoptr v78)) (store v80 v77) - (let (v81 u32) (cast v7)) + (let (v81 u32) (bitcast v7)) (let (v82 u32) (add.checked v81 12)) - (let (v83 u32) (mod.unchecked v82 2)) - (assertz v83) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) (let (v84 (ptr i32)) (inttoptr v82)) (store v84 v58) (let (v85 i32) (const.i32 12)) @@ -880,36 +1189,36 @@ (condbr v10 (block 2) (block 4))) (block 4 - (let (v11 u32) (cast v0)) - (let (v12 u32) (mod.unchecked v11 2)) - (assertz v12) + (let (v11 u32) (bitcast v0)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) (let (v13 (ptr i32)) (inttoptr v11)) (let (v14 i32) (load v13)) (let (v15 i32) (const.i32 0)) - (let (v16 u32) (cast v1)) - (let (v17 u32) (mod.unchecked v16 2)) - (assertz v17) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) (let (v18 (ptr i32)) (inttoptr v16)) (store v18 v15) (let (v19 i32) (const.i32 -8)) (let (v20 i32) (add.wrapping v1 v19)) - (let (v21 u32) (cast v20)) - (let (v22 u32) (mod.unchecked v21 2)) - (assertz v22) + (let (v21 u32) (bitcast v20)) + (let (v22 u32) (mod.unchecked v21 4)) + (assertz 250 v22) (let (v23 (ptr i32)) (inttoptr v21)) (let (v24 i32) (load v23)) (let (v25 i32) (const.i32 -2)) (let (v26 i32) (band v24 v25)) - (let (v27 u32) (cast v20)) - (let (v28 u32) (mod.unchecked v27 2)) - (assertz v28) + (let (v27 u32) (bitcast v20)) + (let (v28 u32) (mod.unchecked v27 4)) + (assertz 250 v28) (let (v29 (ptr i32)) (inttoptr v27)) (store v29 v26) (let (v30 i32) (const.i32 4)) (let (v31 i32) (add.wrapping v20 v30)) - (let (v32 u32) (cast v31)) - (let (v33 u32) (mod.unchecked v32 2)) - (assertz v33) + (let (v32 u32) (bitcast v31)) + (let (v33 u32) (mod.unchecked v32 4)) + (assertz 250 v33) (let (v34 (ptr i32)) (inttoptr v32)) (let (v35 i32) (load v34)) (let (v36 i32) (const.i32 -4)) @@ -920,9 +1229,9 @@ (condbr v40 (block 10 v24 v1 v20 v14 v0) (block 11))) (block 5 (param v181 i32) (param v187 i32) - (let (v189 u32) (cast v181)) - (let (v190 u32) (mod.unchecked v189 2)) - (assertz v190) + (let (v189 u32) (bitcast v181)) + (let (v190 u32) (mod.unchecked v189 4)) + (assertz 250 v190) (let (v191 (ptr i32)) (inttoptr v189)) (store v191 v187) (br (block 2))) @@ -932,9 +1241,9 @@ (param v177 i32) (param v186 i32) (param v188 i32) - (let (v178 u32) (cast v176)) - (let (v179 u32) (mod.unchecked v178 2)) - (assertz v179) + (let (v178 u32) (bitcast v176)) + (let (v179 u32) (mod.unchecked v178 4)) + (assertz 250 v179) (let (v180 (ptr i32)) (inttoptr v178)) (store v180 v177) (br (block 5 v186 v188))) @@ -943,7 +1252,7 @@ (br (block 5 v182 v172))) (block 8 - (let (v147 u32) (cast v52)) + (let (v147 u32) (bitcast v52)) (let (v148 (ptr u8)) (inttoptr v147)) (let (v149 u8) (load v148)) (let (v150 i32) (zext v149)) @@ -972,9 +1281,9 @@ (condbr v55 (block 6 v154 v175 v185 v165) (block 13))) (block 11 - (let (v41 u32) (cast v37)) - (let (v42 u32) (mod.unchecked v41 2)) - (assertz v42) + (let (v41 u32) (bitcast v37)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) (let (v43 (ptr i32)) (inttoptr v41)) (let (v44 i32) (load v43)) (let (v45 i32) (const.i32 1)) @@ -1008,16 +1317,16 @@ (param v183 i32) (let (v119 i32) (const.i32 3)) (let (v120 i32) (band v118 v119)) - (let (v121 u32) (cast v117)) - (let (v122 u32) (mod.unchecked v121 2)) - (assertz v122) + (let (v121 u32) (bitcast v117)) + (let (v122 u32) (mod.unchecked v121 4)) + (assertz 250 v122) (let (v123 (ptr i32)) (inttoptr v121)) (store v123 v120) (let (v126 i32) (const.i32 3)) (let (v127 i32) (band v125 v126)) - (let (v128 u32) (cast v124)) - (let (v129 u32) (mod.unchecked v128 2)) - (assertz v129) + (let (v128 u32) (bitcast v124)) + (let (v129 u32) (mod.unchecked v128 4)) + (assertz 250 v129) (let (v130 (ptr i32)) (inttoptr v128)) (store v130 v127) (let (v131 i32) (const.i32 2)) @@ -1041,19 +1350,19 @@ (let (v101 i32) (const.i32 3)) (let (v102 i32) (band v100 v101)) (let (v103 i32) (bor v99 v102)) - (let (v104 u32) (cast v96)) - (let (v105 u32) (mod.unchecked v104 2)) - (assertz v105) + (let (v104 u32) (bitcast v96)) + (let (v105 u32) (mod.unchecked v104 4)) + (assertz 250 v105) (let (v106 (ptr i32)) (inttoptr v104)) (store v106 v103) - (let (v108 u32) (cast v107)) - (let (v109 u32) (mod.unchecked v108 2)) - (assertz v109) + (let (v108 u32) (bitcast v107)) + (let (v109 u32) (mod.unchecked v108 4)) + (assertz 250 v109) (let (v110 (ptr i32)) (inttoptr v108)) (let (v111 i32) (load v110)) - (let (v113 u32) (cast v112)) - (let (v114 u32) (mod.unchecked v113 2)) - (assertz v114) + (let (v113 u32) (bitcast v112)) + (let (v114 u32) (mod.unchecked v113 4)) + (assertz 250 v114) (let (v115 (ptr i32)) (inttoptr v113)) (let (v116 i32) (load v115)) (br (block 15 v107 v111 v112 v116 v137 v174 v184))) @@ -1068,29 +1377,29 @@ (br (block 16 v37 v26 v44 v31 v20 v37 v14 v0))) (block 19 - (let (v67 u32) (cast v62)) + (let (v67 u32) (bitcast v62)) (let (v68 u32) (add.checked v67 4)) - (let (v69 u32) (mod.unchecked v68 2)) - (assertz v69) + (let (v69 u32) (mod.unchecked v68 4)) + (assertz 250 v69) (let (v70 (ptr i32)) (inttoptr v68)) (let (v71 i32) (load v70)) (let (v72 i32) (const.i32 3)) (let (v73 i32) (band v71 v72)) (let (v74 i32) (bor v73 v37)) - (let (v75 u32) (cast v62)) + (let (v75 u32) (bitcast v62)) (let (v76 u32) (add.checked v75 4)) - (let (v77 u32) (mod.unchecked v76 2)) - (assertz v77) + (let (v77 u32) (mod.unchecked v76 4)) + (assertz 250 v77) (let (v78 (ptr i32)) (inttoptr v76)) (store v78 v74) - (let (v79 u32) (cast v20)) - (let (v80 u32) (mod.unchecked v79 2)) - (assertz v80) + (let (v79 u32) (bitcast v20)) + (let (v80 u32) (mod.unchecked v79 4)) + (assertz 250 v80) (let (v81 (ptr i32)) (inttoptr v79)) (let (v82 i32) (load v81)) - (let (v83 u32) (cast v31)) - (let (v84 u32) (mod.unchecked v83 2)) - (assertz v84) + (let (v83 u32) (bitcast v31)) + (let (v84 u32) (mod.unchecked v83 4)) + (assertz 250 v84) (let (v85 (ptr i32)) (inttoptr v83)) (let (v86 i32) (load v85)) (let (v87 i32) (const.i32 -4)) @@ -1101,120 +1410,4974 @@ (condbr v91 (block 15 v31 v86 v20 v82 v37 v14 v0) (block 20))) (block 20 - (let (v92 u32) (cast v88)) - (let (v93 u32) (mod.unchecked v92 2)) - (assertz v93) + (let (v92 u32) (bitcast v88)) + (let (v93 u32) (mod.unchecked v92 4)) + (assertz 250 v93) (let (v94 (ptr i32)) (inttoptr v92)) (let (v95 i32) (load v94)) (br (block 16 v88 v82 v95 v31 v20 v37 v14 v0))) (block 21 - (let (v138 u32) (cast v136)) - (let (v139 u32) (mod.unchecked v138 2)) - (assertz v139) + (let (v138 u32) (bitcast v136)) + (let (v139 u32) (mod.unchecked v138 4)) + (assertz 250 v139) (let (v140 (ptr i32)) (inttoptr v138)) (let (v141 i32) (load v140)) (let (v142 i32) (const.i32 2)) (let (v143 i32) (bor v141 v142)) - (let (v144 u32) (cast v136)) - (let (v145 u32) (mod.unchecked v144 2)) - (assertz v145) + (let (v144 u32) (bitcast v136)) + (let (v145 u32) (mod.unchecked v144 4)) + (assertz 250 v145) (let (v146 (ptr i32)) (inttoptr v144)) (store v146 v143) (br (block 7 v173 v183))) (block 22 - (let (v155 u32) (cast v52)) + (let (v155 u32) (bitcast v52)) (let (v156 u32) (add.checked v155 8)) - (let (v157 u32) (mod.unchecked v156 2)) - (assertz v157) + (let (v157 u32) (mod.unchecked v156 4)) + (assertz 250 v157) (let (v158 (ptr i32)) (inttoptr v156)) (let (v159 i32) (load v158)) (let (v160 i32) (const.i32 -4)) (let (v161 i32) (band v159 v160)) - (let (v162 u32) (cast v154)) - (let (v163 u32) (mod.unchecked v162 2)) - (assertz v163) + (let (v162 u32) (bitcast v154)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) (let (v164 (ptr i32)) (inttoptr v162)) (store v164 v161) (let (v166 i32) (const.i32 1)) (let (v167 i32) (bor v165 v166)) - (let (v168 u32) (cast v52)) + (let (v168 u32) (bitcast v52)) (let (v169 u32) (add.checked v168 8)) - (let (v170 u32) (mod.unchecked v169 2)) - (assertz v170) + (let (v170 u32) (mod.unchecked v169 4)) + (assertz 250 v170) (let (v171 (ptr i32)) (inttoptr v169)) (store v171 v167) (br (block 7 v175 v185))) ) - (func (export #wit_bindgen::rt::run_ctors_once) - (block 0 - (let (v0 i32) (const.i32 0)) - (let (v1 u32) (cast v0)) - (let (v2 u32) (add.checked v1 1048581)) - (let (v3 (ptr u8)) (inttoptr v2)) - (let (v4 u8) (load v3)) - (let (v5 i32) (zext v4)) - (let (v6 i1) (neq v5 0)) - (condbr v6 (block 2) (block 3))) + (func (export #core::ptr::drop_in_place) + (param i32) + (block 0 (param v0 i32) + (br (block 1))) (block 1 (ret)) + ) - (block 2 + (func (export #core::ptr::drop_in_place) + (param i32) + (block 0 (param v0 i32) (br (block 1))) - (block 3 - (call #__wasm_call_ctors) - (let (v7 i32) (const.i32 0)) - (let (v8 i32) (const.i32 1)) - (let (v9 u8) (trunc v8)) - (let (v10 u32) (cast v7)) - (let (v11 u32) (add.checked v10 1048581)) - (let (v12 (ptr u8)) (inttoptr v11)) - (store v12 v9) - (br (block 2))) + (block 1 + (ret)) ) - (func (export #cabi_realloc) - (param i32) (param i32) (param i32) (param i32) (result i32) - (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) - (let (v5 i1) (neq v1 0)) - (condbr v5 (block 4) (block 5))) + (func (export #core::panicking::panic_fmt) + (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v2 i32) (const.i32 0)) + (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v4 i32) (const.i32 32)) + (let (v5 i32) (sub.wrapping v3 v4)) + (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) + (store v6 v5) + (let (v7 i32) (const.i32 1)) + (let (v8 u32) (bitcast v7)) + (let (v9 u16) (trunc v8)) + (let (v10 u32) (bitcast v5)) + (let (v11 u32) (add.checked v10 28)) + (let (v12 u32) (mod.unchecked v11 2)) + (assertz 250 v12) + (let (v13 (ptr u16)) (inttoptr v11)) + (store v13 v9) + (let (v14 u32) (bitcast v5)) + (let (v15 u32) (add.checked v14 24)) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) + (let (v17 (ptr i32)) (inttoptr v15)) + (store v17 v1) + (let (v18 u32) (bitcast v5)) + (let (v19 u32) (add.checked v18 20)) + (let (v20 u32) (mod.unchecked v19 4)) + (assertz 250 v20) + (let (v21 (ptr i32)) (inttoptr v19)) + (store v21 v0) + (let (v22 i32) (const.i32 1048696)) + (let (v23 u32) (bitcast v5)) + (let (v24 u32) (add.checked v23 16)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) + (let (v26 (ptr i32)) (inttoptr v24)) + (store v26 v22) + (let (v27 i32) (const.i32 1)) + (let (v28 u32) (bitcast v5)) + (let (v29 u32) (add.checked v28 12)) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) + (let (v31 (ptr i32)) (inttoptr v29)) + (store v31 v27) + (let (v32 i32) (const.i32 12)) + (let (v33 i32) (add.wrapping v5 v32)) + (call #rust_begin_unwind v33) + (unreachable)) - (block 1 (param v4 i32) - (ret v4)) + (block 1) + ) - (block 2 (param v19 i32) - (br (block 1 v19))) + (func (export #core::slice::index::slice_start_index_len_fail) + (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (call #core::slice::index::slice_start_index_len_fail_rt v0 v1 v2) + (unreachable)) - (block 3 (param v17 i32) - (let (v18 i1) (neq v17 0)) - (condbr v18 (block 2 v17) (block 7))) + (block 1) + ) + + (func (export #core::panicking::panic_bounds_check) + (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i64) (const.i64 0)) + (let (v5 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v6 i32) (const.i32 48)) + (let (v7 i32) (sub.wrapping v5 v6)) + (let (v8 (ptr i32)) (global.symbol #__stack_pointer)) + (store v8 v7) + (let (v9 u32) (bitcast v7)) + (let (v10 u32) (add.checked v9 4)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) + (let (v12 (ptr i32)) (inttoptr v10)) + (store v12 v1) + (let (v13 u32) (bitcast v7)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) + (let (v15 (ptr i32)) (inttoptr v13)) + (store v15 v0) + (let (v16 i32) (const.i32 2)) + (let (v17 u32) (bitcast v7)) + (let (v18 u32) (add.checked v17 12)) + (let (v19 u32) (mod.unchecked v18 4)) + (assertz 250 v19) + (let (v20 (ptr i32)) (inttoptr v18)) + (store v20 v16) + (let (v21 i32) (const.i32 1048764)) + (let (v22 u32) (bitcast v7)) + (let (v23 u32) (add.checked v22 8)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) + (let (v25 (ptr i32)) (inttoptr v23)) + (store v25 v21) + (let (v26 i64) (const.i64 2)) + (let (v27 u32) (bitcast v7)) + (let (v28 u32) (add.checked v27 20)) + (let (v29 u32) (mod.unchecked v28 4)) + (assertz 250 v29) + (let (v30 (ptr i64)) (inttoptr v28)) + (store v30 v26) + (let (v31 i32) (const.i32 7)) + (let (v32 u32) (bitcast v31)) + (let (v33 u64) (zext v32)) + (let (v34 i64) (bitcast v33)) + (let (v35 i64) (const.i64 32)) + (let (v36 u32) (cast v35)) + (let (v37 i64) (shl.wrapping v34 v36)) + (let (v38 u32) (bitcast v7)) + (let (v39 u64) (zext v38)) + (let (v40 i64) (bitcast v39)) + (let (v41 i64) (bor v37 v40)) + (let (v42 u32) (bitcast v7)) + (let (v43 u32) (add.checked v42 40)) + (let (v44 u32) (mod.unchecked v43 8)) + (assertz 250 v44) + (let (v45 (ptr i64)) (inttoptr v43)) + (store v45 v41) + (let (v46 i32) (const.i32 4)) + (let (v47 i32) (add.wrapping v7 v46)) + (let (v48 u32) (bitcast v47)) + (let (v49 u64) (zext v48)) + (let (v50 i64) (bitcast v49)) + (let (v51 i64) (bor v37 v50)) + (let (v52 u32) (bitcast v7)) + (let (v53 u32) (add.checked v52 32)) + (let (v54 u32) (mod.unchecked v53 8)) + (assertz 250 v54) + (let (v55 (ptr i64)) (inttoptr v53)) + (store v55 v51) + (let (v56 i32) (const.i32 32)) + (let (v57 i32) (add.wrapping v7 v56)) + (let (v58 u32) (bitcast v7)) + (let (v59 u32) (add.checked v58 16)) + (let (v60 u32) (mod.unchecked v59 4)) + (assertz 250 v60) + (let (v61 (ptr i32)) (inttoptr v59)) + (store v61 v57) + (let (v62 i32) (const.i32 8)) + (let (v63 i32) (add.wrapping v7 v62)) + (call #core::panicking::panic_fmt v63 v2) + (unreachable)) + + (block 1) + ) + + (func (export #core::fmt::Formatter::pad) + (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v4 i32) (const.i32 0)) + (let (v5 u32) (bitcast v0)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) + (let (v7 (ptr i32)) (inttoptr v5)) + (let (v8 i32) (load v7)) + (let (v9 u32) (bitcast v0)) + (let (v10 u32) (add.checked v9 8)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) + (let (v12 (ptr i32)) (inttoptr v10)) + (let (v13 i32) (load v12)) + (let (v14 i32) (bor v8 v13)) + (let (v15 i1) (eq v14 0)) + (let (v16 i32) (zext v15)) + (let (v17 i1) (neq v16 0)) + (condbr v17 (block 2) (block 3))) + + (block 1 (param v3 i32) + (ret v3)) + + (block 2 + (let (v479 u32) (bitcast v0)) + (let (v480 u32) (add.checked v479 20)) + (let (v481 u32) (mod.unchecked v480 4)) + (assertz 250 v481) + (let (v482 (ptr i32)) (inttoptr v480)) + (let (v483 i32) (load v482)) + (let (v484 u32) (bitcast v0)) + (let (v485 u32) (add.checked v484 24)) + (let (v486 u32) (mod.unchecked v485 4)) + (assertz 250 v486) + (let (v487 (ptr i32)) (inttoptr v485)) + (let (v488 i32) (load v487)) + (let (v489 u32) (bitcast v488)) + (let (v490 u32) (add.checked v489 12)) + (let (v491 u32) (mod.unchecked v490 4)) + (assertz 250 v491) + (let (v492 (ptr i32)) (inttoptr v490)) + (let (v493 i32) (load v492)) + (br (block 1 v493))) + + (block 3 + (let (v18 i1) (eq v13 0)) + (let (v19 i32) (zext v18)) + (let (v20 i1) (neq v19 0)) + (condbr v20 (block 4 v8 v0 v1 v2) (block 5))) (block 4 - (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) - (br (block 3 v16))) + (param v213 i32) + (param v220 i32) + (param v231 i32) + (param v233 i32) + (let (v219 i1) (neq v213 0)) + (condbr v219 (block 33) (block 34))) (block 5 - (let (v6 i1) (eq v3 0)) - (let (v7 i32) (zext v6)) - (let (v8 i1) (neq v7 0)) - (condbr v8 (block 2 v2) (block 6))) + (let (v21 i32) (add.wrapping v1 v2)) + (let (v22 u32) (bitcast v0)) + (let (v23 u32) (add.checked v22 12)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) + (let (v25 (ptr i32)) (inttoptr v23)) + (let (v26 i32) (load v25)) + (let (v27 i1) (neq v26 0)) + (condbr v27 (block 7) (block 8))) (block 6 - (let (v9 i32) (const.i32 0)) - (let (v10 u32) (cast v9)) - (let (v11 u32) (add.checked v10 1048580)) - (let (v12 (ptr u8)) (inttoptr v11)) - (let (v13 u8) (load v12)) - (let (v14 i32) (zext v13)) - (let (v15 i32) (call #__rust_alloc v3 v2)) - (br (block 3 v15))) + (param v116 i32) + (param v117 i32) + (param v183 i32) + (param v188 i32) + (param v200 i32) + (param v216 i32) + (param v223 i32) + (let (v118 i1) (eq v116 v117)) + (let (v119 i32) (zext v118)) + (let (v120 i1) (neq v119 0)) + (condbr v120 (block 4 v216 v223 v200 v188) (block 21))) (block 7 - (unreachable)) + (let (v29 i32) (const.i32 0)) + (br (block 9 v1 v21 v29 v26 v2 v1 v8 v0))) + + (block 8 + (let (v28 i32) (const.i32 0)) + (br (block 6 v1 v21 v28 v2 v1 v8 v0))) + + (block 9 + (param v30 i32) + (param v31 i32) + (param v105 i32) + (param v111 i32) + (param v190 i32) + (param v202 i32) + (param v214 i32) + (param v221 i32) + (let (v32 i1) (eq v30 v31)) + (let (v33 i32) (zext v32)) + (let (v34 i1) (neq v33 0)) + (condbr v34 (block 4 v214 v221 v202 v190) (block 11))) + + (block 10 + (br (block 6 v108 v115 v109 v189 v201 v215 v222))) + + (block 11 + (let (v35 u32) (bitcast v30)) + (let (v36 (ptr i8)) (inttoptr v35)) + (let (v37 i8) (load v36)) + (let (v38 i32) (sext v37)) + (let (v39 i32) (const.i32 -1)) + (let (v40 i1) (lte v38 v39)) + (let (v41 i32) (sext v40)) + (let (v42 i1) (neq v41 0)) + (condbr v42 (block 13) (block 14))) + + (block 12 + (param v104 i32) + (param v106 i32) + (param v108 i32) + (param v110 i32) + (param v115 i32) + (param v189 i32) + (param v201 i32) + (param v215 i32) + (param v222 i32) + (let (v107 i32) (sub.wrapping v104 v106)) + (let (v109 i32) (add.wrapping v107 v108)) + (let (v112 i32) (const.i32 -1)) + (let (v113 i32) (add.wrapping v110 v112)) + (let (v114 i1) (neq v113 0)) + (condbr v114 (block 9 v108 v115 v109 v113 v189 v201 v215 v222) (block 20))) + + (block 13 + (let (v45 i32) (const.i32 -32)) + (let (v46 u32) (bitcast v38)) + (let (v47 u32) (bitcast v45)) + (let (v48 i1) (gte v46 v47)) + (let (v49 i32) (zext v48)) + (let (v50 i1) (neq v49 0)) + (condbr v50 (block 15) (block 16))) + + (block 14 + (let (v43 i32) (const.i32 1)) + (let (v44 i32) (add.wrapping v30 v43)) + (br (block 12 v105 v30 v44 v111 v31 v190 v202 v214 v221))) + + (block 15 + (let (v53 i32) (const.i32 -16)) + (let (v54 u32) (bitcast v38)) + (let (v55 u32) (bitcast v53)) + (let (v56 i1) (gte v54 v55)) + (let (v57 i32) (zext v56)) + (let (v58 i1) (neq v57 0)) + (condbr v58 (block 17) (block 18))) + + (block 16 + (let (v51 i32) (const.i32 2)) + (let (v52 i32) (add.wrapping v30 v51)) + (br (block 12 v105 v30 v52 v111 v31 v190 v202 v214 v221))) + + (block 17 + (let (v61 u32) (bitcast v30)) + (let (v62 u32) (add.checked v61 2)) + (let (v63 (ptr u8)) (inttoptr v62)) + (let (v64 u8) (load v63)) + (let (v65 i32) (zext v64)) + (let (v66 i32) (const.i32 63)) + (let (v67 i32) (band v65 v66)) + (let (v68 i32) (const.i32 6)) + (let (v69 u32) (bitcast v68)) + (let (v70 i32) (shl.wrapping v67 v69)) + (let (v71 u32) (bitcast v30)) + (let (v72 u32) (add.checked v71 1)) + (let (v73 (ptr u8)) (inttoptr v72)) + (let (v74 u8) (load v73)) + (let (v75 i32) (zext v74)) + (let (v76 i32) (const.i32 63)) + (let (v77 i32) (band v75 v76)) + (let (v78 i32) (const.i32 12)) + (let (v79 u32) (bitcast v78)) + (let (v80 i32) (shl.wrapping v77 v79)) + (let (v81 i32) (bor v70 v80)) + (let (v82 u32) (bitcast v30)) + (let (v83 u32) (add.checked v82 3)) + (let (v84 (ptr u8)) (inttoptr v83)) + (let (v85 u8) (load v84)) + (let (v86 i32) (zext v85)) + (let (v87 i32) (const.i32 63)) + (let (v88 i32) (band v86 v87)) + (let (v89 i32) (bor v81 v88)) + (let (v90 i32) (const.i32 255)) + (let (v91 i32) (band v38 v90)) + (let (v92 i32) (const.i32 18)) + (let (v93 u32) (bitcast v92)) + (let (v94 i32) (shl.wrapping v91 v93)) + (let (v95 i32) (const.i32 1835008)) + (let (v96 i32) (band v94 v95)) + (let (v97 i32) (bor v89 v96)) + (let (v98 i32) (const.i32 1114112)) + (let (v99 i1) (eq v97 v98)) + (let (v100 i32) (zext v99)) + (let (v101 i1) (neq v100 0)) + (condbr v101 (block 4 v214 v221 v202 v190) (block 19))) + + (block 18 + (let (v59 i32) (const.i32 3)) + (let (v60 i32) (add.wrapping v30 v59)) + (br (block 12 v105 v30 v60 v111 v31 v190 v202 v214 v221))) + + (block 19 + (let (v102 i32) (const.i32 4)) + (let (v103 i32) (add.wrapping v30 v102)) + (br (block 12 v105 v30 v103 v111 v31 v190 v202 v214 v221))) + + (block 20 + (br (block 10))) + + (block 21 + (let (v121 u32) (bitcast v116)) + (let (v122 (ptr i8)) (inttoptr v121)) + (let (v123 i8) (load v122)) + (let (v124 i32) (sext v123)) + (let (v125 i32) (const.i32 -1)) + (let (v126 i1) (gt v124 v125)) + (let (v127 i32) (zext v126)) + (let (v128 i1) (neq v127 0)) + (condbr v128 (block 22 v183 v188 v200 v216 v223) (block 23))) + + (block 22 + (param v182 i32) + (param v187 i32) + (param v199 i32) + (param v217 i32) + (param v224 i32) + (let (v184 i1) (eq v182 0)) + (let (v185 i32) (zext v184)) + (let (v186 i1) (neq v185 0)) + (condbr v186 (block 27 v182 v217 v224 v199) (block 28))) + + (block 23 + (let (v129 i32) (const.i32 -32)) + (let (v130 u32) (bitcast v124)) + (let (v131 u32) (bitcast v129)) + (let (v132 i1) (lt v130 v131)) + (let (v133 i32) (sext v132)) + (let (v134 i1) (neq v133 0)) + (condbr v134 (block 22 v183 v188 v200 v216 v223) (block 24))) + + (block 24 + (let (v135 i32) (const.i32 -16)) + (let (v136 u32) (bitcast v124)) + (let (v137 u32) (bitcast v135)) + (let (v138 i1) (lt v136 v137)) + (let (v139 i32) (sext v138)) + (let (v140 i1) (neq v139 0)) + (condbr v140 (block 22 v183 v188 v200 v216 v223) (block 25))) + + (block 25 + (let (v141 u32) (bitcast v116)) + (let (v142 u32) (add.checked v141 2)) + (let (v143 (ptr u8)) (inttoptr v142)) + (let (v144 u8) (load v143)) + (let (v145 i32) (zext v144)) + (let (v146 i32) (const.i32 63)) + (let (v147 i32) (band v145 v146)) + (let (v148 i32) (const.i32 6)) + (let (v149 u32) (bitcast v148)) + (let (v150 i32) (shl.wrapping v147 v149)) + (let (v151 u32) (bitcast v116)) + (let (v152 u32) (add.checked v151 1)) + (let (v153 (ptr u8)) (inttoptr v152)) + (let (v154 u8) (load v153)) + (let (v155 i32) (zext v154)) + (let (v156 i32) (const.i32 63)) + (let (v157 i32) (band v155 v156)) + (let (v158 i32) (const.i32 12)) + (let (v159 u32) (bitcast v158)) + (let (v160 i32) (shl.wrapping v157 v159)) + (let (v161 i32) (bor v150 v160)) + (let (v162 u32) (bitcast v116)) + (let (v163 u32) (add.checked v162 3)) + (let (v164 (ptr u8)) (inttoptr v163)) + (let (v165 u8) (load v164)) + (let (v166 i32) (zext v165)) + (let (v167 i32) (const.i32 63)) + (let (v168 i32) (band v166 v167)) + (let (v169 i32) (bor v161 v168)) + (let (v170 i32) (const.i32 255)) + (let (v171 i32) (band v124 v170)) + (let (v172 i32) (const.i32 18)) + (let (v173 u32) (bitcast v172)) + (let (v174 i32) (shl.wrapping v171 v173)) + (let (v175 i32) (const.i32 1835008)) + (let (v176 i32) (band v174 v175)) + (let (v177 i32) (bor v169 v176)) + (let (v178 i32) (const.i32 1114112)) + (let (v179 i1) (eq v177 v178)) + (let (v180 i32) (zext v179)) + (let (v181 i1) (neq v180 0)) + (condbr v181 (block 4 v216 v223 v200 v188) (block 26))) + + (block 26 + (br (block 22 v183 v188 v200 v216 v223))) + + (block 27 + (param v212 i32) + (param v218 i32) + (param v225 i32) + (param v232 i32) + (br (block 4 v218 v225 v232 v212))) + + (block 28 + (let (v191 u32) (bitcast v182)) + (let (v192 u32) (bitcast v187)) + (let (v193 i1) (lt v191 v192)) + (let (v194 i32) (sext v193)) + (let (v195 i1) (neq v194 0)) + (condbr v195 (block 29) (block 30))) + + (block 29 + (let (v203 i32) (add.wrapping v199 v182)) + (let (v204 u32) (bitcast v203)) + (let (v205 (ptr i8)) (inttoptr v204)) + (let (v206 i8) (load v205)) + (let (v207 i32) (sext v206)) + (let (v208 i32) (const.i32 -64)) + (let (v209 i1) (lt v207 v208)) + (let (v210 i32) (sext v209)) + (let (v211 i1) (neq v210 0)) + (condbr v211 (block 4 v217 v224 v199 v187) (block 32))) + + (block 30 + (let (v196 i1) (eq v182 v187)) + (let (v197 i32) (zext v196)) + (let (v198 i1) (neq v197 0)) + (condbr v198 (block 27 v182 v217 v224 v199) (block 31))) + + (block 31 + (br (block 4 v217 v224 v199 v187))) + + (block 32 + (br (block 27 v182 v217 v224 v199))) + + (block 33 + (let (v244 u32) (bitcast v220)) + (let (v245 u32) (add.checked v244 4)) + (let (v246 u32) (mod.unchecked v245 4)) + (assertz 250 v246) + (let (v247 (ptr i32)) (inttoptr v245)) + (let (v248 i32) (load v247)) + (let (v249 i32) (const.i32 16)) + (let (v250 u32) (bitcast v233)) + (let (v251 u32) (bitcast v249)) + (let (v252 i1) (lt v250 v251)) + (let (v253 i32) (sext v252)) + (let (v254 i1) (neq v253 0)) + (condbr v254 (block 36) (block 37))) + + (block 34 + (let (v226 u32) (bitcast v220)) + (let (v227 u32) (add.checked v226 20)) + (let (v228 u32) (mod.unchecked v227 4)) + (assertz 250 v228) + (let (v229 (ptr i32)) (inttoptr v227)) + (let (v230 i32) (load v229)) + (let (v234 u32) (bitcast v220)) + (let (v235 u32) (add.checked v234 24)) + (let (v236 u32) (mod.unchecked v235 4)) + (assertz 250 v236) + (let (v237 (ptr i32)) (inttoptr v235)) + (let (v238 i32) (load v237)) + (let (v239 u32) (bitcast v238)) + (let (v240 u32) (add.checked v239 12)) + (let (v241 u32) (mod.unchecked v240 4)) + (assertz 250 v241) + (let (v242 (ptr i32)) (inttoptr v240)) + (let (v243 i32) (load v242)) + (ret v243)) + + (block 35 + (param v345 i32) + (param v349 i32) + (param v357 i32) + (param v422 i32) + (param v424 i32) + (let (v350 u32) (bitcast v345)) + (let (v351 u32) (bitcast v349)) + (let (v352 i1) (lte v350 v351)) + (let (v353 i32) (sext v352)) + (let (v354 i1) (neq v353 0)) + (condbr v354 (block 51) (block 52))) + + (block 36 + (let (v256 i1) (neq v233 0)) + (condbr v256 (block 38) (block 39))) + + (block 37 + (let (v255 i32) (call #core::str::count::do_count_chars v231 v233)) + (br (block 35 v248 v255 v220 v231 v233))) + + (block 38 + (let (v258 i32) (const.i32 3)) + (let (v259 i32) (band v233 v258)) + (let (v260 i32) (const.i32 4)) + (let (v261 u32) (bitcast v233)) + (let (v262 u32) (bitcast v260)) + (let (v263 i1) (gte v261 v262)) + (let (v264 i32) (zext v263)) + (let (v265 i1) (neq v264 0)) + (condbr v265 (block 41) (block 42))) + + (block 39 + (let (v257 i32) (const.i32 0)) + (br (block 35 v248 v257 v220 v231 v233))) + + (block 40 + (param v320 i32) + (param v325 i32) + (param v326 i32) + (param v344 i32) + (param v346 i32) + (param v358 i32) + (param v425 i32) + (let (v322 i1) (eq v320 0)) + (let (v323 i32) (zext v322)) + (let (v324 i1) (neq v323 0)) + (condbr v324 (block 35 v346 v344 v358 v325 v425) (block 46))) + + (block 41 + (let (v268 i32) (const.i32 12)) + (let (v269 i32) (band v233 v268)) + (let (v270 i32) (const.i32 0)) + (let (v271 i32) (const.i32 0)) + (br (block 43 v270 v231 v271 v269 v259 v248 v220 v233))) + + (block 42 + (let (v266 i32) (const.i32 0)) + (let (v267 i32) (const.i32 0)) + (br (block 40 v259 v231 v267 v266 v248 v220 v233))) + + (block 43 + (param v272 i32) + (param v273 i32) + (param v274 i32) + (param v314 i32) + (param v321 i32) + (param v347 i32) + (param v359 i32) + (param v426 i32) + (let (v275 i32) (add.wrapping v273 v274)) + (let (v276 u32) (bitcast v275)) + (let (v277 (ptr i8)) (inttoptr v276)) + (let (v278 i8) (load v277)) + (let (v279 i32) (sext v278)) + (let (v280 i32) (const.i32 -65)) + (let (v281 i1) (gt v279 v280)) + (let (v282 i32) (zext v281)) + (let (v283 i32) (add.wrapping v272 v282)) + (let (v284 i32) (const.i32 1)) + (let (v285 i32) (add.wrapping v275 v284)) + (let (v286 u32) (bitcast v285)) + (let (v287 (ptr i8)) (inttoptr v286)) + (let (v288 i8) (load v287)) + (let (v289 i32) (sext v288)) + (let (v290 i32) (const.i32 -65)) + (let (v291 i1) (gt v289 v290)) + (let (v292 i32) (zext v291)) + (let (v293 i32) (add.wrapping v283 v292)) + (let (v294 i32) (const.i32 2)) + (let (v295 i32) (add.wrapping v275 v294)) + (let (v296 u32) (bitcast v295)) + (let (v297 (ptr i8)) (inttoptr v296)) + (let (v298 i8) (load v297)) + (let (v299 i32) (sext v298)) + (let (v300 i32) (const.i32 -65)) + (let (v301 i1) (gt v299 v300)) + (let (v302 i32) (zext v301)) + (let (v303 i32) (add.wrapping v293 v302)) + (let (v304 i32) (const.i32 3)) + (let (v305 i32) (add.wrapping v275 v304)) + (let (v306 u32) (bitcast v305)) + (let (v307 (ptr i8)) (inttoptr v306)) + (let (v308 i8) (load v307)) + (let (v309 i32) (sext v308)) + (let (v310 i32) (const.i32 -65)) + (let (v311 i1) (gt v309 v310)) + (let (v312 i32) (zext v311)) + (let (v313 i32) (add.wrapping v303 v312)) + (let (v315 i32) (const.i32 4)) + (let (v316 i32) (add.wrapping v274 v315)) + (let (v317 i1) (neq v314 v316)) + (let (v318 i32) (zext v317)) + (let (v319 i1) (neq v318 0)) + (condbr v319 (block 43 v313 v273 v316 v314 v321 v347 v359 v426) (block 45))) + + (block 44 + (br (block 40 v321 v273 v316 v313 v347 v359 v426))) + + (block 45 + (br (block 44))) + + (block 46 + (let (v327 i32) (add.wrapping v325 v326)) + (br (block 47 v344 v327 v320 v346 v358 v325 v425))) + + (block 47 + (param v328 i32) + (param v329 i32) + (param v340 i32) + (param v348 i32) + (param v360 i32) + (param v423 i32) + (param v427 i32) + (let (v330 u32) (bitcast v329)) + (let (v331 (ptr i8)) (inttoptr v330)) + (let (v332 i8) (load v331)) + (let (v333 i32) (sext v332)) + (let (v334 i32) (const.i32 -65)) + (let (v335 i1) (gt v333 v334)) + (let (v336 i32) (zext v335)) + (let (v337 i32) (add.wrapping v328 v336)) + (let (v338 i32) (const.i32 1)) + (let (v339 i32) (add.wrapping v329 v338)) + (let (v341 i32) (const.i32 -1)) + (let (v342 i32) (add.wrapping v340 v341)) + (let (v343 i1) (neq v342 0)) + (condbr v343 (block 47 v337 v339 v342 v348 v360 v423 v427) (block 49))) + + (block 48 + (br (block 35 v348 v337 v360 v423 v427))) + + (block 49 + (br (block 48))) + + (block 50 + (let (v438 i32) (const.i32 1)) + (let (v443 u32) (bitcast v407)) + (let (v444 u32) (add.checked v443 12)) + (let (v445 u32) (mod.unchecked v444 4)) + (assertz 250 v445) + (let (v446 (ptr i32)) (inttoptr v444)) + (let (v447 i32) (load v446)) + (let (v448 i1) (neq v447 0)) + (condbr v448 (block 60 v438) (block 61))) + + (block 51 + (let (v417 u32) (bitcast v357)) + (let (v418 u32) (add.checked v417 20)) + (let (v419 u32) (mod.unchecked v418 4)) + (assertz 250 v419) + (let (v420 (ptr i32)) (inttoptr v418)) + (let (v421 i32) (load v420)) + (let (v428 u32) (bitcast v357)) + (let (v429 u32) (add.checked v428 24)) + (let (v430 u32) (mod.unchecked v429 4)) + (assertz 250 v430) + (let (v431 (ptr i32)) (inttoptr v429)) + (let (v432 i32) (load v431)) + (let (v433 u32) (bitcast v432)) + (let (v434 u32) (add.checked v433 12)) + (let (v435 u32) (mod.unchecked v434 4)) + (assertz 250 v435) + (let (v436 (ptr i32)) (inttoptr v434)) + (let (v437 i32) (load v436)) + (ret v437)) + + (block 52 + (let (v355 i32) (sub.wrapping v345 v349)) + (let (v356 i32) (const.i32 0)) + (let (v361 u32) (bitcast v357)) + (let (v362 u32) (add.checked v361 32)) + (let (v363 (ptr u8)) (inttoptr v362)) + (let (v364 u8) (load v363)) + (let (v365 i32) (zext v364)) + (let (v366 u32) (cast v365)) + (switchv366 + (0 . (block 55)) + (1 . (block 54)) + (2 . (block 53 v356 v357 v422 v424 v355)) + (3 . (block 53 v356 v357 v422 v424 v355)) + (_ . (block 53 v356 v357 v422 v424 v355)))) + + (block 53 + (param v380 i32) + (param v383 i32) + (param v440 i32) + (param v442 i32) + (param v469 i32) + (let (v381 i32) (const.i32 1)) + (let (v382 i32) (add.wrapping v380 v381)) + (let (v384 u32) (bitcast v383)) + (let (v385 u32) (add.checked v384 16)) + (let (v386 u32) (mod.unchecked v385 4)) + (assertz 250 v386) + (let (v387 (ptr i32)) (inttoptr v385)) + (let (v388 i32) (load v387)) + (let (v389 u32) (bitcast v383)) + (let (v390 u32) (add.checked v389 24)) + (let (v391 u32) (mod.unchecked v390 4)) + (assertz 250 v391) + (let (v392 (ptr i32)) (inttoptr v390)) + (let (v393 i32) (load v392)) + (let (v394 u32) (bitcast v383)) + (let (v395 u32) (add.checked v394 20)) + (let (v396 u32) (mod.unchecked v395 4)) + (assertz 250 v396) + (let (v397 (ptr i32)) (inttoptr v395)) + (let (v398 i32) (load v397)) + (br (block 56 v382 v398 v388 v393 v440 v442 v469))) + + (block 54 + (let (v368 i32) (const.i32 1)) + (let (v369 u32) (bitcast v355)) + (let (v370 u32) (bitcast v368)) + (let (v371 u32) (shr.wrapping v369 v370)) + (let (v372 i32) (bitcast v371)) + (let (v373 i32) (const.i32 1)) + (let (v374 i32) (add.wrapping v355 v373)) + (let (v375 i32) (const.i32 1)) + (let (v376 u32) (bitcast v374)) + (let (v377 u32) (bitcast v375)) + (let (v378 u32) (shr.wrapping v376 v377)) + (let (v379 i32) (bitcast v378)) + (br (block 53 v372 v357 v422 v424 v379))) + + (block 55 + (let (v367 i32) (const.i32 0)) + (br (block 53 v355 v357 v422 v424 v367))) + + (block 56 + (param v399 i32) + (param v405 i32) + (param v406 i32) + (param v407 i32) + (param v439 i32) + (param v441 i32) + (param v468 i32) + (let (v400 i32) (const.i32 -1)) + (let (v401 i32) (add.wrapping v399 v400)) + (let (v402 i1) (eq v401 0)) + (let (v403 i32) (zext v402)) + (let (v404 i1) (neq v403 0)) + (condbr v404 (block 50) (block 58))) + + (block 57 + (let (v416 i32) (const.i32 1)) + (ret v416)) + + (block 58 + (let (v408 u32) (bitcast v407)) + (let (v409 u32) (add.checked v408 16)) + (let (v410 u32) (mod.unchecked v409 4)) + (assertz 250 v410) + (let (v411 (ptr i32)) (inttoptr v409)) + (let (v412 i32) (load v411)) + (let (v413 i1) (eq v412 0)) + (let (v414 i32) (zext v413)) + (let (v415 i1) (neq v414 0)) + (condbr v415 (block 56 v401 v405 v406 v407 v439 v441 v468) (block 59))) + + (block 59 + (br (block 57))) + + (block 60 (param v478 i32) + (ret v478)) + + (block 61 + (let (v449 i32) (const.i32 0)) + (br (block 63 v468 v449 v405 v406 v407))) + + (block 62 (param v472 i32) (param v473 i32) + (let (v474 u32) (bitcast v472)) + (let (v475 u32) (bitcast v473)) + (let (v476 i1) (lt v474 v475)) + (let (v477 i32) (sext v476)) + (br (block 60 v477))) + + (block 63 + (param v450 i32) + (param v451 i32) + (param v457 i32) + (param v458 i32) + (param v459 i32) + (let (v452 i1) (neq v450 v451)) + (let (v453 i32) (zext v452)) + (let (v454 i1) (neq v453 0)) + (condbr v454 (block 65) (block 66))) + + (block 64 + (let (v470 i32) (const.i32 -1)) + (let (v471 i32) (add.wrapping v456 v470)) + (br (block 62 v471 v450))) + + (block 65 + (let (v455 i32) (const.i32 1)) + (let (v456 i32) (add.wrapping v451 v455)) + (let (v460 u32) (bitcast v459)) + (let (v461 u32) (add.checked v460 16)) + (let (v462 u32) (mod.unchecked v461 4)) + (assertz 250 v462) + (let (v463 (ptr i32)) (inttoptr v461)) + (let (v464 i32) (load v463)) + (let (v465 i1) (eq v464 0)) + (let (v466 i32) (zext v465)) + (let (v467 i1) (neq v466 0)) + (condbr v467 (block 63 v450 v456 v457 v458 v459) (block 67))) + + (block 66 + (br (block 62 v450 v450))) + + (block 67 + (br (block 64))) + ) + + (func (export #core::fmt::num::imp::::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 u32) (bitcast v0)) + (let (v4 u32) (mod.unchecked v3 4)) + (assertz 250 v4) + (let (v5 (ptr u32)) (inttoptr v3)) + (let (v6 u32) (load v5)) + (let (v7 i64) (zext v6)) + (let (v8 i32) (const.i32 1)) + (let (v9 i32) (call #core::fmt::num::imp::fmt_u64 v7 v8 v1)) + (br (block 1 v9))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #core::fmt::write) + (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v4 i32) (const.i32 0)) + (let (v5 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v6 i32) (const.i32 48)) + (let (v7 i32) (sub.wrapping v5 v6)) + (let (v8 (ptr i32)) (global.symbol #__stack_pointer)) + (store v8 v7) + (let (v9 i32) (const.i32 3)) + (let (v10 u32) (bitcast v9)) + (let (v11 u8) (trunc v10)) + (let (v12 u32) (bitcast v7)) + (let (v13 u32) (add.checked v12 44)) + (let (v14 (ptr u8)) (inttoptr v13)) + (store v14 v11) + (let (v15 i32) (const.i32 32)) + (let (v16 u32) (bitcast v7)) + (let (v17 u32) (add.checked v16 28)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) + (let (v19 (ptr i32)) (inttoptr v17)) + (store v19 v15) + (let (v20 i32) (const.i32 0)) + (let (v21 i32) (const.i32 0)) + (let (v22 u32) (bitcast v7)) + (let (v23 u32) (add.checked v22 40)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) + (let (v25 (ptr i32)) (inttoptr v23)) + (store v25 v21) + (let (v26 u32) (bitcast v7)) + (let (v27 u32) (add.checked v26 36)) + (let (v28 u32) (mod.unchecked v27 4)) + (assertz 250 v28) + (let (v29 (ptr i32)) (inttoptr v27)) + (store v29 v1) + (let (v30 u32) (bitcast v7)) + (let (v31 u32) (add.checked v30 32)) + (let (v32 u32) (mod.unchecked v31 4)) + (assertz 250 v32) + (let (v33 (ptr i32)) (inttoptr v31)) + (store v33 v0) + (let (v34 i32) (const.i32 0)) + (let (v35 u32) (bitcast v7)) + (let (v36 u32) (add.checked v35 20)) + (let (v37 u32) (mod.unchecked v36 4)) + (assertz 250 v37) + (let (v38 (ptr i32)) (inttoptr v36)) + (store v38 v34) + (let (v39 i32) (const.i32 0)) + (let (v40 u32) (bitcast v7)) + (let (v41 u32) (add.checked v40 12)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) + (let (v43 (ptr i32)) (inttoptr v41)) + (store v43 v39) + (let (v44 u32) (bitcast v2)) + (let (v45 u32) (add.checked v44 16)) + (let (v46 u32) (mod.unchecked v45 4)) + (assertz 250 v46) + (let (v47 (ptr i32)) (inttoptr v45)) + (let (v48 i32) (load v47)) + (let (v49 i1) (neq v48 0)) + (condbr v49 (block 6) (block 7))) + + (block 1 (param v3 i32) + (ret v3)) + + (block 2 (param v436 i32) (param v442 i32) + (let (v439 i32) (const.i32 48)) + (let (v440 i32) (add.wrapping v436 v439)) + (let (v441 (ptr i32)) (global.symbol #__stack_pointer)) + (store v441 v440) + (br (block 1 v442))) + + (block 3 (param v438 i32) + (let (v435 i32) (const.i32 0)) + (br (block 2 v438 v435))) + + (block 4 (param v437 i32) + (let (v434 i32) (const.i32 1)) + (br (block 2 v437 v434))) + + (block 5 (param v370 i32) (param v379 i32) (param v398 i32) + (let (v388 u32) (bitcast v379)) + (let (v389 u32) (add.checked v388 4)) + (let (v390 u32) (mod.unchecked v389 4)) + (assertz 250 v390) + (let (v391 (ptr i32)) (inttoptr v389)) + (let (v392 i32) (load v391)) + (let (v393 u32) (bitcast v370)) + (let (v394 u32) (bitcast v392)) + (let (v395 i1) (gte v393 v394)) + (let (v396 i32) (zext v395)) + (let (v397 i1) (neq v396 0)) + (condbr v397 (block 3 v398) (block 32))) + + (block 6 + (let (v132 u32) (bitcast v2)) + (let (v133 u32) (add.checked v132 20)) + (let (v134 u32) (mod.unchecked v133 4)) + (assertz 250 v134) + (let (v135 (ptr i32)) (inttoptr v133)) + (let (v136 i32) (load v135)) + (let (v137 i1) (eq v136 0)) + (let (v138 i32) (zext v137)) + (let (v139 i1) (neq v138 0)) + (condbr v139 (block 5 v20 v2 v7) (block 16))) + + (block 7 + (let (v50 u32) (bitcast v2)) + (let (v51 u32) (add.checked v50 12)) + (let (v52 u32) (mod.unchecked v51 4)) + (assertz 250 v52) + (let (v53 (ptr i32)) (inttoptr v51)) + (let (v54 i32) (load v53)) + (let (v55 i1) (eq v54 0)) + (let (v56 i32) (zext v55)) + (let (v57 i1) (neq v56 0)) + (condbr v57 (block 5 v20 v2 v7) (block 8))) + + (block 8 + (let (v58 u32) (bitcast v2)) + (let (v59 u32) (add.checked v58 8)) + (let (v60 u32) (mod.unchecked v59 4)) + (assertz 250 v60) + (let (v61 (ptr i32)) (inttoptr v59)) + (let (v62 i32) (load v61)) + (let (v63 i32) (const.i32 3)) + (let (v64 u32) (bitcast v63)) + (let (v65 i32) (shl.wrapping v54 v64)) + (let (v66 i32) (const.i32 -1)) + (let (v67 i32) (add.wrapping v54 v66)) + (let (v68 i32) (const.i32 536870911)) + (let (v69 i32) (band v67 v68)) + (let (v70 i32) (const.i32 1)) + (let (v71 i32) (add.wrapping v69 v70)) + (let (v72 u32) (bitcast v2)) + (let (v73 u32) (mod.unchecked v72 4)) + (assertz 250 v73) + (let (v74 (ptr i32)) (inttoptr v72)) + (let (v75 i32) (load v74)) + (br (block 9 v75 v7 v62 v65 v71 v2))) + + (block 9 + (param v76 i32) + (param v86 i32) + (param v108 i32) + (param v128 i32) + (param v372 i32) + (param v381 i32) + (let (v77 i32) (const.i32 4)) + (let (v78 i32) (add.wrapping v76 v77)) + (let (v79 u32) (bitcast v78)) + (let (v80 u32) (mod.unchecked v79 4)) + (assertz 250 v80) + (let (v81 (ptr i32)) (inttoptr v79)) + (let (v82 i32) (load v81)) + (let (v83 i1) (eq v82 0)) + (let (v84 i32) (zext v83)) + (let (v85 i1) (neq v84 0)) + (condbr v85 (block 11 v108 v86 v76 v128 v372 v381) (block 12))) + + (block 10) + + (block 11 + (param v107 i32) + (param v113 i32) + (param v124 i32) + (param v127 i32) + (param v371 i32) + (param v380 i32) + (let (v109 u32) (bitcast v107)) + (let (v110 u32) (mod.unchecked v109 4)) + (assertz 250 v110) + (let (v111 (ptr i32)) (inttoptr v109)) + (let (v112 i32) (load v111)) + (let (v114 i32) (const.i32 12)) + (let (v115 i32) (add.wrapping v113 v114)) + (let (v116 u32) (bitcast v107)) + (let (v117 u32) (add.checked v116 4)) + (let (v118 u32) (mod.unchecked v117 4)) + (assertz 250 v118) + (let (v119 (ptr i32)) (inttoptr v117)) + (let (v120 i32) (load v119)) + (let (v121 i1) (neq v120 0)) + (condbr v121 (block 4 v113) (block 14))) + + (block 12 + (let (v87 u32) (bitcast v86)) + (let (v88 u32) (add.checked v87 32)) + (let (v89 u32) (mod.unchecked v88 4)) + (assertz 250 v89) + (let (v90 (ptr i32)) (inttoptr v88)) + (let (v91 i32) (load v90)) + (let (v92 u32) (bitcast v76)) + (let (v93 u32) (mod.unchecked v92 4)) + (assertz 250 v93) + (let (v94 (ptr i32)) (inttoptr v92)) + (let (v95 i32) (load v94)) + (let (v96 u32) (bitcast v86)) + (let (v97 u32) (add.checked v96 36)) + (let (v98 u32) (mod.unchecked v97 4)) + (assertz 250 v98) + (let (v99 (ptr i32)) (inttoptr v97)) + (let (v100 i32) (load v99)) + (let (v101 u32) (bitcast v100)) + (let (v102 u32) (add.checked v101 12)) + (let (v103 u32) (mod.unchecked v102 4)) + (assertz 250 v103) + (let (v104 (ptr i32)) (inttoptr v102)) + (let (v105 i32) (load v104)) + (let (v106 i1) (neq v105 0)) + (condbr v106 (block 4 v86) (block 13))) + + (block 13 + (br (block 11 v108 v86 v76 v128 v372 v381))) + + (block 14 + (let (v122 i32) (const.i32 8)) + (let (v123 i32) (add.wrapping v107 v122)) + (let (v125 i32) (const.i32 8)) + (let (v126 i32) (add.wrapping v124 v125)) + (let (v129 i32) (const.i32 -8)) + (let (v130 i32) (add.wrapping v127 v129)) + (let (v131 i1) (neq v130 0)) + (condbr v131 (block 9 v126 v113 v123 v130 v371 v380) (block 15))) + + (block 15 + (br (block 5 v371 v380 v113))) + + (block 16 + (let (v140 i32) (const.i32 5)) + (let (v141 u32) (bitcast v140)) + (let (v142 i32) (shl.wrapping v136 v141)) + (let (v143 i32) (const.i32 -1)) + (let (v144 i32) (add.wrapping v136 v143)) + (let (v145 i32) (const.i32 134217727)) + (let (v146 i32) (band v144 v145)) + (let (v147 i32) (const.i32 1)) + (let (v148 i32) (add.wrapping v146 v147)) + (let (v149 u32) (bitcast v2)) + (let (v150 u32) (add.checked v149 8)) + (let (v151 u32) (mod.unchecked v150 4)) + (assertz 250 v151) + (let (v152 (ptr i32)) (inttoptr v150)) + (let (v153 i32) (load v152)) + (let (v154 u32) (bitcast v2)) + (let (v155 u32) (mod.unchecked v154 4)) + (assertz 250 v155) + (let (v156 (ptr i32)) (inttoptr v154)) + (let (v157 i32) (load v156)) + (let (v158 i32) (const.i32 0)) + (br (block 17 v157 v7 v48 v158 v153 v142 v148 v2))) + + (block 17 + (param v159 i32) + (param v169 i32) + (param v192 i32) + (param v194 i32) + (param v247 i32) + (param v354 i32) + (param v376 i32) + (param v385 i32) + (let (v160 i32) (const.i32 4)) + (let (v161 i32) (add.wrapping v159 v160)) + (let (v162 u32) (bitcast v161)) + (let (v163 u32) (mod.unchecked v162 4)) + (assertz 250 v163) + (let (v164 (ptr i32)) (inttoptr v162)) + (let (v165 i32) (load v164)) + (let (v166 i1) (eq v165 0)) + (let (v167 i32) (zext v166)) + (let (v168 i1) (neq v167 0)) + (condbr v168 (block 19 v169 v192 v194 v247 v159 v354 v376 v385) (block 20))) + + (block 18 + (br (block 5 v373 v382 v303))) + + (block 19 + (param v190 i32) + (param v191 i32) + (param v193 i32) + (param v246 i32) + (param v346 i32) + (param v353 i32) + (param v375 i32) + (param v384 i32) + (let (v195 i32) (add.wrapping v191 v193)) + (let (v196 i32) (const.i32 16)) + (let (v197 i32) (add.wrapping v195 v196)) + (let (v198 u32) (bitcast v197)) + (let (v199 u32) (mod.unchecked v198 4)) + (assertz 250 v199) + (let (v200 (ptr i32)) (inttoptr v198)) + (let (v201 i32) (load v200)) + (let (v202 u32) (bitcast v190)) + (let (v203 u32) (add.checked v202 28)) + (let (v204 u32) (mod.unchecked v203 4)) + (assertz 250 v204) + (let (v205 (ptr i32)) (inttoptr v203)) + (store v205 v201) + (let (v206 i32) (const.i32 28)) + (let (v207 i32) (add.wrapping v195 v206)) + (let (v208 u32) (bitcast v207)) + (let (v209 (ptr u8)) (inttoptr v208)) + (let (v210 u8) (load v209)) + (let (v211 i32) (zext v210)) + (let (v212 u32) (bitcast v211)) + (let (v213 u8) (trunc v212)) + (let (v214 u32) (bitcast v190)) + (let (v215 u32) (add.checked v214 44)) + (let (v216 (ptr u8)) (inttoptr v215)) + (store v216 v213) + (let (v217 i32) (const.i32 24)) + (let (v218 i32) (add.wrapping v195 v217)) + (let (v219 u32) (bitcast v218)) + (let (v220 u32) (mod.unchecked v219 4)) + (assertz 250 v220) + (let (v221 (ptr i32)) (inttoptr v219)) + (let (v222 i32) (load v221)) + (let (v223 u32) (bitcast v190)) + (let (v224 u32) (add.checked v223 40)) + (let (v225 u32) (mod.unchecked v224 4)) + (assertz 250 v225) + (let (v226 (ptr i32)) (inttoptr v224)) + (store v226 v222) + (let (v227 i32) (const.i32 12)) + (let (v228 i32) (add.wrapping v195 v227)) + (let (v229 u32) (bitcast v228)) + (let (v230 u32) (mod.unchecked v229 4)) + (assertz 250 v230) + (let (v231 (ptr i32)) (inttoptr v229)) + (let (v232 i32) (load v231)) + (let (v233 i32) (const.i32 0)) + (let (v234 i32) (const.i32 0)) + (let (v235 i32) (const.i32 8)) + (let (v236 i32) (add.wrapping v195 v235)) + (let (v237 u32) (bitcast v236)) + (let (v238 u32) (mod.unchecked v237 4)) + (assertz 250 v238) + (let (v239 (ptr i32)) (inttoptr v237)) + (let (v240 i32) (load v239)) + (let (v241 u32) (cast v240)) + (switchv241 + (0 . (block 24)) + (1 . (block 23 v190 v232 v195 v246 v233 v346 v353 v193 v191 v375 v384)) + (2 . (block 22 v190 v232 v234 v195 v246 v233 v346 v353 v193 v191 v375 v384)) + (_ . (block 23 v190 v232 v195 v246 v233 v346 v353 v193 v191 v375 v384)))) + + (block 20 + (let (v170 u32) (bitcast v169)) + (let (v171 u32) (add.checked v170 32)) + (let (v172 u32) (mod.unchecked v171 4)) + (assertz 250 v172) + (let (v173 (ptr i32)) (inttoptr v171)) + (let (v174 i32) (load v173)) + (let (v175 u32) (bitcast v159)) + (let (v176 u32) (mod.unchecked v175 4)) + (assertz 250 v176) + (let (v177 (ptr i32)) (inttoptr v175)) + (let (v178 i32) (load v177)) + (let (v179 u32) (bitcast v169)) + (let (v180 u32) (add.checked v179 36)) + (let (v181 u32) (mod.unchecked v180 4)) + (assertz 250 v181) + (let (v182 (ptr i32)) (inttoptr v180)) + (let (v183 i32) (load v182)) + (let (v184 u32) (bitcast v183)) + (let (v185 u32) (add.checked v184 12)) + (let (v186 u32) (mod.unchecked v185 4)) + (assertz 250 v186) + (let (v187 (ptr i32)) (inttoptr v185)) + (let (v188 i32) (load v187)) + (let (v189 i1) (neq v188 0)) + (condbr v189 (block 4 v169) (block 21))) + + (block 21 + (br (block 19 v169 v192 v194 v247 v159 v354 v376 v385))) + + (block 22 + (param v260 i32) + (param v262 i32) + (param v268 i32) + (param v273 i32) + (param v289 i32) + (param v312 i32) + (param v345 i32) + (param v352 i32) + (param v358 i32) + (param v367 i32) + (param v374 i32) + (param v383 i32) + (let (v264 u32) (bitcast v260)) + (let (v265 u32) (add.checked v264 16)) + (let (v266 u32) (mod.unchecked v265 4)) + (assertz 250 v266) + (let (v267 (ptr i32)) (inttoptr v265)) + (store v267 v262) + (let (v269 u32) (bitcast v260)) + (let (v270 u32) (add.checked v269 12)) + (let (v271 u32) (mod.unchecked v270 4)) + (assertz 250 v271) + (let (v272 (ptr i32)) (inttoptr v270)) + (store v272 v268) + (let (v275 i32) (const.i32 4)) + (let (v276 i32) (add.wrapping v273 v275)) + (let (v277 u32) (bitcast v276)) + (let (v278 u32) (mod.unchecked v277 4)) + (assertz 250 v278) + (let (v279 (ptr i32)) (inttoptr v277)) + (let (v280 i32) (load v279)) + (let (v281 u32) (bitcast v273)) + (let (v282 u32) (mod.unchecked v281 4)) + (assertz 250 v282) + (let (v283 (ptr i32)) (inttoptr v281)) + (let (v284 i32) (load v283)) + (let (v285 u32) (cast v284)) + (switchv285 + (0 . (block 28)) + (1 . (block 27 v260 v280 v289 v273 v345 v352 v358 v367 v374 v383)) + (2 . (block 26 v260 v280 v312 v289 v273 v345 v352 v358 v367 v374 v383)) + (_ . (block 27 v260 v280 v289 v273 v345 v352 v358 v367 v374 v383)))) + + (block 23 + (param v261 i32) + (param v263 i32) + (param v274 i32) + (param v290 i32) + (param v313 i32) + (param v347 i32) + (param v355 i32) + (param v359 i32) + (param v368 i32) + (param v377 i32) + (param v386 i32) + (let (v259 i32) (const.i32 1)) + (br (block 22 v261 v263 v259 v274 v290 v313 v347 v355 v359 v368 v377 v386))) + + (block 24 + (let (v242 i32) (const.i32 3)) + (let (v243 u32) (bitcast v242)) + (let (v244 i32) (shl.wrapping v232 v243)) + (let (v245 i32) (const.i32 0)) + (let (v248 i32) (add.wrapping v246 v244)) + (let (v249 u32) (bitcast v248)) + (let (v250 u32) (add.checked v249 4)) + (let (v251 u32) (mod.unchecked v250 4)) + (assertz 250 v251) + (let (v252 (ptr i32)) (inttoptr v250)) + (let (v253 i32) (load v252)) + (let (v254 i1) (neq v253 0)) + (condbr v254 (block 22 v190 v232 v245 v195 v246 v233 v346 v353 v193 v191 v375 v384) (block 25))) + + (block 25 + (let (v255 u32) (bitcast v248)) + (let (v256 u32) (mod.unchecked v255 4)) + (assertz 250 v256) + (let (v257 (ptr i32)) (inttoptr v255)) + (let (v258 i32) (load v257)) + (br (block 23 v190 v258 v195 v246 v233 v346 v353 v193 v191 v375 v384))) + + (block 26 + (param v303 i32) + (param v305 i32) + (param v311 i32) + (param v318 i32) + (param v320 i32) + (param v344 i32) + (param v351 i32) + (param v357 i32) + (param v366 i32) + (param v373 i32) + (param v382 i32) + (let (v307 u32) (bitcast v303)) + (let (v308 u32) (add.checked v307 24)) + (let (v309 u32) (mod.unchecked v308 4)) + (assertz 250 v309) + (let (v310 (ptr i32)) (inttoptr v308)) + (store v310 v305) + (let (v314 u32) (bitcast v303)) + (let (v315 u32) (add.checked v314 20)) + (let (v316 u32) (mod.unchecked v315 4)) + (assertz 250 v316) + (let (v317 (ptr i32)) (inttoptr v315)) + (store v317 v311) + (let (v322 i32) (const.i32 20)) + (let (v323 i32) (add.wrapping v320 v322)) + (let (v324 u32) (bitcast v323)) + (let (v325 u32) (mod.unchecked v324 4)) + (assertz 250 v325) + (let (v326 (ptr i32)) (inttoptr v324)) + (let (v327 i32) (load v326)) + (let (v328 i32) (const.i32 3)) + (let (v329 u32) (bitcast v328)) + (let (v330 i32) (shl.wrapping v327 v329)) + (let (v331 i32) (add.wrapping v318 v330)) + (let (v332 u32) (bitcast v331)) + (let (v333 u32) (mod.unchecked v332 4)) + (assertz 250 v333) + (let (v334 (ptr i32)) (inttoptr v332)) + (let (v335 i32) (load v334)) + (let (v336 i32) (const.i32 12)) + (let (v337 i32) (add.wrapping v303 v336)) + (let (v338 u32) (bitcast v331)) + (let (v339 u32) (add.checked v338 4)) + (let (v340 u32) (mod.unchecked v339 4)) + (assertz 250 v340) + (let (v341 (ptr i32)) (inttoptr v339)) + (let (v342 i32) (load v341)) + (let (v343 i1) (neq v342 0)) + (condbr v343 (block 4 v303) (block 30))) + + (block 27 + (param v304 i32) + (param v306 i32) + (param v319 i32) + (param v321 i32) + (param v348 i32) + (param v356 i32) + (param v360 i32) + (param v369 i32) + (param v378 i32) + (param v387 i32) + (let (v302 i32) (const.i32 1)) + (br (block 26 v304 v306 v302 v319 v321 v348 v356 v360 v369 v378 v387))) + + (block 28 + (let (v286 i32) (const.i32 3)) + (let (v287 u32) (bitcast v286)) + (let (v288 i32) (shl.wrapping v280 v287)) + (let (v291 i32) (add.wrapping v289 v288)) + (let (v292 u32) (bitcast v291)) + (let (v293 u32) (add.checked v292 4)) + (let (v294 u32) (mod.unchecked v293 4)) + (assertz 250 v294) + (let (v295 (ptr i32)) (inttoptr v293)) + (let (v296 i32) (load v295)) + (let (v297 i1) (neq v296 0)) + (condbr v297 (block 26 v260 v280 v312 v289 v273 v345 v352 v358 v367 v374 v383) (block 29))) + + (block 29 + (let (v298 u32) (bitcast v291)) + (let (v299 u32) (mod.unchecked v298 4)) + (assertz 250 v299) + (let (v300 (ptr i32)) (inttoptr v298)) + (let (v301 i32) (load v300)) + (br (block 27 v260 v301 v289 v273 v345 v352 v358 v367 v374 v383))) + + (block 30 + (let (v349 i32) (const.i32 8)) + (let (v350 i32) (add.wrapping v344 v349)) + (let (v361 i32) (const.i32 32)) + (let (v362 i32) (add.wrapping v357 v361)) + (let (v363 i1) (neq v351 v362)) + (let (v364 i32) (zext v363)) + (let (v365 i1) (neq v364 0)) + (condbr v365 (block 17 v350 v303 v366 v362 v318 v351 v373 v382) (block 31))) + + (block 31 + (br (block 18))) + + (block 32 + (let (v399 u32) (bitcast v398)) + (let (v400 u32) (add.checked v399 32)) + (let (v401 u32) (mod.unchecked v400 4)) + (assertz 250 v401) + (let (v402 (ptr i32)) (inttoptr v400)) + (let (v403 i32) (load v402)) + (let (v404 u32) (bitcast v379)) + (let (v405 u32) (mod.unchecked v404 4)) + (assertz 250 v405) + (let (v406 (ptr i32)) (inttoptr v404)) + (let (v407 i32) (load v406)) + (let (v408 i32) (const.i32 3)) + (let (v409 u32) (bitcast v408)) + (let (v410 i32) (shl.wrapping v370 v409)) + (let (v411 i32) (add.wrapping v407 v410)) + (let (v412 u32) (bitcast v411)) + (let (v413 u32) (mod.unchecked v412 4)) + (assertz 250 v413) + (let (v414 (ptr i32)) (inttoptr v412)) + (let (v415 i32) (load v414)) + (let (v416 u32) (bitcast v411)) + (let (v417 u32) (add.checked v416 4)) + (let (v418 u32) (mod.unchecked v417 4)) + (assertz 250 v418) + (let (v419 (ptr i32)) (inttoptr v417)) + (let (v420 i32) (load v419)) + (let (v421 u32) (bitcast v398)) + (let (v422 u32) (add.checked v421 36)) + (let (v423 u32) (mod.unchecked v422 4)) + (assertz 250 v423) + (let (v424 (ptr i32)) (inttoptr v422)) + (let (v425 i32) (load v424)) + (let (v426 u32) (bitcast v425)) + (let (v427 u32) (add.checked v426 12)) + (let (v428 u32) (mod.unchecked v427 4)) + (assertz 250 v428) + (let (v429 (ptr i32)) (inttoptr v427)) + (let (v430 i32) (load v429)) + (let (v431 i1) (eq v430 0)) + (let (v432 i32) (zext v431)) + (let (v433 i1) (neq v432 0)) + (condbr v433 (block 3 v398) (block 33))) + + (block 33 + (br (block 4 v398))) + ) + + (func (export #::type_id) + (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v2 i64) (const.i64 5799598635382251841)) + (let (v3 u32) (bitcast v0)) + (let (v4 u32) (add.checked v3 8)) + (let (v5 u32) (mod.unchecked v4 8)) + (assertz 250 v5) + (let (v6 (ptr i64)) (inttoptr v4)) + (store v6 v2) + (let (v7 i64) (const.i64 3885382061309546557)) + (let (v8 u32) (bitcast v0)) + (let (v9 u32) (mod.unchecked v8 8)) + (assertz 250 v9) + (let (v10 (ptr i64)) (inttoptr v8)) + (store v10 v7) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #core::fmt::builders::DebugStruct::field) + (param i32) (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 + (param v0 i32) + (param v1 i32) + (param v2 i32) + (param v3 i32) + (param v4 i32) + (let (v6 i32) (const.i32 0)) + (let (v7 i64) (const.i64 0)) + (let (v8 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v9 i32) (const.i32 64)) + (let (v10 i32) (sub.wrapping v8 v9)) + (let (v11 (ptr i32)) (global.symbol #__stack_pointer)) + (store v11 v10) + (let (v12 i32) (const.i32 1)) + (let (v13 u32) (bitcast v0)) + (let (v14 u32) (add.checked v13 4)) + (let (v15 (ptr u8)) (inttoptr v14)) + (let (v16 u8) (load v15)) + (let (v17 i32) (zext v16)) + (let (v18 i1) (neq v17 0)) + (condbr v18 (block 2 v0 v12 v10) (block 3))) + + (block 1 (param v5 i32) + (ret v5)) + + (block 2 (param v246 i32) (param v254 i32) (param v260 i32) + (let (v248 i32) (const.i32 1)) + (let (v249 u32) (bitcast v248)) + (let (v250 u8) (trunc v249)) + (let (v251 u32) (bitcast v246)) + (let (v252 u32) (add.checked v251 5)) + (let (v253 (ptr u8)) (inttoptr v252)) + (store v253 v250) + (let (v255 u32) (bitcast v254)) + (let (v256 u8) (trunc v255)) + (let (v257 u32) (bitcast v246)) + (let (v258 u32) (add.checked v257 4)) + (let (v259 (ptr u8)) (inttoptr v258)) + (store v259 v256) + (let (v261 i32) (const.i32 64)) + (let (v262 i32) (add.wrapping v260 v261)) + (let (v263 (ptr i32)) (global.symbol #__stack_pointer)) + (store v263 v262) + (br (block 1 v246))) + + (block 3 + (let (v19 u32) (bitcast v0)) + (let (v20 u32) (add.checked v19 5)) + (let (v21 (ptr u8)) (inttoptr v20)) + (let (v22 u8) (load v21)) + (let (v23 i32) (zext v22)) + (let (v24 u32) (bitcast v0)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) + (let (v26 (ptr i32)) (inttoptr v24)) + (let (v27 i32) (load v26)) + (let (v28 u32) (bitcast v27)) + (let (v29 u32) (add.checked v28 28)) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) + (let (v31 (ptr i32)) (inttoptr v29)) + (let (v32 i32) (load v31)) + (let (v33 i32) (const.i32 4)) + (let (v34 i32) (band v32 v33)) + (let (v35 i1) (neq v34 0)) + (condbr v35 (block 4) (block 5))) + + (block 4 + (let (v104 i32) (const.i32 255)) + (let (v105 i32) (band v23 v104)) + (let (v106 i1) (neq v105 0)) + (condbr v106 (block 9 v10 v27 v32 v1 v2 v3 v4 v0) (block 10))) + + (block 5 + (let (v36 i32) (const.i32 1)) + (let (v37 u32) (bitcast v27)) + (let (v38 u32) (add.checked v37 20)) + (let (v39 u32) (mod.unchecked v38 4)) + (assertz 250 v39) + (let (v40 (ptr i32)) (inttoptr v38)) + (let (v41 i32) (load v40)) + (let (v42 i32) (const.i32 1048959)) + (let (v43 i32) (const.i32 1048956)) + (let (v44 i32) (const.i32 255)) + (let (v45 i32) (band v23 v44)) + (let (v46 i1) (neq v45 0)) + (let (v47 i32) (select v46 v42 v43)) + (let (v48 i32) (const.i32 2)) + (let (v49 i32) (const.i32 3)) + (let (v50 i1) (neq v45 0)) + (let (v51 i32) (select v50 v48 v49)) + (let (v52 u32) (bitcast v27)) + (let (v53 u32) (add.checked v52 24)) + (let (v54 u32) (mod.unchecked v53 4)) + (assertz 250 v54) + (let (v55 (ptr i32)) (inttoptr v53)) + (let (v56 i32) (load v55)) + (let (v57 u32) (bitcast v56)) + (let (v58 u32) (add.checked v57 12)) + (let (v59 u32) (mod.unchecked v58 4)) + (assertz 250 v59) + (let (v60 (ptr i32)) (inttoptr v58)) + (let (v61 i32) (load v60)) + (let (v62 i1) (neq v61 0)) + (condbr v62 (block 2 v0 v36 v10) (block 6))) + + (block 6 + (let (v63 i32) (const.i32 1)) + (let (v64 u32) (bitcast v27)) + (let (v65 u32) (add.checked v64 20)) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) + (let (v67 (ptr i32)) (inttoptr v65)) + (let (v68 i32) (load v67)) + (let (v69 u32) (bitcast v27)) + (let (v70 u32) (add.checked v69 24)) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) + (let (v72 (ptr i32)) (inttoptr v70)) + (let (v73 i32) (load v72)) + (let (v74 u32) (bitcast v73)) + (let (v75 u32) (add.checked v74 12)) + (let (v76 u32) (mod.unchecked v75 4)) + (assertz 250 v76) + (let (v77 (ptr i32)) (inttoptr v75)) + (let (v78 i32) (load v77)) + (let (v79 i1) (neq v78 0)) + (condbr v79 (block 2 v0 v63 v10) (block 7))) + + (block 7 + (let (v80 i32) (const.i32 1)) + (let (v81 u32) (bitcast v27)) + (let (v82 u32) (add.checked v81 20)) + (let (v83 u32) (mod.unchecked v82 4)) + (assertz 250 v83) + (let (v84 (ptr i32)) (inttoptr v82)) + (let (v85 i32) (load v84)) + (let (v86 i32) (const.i32 1048924)) + (let (v87 i32) (const.i32 2)) + (let (v88 u32) (bitcast v27)) + (let (v89 u32) (add.checked v88 24)) + (let (v90 u32) (mod.unchecked v89 4)) + (assertz 250 v90) + (let (v91 (ptr i32)) (inttoptr v89)) + (let (v92 i32) (load v91)) + (let (v93 u32) (bitcast v92)) + (let (v94 u32) (add.checked v93 12)) + (let (v95 u32) (mod.unchecked v94 4)) + (assertz 250 v95) + (let (v96 (ptr i32)) (inttoptr v94)) + (let (v97 i32) (load v96)) + (let (v98 i1) (neq v97 0)) + (condbr v98 (block 2 v0 v80 v10) (block 8))) + + (block 8 + (let (v99 u32) (bitcast v4)) + (let (v100 u32) (add.checked v99 12)) + (let (v101 u32) (mod.unchecked v100 4)) + (assertz 250 v101) + (let (v102 (ptr i32)) (inttoptr v100)) + (let (v103 i32) (load v102)) + (br (block 2 v0 v103 v10))) + + (block 9 + (param v132 i32) + (param v139 i32) + (param v173 i32) + (param v209 i32) + (param v210 i32) + (param v219 i32) + (param v222 i32) + (param v247 i32) + (let (v131 i32) (const.i32 1)) + (let (v133 i32) (const.i32 1)) + (let (v134 u32) (bitcast v133)) + (let (v135 u8) (trunc v134)) + (let (v136 u32) (bitcast v132)) + (let (v137 u32) (add.checked v136 27)) + (let (v138 (ptr u8)) (inttoptr v137)) + (store v138 v135) + (let (v140 u32) (bitcast v139)) + (let (v141 u32) (add.checked v140 20)) + (let (v142 u32) (mod.unchecked v141 4)) + (assertz 250 v142) + (let (v143 (ptr i64)) (inttoptr v141)) + (let (v144 i64) (load v143)) + (let (v145 u32) (bitcast v132)) + (let (v146 u32) (add.checked v145 12)) + (let (v147 u32) (mod.unchecked v146 4)) + (assertz 250 v147) + (let (v148 (ptr i64)) (inttoptr v146)) + (store v148 v144) + (let (v149 i32) (const.i32 1048928)) + (let (v150 u32) (bitcast v132)) + (let (v151 u32) (add.checked v150 52)) + (let (v152 u32) (mod.unchecked v151 4)) + (assertz 250 v152) + (let (v153 (ptr i32)) (inttoptr v151)) + (store v153 v149) + (let (v154 i32) (const.i32 27)) + (let (v155 i32) (add.wrapping v132 v154)) + (let (v156 u32) (bitcast v132)) + (let (v157 u32) (add.checked v156 20)) + (let (v158 u32) (mod.unchecked v157 4)) + (assertz 250 v158) + (let (v159 (ptr i32)) (inttoptr v157)) + (store v159 v155) + (let (v160 u32) (bitcast v139)) + (let (v161 u32) (add.checked v160 8)) + (let (v162 u32) (mod.unchecked v161 4)) + (assertz 250 v162) + (let (v163 (ptr i64)) (inttoptr v161)) + (let (v164 i64) (load v163)) + (let (v165 u32) (bitcast v132)) + (let (v166 u32) (add.checked v165 36)) + (let (v167 u32) (mod.unchecked v166 4)) + (assertz 250 v167) + (let (v168 (ptr i64)) (inttoptr v166)) + (store v168 v164) + (let (v169 u32) (bitcast v139)) + (let (v170 u32) (mod.unchecked v169 4)) + (assertz 250 v170) + (let (v171 (ptr i64)) (inttoptr v169)) + (let (v172 i64) (load v171)) + (let (v174 u32) (bitcast v132)) + (let (v175 u32) (add.checked v174 56)) + (let (v176 u32) (mod.unchecked v175 4)) + (assertz 250 v176) + (let (v177 (ptr i32)) (inttoptr v175)) + (store v177 v173) + (let (v178 u32) (bitcast v139)) + (let (v179 u32) (add.checked v178 16)) + (let (v180 u32) (mod.unchecked v179 4)) + (assertz 250 v180) + (let (v181 (ptr i32)) (inttoptr v179)) + (let (v182 i32) (load v181)) + (let (v183 u32) (bitcast v132)) + (let (v184 u32) (add.checked v183 44)) + (let (v185 u32) (mod.unchecked v184 4)) + (assertz 250 v185) + (let (v186 (ptr i32)) (inttoptr v184)) + (store v186 v182) + (let (v187 u32) (bitcast v139)) + (let (v188 u32) (add.checked v187 32)) + (let (v189 (ptr u8)) (inttoptr v188)) + (let (v190 u8) (load v189)) + (let (v191 i32) (zext v190)) + (let (v192 u32) (bitcast v191)) + (let (v193 u8) (trunc v192)) + (let (v194 u32) (bitcast v132)) + (let (v195 u32) (add.checked v194 60)) + (let (v196 (ptr u8)) (inttoptr v195)) + (store v196 v193) + (let (v197 u32) (bitcast v132)) + (let (v198 u32) (add.checked v197 28)) + (let (v199 u32) (mod.unchecked v198 4)) + (assertz 250 v199) + (let (v200 (ptr i64)) (inttoptr v198)) + (store v200 v172) + (let (v201 i32) (const.i32 12)) + (let (v202 i32) (add.wrapping v132 v201)) + (let (v203 u32) (bitcast v132)) + (let (v204 u32) (add.checked v203 48)) + (let (v205 u32) (mod.unchecked v204 4)) + (assertz 250 v205) + (let (v206 (ptr i32)) (inttoptr v204)) + (store v206 v202) + (let (v207 i32) (const.i32 12)) + (let (v208 i32) (add.wrapping v132 v207)) + (let (v211 i32) (call #::write_str v208 v209 v210)) + (let (v212 i1) (neq v211 0)) + (condbr v212 (block 2 v247 v131 v132) (block 12))) + + (block 10 + (let (v107 i32) (const.i32 1)) + (let (v108 u32) (bitcast v27)) + (let (v109 u32) (add.checked v108 20)) + (let (v110 u32) (mod.unchecked v109 4)) + (assertz 250 v110) + (let (v111 (ptr i32)) (inttoptr v109)) + (let (v112 i32) (load v111)) + (let (v113 i32) (const.i32 1048961)) + (let (v114 i32) (const.i32 3)) + (let (v115 u32) (bitcast v27)) + (let (v116 u32) (add.checked v115 24)) + (let (v117 u32) (mod.unchecked v116 4)) + (assertz 250 v117) + (let (v118 (ptr i32)) (inttoptr v116)) + (let (v119 i32) (load v118)) + (let (v120 u32) (bitcast v119)) + (let (v121 u32) (add.checked v120 12)) + (let (v122 u32) (mod.unchecked v121 4)) + (assertz 250 v122) + (let (v123 (ptr i32)) (inttoptr v121)) + (let (v124 i32) (load v123)) + (let (v125 i1) (neq v124 0)) + (condbr v125 (block 2 v0 v107 v10) (block 11))) + + (block 11 + (let (v126 u32) (bitcast v27)) + (let (v127 u32) (add.checked v126 28)) + (let (v128 u32) (mod.unchecked v127 4)) + (assertz 250 v128) + (let (v129 (ptr i32)) (inttoptr v127)) + (let (v130 i32) (load v129)) + (br (block 9 v10 v27 v130 v1 v2 v3 v4 v0))) + + (block 12 + (let (v213 i32) (const.i32 12)) + (let (v214 i32) (add.wrapping v132 v213)) + (let (v215 i32) (const.i32 1048924)) + (let (v216 i32) (const.i32 2)) + (let (v217 i32) (call #::write_str v214 v215 v216)) + (let (v218 i1) (neq v217 0)) + (condbr v218 (block 2 v247 v131 v132) (block 13))) + + (block 13 + (let (v220 i32) (const.i32 28)) + (let (v221 i32) (add.wrapping v132 v220)) + (let (v223 u32) (bitcast v222)) + (let (v224 u32) (add.checked v223 12)) + (let (v225 u32) (mod.unchecked v224 4)) + (assertz 250 v225) + (let (v226 (ptr i32)) (inttoptr v224)) + (let (v227 i32) (load v226)) + (let (v228 i1) (neq v227 0)) + (condbr v228 (block 2 v247 v131 v132) (block 14))) + + (block 14 + (let (v229 u32) (bitcast v132)) + (let (v230 u32) (add.checked v229 48)) + (let (v231 u32) (mod.unchecked v230 4)) + (assertz 250 v231) + (let (v232 (ptr i32)) (inttoptr v230)) + (let (v233 i32) (load v232)) + (let (v234 i32) (const.i32 1048964)) + (let (v235 i32) (const.i32 2)) + (let (v236 u32) (bitcast v132)) + (let (v237 u32) (add.checked v236 52)) + (let (v238 u32) (mod.unchecked v237 4)) + (assertz 250 v238) + (let (v239 (ptr i32)) (inttoptr v237)) + (let (v240 i32) (load v239)) + (let (v241 u32) (bitcast v240)) + (let (v242 u32) (add.checked v241 12)) + (let (v243 u32) (mod.unchecked v242 4)) + (assertz 250 v243) + (let (v244 (ptr i32)) (inttoptr v242)) + (let (v245 i32) (load v244)) + (br (block 2 v247 v245 v132))) + ) + + (func (export #<&T as core::fmt::Display>::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 u32) (bitcast v0)) + (let (v4 u32) (mod.unchecked v3 4)) + (assertz 250 v4) + (let (v5 (ptr i32)) (inttoptr v3)) + (let (v6 i32) (load v5)) + (let (v7 u32) (bitcast v0)) + (let (v8 u32) (add.checked v7 4)) + (let (v9 u32) (mod.unchecked v8 4)) + (assertz 250 v9) + (let (v10 (ptr i32)) (inttoptr v8)) + (let (v11 i32) (load v10)) + (let (v12 i32) (call #core::fmt::Formatter::pad v1 v6 v11)) + (br (block 1 v12))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #core::panicking::assert_failed_inner) + (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) + (block 0 + (param v0 i32) + (param v1 i32) + (param v2 i32) + (param v3 i32) + (param v4 i32) + (param v5 i32) + (param v6 i32) + (let (v7 i32) (const.i32 0)) + (let (v8 i64) (const.i64 0)) + (let (v9 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v10 i32) (const.i32 112)) + (let (v11 i32) (sub.wrapping v9 v10)) + (let (v12 (ptr i32)) (global.symbol #__stack_pointer)) + (store v12 v11) + (let (v13 u32) (bitcast v11)) + (let (v14 u32) (add.checked v13 12)) + (let (v15 u32) (mod.unchecked v14 4)) + (assertz 250 v15) + (let (v16 (ptr i32)) (inttoptr v14)) + (store v16 v2) + (let (v17 u32) (bitcast v11)) + (let (v18 u32) (add.checked v17 8)) + (let (v19 u32) (mod.unchecked v18 4)) + (assertz 250 v19) + (let (v20 (ptr i32)) (inttoptr v18)) + (store v20 v1) + (let (v21 u32) (bitcast v11)) + (let (v22 u32) (add.checked v21 20)) + (let (v23 u32) (mod.unchecked v22 4)) + (assertz 250 v23) + (let (v24 (ptr i32)) (inttoptr v22)) + (store v24 v4) + (let (v25 u32) (bitcast v11)) + (let (v26 u32) (add.checked v25 16)) + (let (v27 u32) (mod.unchecked v26 4)) + (assertz 250 v27) + (let (v28 (ptr i32)) (inttoptr v26)) + (store v28 v3) + (let (v29 i32) (const.i32 255)) + (let (v30 i32) (band v0 v29)) + (let (v31 u32) (cast v30)) + (switchv31 + (0 . (block 5)) + (1 . (block 4)) + (2 . (block 3)) + (_ . (block 5)))) + + (block 1) + + (block 2 + (param v50 i32) + (param v51 i32) + (param v56 i32) + (param v129 i32) + (let (v52 u32) (bitcast v50)) + (let (v53 u32) (add.checked v52 28)) + (let (v54 u32) (mod.unchecked v53 4)) + (assertz 250 v54) + (let (v55 (ptr i32)) (inttoptr v53)) + (store v55 v51) + (let (v57 u32) (bitcast v56)) + (let (v58 u32) (mod.unchecked v57 4)) + (assertz 250 v58) + (let (v59 (ptr i32)) (inttoptr v57)) + (let (v60 i32) (load v59)) + (let (v61 i1) (neq v60 0)) + (condbr v61 (block 6) (block 7))) + + (block 3 + (let (v44 i32) (const.i32 1048784)) + (let (v45 u32) (bitcast v11)) + (let (v46 u32) (add.checked v45 24)) + (let (v47 u32) (mod.unchecked v46 4)) + (assertz 250 v47) + (let (v48 (ptr i32)) (inttoptr v46)) + (store v48 v44) + (let (v49 i32) (const.i32 7)) + (br (block 2 v11 v49 v5 v6))) + + (block 4 + (let (v38 i32) (const.i32 1048782)) + (let (v39 u32) (bitcast v11)) + (let (v40 u32) (add.checked v39 24)) + (let (v41 u32) (mod.unchecked v40 4)) + (assertz 250 v41) + (let (v42 (ptr i32)) (inttoptr v40)) + (store v42 v38) + (let (v43 i32) (const.i32 2)) + (br (block 2 v11 v43 v5 v6))) + + (block 5 + (let (v32 i32) (const.i32 1048780)) + (let (v33 u32) (bitcast v11)) + (let (v34 u32) (add.checked v33 24)) + (let (v35 u32) (mod.unchecked v34 4)) + (assertz 250 v35) + (let (v36 (ptr i32)) (inttoptr v34)) + (store v36 v32) + (let (v37 i32) (const.i32 2)) + (br (block 2 v11 v37 v5 v6))) + + (block 6 + (let (v130 i32) (const.i32 32)) + (let (v131 i32) (add.wrapping v50 v130)) + (let (v132 i32) (const.i32 16)) + (let (v133 i32) (add.wrapping v131 v132)) + (let (v134 i32) (const.i32 16)) + (let (v135 i32) (add.wrapping v56 v134)) + (let (v136 u32) (bitcast v135)) + (let (v137 u32) (mod.unchecked v136 4)) + (assertz 250 v137) + (let (v138 (ptr i64)) (inttoptr v136)) + (let (v139 i64) (load v138)) + (let (v140 u32) (bitcast v133)) + (let (v141 u32) (mod.unchecked v140 8)) + (assertz 250 v141) + (let (v142 (ptr i64)) (inttoptr v140)) + (store v142 v139) + (let (v143 i32) (const.i32 32)) + (let (v144 i32) (add.wrapping v50 v143)) + (let (v145 i32) (const.i32 8)) + (let (v146 i32) (add.wrapping v144 v145)) + (let (v147 i32) (const.i32 8)) + (let (v148 i32) (add.wrapping v56 v147)) + (let (v149 u32) (bitcast v148)) + (let (v150 u32) (mod.unchecked v149 4)) + (assertz 250 v150) + (let (v151 (ptr i64)) (inttoptr v149)) + (let (v152 i64) (load v151)) + (let (v153 u32) (bitcast v146)) + (let (v154 u32) (mod.unchecked v153 8)) + (assertz 250 v154) + (let (v155 (ptr i64)) (inttoptr v153)) + (store v155 v152) + (let (v156 u32) (bitcast v56)) + (let (v157 u32) (mod.unchecked v156 4)) + (assertz 250 v157) + (let (v158 (ptr i64)) (inttoptr v156)) + (let (v159 i64) (load v158)) + (let (v160 u32) (bitcast v50)) + (let (v161 u32) (add.checked v160 32)) + (let (v162 u32) (mod.unchecked v161 8)) + (assertz 250 v162) + (let (v163 (ptr i64)) (inttoptr v161)) + (store v163 v159) + (let (v164 i32) (const.i32 4)) + (let (v165 u32) (bitcast v50)) + (let (v166 u32) (add.checked v165 92)) + (let (v167 u32) (mod.unchecked v166 4)) + (assertz 250 v167) + (let (v168 (ptr i32)) (inttoptr v166)) + (store v168 v164) + (let (v169 i32) (const.i32 1048892)) + (let (v170 u32) (bitcast v50)) + (let (v171 u32) (add.checked v170 88)) + (let (v172 u32) (mod.unchecked v171 4)) + (assertz 250 v172) + (let (v173 (ptr i32)) (inttoptr v171)) + (store v173 v169) + (let (v174 i64) (const.i64 4)) + (let (v175 u32) (bitcast v50)) + (let (v176 u32) (add.checked v175 100)) + (let (v177 u32) (mod.unchecked v176 4)) + (assertz 250 v177) + (let (v178 (ptr i64)) (inttoptr v176)) + (store v178 v174) + (let (v179 i32) (const.i32 8)) + (let (v180 u32) (bitcast v179)) + (let (v181 u64) (zext v180)) + (let (v182 i64) (bitcast v181)) + (let (v183 i64) (const.i64 32)) + (let (v184 u32) (cast v183)) + (let (v185 i64) (shl.wrapping v182 v184)) + (let (v186 i32) (const.i32 16)) + (let (v187 i32) (add.wrapping v50 v186)) + (let (v188 u32) (bitcast v187)) + (let (v189 u64) (zext v188)) + (let (v190 i64) (bitcast v189)) + (let (v191 i64) (bor v185 v190)) + (let (v192 u32) (bitcast v50)) + (let (v193 u32) (add.checked v192 80)) + (let (v194 u32) (mod.unchecked v193 8)) + (assertz 250 v194) + (let (v195 (ptr i64)) (inttoptr v193)) + (store v195 v191) + (let (v196 i32) (const.i32 8)) + (let (v197 i32) (add.wrapping v50 v196)) + (let (v198 u32) (bitcast v197)) + (let (v199 u64) (zext v198)) + (let (v200 i64) (bitcast v199)) + (let (v201 i64) (bor v185 v200)) + (let (v202 u32) (bitcast v50)) + (let (v203 u32) (add.checked v202 72)) + (let (v204 u32) (mod.unchecked v203 8)) + (assertz 250 v204) + (let (v205 (ptr i64)) (inttoptr v203)) + (store v205 v201) + (let (v206 i32) (const.i32 10)) + (let (v207 u32) (bitcast v206)) + (let (v208 u64) (zext v207)) + (let (v209 i64) (bitcast v208)) + (let (v210 i64) (const.i64 32)) + (let (v211 u32) (cast v210)) + (let (v212 i64) (shl.wrapping v209 v211)) + (let (v213 i32) (const.i32 32)) + (let (v214 i32) (add.wrapping v50 v213)) + (let (v215 u32) (bitcast v214)) + (let (v216 u64) (zext v215)) + (let (v217 i64) (bitcast v216)) + (let (v218 i64) (bor v212 v217)) + (let (v219 u32) (bitcast v50)) + (let (v220 u32) (add.checked v219 64)) + (let (v221 u32) (mod.unchecked v220 8)) + (assertz 250 v221) + (let (v222 (ptr i64)) (inttoptr v220)) + (store v222 v218) + (let (v223 i32) (const.i32 9)) + (let (v224 u32) (bitcast v223)) + (let (v225 u64) (zext v224)) + (let (v226 i64) (bitcast v225)) + (let (v227 i64) (const.i64 32)) + (let (v228 u32) (cast v227)) + (let (v229 i64) (shl.wrapping v226 v228)) + (let (v230 i32) (const.i32 24)) + (let (v231 i32) (add.wrapping v50 v230)) + (let (v232 u32) (bitcast v231)) + (let (v233 u64) (zext v232)) + (let (v234 i64) (bitcast v233)) + (let (v235 i64) (bor v229 v234)) + (let (v236 u32) (bitcast v50)) + (let (v237 u32) (add.checked v236 56)) + (let (v238 u32) (mod.unchecked v237 8)) + (assertz 250 v238) + (let (v239 (ptr i64)) (inttoptr v237)) + (store v239 v235) + (let (v240 i32) (const.i32 56)) + (let (v241 i32) (add.wrapping v50 v240)) + (let (v242 u32) (bitcast v50)) + (let (v243 u32) (add.checked v242 96)) + (let (v244 u32) (mod.unchecked v243 4)) + (assertz 250 v244) + (let (v245 (ptr i32)) (inttoptr v243)) + (store v245 v241) + (let (v246 i32) (const.i32 88)) + (let (v247 i32) (add.wrapping v50 v246)) + (call #core::panicking::panic_fmt v247 v129) + (unreachable)) + + (block 7 + (let (v62 i32) (const.i32 3)) + (let (v63 u32) (bitcast v50)) + (let (v64 u32) (add.checked v63 92)) + (let (v65 u32) (mod.unchecked v64 4)) + (assertz 250 v65) + (let (v66 (ptr i32)) (inttoptr v64)) + (store v66 v62) + (let (v67 i32) (const.i32 1048840)) + (let (v68 u32) (bitcast v50)) + (let (v69 u32) (add.checked v68 88)) + (let (v70 u32) (mod.unchecked v69 4)) + (assertz 250 v70) + (let (v71 (ptr i32)) (inttoptr v69)) + (store v71 v67) + (let (v72 i64) (const.i64 3)) + (let (v73 u32) (bitcast v50)) + (let (v74 u32) (add.checked v73 100)) + (let (v75 u32) (mod.unchecked v74 4)) + (assertz 250 v75) + (let (v76 (ptr i64)) (inttoptr v74)) + (store v76 v72) + (let (v77 i32) (const.i32 8)) + (let (v78 u32) (bitcast v77)) + (let (v79 u64) (zext v78)) + (let (v80 i64) (bitcast v79)) + (let (v81 i64) (const.i64 32)) + (let (v82 u32) (cast v81)) + (let (v83 i64) (shl.wrapping v80 v82)) + (let (v84 i32) (const.i32 16)) + (let (v85 i32) (add.wrapping v50 v84)) + (let (v86 u32) (bitcast v85)) + (let (v87 u64) (zext v86)) + (let (v88 i64) (bitcast v87)) + (let (v89 i64) (bor v83 v88)) + (let (v90 u32) (bitcast v50)) + (let (v91 u32) (add.checked v90 72)) + (let (v92 u32) (mod.unchecked v91 8)) + (assertz 250 v92) + (let (v93 (ptr i64)) (inttoptr v91)) + (store v93 v89) + (let (v94 i32) (const.i32 8)) + (let (v95 i32) (add.wrapping v50 v94)) + (let (v96 u32) (bitcast v95)) + (let (v97 u64) (zext v96)) + (let (v98 i64) (bitcast v97)) + (let (v99 i64) (bor v83 v98)) + (let (v100 u32) (bitcast v50)) + (let (v101 u32) (add.checked v100 64)) + (let (v102 u32) (mod.unchecked v101 8)) + (assertz 250 v102) + (let (v103 (ptr i64)) (inttoptr v101)) + (store v103 v99) + (let (v104 i32) (const.i32 9)) + (let (v105 u32) (bitcast v104)) + (let (v106 u64) (zext v105)) + (let (v107 i64) (bitcast v106)) + (let (v108 i64) (const.i64 32)) + (let (v109 u32) (cast v108)) + (let (v110 i64) (shl.wrapping v107 v109)) + (let (v111 i32) (const.i32 24)) + (let (v112 i32) (add.wrapping v50 v111)) + (let (v113 u32) (bitcast v112)) + (let (v114 u64) (zext v113)) + (let (v115 i64) (bitcast v114)) + (let (v116 i64) (bor v110 v115)) + (let (v117 u32) (bitcast v50)) + (let (v118 u32) (add.checked v117 56)) + (let (v119 u32) (mod.unchecked v118 8)) + (assertz 250 v119) + (let (v120 (ptr i64)) (inttoptr v118)) + (store v120 v116) + (let (v121 i32) (const.i32 56)) + (let (v122 i32) (add.wrapping v50 v121)) + (let (v123 u32) (bitcast v50)) + (let (v124 u32) (add.checked v123 96)) + (let (v125 u32) (mod.unchecked v124 4)) + (assertz 250 v125) + (let (v126 (ptr i32)) (inttoptr v124)) + (store v126 v122) + (let (v127 i32) (const.i32 88)) + (let (v128 i32) (add.wrapping v50 v127)) + (call #core::panicking::panic_fmt v128 v129) + (unreachable)) + ) + + (func (export #<&T as core::fmt::Debug>::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 u32) (bitcast v0)) + (let (v4 u32) (mod.unchecked v3 4)) + (assertz 250 v4) + (let (v5 (ptr i32)) (inttoptr v3)) + (let (v6 i32) (load v5)) + (let (v7 u32) (bitcast v0)) + (let (v8 u32) (add.checked v7 4)) + (let (v9 u32) (mod.unchecked v8 4)) + (assertz 250 v9) + (let (v10 (ptr i32)) (inttoptr v8)) + (let (v11 i32) (load v10)) + (let (v12 u32) (bitcast v11)) + (let (v13 u32) (add.checked v12 12)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) + (let (v15 (ptr i32)) (inttoptr v13)) + (let (v16 i32) (load v15)) + (br (block 1 v16))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 u32) (bitcast v1)) + (let (v4 u32) (add.checked v3 20)) + (let (v5 u32) (mod.unchecked v4 4)) + (assertz 250 v5) + (let (v6 (ptr i32)) (inttoptr v4)) + (let (v7 i32) (load v6)) + (let (v8 u32) (bitcast v1)) + (let (v9 u32) (add.checked v8 24)) + (let (v10 u32) (mod.unchecked v9 4)) + (assertz 250 v10) + (let (v11 (ptr i32)) (inttoptr v9)) + (let (v12 i32) (load v11)) + (let (v13 i32) (call #core::fmt::write v7 v12 v0)) + (br (block 1 v13))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #::write_str) + (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v4 i32) (const.i32 0)) + (let (v5 i32) (const.i32 -1)) + (let (v6 i32) (add.wrapping v1 v5)) + (let (v7 u32) (bitcast v0)) + (let (v8 u32) (add.checked v7 4)) + (let (v9 u32) (mod.unchecked v8 4)) + (assertz 250 v9) + (let (v10 (ptr i32)) (inttoptr v8)) + (let (v11 i32) (load v10)) + (let (v12 u32) (bitcast v0)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) + (let (v14 (ptr i32)) (inttoptr v12)) + (let (v15 i32) (load v14)) + (let (v16 u32) (bitcast v0)) + (let (v17 u32) (add.checked v16 8)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) + (let (v19 (ptr i32)) (inttoptr v17)) + (let (v20 i32) (load v19)) + (let (v21 i32) (const.i32 0)) + (let (v22 i32) (const.i32 0)) + (br (block 2 v21 v2 v1 v22 v20 v15 v11 v6))) + + (block 1 (param v3 i32) + (ret v3)) + + (block 2 + (param v23 i32) + (param v24 i32) + (param v210 i32) + (param v221 i32) + (param v240 i32) + (param v259 i32) + (param v273 i32) + (param v304 i32) + (let (v25 u32) (bitcast v23)) + (let (v26 u32) (bitcast v24)) + (let (v27 i1) (gt v25 v26)) + (let (v28 i32) (sext v27)) + (let (v29 i1) (neq v28 0)) + (condbr v29 (block 5 v221 v24 v240 v259 v273 v304 v210 v23) (block 6))) + + (block 3 + (br (block 1 v345))) + + (block 4 + (param v236 i32) + (param v255 i32) + (param v269 i32) + (param v291 i32) + (param v293 i32) + (param v300 i32) + (param v322 i32) + (param v335 i32) + (param v348 i32) + (param v355 i32) + (param v359 i32) + (let (v248 u32) (bitcast v236)) + (let (v249 (ptr u8)) (inttoptr v248)) + (let (v250 u8) (load v249)) + (let (v251 i32) (zext v250)) + (let (v252 i1) (eq v251 0)) + (let (v253 i32) (zext v252)) + (let (v254 i1) (neq v253 0)) + (condbr v254 (block 43 v291 v293 v300 v322 v236 v335 v255 v269 v348 v355 v359) (block 44))) + + (block 5 + (param v220 i32) + (param v231 i32) + (param v247 i32) + (param v266 i32) + (param v280 i32) + (param v311 i32) + (param v323 i32) + (param v356 i32) + (let (v219 i32) (const.i32 1)) + (let (v232 i1) (neq v220 v231)) + (let (v233 i32) (zext v232)) + (let (v234 i1) (neq v233 0)) + (condbr v234 (block 4 v247 v266 v280 v231 v220 v311 v323 v220 v219 v356 v231) (block 42))) + + (block 6 + (br (block 7 v210 v23 v24 v221 v240 v259 v273 v304))) + + (block 7 + (param v30 i32) + (param v31 i32) + (param v33 i32) + (param v222 i32) + (param v239 i32) + (param v258 i32) + (param v272 i32) + (param v303 i32) + (let (v32 i32) (add.wrapping v30 v31)) + (let (v34 i32) (sub.wrapping v33 v31)) + (let (v35 i32) (const.i32 8)) + (let (v36 u32) (bitcast v34)) + (let (v37 u32) (bitcast v35)) + (let (v38 i1) (lt v36 v37)) + (let (v39 i32) (sext v38)) + (let (v40 i1) (neq v39 0)) + (condbr v40 (block 11) (block 12))) + + (block 8 + (br (block 5 v223 v204 v241 v260 v274 v305 v211 v203))) + + (block 9 + (param v175 i32) + (param v176 i32) + (param v186 i32) + (param v192 i32) + (param v212 i32) + (param v224 i32) + (param v237 i32) + (param v256 i32) + (param v270 i32) + (param v301 i32) + (let (v183 i32) (add.wrapping v175 v176)) + (let (v184 i32) (const.i32 1)) + (let (v185 i32) (add.wrapping v183 v184)) + (let (v187 u32) (bitcast v183)) + (let (v188 u32) (bitcast v186)) + (let (v189 i1) (gte v187 v188)) + (let (v190 i32) (zext v189)) + (let (v191 i1) (neq v190 0)) + (condbr v191 (block 38 v185 v186 v212 v224 v237 v256 v270 v301) (block 39))) + + (block 10 + (param v143 i32) + (param v146 i32) + (param v150 i32) + (param v171 i32) + (param v180 i32) + (param v216 i32) + (param v228 i32) + (param v244 i32) + (param v263 i32) + (param v277 i32) + (param v308 i32) + (let (v147 i1) (neq v143 v146)) + (let (v148 i32) (zext v147)) + (let (v149 i1) (neq v148 0)) + (condbr v149 (block 31) (block 32))) + + (block 11 + (let (v121 i1) (neq v33 v31)) + (let (v122 i32) (zext v121)) + (let (v123 i1) (neq v122 0)) + (condbr v123 (block 25) (block 26))) + + (block 12 + (let (v41 i32) (const.i32 3)) + (let (v42 i32) (add.wrapping v32 v41)) + (let (v43 i32) (const.i32 -4)) + (let (v44 i32) (band v42 v43)) + (let (v45 i32) (sub.wrapping v44 v32)) + (let (v46 i1) (eq v45 0)) + (let (v47 i32) (zext v46)) + (let (v48 i1) (neq v47 0)) + (condbr v48 (block 14) (block 15))) + + (block 13 + (param v117 i32) + (param v119 i32) + (param v120 i32) + (param v145 i32) + (param v153 i32) + (param v173 i32) + (param v182 i32) + (param v218 i32) + (param v230 i32) + (param v246 i32) + (param v265 i32) + (param v279 i32) + (param v310 i32) + (br (block 21 v117 v119 v120 v145 v153 v173 v182 v218 v230 v246 v265 v279 v310))) + + (block 14 + (let (v75 i32) (const.i32 -8)) + (let (v76 i32) (add.wrapping v34 v75)) + (br (block 13 v44 v45 v76 v34 v33 v32 v31 v30 v222 v239 v258 v272 v303))) + + (block 15 + (let (v49 i32) (const.i32 0)) + (br (block 16 v32 v49 v45 v34 v44 v33 v31 v30 v222 v239 v258 v272 v303))) + + (block 16 + (param v50 i32) + (param v51 i32) + (param v61 i32) + (param v67 i32) + (param v118 i32) + (param v151 i32) + (param v177 i32) + (param v213 i32) + (param v225 i32) + (param v238 i32) + (param v257 i32) + (param v271 i32) + (param v302 i32) + (let (v52 i32) (add.wrapping v50 v51)) + (let (v53 u32) (bitcast v52)) + (let (v54 (ptr u8)) (inttoptr v53)) + (let (v55 u8) (load v54)) + (let (v56 i32) (zext v55)) + (let (v57 i32) (const.i32 10)) + (let (v58 i1) (eq v56 v57)) + (let (v59 i32) (zext v58)) + (let (v60 i1) (neq v59 0)) + (condbr v60 (block 9 v51 v177 v151 v50 v213 v225 v238 v257 v271 v302) (block 18))) + + (block 17 + (let (v68 i32) (const.i32 -8)) + (let (v69 i32) (add.wrapping v67 v68)) + (let (v70 u32) (bitcast v61)) + (let (v71 u32) (bitcast v69)) + (let (v72 i1) (lte v70 v71)) + (let (v73 i32) (sext v72)) + (let (v74 i1) (neq v73 0)) + (condbr v74 (block 13 v118 v61 v69 v67 v151 v50 v177 v213 v225 v238 v257 v271 v302) (block 20))) + + (block 18 + (let (v62 i32) (const.i32 1)) + (let (v63 i32) (add.wrapping v51 v62)) + (let (v64 i1) (neq v61 v63)) + (let (v65 i32) (zext v64)) + (let (v66 i1) (neq v65 0)) + (condbr v66 (block 16 v50 v63 v61 v67 v118 v151 v177 v213 v225 v238 v257 v271 v302) (block 19))) + + (block 19 + (br (block 17))) + + (block 20 + (br (block 10 v67 v61 v151 v50 v177 v213 v225 v238 v257 v271 v302))) + + (block 21 + (param v77 i32) + (param v108 i32) + (param v111 i32) + (param v144 i32) + (param v152 i32) + (param v172 i32) + (param v181 i32) + (param v217 i32) + (param v229 i32) + (param v245 i32) + (param v264 i32) + (param v278 i32) + (param v309 i32) + (let (v78 i32) (const.i32 4)) + (let (v79 i32) (add.wrapping v77 v78)) + (let (v80 u32) (bitcast v79)) + (let (v81 u32) (mod.unchecked v80 4)) + (assertz 250 v81) + (let (v82 (ptr i32)) (inttoptr v80)) + (let (v83 i32) (load v82)) + (let (v84 i32) (const.i32 168430090)) + (let (v85 i32) (bxor v83 v84)) + (let (v86 i32) (const.i32 -16843009)) + (let (v87 i32) (add.wrapping v85 v86)) + (let (v88 i32) (const.i32 -1)) + (let (v89 i32) (bxor v83 v88)) + (let (v90 i32) (band v87 v89)) + (let (v91 u32) (bitcast v77)) + (let (v92 u32) (mod.unchecked v91 4)) + (assertz 250 v92) + (let (v93 (ptr i32)) (inttoptr v91)) + (let (v94 i32) (load v93)) + (let (v95 i32) (const.i32 168430090)) + (let (v96 i32) (bxor v94 v95)) + (let (v97 i32) (const.i32 -16843009)) + (let (v98 i32) (add.wrapping v96 v97)) + (let (v99 i32) (const.i32 -1)) + (let (v100 i32) (bxor v94 v99)) + (let (v101 i32) (band v98 v100)) + (let (v102 i32) (bor v90 v101)) + (let (v103 i32) (const.i32 -2139062144)) + (let (v104 i32) (band v102 v103)) + (let (v105 i1) (neq v104 0)) + (condbr v105 (block 10 v144 v108 v152 v172 v181 v217 v229 v245 v264 v278 v309) (block 23))) + + (block 22) + + (block 23 + (let (v106 i32) (const.i32 8)) + (let (v107 i32) (add.wrapping v77 v106)) + (let (v109 i32) (const.i32 8)) + (let (v110 i32) (add.wrapping v108 v109)) + (let (v112 u32) (bitcast v110)) + (let (v113 u32) (bitcast v111)) + (let (v114 i1) (lte v112 v113)) + (let (v115 i32) (sext v114)) + (let (v116 i1) (neq v115 0)) + (condbr v116 (block 21 v107 v110 v111 v144 v152 v172 v181 v217 v229 v245 v264 v278 v309) (block 24))) + + (block 24 + (br (block 10 v144 v110 v152 v172 v181 v217 v229 v245 v264 v278 v309))) + + (block 25 + (let (v124 i32) (const.i32 0)) + (br (block 27 v32 v124 v34 v33 v31 v30 v222 v239 v258 v272 v303))) + + (block 26 + (br (block 5 v222 v33 v239 v258 v272 v303 v30 v33))) + + (block 27 + (param v125 i32) + (param v126 i32) + (param v136 i32) + (param v142 i32) + (param v178 i32) + (param v214 i32) + (param v226 i32) + (param v242 i32) + (param v261 i32) + (param v275 i32) + (param v306 i32) + (let (v127 i32) (add.wrapping v125 v126)) + (let (v128 u32) (bitcast v127)) + (let (v129 (ptr u8)) (inttoptr v128)) + (let (v130 u8) (load v129)) + (let (v131 i32) (zext v130)) + (let (v132 i32) (const.i32 10)) + (let (v133 i1) (eq v131 v132)) + (let (v134 i32) (zext v133)) + (let (v135 i1) (neq v134 0)) + (condbr v135 (block 9 v126 v178 v142 v125 v214 v226 v242 v261 v275 v306) (block 29))) + + (block 28 + (br (block 5 v226 v142 v242 v261 v275 v306 v214 v142))) + + (block 29 + (let (v137 i32) (const.i32 1)) + (let (v138 i32) (add.wrapping v126 v137)) + (let (v139 i1) (neq v136 v138)) + (let (v140 i32) (zext v139)) + (let (v141 i1) (neq v140 0)) + (condbr v141 (block 27 v125 v138 v136 v142 v178 v214 v226 v242 v261 v275 v306) (block 30))) + + (block 30 + (br (block 28))) + + (block 31 + (br (block 33 v171 v146 v143 v150 v180 v216 v228 v244 v263 v277 v308))) + + (block 32 + (br (block 5 v228 v150 v244 v263 v277 v308 v216 v150))) + + (block 33 + (param v154 i32) + (param v155 i32) + (param v165 i32) + (param v174 i32) + (param v179 i32) + (param v215 i32) + (param v227 i32) + (param v243 i32) + (param v262 i32) + (param v276 i32) + (param v307 i32) + (let (v156 i32) (add.wrapping v154 v155)) + (let (v157 u32) (bitcast v156)) + (let (v158 (ptr u8)) (inttoptr v157)) + (let (v159 u8) (load v158)) + (let (v160 i32) (zext v159)) + (let (v161 i32) (const.i32 10)) + (let (v162 i1) (neq v160 v161)) + (let (v163 i32) (zext v162)) + (let (v164 i1) (neq v163 0)) + (condbr v164 (block 35) (block 36))) + + (block 34 + (br (block 5 v227 v174 v243 v262 v276 v307 v215 v174))) + + (block 35 + (let (v166 i32) (const.i32 1)) + (let (v167 i32) (add.wrapping v155 v166)) + (let (v168 i1) (neq v165 v167)) + (let (v169 i32) (zext v168)) + (let (v170 i1) (neq v169 0)) + (condbr v170 (block 33 v154 v167 v165 v174 v179 v215 v227 v243 v262 v276 v307) (block 37))) + + (block 36 + (br (block 9 v155 v179 v174 v154 v215 v227 v243 v262 v276 v307))) + + (block 37 + (br (block 34))) + + (block 38 + (param v203 i32) + (param v204 i32) + (param v211 i32) + (param v223 i32) + (param v241 i32) + (param v260 i32) + (param v274 i32) + (param v305 i32) + (let (v205 u32) (bitcast v203)) + (let (v206 u32) (bitcast v204)) + (let (v207 i1) (lte v205 v206)) + (let (v208 i32) (sext v207)) + (let (v209 i1) (neq v208 0)) + (condbr v209 (block 7 v211 v203 v204 v223 v241 v260 v274 v305) (block 41))) + + (block 39 + (let (v193 i32) (add.wrapping v192 v175)) + (let (v194 u32) (bitcast v193)) + (let (v195 (ptr u8)) (inttoptr v194)) + (let (v196 u8) (load v195)) + (let (v197 i32) (zext v196)) + (let (v198 i32) (const.i32 10)) + (let (v199 i1) (neq v197 v198)) + (let (v200 i32) (zext v199)) + (let (v201 i1) (neq v200 0)) + (condbr v201 (block 38 v185 v186 v212 v224 v237 v256 v270 v301) (block 40))) + + (block 40 + (let (v202 i32) (const.i32 0)) + (br (block 4 v237 v256 v270 v185 v224 v301 v212 v185 v202 v185 v186))) + + (block 41 + (br (block 8))) + + (block 42 + (let (v235 i32) (const.i32 0)) + (ret v235)) + + (block 43 + (param v290 i32) + (param v292 i32) + (param v299 i32) + (param v321 i32) + (param v327 i32) + (param v334 i32) + (param v337 i32) + (param v340 i32) + (param v347 i32) + (param v354 i32) + (param v358 i32) + (let (v294 i32) (sub.wrapping v290 v292)) + (let (v295 i32) (const.i32 0)) + (let (v296 i1) (eq v290 v292)) + (let (v297 i32) (zext v296)) + (let (v298 i1) (neq v297 0)) + (condbr v298 (block 46 v321 v292 v327 v295 v334 v337 v294 v340 v347 v354 v358 v299) (block 47))) + + (block 44 + (let (v267 i32) (const.i32 1048952)) + (let (v268 i32) (const.i32 4)) + (let (v281 u32) (bitcast v269)) + (let (v282 u32) (add.checked v281 12)) + (let (v283 u32) (mod.unchecked v282 4)) + (assertz 250 v283) + (let (v284 (ptr i32)) (inttoptr v282)) + (let (v285 i32) (load v284)) + (let (v286 i1) (eq v285 0)) + (let (v287 i32) (zext v286)) + (let (v288 i1) (neq v287 0)) + (condbr v288 (block 43 v291 v293 v300 v322 v236 v335 v255 v269 v348 v355 v359) (block 45))) + + (block 45 + (let (v289 i32) (const.i32 1)) + (ret v289)) + + (block 46 + (param v320 i32) + (param v324 i32) + (param v326 i32) + (param v328 i32) + (param v333 i32) + (param v336 i32) + (param v338 i32) + (param v339 i32) + (param v346 i32) + (param v353 i32) + (param v357 i32) + (param v360 i32) + (let (v325 i32) (add.wrapping v320 v324)) + (let (v329 u32) (bitcast v328)) + (let (v330 u8) (trunc v329)) + (let (v331 u32) (bitcast v326)) + (let (v332 (ptr u8)) (inttoptr v331)) + (store v332 v330) + (let (v341 u32) (bitcast v339)) + (let (v342 u32) (add.checked v341 12)) + (let (v343 u32) (mod.unchecked v342 4)) + (assertz 250 v343) + (let (v344 (ptr i32)) (inttoptr v342)) + (let (v345 i32) (load v344)) + (let (v349 i32) (bor v345 v346)) + (let (v350 i1) (eq v349 0)) + (let (v351 i32) (zext v350)) + (let (v352 i1) (neq v351 0)) + (condbr v352 (block 2 v353 v357 v320 v333 v326 v336 v339 v360) (block 48))) + + (block 47 + (let (v312 i32) (add.wrapping v299 v290)) + (let (v313 u32) (bitcast v312)) + (let (v314 (ptr u8)) (inttoptr v313)) + (let (v315 u8) (load v314)) + (let (v316 i32) (zext v315)) + (let (v317 i32) (const.i32 10)) + (let (v318 i1) (eq v316 v317)) + (let (v319 i32) (zext v318)) + (br (block 46 v321 v292 v327 v319 v334 v337 v294 v340 v347 v354 v358 v299))) + + (block 48 + (br (block 3))) + ) + + (func (export #::write_char) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 u32) (bitcast v0)) + (let (v5 u32) (add.checked v4 4)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) + (let (v7 (ptr i32)) (inttoptr v5)) + (let (v8 i32) (load v7)) + (let (v9 u32) (bitcast v0)) + (let (v10 u32) (mod.unchecked v9 4)) + (assertz 250 v10) + (let (v11 (ptr i32)) (inttoptr v9)) + (let (v12 i32) (load v11)) + (let (v13 u32) (bitcast v0)) + (let (v14 u32) (add.checked v13 8)) + (let (v15 u32) (mod.unchecked v14 4)) + (assertz 250 v15) + (let (v16 (ptr i32)) (inttoptr v14)) + (let (v17 i32) (load v16)) + (let (v18 u32) (bitcast v17)) + (let (v19 (ptr u8)) (inttoptr v18)) + (let (v20 u8) (load v19)) + (let (v21 i32) (zext v20)) + (let (v22 i1) (eq v21 0)) + (let (v23 i32) (zext v22)) + (let (v24 i1) (neq v23 0)) + (condbr v24 (block 2 v17 v1 v12 v8) (block 3))) + + (block 1 (param v2 i32) + (ret v2)) + + (block 2 + (param v36 i32) + (param v37 i32) + (param v45 i32) + (param v46 i32) + (let (v38 i32) (const.i32 10)) + (let (v39 i1) (eq v37 v38)) + (let (v40 i32) (zext v39)) + (let (v41 u32) (bitcast v40)) + (let (v42 u8) (trunc v41)) + (let (v43 u32) (bitcast v36)) + (let (v44 (ptr u8)) (inttoptr v43)) + (store v44 v42) + (let (v47 u32) (bitcast v46)) + (let (v48 u32) (add.checked v47 16)) + (let (v49 u32) (mod.unchecked v48 4)) + (assertz 250 v49) + (let (v50 (ptr i32)) (inttoptr v48)) + (let (v51 i32) (load v50)) + (br (block 1 v51))) + + (block 3 + (let (v25 i32) (const.i32 1048952)) + (let (v26 i32) (const.i32 4)) + (let (v27 u32) (bitcast v8)) + (let (v28 u32) (add.checked v27 12)) + (let (v29 u32) (mod.unchecked v28 4)) + (assertz 250 v29) + (let (v30 (ptr i32)) (inttoptr v28)) + (let (v31 i32) (load v30)) + (let (v32 i1) (eq v31 0)) + (let (v33 i32) (zext v32)) + (let (v34 i1) (neq v33 0)) + (condbr v34 (block 2 v17 v1 v12 v8) (block 4))) + + (block 4 + (let (v35 i32) (const.i32 1)) + (ret v35)) + ) + + (func (export #core::fmt::builders::DebugStruct::finish) + (param i32) (result i32) + (block 0 (param v0 i32) + (let (v2 i32) (const.i32 0)) + (let (v3 u32) (bitcast v0)) + (let (v4 u32) (add.checked v3 4)) + (let (v5 (ptr u8)) (inttoptr v4)) + (let (v6 u8) (load v5)) + (let (v7 i32) (zext v6)) + (let (v8 u32) (bitcast v0)) + (let (v9 u32) (add.checked v8 5)) + (let (v10 (ptr u8)) (inttoptr v9)) + (let (v11 u8) (load v10)) + (let (v12 i32) (zext v11)) + (let (v13 i1) (neq v12 0)) + (condbr v13 (block 2) (block 3))) + + (block 1 (param v1 i32) + (ret v1)) + + (block 2 + (let (v19 i32) (const.i32 1)) + (let (v20 i32) (const.i32 255)) + (let (v21 i32) (band v7 v20)) + (let (v22 i1) (neq v21 0)) + (condbr v22 (block 4 v0 v19) (block 5))) + + (block 3 + (let (v14 i32) (const.i32 255)) + (let (v15 i32) (band v7 v14)) + (let (v16 i32) (const.i32 0)) + (let (v17 i1) (neq v15 v16)) + (let (v18 i32) (zext v17)) + (ret v18)) + + (block 4 (param v74 i32) (param v75 i32) + (let (v76 u32) (bitcast v75)) + (let (v77 u8) (trunc v76)) + (let (v78 u32) (bitcast v74)) + (let (v79 u32) (add.checked v78 4)) + (let (v80 (ptr u8)) (inttoptr v79)) + (store v80 v77) + (br (block 1 v75))) + + (block 5 + (let (v23 u32) (bitcast v0)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) + (let (v25 (ptr i32)) (inttoptr v23)) + (let (v26 i32) (load v25)) + (let (v27 u32) (bitcast v26)) + (let (v28 u32) (add.checked v27 28)) + (let (v29 (ptr u8)) (inttoptr v28)) + (let (v30 u8) (load v29)) + (let (v31 i32) (zext v30)) + (let (v32 i32) (const.i32 4)) + (let (v33 i32) (band v31 v32)) + (let (v34 i1) (neq v33 0)) + (condbr v34 (block 6) (block 7))) + + (block 6 + (let (v57 u32) (bitcast v26)) + (let (v58 u32) (add.checked v57 20)) + (let (v59 u32) (mod.unchecked v58 4)) + (assertz 250 v59) + (let (v60 (ptr i32)) (inttoptr v58)) + (let (v61 i32) (load v60)) + (let (v62 i32) (const.i32 1048966)) + (let (v63 i32) (const.i32 1)) + (let (v64 u32) (bitcast v26)) + (let (v65 u32) (add.checked v64 24)) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) + (let (v67 (ptr i32)) (inttoptr v65)) + (let (v68 i32) (load v67)) + (let (v69 u32) (bitcast v68)) + (let (v70 u32) (add.checked v69 12)) + (let (v71 u32) (mod.unchecked v70 4)) + (assertz 250 v71) + (let (v72 (ptr i32)) (inttoptr v70)) + (let (v73 i32) (load v72)) + (br (block 4 v0 v73))) + + (block 7 + (let (v35 u32) (bitcast v26)) + (let (v36 u32) (add.checked v35 20)) + (let (v37 u32) (mod.unchecked v36 4)) + (assertz 250 v37) + (let (v38 (ptr i32)) (inttoptr v36)) + (let (v39 i32) (load v38)) + (let (v40 i32) (const.i32 1048967)) + (let (v41 i32) (const.i32 2)) + (let (v42 u32) (bitcast v26)) + (let (v43 u32) (add.checked v42 24)) + (let (v44 u32) (mod.unchecked v43 4)) + (assertz 250 v44) + (let (v45 (ptr i32)) (inttoptr v43)) + (let (v46 i32) (load v45)) + (let (v47 u32) (bitcast v46)) + (let (v48 u32) (add.checked v47 12)) + (let (v49 u32) (mod.unchecked v48 4)) + (assertz 250 v49) + (let (v50 (ptr i32)) (inttoptr v48)) + (let (v51 i32) (load v50)) + (let (v52 u32) (bitcast v51)) + (let (v53 u8) (trunc v52)) + (let (v54 u32) (bitcast v41)) + (let (v55 u32) (add.checked v54 4)) + (let (v56 (ptr u8)) (inttoptr v55)) + (store v56 v53) + (ret v51)) + ) + + (func (export #core::fmt::Formatter::pad_integral) + (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 + (param v0 i32) + (param v1 i32) + (param v2 i32) + (param v3 i32) + (param v4 i32) + (param v5 i32) + (let (v7 i32) (const.i32 0)) + (let (v8 i1) (neq v1 0)) + (condbr v8 (block 3) (block 4))) + + (block 1 (param v6 i32) + (ret v6)) + + (block 2 + (param v29 i32) + (param v34 i32) + (param v41 i32) + (param v134 i32) + (param v140 i32) + (param v162 i32) + (param v178 i32) + (param v184 i32) + (let (v30 i32) (const.i32 4)) + (let (v31 i32) (band v29 v30)) + (let (v32 i1) (neq v31 0)) + (condbr v32 (block 6) (block 7))) + + (block 3 + (let (v17 i32) (const.i32 43)) + (let (v18 i32) (const.i32 1114112)) + (let (v19 u32) (bitcast v0)) + (let (v20 u32) (add.checked v19 28)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) + (let (v22 (ptr i32)) (inttoptr v20)) + (let (v23 i32) (load v22)) + (let (v24 i32) (const.i32 1)) + (let (v25 i32) (band v23 v24)) + (let (v26 i1) (neq v25 0)) + (let (v27 i32) (select v26 v17 v18)) + (let (v28 i32) (add.wrapping v25 v5)) + (br (block 2 v23 v3 v2 v28 v0 v27 v4 v5))) + + (block 4 + (let (v9 i32) (const.i32 1)) + (let (v10 i32) (add.wrapping v5 v9)) + (let (v11 u32) (bitcast v0)) + (let (v12 u32) (add.checked v11 28)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) + (let (v14 (ptr i32)) (inttoptr v12)) + (let (v15 i32) (load v14)) + (let (v16 i32) (const.i32 45)) + (br (block 2 v15 v3 v2 v10 v0 v16 v4 v5))) + + (block 5 + (param v139 i32) + (param v161 i32) + (param v167 i32) + (param v170 i32) + (param v177 i32) + (param v183 i32) + (param v199 i32) + (param v223 i32) + (let (v145 u32) (bitcast v139)) + (let (v146 u32) (mod.unchecked v145 4)) + (assertz 250 v146) + (let (v147 (ptr i32)) (inttoptr v145)) + (let (v148 i32) (load v147)) + (let (v149 i1) (neq v148 0)) + (condbr v149 (block 24) (block 25))) + + (block 6 + (let (v35 i32) (const.i32 16)) + (let (v36 u32) (bitcast v34)) + (let (v37 u32) (bitcast v35)) + (let (v38 i1) (lt v36 v37)) + (let (v39 i32) (sext v38)) + (let (v40 i1) (neq v39 0)) + (condbr v40 (block 9) (block 10))) + + (block 7 + (let (v33 i32) (const.i32 0)) + (br (block 5 v140 v162 v33 v34 v178 v184 v134 v29))) + + (block 8 + (param v132 i32) + (param v133 i32) + (param v141 i32) + (param v163 i32) + (param v168 i32) + (param v171 i32) + (param v179 i32) + (param v185 i32) + (param v224 i32) + (let (v138 i32) (add.wrapping v132 v133)) + (br (block 5 v141 v163 v168 v171 v179 v185 v138 v224))) + + (block 9 + (let (v43 i1) (neq v34 0)) + (condbr v43 (block 11) (block 12))) + + (block 10 + (let (v42 i32) (call #core::str::count::do_count_chars v41 v34)) + (br (block 8 v42 v134 v140 v162 v41 v34 v178 v184 v29))) + + (block 11 + (let (v45 i32) (const.i32 3)) + (let (v46 i32) (band v34 v45)) + (let (v47 i32) (const.i32 4)) + (let (v48 u32) (bitcast v34)) + (let (v49 u32) (bitcast v47)) + (let (v50 i1) (gte v48 v49)) + (let (v51 i32) (zext v50)) + (let (v52 i1) (neq v51 0)) + (condbr v52 (block 14) (block 15))) + + (block 12 + (let (v44 i32) (const.i32 0)) + (br (block 8 v44 v134 v140 v162 v41 v34 v178 v184 v29))) + + (block 13 + (param v107 i32) + (param v112 i32) + (param v113 i32) + (param v131 i32) + (param v135 i32) + (param v142 i32) + (param v164 i32) + (param v172 i32) + (param v180 i32) + (param v186 i32) + (param v225 i32) + (let (v109 i1) (eq v107 0)) + (let (v110 i32) (zext v109)) + (let (v111 i1) (neq v110 0)) + (condbr v111 (block 8 v131 v135 v142 v164 v112 v172 v180 v186 v225) (block 19))) + + (block 14 + (let (v55 i32) (const.i32 12)) + (let (v56 i32) (band v34 v55)) + (let (v57 i32) (const.i32 0)) + (let (v58 i32) (const.i32 0)) + (br (block 16 v57 v41 v58 v56 v46 v134 v140 v162 v34 v178 v184 v29))) + + (block 15 + (let (v53 i32) (const.i32 0)) + (let (v54 i32) (const.i32 0)) + (br (block 13 v46 v41 v54 v53 v134 v140 v162 v34 v178 v184 v29))) + + (block 16 + (param v59 i32) + (param v60 i32) + (param v61 i32) + (param v101 i32) + (param v108 i32) + (param v136 i32) + (param v143 i32) + (param v165 i32) + (param v173 i32) + (param v181 i32) + (param v187 i32) + (param v226 i32) + (let (v62 i32) (add.wrapping v60 v61)) + (let (v63 u32) (bitcast v62)) + (let (v64 (ptr i8)) (inttoptr v63)) + (let (v65 i8) (load v64)) + (let (v66 i32) (sext v65)) + (let (v67 i32) (const.i32 -65)) + (let (v68 i1) (gt v66 v67)) + (let (v69 i32) (zext v68)) + (let (v70 i32) (add.wrapping v59 v69)) + (let (v71 i32) (const.i32 1)) + (let (v72 i32) (add.wrapping v62 v71)) + (let (v73 u32) (bitcast v72)) + (let (v74 (ptr i8)) (inttoptr v73)) + (let (v75 i8) (load v74)) + (let (v76 i32) (sext v75)) + (let (v77 i32) (const.i32 -65)) + (let (v78 i1) (gt v76 v77)) + (let (v79 i32) (zext v78)) + (let (v80 i32) (add.wrapping v70 v79)) + (let (v81 i32) (const.i32 2)) + (let (v82 i32) (add.wrapping v62 v81)) + (let (v83 u32) (bitcast v82)) + (let (v84 (ptr i8)) (inttoptr v83)) + (let (v85 i8) (load v84)) + (let (v86 i32) (sext v85)) + (let (v87 i32) (const.i32 -65)) + (let (v88 i1) (gt v86 v87)) + (let (v89 i32) (zext v88)) + (let (v90 i32) (add.wrapping v80 v89)) + (let (v91 i32) (const.i32 3)) + (let (v92 i32) (add.wrapping v62 v91)) + (let (v93 u32) (bitcast v92)) + (let (v94 (ptr i8)) (inttoptr v93)) + (let (v95 i8) (load v94)) + (let (v96 i32) (sext v95)) + (let (v97 i32) (const.i32 -65)) + (let (v98 i1) (gt v96 v97)) + (let (v99 i32) (zext v98)) + (let (v100 i32) (add.wrapping v90 v99)) + (let (v102 i32) (const.i32 4)) + (let (v103 i32) (add.wrapping v61 v102)) + (let (v104 i1) (neq v101 v103)) + (let (v105 i32) (zext v104)) + (let (v106 i1) (neq v105 0)) + (condbr v106 (block 16 v100 v60 v103 v101 v108 v136 v143 v165 v173 v181 v187 v226) (block 18))) + + (block 17 + (br (block 13 v108 v60 v103 v100 v136 v143 v165 v173 v181 v187 v226))) + + (block 18 + (br (block 17))) + + (block 19 + (let (v114 i32) (add.wrapping v112 v113)) + (br (block 20 v131 v114 v107 v135 v142 v164 v112 v172 v180 v186 v225))) + + (block 20 + (param v115 i32) + (param v116 i32) + (param v127 i32) + (param v137 i32) + (param v144 i32) + (param v166 i32) + (param v169 i32) + (param v174 i32) + (param v182 i32) + (param v188 i32) + (param v227 i32) + (let (v117 u32) (bitcast v116)) + (let (v118 (ptr i8)) (inttoptr v117)) + (let (v119 i8) (load v118)) + (let (v120 i32) (sext v119)) + (let (v121 i32) (const.i32 -65)) + (let (v122 i1) (gt v120 v121)) + (let (v123 i32) (zext v122)) + (let (v124 i32) (add.wrapping v115 v123)) + (let (v125 i32) (const.i32 1)) + (let (v126 i32) (add.wrapping v116 v125)) + (let (v128 i32) (const.i32 -1)) + (let (v129 i32) (add.wrapping v127 v128)) + (let (v130 i1) (neq v129 0)) + (condbr v130 (block 20 v124 v126 v129 v137 v144 v166 v169 v174 v182 v188 v227) (block 22))) + + (block 21 + (br (block 8 v124 v137 v144 v166 v169 v174 v182 v188 v227))) + + (block 22 + (br (block 21))) + + (block 23 (param v417 i32) + (br (block 1 v417))) + + (block 24 + (let (v194 u32) (bitcast v139)) + (let (v195 u32) (add.checked v194 4)) + (let (v196 u32) (mod.unchecked v195 4)) + (assertz 250 v196) + (let (v197 (ptr i32)) (inttoptr v195)) + (let (v198 i32) (load v197)) + (let (v200 u32) (bitcast v198)) + (let (v201 u32) (bitcast v199)) + (let (v202 i1) (gt v200 v201)) + (let (v203 i32) (sext v202)) + (let (v204 i1) (neq v203 0)) + (condbr v204 (block 27) (block 28))) + + (block 25 + (let (v150 i32) (const.i32 1)) + (let (v151 u32) (bitcast v139)) + (let (v152 u32) (add.checked v151 20)) + (let (v153 u32) (mod.unchecked v152 4)) + (assertz 250 v153) + (let (v154 (ptr i32)) (inttoptr v152)) + (let (v155 i32) (load v154)) + (let (v156 u32) (bitcast v139)) + (let (v157 u32) (add.checked v156 24)) + (let (v158 u32) (mod.unchecked v157 4)) + (assertz 250 v158) + (let (v159 (ptr i32)) (inttoptr v157)) + (let (v160 i32) (load v159)) + (let (v175 i32) (call #core::fmt::Formatter::pad_integral::write_prefix v155 v160 v161 v167 v170)) + (let (v176 i1) (neq v175 0)) + (condbr v176 (block 23 v150) (block 26))) + + (block 26 + (let (v189 u32) (bitcast v160)) + (let (v190 u32) (add.checked v189 12)) + (let (v191 u32) (mod.unchecked v190 4)) + (assertz 250 v191) + (let (v192 (ptr i32)) (inttoptr v190)) + (let (v193 i32) (load v192)) + (ret v193)) + + (block 27 + (let (v228 i32) (const.i32 8)) + (let (v229 i32) (band v223 v228)) + (let (v230 i1) (eq v229 0)) + (let (v231 i32) (zext v230)) + (let (v232 i1) (neq v231 0)) + (condbr v232 (block 30) (block 31))) + + (block 28 + (let (v205 i32) (const.i32 1)) + (let (v206 u32) (bitcast v139)) + (let (v207 u32) (add.checked v206 20)) + (let (v208 u32) (mod.unchecked v207 4)) + (assertz 250 v208) + (let (v209 (ptr i32)) (inttoptr v207)) + (let (v210 i32) (load v209)) + (let (v211 u32) (bitcast v139)) + (let (v212 u32) (add.checked v211 24)) + (let (v213 u32) (mod.unchecked v212 4)) + (assertz 250 v213) + (let (v214 (ptr i32)) (inttoptr v212)) + (let (v215 i32) (load v214)) + (let (v216 i32) (call #core::fmt::Formatter::pad_integral::write_prefix v210 v215 v161 v167 v170)) + (let (v217 i1) (neq v216 0)) + (condbr v217 (block 23 v205) (block 29))) + + (block 29 + (let (v218 u32) (bitcast v215)) + (let (v219 u32) (add.checked v218 12)) + (let (v220 u32) (mod.unchecked v219 4)) + (assertz 250 v220) + (let (v221 (ptr i32)) (inttoptr v219)) + (let (v222 i32) (load v221)) + (ret v222)) + + (block 30 + (let (v310 i32) (sub.wrapping v198 v199)) + (let (v311 u32) (bitcast v139)) + (let (v312 u32) (add.checked v311 32)) + (let (v313 (ptr u8)) (inttoptr v312)) + (let (v314 u8) (load v313)) + (let (v315 i32) (zext v314)) + (let (v316 u32) (cast v315)) + (switchv316 + (0 . (block 41)) + (1 . (block 41)) + (2 . (block 40)) + (3 . (block 39 v315 v139 v161 v167 v170 v177 v183 v310)) + (_ . (block 39 v315 v139 v161 v167 v170 v177 v183 v310)))) + + (block 31 + (let (v233 u32) (bitcast v139)) + (let (v234 u32) (add.checked v233 16)) + (let (v235 u32) (mod.unchecked v234 4)) + (assertz 250 v235) + (let (v236 (ptr i32)) (inttoptr v234)) + (let (v237 i32) (load v236)) + (let (v238 i32) (const.i32 48)) + (let (v239 u32) (bitcast v139)) + (let (v240 u32) (add.checked v239 16)) + (let (v241 u32) (mod.unchecked v240 4)) + (assertz 250 v241) + (let (v242 (ptr i32)) (inttoptr v240)) + (store v242 v238) + (let (v243 u32) (bitcast v139)) + (let (v244 u32) (add.checked v243 32)) + (let (v245 (ptr u8)) (inttoptr v244)) + (let (v246 u8) (load v245)) + (let (v247 i32) (zext v246)) + (let (v248 i32) (const.i32 1)) + (let (v249 i32) (const.i32 1)) + (let (v250 u32) (bitcast v249)) + (let (v251 u8) (trunc v250)) + (let (v252 u32) (bitcast v139)) + (let (v253 u32) (add.checked v252 32)) + (let (v254 (ptr u8)) (inttoptr v253)) + (store v254 v251) + (let (v255 u32) (bitcast v139)) + (let (v256 u32) (add.checked v255 20)) + (let (v257 u32) (mod.unchecked v256 4)) + (assertz 250 v257) + (let (v258 (ptr i32)) (inttoptr v256)) + (let (v259 i32) (load v258)) + (let (v260 u32) (bitcast v139)) + (let (v261 u32) (add.checked v260 24)) + (let (v262 u32) (mod.unchecked v261 4)) + (assertz 250 v262) + (let (v263 (ptr i32)) (inttoptr v261)) + (let (v264 i32) (load v263)) + (let (v265 i32) (call #core::fmt::Formatter::pad_integral::write_prefix v259 v264 v161 v167 v170)) + (let (v266 i1) (neq v265 0)) + (condbr v266 (block 23 v248) (block 32))) + + (block 32 + (let (v267 i32) (sub.wrapping v198 v199)) + (let (v268 i32) (const.i32 1)) + (let (v269 i32) (add.wrapping v267 v268)) + (br (block 34 v269 v259 v264 v177 v183 v139 v247 v237))) + + (block 33 + (let (v288 i32) (const.i32 1)) + (let (v291 u32) (bitcast v278)) + (let (v292 u32) (add.checked v291 12)) + (let (v293 u32) (mod.unchecked v292 4)) + (assertz 250 v293) + (let (v294 (ptr i32)) (inttoptr v292)) + (let (v295 i32) (load v294)) + (let (v296 i1) (neq v295 0)) + (condbr v296 (block 23 v288) (block 38))) + + (block 34 + (param v270 i32) + (param v276 i32) + (param v278 i32) + (param v289 i32) + (param v290 i32) + (param v297 i32) + (param v298 i32) + (param v304 i32) + (let (v271 i32) (const.i32 -1)) + (let (v272 i32) (add.wrapping v270 v271)) + (let (v273 i1) (eq v272 0)) + (let (v274 i32) (zext v273)) + (let (v275 i1) (neq v274 0)) + (condbr v275 (block 33) (block 36))) + + (block 35 + (let (v287 i32) (const.i32 1)) + (ret v287)) + + (block 36 + (let (v277 i32) (const.i32 48)) + (let (v279 u32) (bitcast v278)) + (let (v280 u32) (add.checked v279 16)) + (let (v281 u32) (mod.unchecked v280 4)) + (assertz 250 v281) + (let (v282 (ptr i32)) (inttoptr v280)) + (let (v283 i32) (load v282)) + (let (v284 i1) (eq v283 0)) + (let (v285 i32) (zext v284)) + (let (v286 i1) (neq v285 0)) + (condbr v286 (block 34 v272 v276 v278 v289 v290 v297 v298 v304) (block 37))) + + (block 37 + (br (block 35))) + + (block 38 + (let (v299 u32) (bitcast v298)) + (let (v300 u8) (trunc v299)) + (let (v301 u32) (bitcast v297)) + (let (v302 u32) (add.checked v301 32)) + (let (v303 (ptr u8)) (inttoptr v302)) + (store v303 v300) + (let (v305 u32) (bitcast v297)) + (let (v306 u32) (add.checked v305 16)) + (let (v307 u32) (mod.unchecked v306 4)) + (assertz 250 v307) + (let (v308 (ptr i32)) (inttoptr v306)) + (store v308 v304) + (let (v309 i32) (const.i32 0)) + (br (block 23 v309))) + + (block 39 + (param v330 i32) + (param v333 i32) + (param v369 i32) + (param v371 i32) + (param v373 i32) + (param v377 i32) + (param v379 i32) + (param v410 i32) + (let (v331 i32) (const.i32 1)) + (let (v332 i32) (add.wrapping v330 v331)) + (let (v334 u32) (bitcast v333)) + (let (v335 u32) (add.checked v334 16)) + (let (v336 u32) (mod.unchecked v335 4)) + (assertz 250 v336) + (let (v337 (ptr i32)) (inttoptr v335)) + (let (v338 i32) (load v337)) + (let (v339 u32) (bitcast v333)) + (let (v340 u32) (add.checked v339 24)) + (let (v341 u32) (mod.unchecked v340 4)) + (assertz 250 v341) + (let (v342 (ptr i32)) (inttoptr v340)) + (let (v343 i32) (load v342)) + (let (v344 u32) (bitcast v333)) + (let (v345 u32) (add.checked v344 20)) + (let (v346 u32) (mod.unchecked v345 4)) + (assertz 250 v346) + (let (v347 (ptr i32)) (inttoptr v345)) + (let (v348 i32) (load v347)) + (br (block 43 v332 v348 v338 v343 v369 v371 v373 v377 v379 v410))) + + (block 40 + (let (v318 i32) (const.i32 1)) + (let (v319 u32) (bitcast v310)) + (let (v320 u32) (bitcast v318)) + (let (v321 u32) (shr.wrapping v319 v320)) + (let (v322 i32) (bitcast v321)) + (let (v323 i32) (const.i32 1)) + (let (v324 i32) (add.wrapping v310 v323)) + (let (v325 i32) (const.i32 1)) + (let (v326 u32) (bitcast v324)) + (let (v327 u32) (bitcast v325)) + (let (v328 u32) (shr.wrapping v326 v327)) + (let (v329 i32) (bitcast v328)) + (br (block 39 v322 v139 v161 v167 v170 v177 v183 v329))) + + (block 41 + (let (v317 i32) (const.i32 0)) + (br (block 39 v310 v139 v161 v167 v170 v177 v183 v317))) + + (block 42 + (let (v367 i32) (const.i32 1)) + (let (v374 i32) (call #core::fmt::Formatter::pad_integral::write_prefix v355 v357 v368 v370 v372)) + (let (v375 i1) (neq v374 0)) + (condbr v375 (block 23 v367) (block 47))) + + (block 43 + (param v349 i32) + (param v355 i32) + (param v356 i32) + (param v357 i32) + (param v368 i32) + (param v370 i32) + (param v372 i32) + (param v376 i32) + (param v378 i32) + (param v409 i32) + (let (v350 i32) (const.i32 -1)) + (let (v351 i32) (add.wrapping v349 v350)) + (let (v352 i1) (eq v351 0)) + (let (v353 i32) (zext v352)) + (let (v354 i1) (neq v353 0)) + (condbr v354 (block 42) (block 45))) + + (block 44 + (let (v366 i32) (const.i32 1)) + (ret v366)) + + (block 45 + (let (v358 u32) (bitcast v357)) + (let (v359 u32) (add.checked v358 16)) + (let (v360 u32) (mod.unchecked v359 4)) + (assertz 250 v360) + (let (v361 (ptr i32)) (inttoptr v359)) + (let (v362 i32) (load v361)) + (let (v363 i1) (eq v362 0)) + (let (v364 i32) (zext v363)) + (let (v365 i1) (neq v364 0)) + (condbr v365 (block 43 v351 v355 v356 v357 v368 v370 v372 v376 v378 v409) (block 46))) + + (block 46 + (br (block 44))) + + (block 47 + (let (v380 u32) (bitcast v357)) + (let (v381 u32) (add.checked v380 12)) + (let (v382 u32) (mod.unchecked v381 4)) + (assertz 250 v382) + (let (v383 (ptr i32)) (inttoptr v381)) + (let (v384 i32) (load v383)) + (let (v385 i1) (neq v384 0)) + (condbr v385 (block 23 v367) (block 48))) + + (block 48 + (let (v386 i32) (const.i32 0)) + (br (block 49 v409 v386 v355 v356 v357))) + + (block 49 + (param v387 i32) + (param v388 i32) + (param v398 i32) + (param v399 i32) + (param v400 i32) + (let (v389 i1) (neq v387 v388)) + (let (v390 i32) (zext v389)) + (let (v391 i1) (neq v390 0)) + (condbr v391 (block 51) (block 52))) + + (block 50 + (let (v411 i32) (const.i32 -1)) + (let (v412 i32) (add.wrapping v397 v411)) + (let (v413 u32) (bitcast v412)) + (let (v414 u32) (bitcast v387)) + (let (v415 i1) (lt v413 v414)) + (let (v416 i32) (sext v415)) + (ret v416)) + + (block 51 + (let (v396 i32) (const.i32 1)) + (let (v397 i32) (add.wrapping v388 v396)) + (let (v401 u32) (bitcast v400)) + (let (v402 u32) (add.checked v401 16)) + (let (v403 u32) (mod.unchecked v402 4)) + (assertz 250 v403) + (let (v404 (ptr i32)) (inttoptr v402)) + (let (v405 i32) (load v404)) + (let (v406 i1) (eq v405 0)) + (let (v407 i32) (zext v406)) + (let (v408 i1) (neq v407 0)) + (condbr v408 (block 49 v387 v397 v398 v399 v400) (block 53))) + + (block 52 + (let (v392 u32) (bitcast v387)) + (let (v393 u32) (bitcast v387)) + (let (v394 i1) (lt v392 v393)) + (let (v395 i32) (sext v394)) + (ret v395)) + + (block 53 + (br (block 50))) + ) + + (func (export #core::fmt::Write::write_fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 1048928)) + (let (v4 i32) (call #core::fmt::write v0 v3 v1)) + (br (block 1 v4))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #core::str::count::do_count_chars) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i32) (const.i32 3)) + (let (v5 i32) (add.wrapping v0 v4)) + (let (v6 i32) (const.i32 -4)) + (let (v7 i32) (band v5 v6)) + (let (v8 i32) (sub.wrapping v7 v0)) + (let (v9 u32) (bitcast v1)) + (let (v10 u32) (bitcast v8)) + (let (v11 i1) (lt v9 v10)) + (let (v12 i32) (sext v11)) + (let (v13 i1) (neq v12 0)) + (condbr v13 (block 3 v1 v0) (block 4))) + + (block 1 (param v2 i32) + (ret v2)) + + (block 2 (param v520 i32) + (br (block 1 v520))) + + (block 3 (param v429 i32) (param v494 i32) + (let (v430 i1) (neq v429 0)) + (condbr v430 (block 34) (block 35))) + + (block 4 + (let (v14 i32) (sub.wrapping v1 v8)) + (let (v15 i32) (const.i32 4)) + (let (v16 u32) (bitcast v14)) + (let (v17 u32) (bitcast v15)) + (let (v18 i1) (lt v16 v17)) + (let (v19 i32) (sext v18)) + (let (v20 i1) (neq v19 0)) + (condbr v20 (block 3 v1 v0) (block 5))) + + (block 5 + (let (v21 i32) (const.i32 3)) + (let (v22 i32) (band v14 v21)) + (let (v23 i32) (const.i32 0)) + (let (v24 i32) (const.i32 0)) + (let (v25 i1) (eq v7 v0)) + (let (v26 i32) (zext v25)) + (let (v27 i1) (neq v26 0)) + (condbr v27 (block 6 v0 v8 v22 v14 v23 v24) (block 7))) + + (block 6 + (param v108 i32) + (param v110 i32) + (param v115 i32) + (param v122 i32) + (param v169 i32) + (param v174 i32) + (let (v114 i32) (add.wrapping v108 v110)) + (let (v119 i1) (eq v115 0)) + (let (v120 i32) (zext v119)) + (let (v121 i1) (neq v120 0)) + (condbr v121 (block 18 v122 v169 v174 v114) (block 19))) + + (block 7 + (let (v28 i32) (const.i32 0)) + (let (v29 i32) (sub.wrapping v0 v7)) + (let (v30 i32) (const.i32 -4)) + (let (v31 u32) (bitcast v29)) + (let (v32 u32) (bitcast v30)) + (let (v33 i1) (lte v31 v32)) + (let (v34 i32) (sext v33)) + (let (v35 i1) (neq v34 0)) + (condbr v35 (block 9) (block 10))) + + (block 8 + (param v83 i32) + (param v86 i32) + (param v87 i32) + (param v105 i32) + (param v106 i32) + (param v111 i32) + (param v116 i32) + (param v123 i32) + (param v170 i32) + (let (v85 i1) (neq v83 0)) + (condbr v85 (block 6 v86 v111 v116 v123 v170 v105) (block 14))) + + (block 9 + (let (v37 i32) (const.i32 0)) + (br (block 11 v28 v0 v37 v26 v29 v8 v22 v14 v23))) + + (block 10 + (let (v36 i32) (const.i32 0)) + (br (block 8 v26 v0 v36 v28 v29 v8 v22 v14 v23))) + + (block 11 + (param v38 i32) + (param v39 i32) + (param v40 i32) + (param v84 i32) + (param v107 i32) + (param v112 i32) + (param v117 i32) + (param v124 i32) + (param v171 i32) + (let (v41 i32) (add.wrapping v39 v40)) + (let (v42 u32) (bitcast v41)) + (let (v43 (ptr i8)) (inttoptr v42)) + (let (v44 i8) (load v43)) + (let (v45 i32) (sext v44)) + (let (v46 i32) (const.i32 -65)) + (let (v47 i1) (gt v45 v46)) + (let (v48 i32) (zext v47)) + (let (v49 i32) (add.wrapping v38 v48)) + (let (v50 i32) (const.i32 1)) + (let (v51 i32) (add.wrapping v41 v50)) + (let (v52 u32) (bitcast v51)) + (let (v53 (ptr i8)) (inttoptr v52)) + (let (v54 i8) (load v53)) + (let (v55 i32) (sext v54)) + (let (v56 i32) (const.i32 -65)) + (let (v57 i1) (gt v55 v56)) + (let (v58 i32) (zext v57)) + (let (v59 i32) (add.wrapping v49 v58)) + (let (v60 i32) (const.i32 2)) + (let (v61 i32) (add.wrapping v41 v60)) + (let (v62 u32) (bitcast v61)) + (let (v63 (ptr i8)) (inttoptr v62)) + (let (v64 i8) (load v63)) + (let (v65 i32) (sext v64)) + (let (v66 i32) (const.i32 -65)) + (let (v67 i1) (gt v65 v66)) + (let (v68 i32) (zext v67)) + (let (v69 i32) (add.wrapping v59 v68)) + (let (v70 i32) (const.i32 3)) + (let (v71 i32) (add.wrapping v41 v70)) + (let (v72 u32) (bitcast v71)) + (let (v73 (ptr i8)) (inttoptr v72)) + (let (v74 i8) (load v73)) + (let (v75 i32) (sext v74)) + (let (v76 i32) (const.i32 -65)) + (let (v77 i1) (gt v75 v76)) + (let (v78 i32) (zext v77)) + (let (v79 i32) (add.wrapping v69 v78)) + (let (v80 i32) (const.i32 4)) + (let (v81 i32) (add.wrapping v40 v80)) + (let (v82 i1) (neq v81 0)) + (condbr v82 (block 11 v79 v39 v81 v84 v107 v112 v117 v124 v171) (block 13))) + + (block 12 + (br (block 8 v84 v39 v81 v79 v107 v112 v117 v124 v171))) + + (block 13 + (br (block 12))) + + (block 14 + (let (v88 i32) (add.wrapping v86 v87)) + (br (block 15 v105 v88 v106 v86 v111 v116 v123 v170))) + + (block 15 + (param v89 i32) + (param v90 i32) + (param v101 i32) + (param v109 i32) + (param v113 i32) + (param v118 i32) + (param v125 i32) + (param v172 i32) + (let (v91 u32) (bitcast v90)) + (let (v92 (ptr i8)) (inttoptr v91)) + (let (v93 i8) (load v92)) + (let (v94 i32) (sext v93)) + (let (v95 i32) (const.i32 -65)) + (let (v96 i1) (gt v94 v95)) + (let (v97 i32) (zext v96)) + (let (v98 i32) (add.wrapping v89 v97)) + (let (v99 i32) (const.i32 1)) + (let (v100 i32) (add.wrapping v90 v99)) + (let (v102 i32) (const.i32 1)) + (let (v103 i32) (add.wrapping v101 v102)) + (let (v104 i1) (neq v103 0)) + (condbr v104 (block 15 v98 v100 v103 v109 v113 v118 v125 v172) (block 17))) + + (block 16 + (br (block 6 v109 v113 v118 v125 v172 v98))) + + (block 17 + (br (block 16))) + + (block 18 + (param v162 i32) + (param v168 i32) + (param v173 i32) + (param v333 i32) + (let (v163 i32) (const.i32 2)) + (let (v164 u32) (bitcast v162)) + (let (v165 u32) (bitcast v163)) + (let (v166 u32) (shr.wrapping v164 v165)) + (let (v167 i32) (bitcast v166)) + (let (v175 i32) (add.wrapping v168 v173)) + (br (block 22 v333 v167 v175))) + + (block 19 + (let (v126 i32) (const.i32 -4)) + (let (v127 i32) (band v122 v126)) + (let (v128 i32) (add.wrapping v114 v127)) + (let (v129 u32) (bitcast v128)) + (let (v130 (ptr i8)) (inttoptr v129)) + (let (v131 i8) (load v130)) + (let (v132 i32) (sext v131)) + (let (v133 i32) (const.i32 -65)) + (let (v134 i1) (gt v132 v133)) + (let (v135 i32) (zext v134)) + (let (v136 i32) (const.i32 1)) + (let (v137 i1) (eq v115 v136)) + (let (v138 i32) (zext v137)) + (let (v139 i1) (neq v138 0)) + (condbr v139 (block 18 v122 v135 v174 v114) (block 20))) + + (block 20 + (let (v140 u32) (bitcast v128)) + (let (v141 u32) (add.checked v140 1)) + (let (v142 (ptr i8)) (inttoptr v141)) + (let (v143 i8) (load v142)) + (let (v144 i32) (sext v143)) + (let (v145 i32) (const.i32 -65)) + (let (v146 i1) (gt v144 v145)) + (let (v147 i32) (zext v146)) + (let (v148 i32) (add.wrapping v135 v147)) + (let (v149 i32) (const.i32 2)) + (let (v150 i1) (eq v115 v149)) + (let (v151 i32) (zext v150)) + (let (v152 i1) (neq v151 0)) + (condbr v152 (block 18 v122 v148 v174 v114) (block 21))) + + (block 21 + (let (v153 u32) (bitcast v128)) + (let (v154 u32) (add.checked v153 2)) + (let (v155 (ptr i8)) (inttoptr v154)) + (let (v156 i8) (load v155)) + (let (v157 i32) (sext v156)) + (let (v158 i32) (const.i32 -65)) + (let (v159 i1) (gt v157 v158)) + (let (v160 i32) (zext v159)) + (let (v161 i32) (add.wrapping v148 v160)) + (br (block 18 v122 v161 v174 v114))) + + (block 22 (param v176 i32) (param v177 i32) (param v325 i32) + (let (v178 i1) (eq v177 0)) + (let (v179 i32) (zext v178)) + (let (v180 i1) (neq v179 0)) + (condbr v180 (block 2 v325) (block 24))) + + (block 23 + (let (v334 i32) (const.i32 252)) + (let (v335 i32) (band v298 v334)) + (let (v336 i32) (const.i32 2)) + (let (v337 u32) (bitcast v336)) + (let (v338 i32) (shl.wrapping v335 v337)) + (let (v339 i32) (add.wrapping v301 v338)) + (let (v340 u32) (bitcast v339)) + (let (v341 u32) (mod.unchecked v340 4)) + (assertz 250 v341) + (let (v342 (ptr i32)) (inttoptr v340)) + (let (v343 i32) (load v342)) + (let (v344 i32) (const.i32 -1)) + (let (v345 i32) (bxor v343 v344)) + (let (v346 i32) (const.i32 7)) + (let (v347 u32) (bitcast v345)) + (let (v348 u32) (bitcast v346)) + (let (v349 u32) (shr.wrapping v347 v348)) + (let (v350 i32) (bitcast v349)) + (let (v351 i32) (const.i32 6)) + (let (v352 u32) (bitcast v343)) + (let (v353 u32) (bitcast v351)) + (let (v354 u32) (shr.wrapping v352 v353)) + (let (v355 i32) (bitcast v354)) + (let (v356 i32) (bor v350 v355)) + (let (v357 i32) (const.i32 16843009)) + (let (v358 i32) (band v356 v357)) + (let (v359 i32) (const.i32 1)) + (let (v360 i1) (eq v328 v359)) + (let (v361 i32) (zext v360)) + (let (v362 i1) (neq v361 0)) + (condbr v362 (block 31 v358 v327) (block 32))) + + (block 24 + (let (v181 i32) (const.i32 192)) + (let (v182 i32) (const.i32 192)) + (let (v183 u32) (bitcast v177)) + (let (v184 u32) (bitcast v182)) + (let (v185 i1) (lt v183 v184)) + (let (v186 i32) (sext v185)) + (let (v187 i1) (neq v186 0)) + (let (v188 i32) (select v187 v177 v181)) + (let (v189 i32) (const.i32 3)) + (let (v190 i32) (band v188 v189)) + (let (v191 i32) (const.i32 2)) + (let (v192 u32) (bitcast v191)) + (let (v193 i32) (shl.wrapping v188 v192)) + (let (v194 i32) (const.i32 0)) + (let (v195 i32) (const.i32 4)) + (let (v196 u32) (bitcast v177)) + (let (v197 u32) (bitcast v195)) + (let (v198 i1) (lt v196 v197)) + (let (v199 i32) (sext v198)) + (let (v200 i1) (neq v199 0)) + (condbr v200 (block 25 v177 v188 v176 v193 v194 v325 v190) (block 26))) + + (block 25 + (param v296 i32) + (param v298 i32) + (param v301 i32) + (param v303 i32) + (param v306 i32) + (param v324 i32) + (param v328 i32) + (let (v300 i32) (sub.wrapping v296 v298)) + (let (v305 i32) (add.wrapping v301 v303)) + (let (v307 i32) (const.i32 8)) + (let (v308 u32) (bitcast v306)) + (let (v309 u32) (bitcast v307)) + (let (v310 u32) (shr.wrapping v308 v309)) + (let (v311 i32) (bitcast v310)) + (let (v312 i32) (const.i32 16711935)) + (let (v313 i32) (band v311 v312)) + (let (v314 i32) (const.i32 16711935)) + (let (v315 i32) (band v306 v314)) + (let (v316 i32) (add.wrapping v313 v315)) + (let (v317 i32) (const.i32 65537)) + (let (v318 i32) (mul.wrapping v316 v317)) + (let (v319 i32) (const.i32 16)) + (let (v320 u32) (bitcast v318)) + (let (v321 u32) (bitcast v319)) + (let (v322 u32) (shr.wrapping v320 v321)) + (let (v323 i32) (bitcast v322)) + (let (v327 i32) (add.wrapping v323 v324)) + (let (v330 i1) (eq v328 0)) + (let (v331 i32) (zext v330)) + (let (v332 i1) (neq v331 0)) + (condbr v332 (block 22 v305 v300 v327) (block 30))) + + (block 26 + (let (v201 i32) (const.i32 1008)) + (let (v202 i32) (band v193 v201)) + (let (v203 i32) (add.wrapping v176 v202)) + (let (v204 i32) (const.i32 0)) + (br (block 27 v176 v204 v203 v177 v188 v176 v193 v325 v190))) + + (block 27 + (param v205 i32) + (param v285 i32) + (param v292 i32) + (param v297 i32) + (param v299 i32) + (param v302 i32) + (param v304 i32) + (param v326 i32) + (param v329 i32) + (let (v206 u32) (bitcast v205)) + (let (v207 u32) (add.checked v206 12)) + (let (v208 u32) (mod.unchecked v207 4)) + (assertz 250 v208) + (let (v209 (ptr i32)) (inttoptr v207)) + (let (v210 i32) (load v209)) + (let (v211 i32) (const.i32 -1)) + (let (v212 i32) (bxor v210 v211)) + (let (v213 i32) (const.i32 7)) + (let (v214 u32) (bitcast v212)) + (let (v215 u32) (bitcast v213)) + (let (v216 u32) (shr.wrapping v214 v215)) + (let (v217 i32) (bitcast v216)) + (let (v218 i32) (const.i32 6)) + (let (v219 u32) (bitcast v210)) + (let (v220 u32) (bitcast v218)) + (let (v221 u32) (shr.wrapping v219 v220)) + (let (v222 i32) (bitcast v221)) + (let (v223 i32) (bor v217 v222)) + (let (v224 i32) (const.i32 16843009)) + (let (v225 i32) (band v223 v224)) + (let (v226 u32) (bitcast v205)) + (let (v227 u32) (add.checked v226 8)) + (let (v228 u32) (mod.unchecked v227 4)) + (assertz 250 v228) + (let (v229 (ptr i32)) (inttoptr v227)) + (let (v230 i32) (load v229)) + (let (v231 i32) (const.i32 -1)) + (let (v232 i32) (bxor v230 v231)) + (let (v233 i32) (const.i32 7)) + (let (v234 u32) (bitcast v232)) + (let (v235 u32) (bitcast v233)) + (let (v236 u32) (shr.wrapping v234 v235)) + (let (v237 i32) (bitcast v236)) + (let (v238 i32) (const.i32 6)) + (let (v239 u32) (bitcast v230)) + (let (v240 u32) (bitcast v238)) + (let (v241 u32) (shr.wrapping v239 v240)) + (let (v242 i32) (bitcast v241)) + (let (v243 i32) (bor v237 v242)) + (let (v244 i32) (const.i32 16843009)) + (let (v245 i32) (band v243 v244)) + (let (v246 u32) (bitcast v205)) + (let (v247 u32) (add.checked v246 4)) + (let (v248 u32) (mod.unchecked v247 4)) + (assertz 250 v248) + (let (v249 (ptr i32)) (inttoptr v247)) + (let (v250 i32) (load v249)) + (let (v251 i32) (const.i32 -1)) + (let (v252 i32) (bxor v250 v251)) + (let (v253 i32) (const.i32 7)) + (let (v254 u32) (bitcast v252)) + (let (v255 u32) (bitcast v253)) + (let (v256 u32) (shr.wrapping v254 v255)) + (let (v257 i32) (bitcast v256)) + (let (v258 i32) (const.i32 6)) + (let (v259 u32) (bitcast v250)) + (let (v260 u32) (bitcast v258)) + (let (v261 u32) (shr.wrapping v259 v260)) + (let (v262 i32) (bitcast v261)) + (let (v263 i32) (bor v257 v262)) + (let (v264 i32) (const.i32 16843009)) + (let (v265 i32) (band v263 v264)) + (let (v266 u32) (bitcast v205)) + (let (v267 u32) (mod.unchecked v266 4)) + (assertz 250 v267) + (let (v268 (ptr i32)) (inttoptr v266)) + (let (v269 i32) (load v268)) + (let (v270 i32) (const.i32 -1)) + (let (v271 i32) (bxor v269 v270)) + (let (v272 i32) (const.i32 7)) + (let (v273 u32) (bitcast v271)) + (let (v274 u32) (bitcast v272)) + (let (v275 u32) (shr.wrapping v273 v274)) + (let (v276 i32) (bitcast v275)) + (let (v277 i32) (const.i32 6)) + (let (v278 u32) (bitcast v269)) + (let (v279 u32) (bitcast v277)) + (let (v280 u32) (shr.wrapping v278 v279)) + (let (v281 i32) (bitcast v280)) + (let (v282 i32) (bor v276 v281)) + (let (v283 i32) (const.i32 16843009)) + (let (v284 i32) (band v282 v283)) + (let (v286 i32) (add.wrapping v284 v285)) + (let (v287 i32) (add.wrapping v265 v286)) + (let (v288 i32) (add.wrapping v245 v287)) + (let (v289 i32) (add.wrapping v225 v288)) + (let (v290 i32) (const.i32 16)) + (let (v291 i32) (add.wrapping v205 v290)) + (let (v293 i1) (neq v291 v292)) + (let (v294 i32) (zext v293)) + (let (v295 i1) (neq v294 0)) + (condbr v295 (block 27 v291 v289 v292 v297 v299 v302 v304 v326 v329) (block 29))) + + (block 28 + (br (block 25 v297 v299 v302 v304 v289 v326 v329))) + + (block 29 + (br (block 28))) + + (block 30 + (br (block 23))) + + (block 31 (param v409 i32) (param v427 i32) + (let (v410 i32) (const.i32 8)) + (let (v411 u32) (bitcast v409)) + (let (v412 u32) (bitcast v410)) + (let (v413 u32) (shr.wrapping v411 v412)) + (let (v414 i32) (bitcast v413)) + (let (v415 i32) (const.i32 459007)) + (let (v416 i32) (band v414 v415)) + (let (v417 i32) (const.i32 16711935)) + (let (v418 i32) (band v409 v417)) + (let (v419 i32) (add.wrapping v416 v418)) + (let (v420 i32) (const.i32 65537)) + (let (v421 i32) (mul.wrapping v419 v420)) + (let (v422 i32) (const.i32 16)) + (let (v423 u32) (bitcast v421)) + (let (v424 u32) (bitcast v422)) + (let (v425 u32) (shr.wrapping v423 v424)) + (let (v426 i32) (bitcast v425)) + (let (v428 i32) (add.wrapping v426 v427)) + (ret v428)) + + (block 32 + (let (v363 u32) (bitcast v339)) + (let (v364 u32) (add.checked v363 4)) + (let (v365 u32) (mod.unchecked v364 4)) + (assertz 250 v365) + (let (v366 (ptr i32)) (inttoptr v364)) + (let (v367 i32) (load v366)) + (let (v368 i32) (const.i32 -1)) + (let (v369 i32) (bxor v367 v368)) + (let (v370 i32) (const.i32 7)) + (let (v371 u32) (bitcast v369)) + (let (v372 u32) (bitcast v370)) + (let (v373 u32) (shr.wrapping v371 v372)) + (let (v374 i32) (bitcast v373)) + (let (v375 i32) (const.i32 6)) + (let (v376 u32) (bitcast v367)) + (let (v377 u32) (bitcast v375)) + (let (v378 u32) (shr.wrapping v376 v377)) + (let (v379 i32) (bitcast v378)) + (let (v380 i32) (bor v374 v379)) + (let (v381 i32) (const.i32 16843009)) + (let (v382 i32) (band v380 v381)) + (let (v383 i32) (add.wrapping v382 v358)) + (let (v384 i32) (const.i32 2)) + (let (v385 i1) (eq v328 v384)) + (let (v386 i32) (zext v385)) + (let (v387 i1) (neq v386 0)) + (condbr v387 (block 31 v383 v327) (block 33))) + + (block 33 + (let (v388 u32) (bitcast v339)) + (let (v389 u32) (add.checked v388 8)) + (let (v390 u32) (mod.unchecked v389 4)) + (assertz 250 v390) + (let (v391 (ptr i32)) (inttoptr v389)) + (let (v392 i32) (load v391)) + (let (v393 i32) (const.i32 -1)) + (let (v394 i32) (bxor v392 v393)) + (let (v395 i32) (const.i32 7)) + (let (v396 u32) (bitcast v394)) + (let (v397 u32) (bitcast v395)) + (let (v398 u32) (shr.wrapping v396 v397)) + (let (v399 i32) (bitcast v398)) + (let (v400 i32) (const.i32 6)) + (let (v401 u32) (bitcast v392)) + (let (v402 u32) (bitcast v400)) + (let (v403 u32) (shr.wrapping v401 v402)) + (let (v404 i32) (bitcast v403)) + (let (v405 i32) (bor v399 v404)) + (let (v406 i32) (const.i32 16843009)) + (let (v407 i32) (band v405 v406)) + (let (v408 i32) (add.wrapping v407 v383)) + (br (block 31 v408 v327))) + + (block 34 + (let (v432 i32) (const.i32 3)) + (let (v433 i32) (band v429 v432)) + (let (v434 i32) (const.i32 4)) + (let (v435 u32) (bitcast v429)) + (let (v436 u32) (bitcast v434)) + (let (v437 i1) (gte v435 v436)) + (let (v438 i32) (zext v437)) + (let (v439 i1) (neq v438 0)) + (condbr v439 (block 37) (block 38))) + + (block 35 + (let (v431 i32) (const.i32 0)) + (ret v431)) + + (block 36 + (param v495 i32) + (param v500 i32) + (param v501 i32) + (param v519 i32) + (let (v497 i1) (eq v495 0)) + (let (v498 i32) (zext v497)) + (let (v499 i1) (neq v498 0)) + (condbr v499 (block 2 v519) (block 42))) + + (block 37 + (let (v442 i32) (const.i32 -4)) + (let (v443 i32) (band v429 v442)) + (let (v444 i32) (const.i32 0)) + (let (v445 i32) (const.i32 0)) + (br (block 39 v444 v494 v445 v443 v433))) + + (block 38 + (let (v440 i32) (const.i32 0)) + (let (v441 i32) (const.i32 0)) + (br (block 36 v433 v494 v441 v440))) + + (block 39 + (param v446 i32) + (param v447 i32) + (param v448 i32) + (param v488 i32) + (param v496 i32) + (let (v449 i32) (add.wrapping v447 v448)) + (let (v450 u32) (bitcast v449)) + (let (v451 (ptr i8)) (inttoptr v450)) + (let (v452 i8) (load v451)) + (let (v453 i32) (sext v452)) + (let (v454 i32) (const.i32 -65)) + (let (v455 i1) (gt v453 v454)) + (let (v456 i32) (zext v455)) + (let (v457 i32) (add.wrapping v446 v456)) + (let (v458 i32) (const.i32 1)) + (let (v459 i32) (add.wrapping v449 v458)) + (let (v460 u32) (bitcast v459)) + (let (v461 (ptr i8)) (inttoptr v460)) + (let (v462 i8) (load v461)) + (let (v463 i32) (sext v462)) + (let (v464 i32) (const.i32 -65)) + (let (v465 i1) (gt v463 v464)) + (let (v466 i32) (zext v465)) + (let (v467 i32) (add.wrapping v457 v466)) + (let (v468 i32) (const.i32 2)) + (let (v469 i32) (add.wrapping v449 v468)) + (let (v470 u32) (bitcast v469)) + (let (v471 (ptr i8)) (inttoptr v470)) + (let (v472 i8) (load v471)) + (let (v473 i32) (sext v472)) + (let (v474 i32) (const.i32 -65)) + (let (v475 i1) (gt v473 v474)) + (let (v476 i32) (zext v475)) + (let (v477 i32) (add.wrapping v467 v476)) + (let (v478 i32) (const.i32 3)) + (let (v479 i32) (add.wrapping v449 v478)) + (let (v480 u32) (bitcast v479)) + (let (v481 (ptr i8)) (inttoptr v480)) + (let (v482 i8) (load v481)) + (let (v483 i32) (sext v482)) + (let (v484 i32) (const.i32 -65)) + (let (v485 i1) (gt v483 v484)) + (let (v486 i32) (zext v485)) + (let (v487 i32) (add.wrapping v477 v486)) + (let (v489 i32) (const.i32 4)) + (let (v490 i32) (add.wrapping v448 v489)) + (let (v491 i1) (neq v488 v490)) + (let (v492 i32) (zext v491)) + (let (v493 i1) (neq v492 0)) + (condbr v493 (block 39 v487 v447 v490 v488 v496) (block 41))) + + (block 40 + (br (block 36 v496 v447 v490 v487))) + + (block 41 + (br (block 40))) + + (block 42 + (let (v502 i32) (add.wrapping v500 v501)) + (br (block 43 v519 v502 v495))) + + (block 43 (param v503 i32) (param v504 i32) (param v515 i32) + (let (v505 u32) (bitcast v504)) + (let (v506 (ptr i8)) (inttoptr v505)) + (let (v507 i8) (load v506)) + (let (v508 i32) (sext v507)) + (let (v509 i32) (const.i32 -65)) + (let (v510 i1) (gt v508 v509)) + (let (v511 i32) (zext v510)) + (let (v512 i32) (add.wrapping v503 v511)) + (let (v513 i32) (const.i32 1)) + (let (v514 i32) (add.wrapping v504 v513)) + (let (v516 i32) (const.i32 -1)) + (let (v517 i32) (add.wrapping v515 v516)) + (let (v518 i1) (neq v517 0)) + (condbr v518 (block 43 v512 v514 v517) (block 45))) + + (block 44 + (br (block 2 v512))) + + (block 45 + (br (block 44))) + ) + + (func (export #core::fmt::Formatter::pad_integral::write_prefix) + (param i32) (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 + (param v0 i32) + (param v1 i32) + (param v2 i32) + (param v3 i32) + (param v4 i32) + (let (v6 i32) (const.i32 0)) + (let (v7 i32) (const.i32 1114112)) + (let (v8 i1) (eq v2 v7)) + (let (v9 i32) (zext v8)) + (let (v10 i1) (neq v9 0)) + (condbr v10 (block 4 v3 v0 v4 v1) (block 5))) + + (block 1 (param v5 i32) + (ret v5)) + + (block 2 + (let (v25 u32) (bitcast v24)) + (let (v26 u32) (add.checked v25 12)) + (let (v27 u32) (mod.unchecked v26 4)) + (assertz 250 v27) + (let (v28 (ptr i32)) (inttoptr v26)) + (let (v29 i32) (load v28)) + (br (block 1 v29))) + + (block 3 (param v21 i32) + (ret v21)) + + (block 4 + (param v18 i32) + (param v22 i32) + (param v23 i32) + (param v24 i32) + (let (v19 i1) (neq v18 0)) + (condbr v19 (block 2) (block 7))) + + (block 5 + (let (v11 i32) (const.i32 1)) + (let (v12 u32) (bitcast v1)) + (let (v13 u32) (add.checked v12 16)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) + (let (v15 (ptr i32)) (inttoptr v13)) + (let (v16 i32) (load v15)) + (let (v17 i1) (neq v16 0)) + (condbr v17 (block 3 v11) (block 6))) + + (block 6 + (br (block 4 v3 v0 v4 v1))) + + (block 7 + (let (v20 i32) (const.i32 0)) + (br (block 3 v20))) + ) + + (func (export #core::fmt::Formatter::debug_struct) + (param i32) (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v4 u32) (bitcast v1)) + (let (v5 u32) (add.checked v4 20)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) + (let (v7 (ptr i32)) (inttoptr v5)) + (let (v8 i32) (load v7)) + (let (v9 u32) (bitcast v1)) + (let (v10 u32) (add.checked v9 24)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) + (let (v12 (ptr i32)) (inttoptr v10)) + (let (v13 i32) (load v12)) + (let (v14 u32) (bitcast v13)) + (let (v15 u32) (add.checked v14 12)) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) + (let (v17 (ptr i32)) (inttoptr v15)) + (let (v18 i32) (load v17)) + (let (v19 i32) (const.i32 0)) + (let (v20 u32) (bitcast v19)) + (let (v21 u8) (trunc v20)) + (let (v22 u32) (bitcast v0)) + (let (v23 u32) (add.checked v22 5)) + (let (v24 (ptr u8)) (inttoptr v23)) + (store v24 v21) + (let (v25 u32) (bitcast v18)) + (let (v26 u8) (trunc v25)) + (let (v27 u32) (bitcast v0)) + (let (v28 u32) (add.checked v27 4)) + (let (v29 (ptr u8)) (inttoptr v28)) + (store v29 v26) + (let (v30 u32) (bitcast v0)) + (let (v31 u32) (mod.unchecked v30 4)) + (assertz 250 v31) + (let (v32 (ptr i32)) (inttoptr v30)) + (store v32 v1) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #core::slice::index::slice_start_index_len_fail_rt) + (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i64) (const.i64 0)) + (let (v5 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v6 i32) (const.i32 48)) + (let (v7 i32) (sub.wrapping v5 v6)) + (let (v8 (ptr i32)) (global.symbol #__stack_pointer)) + (store v8 v7) + (let (v9 u32) (bitcast v7)) + (let (v10 u32) (add.checked v9 4)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) + (let (v12 (ptr i32)) (inttoptr v10)) + (store v12 v1) + (let (v13 u32) (bitcast v7)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) + (let (v15 (ptr i32)) (inttoptr v13)) + (store v15 v0) + (let (v16 i32) (const.i32 2)) + (let (v17 u32) (bitcast v7)) + (let (v18 u32) (add.checked v17 12)) + (let (v19 u32) (mod.unchecked v18 4)) + (assertz 250 v19) + (let (v20 (ptr i32)) (inttoptr v18)) + (store v20 v16) + (let (v21 i32) (const.i32 1049268)) + (let (v22 u32) (bitcast v7)) + (let (v23 u32) (add.checked v22 8)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) + (let (v25 (ptr i32)) (inttoptr v23)) + (store v25 v21) + (let (v26 i64) (const.i64 2)) + (let (v27 u32) (bitcast v7)) + (let (v28 u32) (add.checked v27 20)) + (let (v29 u32) (mod.unchecked v28 4)) + (assertz 250 v29) + (let (v30 (ptr i64)) (inttoptr v28)) + (store v30 v26) + (let (v31 i32) (const.i32 7)) + (let (v32 u32) (bitcast v31)) + (let (v33 u64) (zext v32)) + (let (v34 i64) (bitcast v33)) + (let (v35 i64) (const.i64 32)) + (let (v36 u32) (cast v35)) + (let (v37 i64) (shl.wrapping v34 v36)) + (let (v38 i32) (const.i32 4)) + (let (v39 i32) (add.wrapping v7 v38)) + (let (v40 u32) (bitcast v39)) + (let (v41 u64) (zext v40)) + (let (v42 i64) (bitcast v41)) + (let (v43 i64) (bor v37 v42)) + (let (v44 u32) (bitcast v7)) + (let (v45 u32) (add.checked v44 40)) + (let (v46 u32) (mod.unchecked v45 8)) + (assertz 250 v46) + (let (v47 (ptr i64)) (inttoptr v45)) + (store v47 v43) + (let (v48 u32) (bitcast v7)) + (let (v49 u64) (zext v48)) + (let (v50 i64) (bitcast v49)) + (let (v51 i64) (bor v37 v50)) + (let (v52 u32) (bitcast v7)) + (let (v53 u32) (add.checked v52 32)) + (let (v54 u32) (mod.unchecked v53 8)) + (assertz 250 v54) + (let (v55 (ptr i64)) (inttoptr v53)) + (store v55 v51) + (let (v56 i32) (const.i32 32)) + (let (v57 i32) (add.wrapping v7 v56)) + (let (v58 u32) (bitcast v7)) + (let (v59 u32) (add.checked v58 16)) + (let (v60 u32) (mod.unchecked v59 4)) + (assertz 250 v60) + (let (v61 (ptr i32)) (inttoptr v59)) + (store v61 v57) + (let (v62 i32) (const.i32 8)) + (let (v63 i32) (add.wrapping v7 v62)) + (call #core::panicking::panic_fmt v63 v2) + (unreachable)) + + (block 1) + ) + + (func (export #core::fmt::num::imp::::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 u32) (bitcast v0)) + (let (v4 u32) (mod.unchecked v3 8)) + (assertz 250 v4) + (let (v5 (ptr i64)) (inttoptr v3)) + (let (v6 i64) (load v5)) + (let (v7 i32) (const.i32 1)) + (let (v8 i32) (call #core::fmt::num::imp::fmt_u64 v6 v7 v1)) + (br (block 1 v8))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #core::fmt::num::imp::fmt_u64) + (param i64) (param i32) (param i32) (result i32) + (block 0 (param v0 i64) (param v1 i32) (param v2 i32) + (let (v4 i32) (const.i32 0)) + (let (v5 i64) (const.i64 0)) + (let (v6 i32) (const.i32 0)) + (let (v7 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v8 i32) (const.i32 48)) + (let (v9 i32) (sub.wrapping v7 v8)) + (let (v10 (ptr i32)) (global.symbol #__stack_pointer)) + (store v10 v9) + (let (v11 i32) (const.i32 39)) + (let (v12 i64) (const.i64 10000)) + (let (v13 u64) (bitcast v0)) + (let (v14 u64) (bitcast v12)) + (let (v15 i1) (gte v13 v14)) + (let (v16 i32) (zext v15)) + (let (v17 i1) (neq v16 0)) + (condbr v17 (block 3) (block 4))) + + (block 1 (param v3 i32) + (ret v3)) + + (block 2 + (param v84 i64) + (param v92 i32) + (param v95 i32) + (param v165 i32) + (param v169 i32) + (let (v85 i32) (trunc v84)) + (let (v86 i32) (const.i32 99)) + (let (v87 u32) (bitcast v85)) + (let (v88 u32) (bitcast v86)) + (let (v89 i1) (lte v87 v88)) + (let (v90 i32) (sext v89)) + (let (v91 i1) (neq v90 0)) + (condbr v91 (block 8 v85 v92 v95 v165 v169) (block 9))) + + (block 3 + (let (v18 i32) (const.i32 39)) + (br (block 5 v9 v18 v0 v2 v1))) + + (block 4 + (br (block 2 v0 v9 v11 v2 v1))) + + (block 5 + (param v19 i32) + (param v22 i32) + (param v26 i64) + (param v166 i32) + (param v170 i32) + (let (v20 i32) (const.i32 9)) + (let (v21 i32) (add.wrapping v19 v20)) + (let (v23 i32) (add.wrapping v21 v22)) + (let (v24 i32) (const.i32 -4)) + (let (v25 i32) (add.wrapping v23 v24)) + (let (v27 i64) (const.i64 10000)) + (let (v28 u64) (bitcast v26)) + (let (v29 u64) (bitcast v27)) + (let (v30 u64) (div.unchecked v28 v29)) + (let (v31 i64) (bitcast v30)) + (let (v32 i64) (const.i64 10000)) + (let (v33 i64) (mul.wrapping v31 v32)) + (let (v34 i64) (sub.wrapping v26 v33)) + (let (v35 i32) (trunc v34)) + (let (v36 i32) (const.i32 65535)) + (let (v37 i32) (band v35 v36)) + (let (v38 i32) (const.i32 100)) + (let (v39 u32) (bitcast v37)) + (let (v40 u32) (bitcast v38)) + (let (v41 u32) (div.unchecked v39 v40)) + (let (v42 i32) (bitcast v41)) + (let (v43 i32) (const.i32 1)) + (let (v44 u32) (bitcast v43)) + (let (v45 i32) (shl.wrapping v42 v44)) + (let (v46 i32) (const.i32 1049014)) + (let (v47 i32) (add.wrapping v45 v46)) + (let (v48 u32) (bitcast v47)) + (let (v49 (ptr u16)) (inttoptr v48)) + (let (v50 u16) (load v49)) + (let (v51 i32) (zext v50)) + (let (v52 u32) (bitcast v51)) + (let (v53 u16) (trunc v52)) + (let (v54 u32) (bitcast v25)) + (let (v55 (ptr u16)) (inttoptr v54)) + (store v55 v53) + (let (v56 i32) (const.i32 -2)) + (let (v57 i32) (add.wrapping v23 v56)) + (let (v58 i32) (const.i32 100)) + (let (v59 i32) (mul.wrapping v42 v58)) + (let (v60 i32) (sub.wrapping v35 v59)) + (let (v61 i32) (const.i32 65535)) + (let (v62 i32) (band v60 v61)) + (let (v63 i32) (const.i32 1)) + (let (v64 u32) (bitcast v63)) + (let (v65 i32) (shl.wrapping v62 v64)) + (let (v66 i32) (const.i32 1049014)) + (let (v67 i32) (add.wrapping v65 v66)) + (let (v68 u32) (bitcast v67)) + (let (v69 (ptr u16)) (inttoptr v68)) + (let (v70 u16) (load v69)) + (let (v71 i32) (zext v70)) + (let (v72 u32) (bitcast v71)) + (let (v73 u16) (trunc v72)) + (let (v74 u32) (bitcast v57)) + (let (v75 (ptr u16)) (inttoptr v74)) + (store v75 v73) + (let (v76 i32) (const.i32 -4)) + (let (v77 i32) (add.wrapping v22 v76)) + (let (v78 i64) (const.i64 99999999)) + (let (v79 u64) (bitcast v26)) + (let (v80 u64) (bitcast v78)) + (let (v81 i1) (gt v79 v80)) + (let (v82 i32) (sext v81)) + (let (v83 i1) (neq v82 0)) + (condbr v83 (block 5 v19 v77 v31 v166 v170) (block 7))) + + (block 6 + (br (block 2 v31 v19 v77 v166 v170))) + + (block 7 + (br (block 6))) + + (block 8 + (param v125 i32) + (param v132 i32) + (param v135 i32) + (param v164 i32) + (param v168 i32) + (let (v126 i32) (const.i32 10)) + (let (v127 u32) (bitcast v125)) + (let (v128 u32) (bitcast v126)) + (let (v129 i1) (lt v127 v128)) + (let (v130 i32) (sext v129)) + (let (v131 i1) (neq v130 0)) + (condbr v131 (block 11) (block 12))) + + (block 9 + (let (v93 i32) (const.i32 9)) + (let (v94 i32) (add.wrapping v92 v93)) + (let (v96 i32) (const.i32 -2)) + (let (v97 i32) (add.wrapping v95 v96)) + (let (v98 i32) (add.wrapping v94 v97)) + (let (v99 i32) (trunc v84)) + (let (v100 i32) (const.i32 65535)) + (let (v101 i32) (band v99 v100)) + (let (v102 i32) (const.i32 100)) + (let (v103 u32) (bitcast v101)) + (let (v104 u32) (bitcast v102)) + (let (v105 u32) (div.unchecked v103 v104)) + (let (v106 i32) (bitcast v105)) + (let (v107 i32) (const.i32 100)) + (let (v108 i32) (mul.wrapping v106 v107)) + (let (v109 i32) (sub.wrapping v99 v108)) + (let (v110 i32) (const.i32 65535)) + (let (v111 i32) (band v109 v110)) + (let (v112 i32) (const.i32 1)) + (let (v113 u32) (bitcast v112)) + (let (v114 i32) (shl.wrapping v111 v113)) + (let (v115 i32) (const.i32 1049014)) + (let (v116 i32) (add.wrapping v114 v115)) + (let (v117 u32) (bitcast v116)) + (let (v118 (ptr u16)) (inttoptr v117)) + (let (v119 u16) (load v118)) + (let (v120 i32) (zext v119)) + (let (v121 u32) (bitcast v120)) + (let (v122 u16) (trunc v121)) + (let (v123 u32) (bitcast v98)) + (let (v124 (ptr u16)) (inttoptr v123)) + (store v124 v122) + (br (block 8 v106 v92 v97 v165 v169))) + + (block 10 + (param v163 i32) + (param v167 i32) + (param v173 i32) + (param v176 i32) + (let (v171 i32) (const.i32 1)) + (let (v172 i32) (const.i32 0)) + (let (v174 i32) (const.i32 9)) + (let (v175 i32) (add.wrapping v173 v174)) + (let (v177 i32) (add.wrapping v175 v176)) + (let (v178 i32) (const.i32 39)) + (let (v179 i32) (sub.wrapping v178 v176)) + (let (v180 i32) (call #core::fmt::Formatter::pad_integral v163 v167 v171 v172 v177 v179)) + (let (v181 i32) (const.i32 48)) + (let (v182 i32) (add.wrapping v173 v181)) + (let (v183 (ptr i32)) (global.symbol #__stack_pointer)) + (store v183 v182) + (br (block 1 v180))) + + (block 11 + (let (v152 i32) (const.i32 9)) + (let (v153 i32) (add.wrapping v132 v152)) + (let (v154 i32) (const.i32 -1)) + (let (v155 i32) (add.wrapping v135 v154)) + (let (v156 i32) (add.wrapping v153 v155)) + (let (v157 i32) (const.i32 48)) + (let (v158 i32) (bor v125 v157)) + (let (v159 u32) (bitcast v158)) + (let (v160 u8) (trunc v159)) + (let (v161 u32) (bitcast v156)) + (let (v162 (ptr u8)) (inttoptr v161)) + (store v162 v160) + (br (block 10 v164 v168 v132 v155))) + + (block 12 + (let (v133 i32) (const.i32 9)) + (let (v134 i32) (add.wrapping v132 v133)) + (let (v136 i32) (const.i32 -2)) + (let (v137 i32) (add.wrapping v135 v136)) + (let (v138 i32) (add.wrapping v134 v137)) + (let (v139 i32) (const.i32 1)) + (let (v140 u32) (bitcast v139)) + (let (v141 i32) (shl.wrapping v125 v140)) + (let (v142 i32) (const.i32 1049014)) + (let (v143 i32) (add.wrapping v141 v142)) + (let (v144 u32) (bitcast v143)) + (let (v145 (ptr u16)) (inttoptr v144)) + (let (v146 u16) (load v145)) + (let (v147 i32) (zext v146)) + (let (v148 u32) (bitcast v147)) + (let (v149 u16) (trunc v148)) + (let (v150 u32) (bitcast v138)) + (let (v151 (ptr u16)) (inttoptr v150)) + (store v151 v149) + (br (block 10 v164 v168 v132 v137))) + ) + + (func (export #core::fmt::num::::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i64) (const.i64 0)) + (let (v5 i32) (const.i32 0)) + (let (v6 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v7 i32) (const.i32 128)) + (let (v8 i32) (sub.wrapping v6 v7)) + (let (v9 (ptr i32)) (global.symbol #__stack_pointer)) + (store v9 v8) + (let (v10 u32) (bitcast v0)) + (let (v11 u32) (mod.unchecked v10 8)) + (assertz 250 v11) + (let (v12 (ptr i64)) (inttoptr v10)) + (let (v13 i64) (load v12)) + (let (v14 i32) (const.i32 0)) + (br (block 2 v8 v14 v13 v1))) + + (block 1 (param v2 i32) + (ret v2)) + + (block 2 + (param v15 i32) + (param v16 i32) + (param v20 i64) + (param v64 i32) + (let (v17 i32) (add.wrapping v15 v16)) + (let (v18 i32) (const.i32 127)) + (let (v19 i32) (add.wrapping v17 v18)) + (let (v21 i32) (trunc v20)) + (let (v22 i32) (const.i32 15)) + (let (v23 i32) (band v21 v22)) + (let (v24 i32) (const.i32 48)) + (let (v25 i32) (bor v23 v24)) + (let (v26 i32) (const.i32 87)) + (let (v27 i32) (add.wrapping v23 v26)) + (let (v28 i32) (const.i32 10)) + (let (v29 u32) (bitcast v23)) + (let (v30 u32) (bitcast v28)) + (let (v31 i1) (lt v29 v30)) + (let (v32 i32) (sext v31)) + (let (v33 i1) (neq v32 0)) + (let (v34 i32) (select v33 v25 v27)) + (let (v35 u32) (bitcast v34)) + (let (v36 u8) (trunc v35)) + (let (v37 u32) (bitcast v19)) + (let (v38 (ptr u8)) (inttoptr v37)) + (store v38 v36) + (let (v39 i32) (const.i32 -1)) + (let (v40 i32) (add.wrapping v16 v39)) + (let (v41 i64) (const.i64 16)) + (let (v42 u64) (bitcast v20)) + (let (v43 u64) (bitcast v41)) + (let (v44 i1) (lt v42 v43)) + (let (v45 i32) (sext v44)) + (let (v46 i64) (const.i64 4)) + (let (v47 u64) (bitcast v20)) + (let (v48 u32) (cast v46)) + (let (v49 u64) (shr.wrapping v47 v48)) + (let (v50 i64) (bitcast v49)) + (let (v51 i1) (eq v45 0)) + (let (v52 i32) (zext v51)) + (let (v53 i1) (neq v52 0)) + (condbr v53 (block 2 v15 v40 v50 v64) (block 4))) + + (block 3 + (let (v54 i32) (const.i32 128)) + (let (v55 i32) (add.wrapping v40 v54)) + (let (v56 i32) (const.i32 129)) + (let (v57 u32) (bitcast v55)) + (let (v58 u32) (bitcast v56)) + (let (v59 i1) (lt v57 v58)) + (let (v60 i32) (sext v59)) + (let (v61 i1) (neq v60 0)) + (condbr v61 (block 5) (block 6))) + + (block 4 + (br (block 3))) + + (block 5 + (let (v65 i32) (const.i32 1)) + (let (v66 i32) (const.i32 1049012)) + (let (v67 i32) (const.i32 2)) + (let (v68 i32) (add.wrapping v15 v40)) + (let (v69 i32) (const.i32 128)) + (let (v70 i32) (add.wrapping v68 v69)) + (let (v71 i32) (const.i32 0)) + (let (v72 i32) (sub.wrapping v71 v40)) + (let (v73 i32) (call #core::fmt::Formatter::pad_integral v64 v65 v66 v67 v70 v72)) + (let (v74 i32) (const.i32 128)) + (let (v75 i32) (add.wrapping v15 v74)) + (let (v76 (ptr i32)) (global.symbol #__stack_pointer)) + (store v76 v75) + (br (block 1 v73))) + + (block 6 + (let (v62 i32) (const.i32 128)) + (let (v63 i32) (const.i32 1048996)) + (call #core::slice::index::slice_start_index_len_fail v55 v62 v63) + (unreachable)) + ) + + (func (export #core::fmt::num::::fmt) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i64) (const.i64 0)) + (let (v5 i32) (const.i32 0)) + (let (v6 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v7 i32) (const.i32 128)) + (let (v8 i32) (sub.wrapping v6 v7)) + (let (v9 (ptr i32)) (global.symbol #__stack_pointer)) + (store v9 v8) + (let (v10 u32) (bitcast v0)) + (let (v11 u32) (mod.unchecked v10 8)) + (assertz 250 v11) + (let (v12 (ptr i64)) (inttoptr v10)) + (let (v13 i64) (load v12)) + (let (v14 i32) (const.i32 0)) + (br (block 2 v8 v14 v13 v1))) + + (block 1 (param v2 i32) + (ret v2)) + + (block 2 + (param v15 i32) + (param v16 i32) + (param v20 i64) + (param v64 i32) + (let (v17 i32) (add.wrapping v15 v16)) + (let (v18 i32) (const.i32 127)) + (let (v19 i32) (add.wrapping v17 v18)) + (let (v21 i32) (trunc v20)) + (let (v22 i32) (const.i32 15)) + (let (v23 i32) (band v21 v22)) + (let (v24 i32) (const.i32 48)) + (let (v25 i32) (bor v23 v24)) + (let (v26 i32) (const.i32 55)) + (let (v27 i32) (add.wrapping v23 v26)) + (let (v28 i32) (const.i32 10)) + (let (v29 u32) (bitcast v23)) + (let (v30 u32) (bitcast v28)) + (let (v31 i1) (lt v29 v30)) + (let (v32 i32) (sext v31)) + (let (v33 i1) (neq v32 0)) + (let (v34 i32) (select v33 v25 v27)) + (let (v35 u32) (bitcast v34)) + (let (v36 u8) (trunc v35)) + (let (v37 u32) (bitcast v19)) + (let (v38 (ptr u8)) (inttoptr v37)) + (store v38 v36) + (let (v39 i32) (const.i32 -1)) + (let (v40 i32) (add.wrapping v16 v39)) + (let (v41 i64) (const.i64 16)) + (let (v42 u64) (bitcast v20)) + (let (v43 u64) (bitcast v41)) + (let (v44 i1) (lt v42 v43)) + (let (v45 i32) (sext v44)) + (let (v46 i64) (const.i64 4)) + (let (v47 u64) (bitcast v20)) + (let (v48 u32) (cast v46)) + (let (v49 u64) (shr.wrapping v47 v48)) + (let (v50 i64) (bitcast v49)) + (let (v51 i1) (eq v45 0)) + (let (v52 i32) (zext v51)) + (let (v53 i1) (neq v52 0)) + (condbr v53 (block 2 v15 v40 v50 v64) (block 4))) + + (block 3 + (let (v54 i32) (const.i32 128)) + (let (v55 i32) (add.wrapping v40 v54)) + (let (v56 i32) (const.i32 129)) + (let (v57 u32) (bitcast v55)) + (let (v58 u32) (bitcast v56)) + (let (v59 i1) (lt v57 v58)) + (let (v60 i32) (sext v59)) + (let (v61 i1) (neq v60 0)) + (condbr v61 (block 5) (block 6))) + + (block 4 + (br (block 3))) + + (block 5 + (let (v65 i32) (const.i32 1)) + (let (v66 i32) (const.i32 1049012)) + (let (v67 i32) (const.i32 2)) + (let (v68 i32) (add.wrapping v15 v40)) + (let (v69 i32) (const.i32 128)) + (let (v70 i32) (add.wrapping v68 v69)) + (let (v71 i32) (const.i32 0)) + (let (v72 i32) (sub.wrapping v71 v40)) + (let (v73 i32) (call #core::fmt::Formatter::pad_integral v64 v65 v66 v67 v70 v72)) + (let (v74 i32) (const.i32 128)) + (let (v75 i32) (add.wrapping v15 v74)) + (let (v76 (ptr i32)) (global.symbol #__stack_pointer)) + (store v76 v75) + (br (block 1 v73))) + + (block 6 + (let (v62 i32) (const.i32 128)) + (let (v63 i32) (const.i32 1048996)) + (call #core::slice::index::slice_start_index_len_fail v55 v62 v63) + (unreachable)) + ) + + (func (export #cabi_realloc) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i32) (call #cabi_realloc_wit_bindgen_0_28_0 v0 v1 v2 v3)) + (br (block 1 v5))) + + (block 1 (param v4 i32) + (ret v4)) ) ;; Imports diff --git a/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet_p2id_note.wat b/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet_p2id_note.wat index de2b7eef..37807d4c 100644 --- a/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet_p2id_note.wat +++ b/tests/integration/expected/wit_sdk_basic_wallet/basic_wallet_p2id_note.wat @@ -52,123 +52,163 @@ ) (import "miden:basic-wallet/basic-wallet@1.0.0" (instance (;3;) (type 7))) (core module (;0;) - (type (;0;) (func (param i32))) - (type (;1;) (func (param i64) (result i64))) - (type (;2;) (func (result i64))) - (type (;3;) (func (param i64 i64 i64 i64))) - (type (;4;) (func)) - (type (;5;) (func (param i32 i32) (result i32))) - (type (;6;) (func (param i32 i32 i32 i32) (result i32))) - (type (;7;) (func (param i32 i32 i32) (result i32))) - (type (;8;) (func (param i32 i32 i32 i32))) - (import "miden:base/note@1.0.0" "get-inputs" (func $basic_wallet_p2id_note::bindings::miden::base::note::get_inputs::wit_import (;0;) (type 0))) - (import "miden:base/core-types@1.0.0" "account-id-from-felt" (func $basic_wallet_p2id_note::bindings::miden::base::core_types::account_id_from_felt::wit_import (;1;) (type 1))) - (import "miden:base/account@1.0.0" "get-id" (func $basic_wallet_p2id_note::bindings::miden::base::account::get_id::wit_import (;2;) (type 2))) - (import "miden:base/note@1.0.0" "get-assets" (func $basic_wallet_p2id_note::bindings::miden::base::note::get_assets::wit_import (;3;) (type 0))) - (import "miden:basic-wallet/basic-wallet@1.0.0" "receive-asset" (func $basic_wallet_p2id_note::bindings::miden::basic_wallet::basic_wallet::receive_asset::wit_import (;4;) (type 3))) - (func $__wasm_call_ctors (;5;) (type 4)) - (func $miden:base/note-script@1.0.0#note-script (;6;) (type 4) - (local i32 i32 i32 i32 i32 i32 i32) + (type (;0;) (func (param i32 i32 i32) (result i32))) + (type (;1;) (func (param i32 i32) (result i32))) + (type (;2;) (func (param i32))) + (type (;3;) (func (param i64) (result i64))) + (type (;4;) (func (result i64))) + (type (;5;) (func (param i64 i64 i64 i64))) + (type (;6;) (func)) + (type (;7;) (func (param i32 i32 i32))) + (type (;8;) (func (param i32 i32 i32 i32) (result i32))) + (type (;9;) (func (param i32 i32 i32 i32))) + (type (;10;) (func (param i32 i32))) + (type (;11;) (func (param i32 i32 i32 i32 i32) (result i32))) + (type (;12;) (func (param i32 i32 i32 i32 i32 i32 i32))) + (type (;13;) (func (param i32) (result i32))) + (type (;14;) (func (param i32 i32 i32 i32 i32 i32) (result i32))) + (type (;15;) (func (param i64 i32 i32) (result i32))) + (import "miden:base/note@1.0.0" "get-inputs" (func $basic_wallet_p2id_note::bindings::miden::base::note::get_inputs::wit_import (;0;) (type 2))) + (import "miden:base/core-types@1.0.0" "account-id-from-felt" (func $basic_wallet_p2id_note::bindings::miden::base::core_types::account_id_from_felt::wit_import (;1;) (type 3))) + (import "miden:base/account@1.0.0" "get-id" (func $basic_wallet_p2id_note::bindings::miden::base::account::get_id::wit_import (;2;) (type 4))) + (import "miden:base/note@1.0.0" "get-assets" (func $basic_wallet_p2id_note::bindings::miden::base::note::get_assets::wit_import (;3;) (type 2))) + (import "miden:basic-wallet/basic-wallet@1.0.0" "receive-asset" (func $basic_wallet_p2id_note::bindings::miden::basic_wallet::basic_wallet::receive_asset::wit_import (;4;) (type 5))) + (func $__wasm_call_ctors (;5;) (type 6)) + (func $<&T as core::fmt::Debug>::fmt (;6;) (type 1) (param i32 i32) (result i32) + (local i32) global.get $__stack_pointer i32.const 16 i32.sub - local.tee 0 + local.tee 2 global.set $__stack_pointer - call $wit_bindgen::rt::run_ctors_once local.get 0 + i32.load + local.set 0 + local.get 2 i32.const 8 i32.add - call $basic_wallet_p2id_note::bindings::miden::base::note::get_inputs::wit_import + local.get 1 + i32.const 1048620 + i32.const 9 + call $core::fmt::Formatter::debug_struct + local.get 2 + i32.const 8 + i32.add + i32.const 1048596 + i32.const 5 + local.get 0 + i32.const 1048632 + call $core::fmt::builders::DebugStruct::field + call $core::fmt::builders::DebugStruct::finish + local.set 0 + local.get 2 + i32.const 16 + i32.add + global.set $__stack_pointer + local.get 0 + ) + (func $core::fmt::num::::fmt (;7;) (type 1) (param i32 i32) (result i32) + (local i32) block ;; label = @1 - local.get 0 - i32.const 12 - i32.add - i32.load - local.tee 1 - i32.eqz - br_if 0 (;@1;) - local.get 0 - i32.load offset=8 + local.get 1 + i32.load offset=28 local.tee 2 - i64.load - call $basic_wallet_p2id_note::bindings::miden::base::core_types::account_id_from_felt::wit_import - call $basic_wallet_p2id_note::bindings::miden::base::account::get_id::wit_import - i64.ne + i32.const 16 + i32.and br_if 0 (;@1;) - local.get 0 - i32.const 8 - i32.add - call $basic_wallet_p2id_note::bindings::miden::base::note::get_assets::wit_import block ;; label = @2 - local.get 0 - i32.const 12 - i32.add - i32.load - local.tee 3 - i32.eqz + local.get 2 + i32.const 32 + i32.and br_if 0 (;@2;) local.get 0 - i32.load offset=8 - local.tee 4 - local.get 3 - i32.const 5 - i32.shl - i32.add - local.set 5 - local.get 4 - local.set 6 - loop ;; label = @3 - local.get 6 - i64.load - local.get 6 - i64.load offset=8 - local.get 6 - i64.load offset=16 - local.get 6 - i64.load offset=24 - call $basic_wallet_p2id_note::bindings::miden::basic_wallet::basic_wallet::receive_asset::wit_import - local.get 6 - i32.const 32 - i32.add - local.tee 6 - local.get 5 - i32.ne - br_if 0 (;@3;) - end - i32.const 1048576 - local.get 4 - i32.const 8 - local.get 3 - i32.const 5 - i32.shl - call $::dealloc + local.get 1 + call $core::fmt::num::imp::::fmt + return end - i32.const 1048576 - local.get 2 - i32.const 8 - local.get 1 - i32.const 3 - i32.shl - call $::dealloc local.get 0 - i32.const 16 - i32.add - global.set $__stack_pointer + local.get 1 + call $core::fmt::num::::fmt return end - unreachable - unreachable + local.get 0 + local.get 1 + call $core::fmt::num::::fmt ) - (func $__rust_alloc (;7;) (type 5) (param i32 i32) (result i32) + (func $core::ptr::drop_in_place (;8;) (type 2) (param i32)) + (func $core::ptr::drop_in_place<&basic_wallet_p2id_note::bindings::miden::base::core_types::AccountId> (;9;) (type 2) (param i32)) + (func $core::panicking::assert_failed (;10;) (type 7) (param i32 i32 i32) + (local i32) + global.get $__stack_pointer + i32.const 16 + i32.sub + local.tee 3 + global.set $__stack_pointer + local.get 3 + local.get 1 + i32.store offset=12 + local.get 3 + local.get 0 + i32.store offset=8 + i32.const 0 + local.get 3 + i32.const 8 + i32.add + i32.const 1048576 + local.get 3 + i32.const 12 + i32.add i32.const 1048576 + local.get 2 + i32.const 1048676 + call $core::panicking::assert_failed_inner + unreachable + ) + (func $rust_begin_unwind (;11;) (type 2) (param i32) + loop ;; label = @1 + br 0 (;@1;) + end + ) + (func $::fmt (;12;) (type 1) (param i32 i32) (result i32) + (local i32) + global.get $__stack_pointer + i32.const 16 + i32.sub + local.tee 2 + global.set $__stack_pointer + local.get 2 + i32.const 8 + i32.add + local.get 1 + i32.const 1048592 + i32.const 4 + call $core::fmt::Formatter::debug_struct + local.get 2 + i32.const 8 + i32.add + i32.const 1048596 + i32.const 5 + local.get 0 + i32.const 1048604 + call $core::fmt::builders::DebugStruct::field + call $core::fmt::builders::DebugStruct::finish + local.set 1 + local.get 2 + i32.const 16 + i32.add + global.set $__stack_pointer + local.get 1 + ) + (func $__rust_alloc (;13;) (type 1) (param i32 i32) (result i32) + i32.const 1049284 local.get 1 local.get 0 call $::alloc ) - (func $__rust_realloc (;8;) (type 6) (param i32 i32 i32 i32) (result i32) + (func $__rust_realloc (;14;) (type 8) (param i32 i32 i32 i32) (result i32) (local i32) block ;; label = @1 - i32.const 1048576 + i32.const 1049284 local.get 2 local.get 3 call $::alloc @@ -184,7 +224,7 @@ i32.lt_u select memory.copy - i32.const 1048576 + i32.const 1049284 local.get 0 local.get 2 local.get 1 @@ -192,309 +232,480 @@ end local.get 4 ) - (func $wee_alloc::alloc_first_fit (;9;) (type 7) (param i32 i32 i32) (result i32) - (local i32 i32 i32 i32 i32 i32) + (func $miden:base/note-script@1.0.0#note-script (;15;) (type 6) + (local i32 i32 i32 i64 i64 i32 i32 i32 i32) + global.get $__stack_pointer + i32.const 48 + i32.sub + local.tee 0 + global.set $__stack_pointer + call $wit_bindgen_rt::run_ctors_once + local.get 0 + i64.const 0 + i64.store offset=24 + local.get 0 + i32.const 24 + i32.add + call $basic_wallet_p2id_note::bindings::miden::base::note::get_inputs::wit_import block ;; label = @1 - local.get 2 - i32.load - local.tee 3 - i32.eqz - br_if 0 (;@1;) - local.get 1 - i32.const -1 - i32.add - local.set 4 - i32.const 0 - local.get 1 - i32.sub - local.set 5 - local.get 0 - i32.const 2 - i32.shl - local.set 6 - loop ;; label = @2 + block ;; label = @2 + local.get 0 + i32.load offset=28 + local.tee 1 + i32.eqz + br_if 0 (;@2;) + local.get 0 + local.get 0 + i32.load offset=24 + local.tee 2 + i64.load + call $basic_wallet_p2id_note::bindings::miden::base::core_types::account_id_from_felt::wit_import + local.tee 3 + i64.store offset=8 + local.get 0 + call $basic_wallet_p2id_note::bindings::miden::base::account::get_id::wit_import + local.tee 4 + i64.store offset=16 + local.get 4 local.get 3 + i64.ne + br_if 1 (;@1;) + local.get 0 + i64.const 0 + i64.store offset=24 + local.get 0 + i32.const 24 + i32.add + call $basic_wallet_p2id_note::bindings::miden::base::note::get_assets::wit_import + block ;; label = @3 + local.get 0 + i32.load offset=28 + local.tee 5 + i32.eqz + br_if 0 (;@3;) + local.get 0 + i32.load offset=24 + local.tee 6 + local.get 5 + i32.const 5 + i32.shl + i32.add + local.set 7 + local.get 6 + local.set 8 + loop ;; label = @4 + local.get 8 + i64.load + local.get 8 + i64.load offset=8 + local.get 8 + i64.load offset=16 + local.get 8 + i64.load offset=24 + call $basic_wallet_p2id_note::bindings::miden::basic_wallet::basic_wallet::receive_asset::wit_import + local.get 8 + i32.const 32 + i32.add + local.tee 8 + local.get 7 + i32.ne + br_if 0 (;@4;) + end + i32.const 1049284 + local.get 6 + i32.const 8 + local.get 5 + i32.const 5 + i32.shl + call $::dealloc + end + i32.const 1049284 + local.get 2 i32.const 8 + local.get 1 + i32.const 3 + i32.shl + call $::dealloc + local.get 0 + i32.const 48 i32.add - local.set 7 + global.set $__stack_pointer + return + end + i32.const 0 + i32.const 0 + i32.const 1048660 + call $core::panicking::panic_bounds_check + unreachable + end + local.get 0 + i32.const 0 + i32.store offset=24 + local.get 0 + i32.const 16 + i32.add + local.get 0 + i32.const 8 + i32.add + local.get 0 + i32.const 24 + i32.add + call $core::panicking::assert_failed + unreachable + ) + (func $cabi_realloc_wit_bindgen_0_28_0 (;16;) (type 8) (param i32 i32 i32 i32) (result i32) + block ;; label = @1 + block ;; label = @2 block ;; label = @3 block ;; label = @4 - local.get 3 - i32.load offset=8 - local.tee 0 - i32.const 1 - i32.and + local.get 1 br_if 0 (;@4;) local.get 3 - local.set 1 + i32.eqz + br_if 2 (;@2;) + i32.const 0 + i32.load8_u offset=1049288 + drop + local.get 3 + local.get 2 + call $__rust_alloc + local.set 2 br 1 (;@3;) end - loop ;; label = @4 - local.get 7 - local.get 0 - i32.const -2 - i32.and - i32.store - local.get 3 - i32.load offset=4 - i32.const -4 - i32.and - local.tee 1 - i32.load - local.set 7 - block ;; label = @5 - block ;; label = @6 - block ;; label = @7 - local.get 3 - i32.load - local.tee 8 - i32.const -4 - i32.and - local.tee 0 - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - block ;; label = @7 - local.get 8 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - local.get 0 - local.get 0 - i32.load offset=4 - i32.const 3 - i32.and - local.get 1 - i32.or - i32.store offset=4 - local.get 3 - i32.load - local.set 0 - local.get 3 - i32.load offset=4 - local.tee 7 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 1 (;@5;) - local.get 0 - i32.const -4 - i32.and - local.set 0 - local.get 8 - i32.load - local.set 7 - end - local.get 8 - local.get 7 - i32.const 3 - i32.and - local.get 0 - i32.or - i32.store - local.get 3 - i32.load offset=4 - local.set 7 - local.get 3 - i32.load - local.set 0 - end - local.get 3 - local.get 7 - i32.const 3 - i32.and - i32.store offset=4 - local.get 3 - local.get 0 - i32.const 3 - i32.and - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@5;) - local.get 1 - local.get 1 - i32.load - i32.const 2 - i32.or - i32.store - end - local.get 2 - local.get 1 - i32.store - local.get 1 - i32.const 8 - i32.add - local.set 7 - local.get 1 - local.set 3 - local.get 1 - i32.load offset=8 - local.tee 0 - i32.const 1 - i32.and - br_if 0 (;@4;) - end + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $__rust_realloc + local.set 2 end + local.get 2 + i32.eqz + br_if 1 (;@1;) + end + local.get 2 + return + end + unreachable + unreachable + ) + (func $wit_bindgen_rt::run_ctors_once (;17;) (type 6) + block ;; label = @1 + i32.const 0 + i32.load8_u offset=1049289 + br_if 0 (;@1;) + call $__wasm_call_ctors + i32.const 0 + i32.const 1 + i32.store8 offset=1049289 + end + ) + (func $wee_alloc::alloc_first_fit (;18;) (type 0) (param i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32) + block ;; label = @1 + local.get 2 + i32.load + local.tee 3 + br_if 0 (;@1;) + i32.const 0 + return + end + local.get 1 + i32.const -1 + i32.add + local.set 4 + i32.const 0 + local.get 1 + i32.sub + local.set 5 + local.get 0 + i32.const 2 + i32.shl + local.set 6 + loop ;; label = @1 + block ;; label = @2 block ;; label = @3 - local.get 1 - i32.load - i32.const -4 + local.get 3 + i32.load offset=8 + local.tee 1 + i32.const 1 i32.and - local.tee 3 - local.get 7 - i32.sub - local.get 6 - i32.lt_u br_if 0 (;@3;) + local.get 3 + i32.const 8 + i32.add + local.set 0 + br 1 (;@2;) + end + loop ;; label = @3 + local.get 3 + local.get 1 + i32.const -2 + i32.and + i32.store offset=8 block ;; label = @4 block ;; label = @5 - local.get 7 - i32.const 72 - i32.add local.get 3 - local.get 6 - i32.sub - local.get 5 - i32.and - local.tee 3 - i32.le_u - br_if 0 (;@5;) - local.get 4 - local.get 7 - i32.and - br_if 2 (;@3;) - local.get 2 - local.get 0 + i32.load offset=4 + local.tee 7 i32.const -4 i32.and - i32.store - local.get 1 - i32.load - local.set 0 - local.get 1 - local.set 3 + local.tee 0 + br_if 0 (;@5;) + i32.const 0 + local.set 8 br 1 (;@4;) end i32.const 0 - local.set 0 - local.get 3 - i32.const 0 - i32.store - local.get 3 - i32.const -8 - i32.add - local.tee 3 - i64.const 0 - i64.store align=4 + local.get 0 + local.get 0 + i32.load8_u + i32.const 1 + i32.and + select + local.set 8 + end + block ;; label = @4 local.get 3 - local.get 1 i32.load + local.tee 1 i32.const -4 i32.and - i32.store - block ;; label = @5 - local.get 1 - i32.load - local.tee 2 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 0 (;@5;) - local.get 2 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 8 - local.get 8 - i32.load offset=4 - i32.const 3 - i32.and - local.get 3 - i32.or - i32.store offset=4 - local.get 3 - i32.load offset=4 - i32.const 3 - i32.and - local.set 0 - end - local.get 3 - local.get 0 + local.tee 9 + i32.eqz + br_if 0 (;@4;) local.get 1 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 9 + local.get 9 + i32.load offset=4 + i32.const 3 + i32.and + local.get 0 i32.or i32.store offset=4 - local.get 7 - local.get 7 - i32.load - i32.const -2 + local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 i32.and - i32.store - local.get 1 - local.get 1 + local.set 0 + local.get 3 + i32.load + local.set 1 + end + block ;; label = @4 + local.get 0 + i32.eqz + br_if 0 (;@4;) + local.get 0 + local.get 0 i32.load - local.tee 0 i32.const 3 i32.and - local.get 3 - i32.or - local.tee 7 - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 3 - i32.load - local.set 0 - br 1 (;@4;) - end local.get 1 - local.get 7 - i32.const -3 + i32.const -4 i32.and + i32.or i32.store local.get 3 + i32.load offset=4 + local.set 7 + local.get 3 i32.load - i32.const 2 - i32.or - local.set 0 + local.set 1 end local.get 3 - local.get 0 - i32.const 1 - i32.or - i32.store + local.get 7 + i32.const 3 + i32.and + i32.store offset=4 local.get 3 - i32.const 8 - i32.add - return - end - local.get 2 - local.get 0 - i32.store - local.get 0 + local.get 1 + i32.const 3 + i32.and + i32.store + block ;; label = @4 + local.get 1 + i32.const 2 + i32.and + i32.eqz + br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load + i32.const 2 + i32.or + i32.store + end + local.get 2 + local.get 8 + i32.store + local.get 8 + local.set 3 + local.get 8 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) + end + local.get 8 + i32.const 8 + i32.add + local.set 0 + local.get 8 local.set 3 + end + block ;; label = @2 + local.get 3 + i32.load + i32.const -4 + i32.and + local.tee 8 local.get 0 + i32.sub + local.get 6 + i32.lt_u br_if 0 (;@2;) + block ;; label = @3 + block ;; label = @4 + local.get 0 + i32.const 72 + i32.add + local.get 8 + local.get 6 + i32.sub + local.get 5 + i32.and + local.tee 8 + i32.le_u + br_if 0 (;@4;) + local.get 4 + local.get 0 + i32.and + br_if 2 (;@2;) + local.get 2 + local.get 1 + i32.const -4 + i32.and + i32.store + local.get 3 + i32.load + local.set 0 + local.get 3 + local.set 1 + br 1 (;@3;) + end + i32.const 0 + local.set 7 + local.get 8 + i32.const 0 + i32.store + local.get 8 + i32.const -8 + i32.add + local.tee 1 + i64.const 0 + i64.store align=4 + local.get 1 + local.get 3 + i32.load + i32.const -4 + i32.and + i32.store + block ;; label = @4 + local.get 3 + i32.load + local.tee 9 + i32.const -4 + i32.and + local.tee 8 + i32.eqz + br_if 0 (;@4;) + local.get 9 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load offset=4 + i32.const 3 + i32.and + local.get 1 + i32.or + i32.store offset=4 + local.get 1 + i32.load offset=4 + i32.const 3 + i32.and + local.set 7 + end + local.get 1 + local.get 7 + local.get 3 + i32.or + i32.store offset=4 + local.get 0 + local.get 0 + i32.load + i32.const -2 + i32.and + i32.store + local.get 3 + local.get 3 + i32.load + local.tee 0 + i32.const 3 + i32.and + local.get 1 + i32.or + local.tee 8 + i32.store + block ;; label = @4 + local.get 0 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 1 + i32.load + local.set 0 + br 1 (;@3;) + end + local.get 3 + local.get 8 + i32.const -3 + i32.and + i32.store + local.get 1 + i32.load + i32.const 2 + i32.or + local.set 0 + end + local.get 1 + local.get 0 + i32.const 1 + i32.or + i32.store + local.get 1 + i32.const 8 + i32.add + return end + local.get 2 + local.get 1 + i32.store + local.get 1 + local.set 3 + local.get 1 + br_if 0 (;@1;) end i32.const 0 ) - (func $::alloc (;10;) (type 7) (param i32 i32 i32) (result i32) + (func $::alloc (;19;) (type 0) (param i32 i32 i32) (result i32) (local i32 i32 i32) global.get $__stack_pointer i32.const 16 @@ -598,7 +809,7 @@ global.set $__stack_pointer local.get 2 ) - (func $::dealloc (;11;) (type 8) (param i32 i32 i32 i32) + (func $::dealloc (;20;) (type 9) (param i32 i32 i32 i32) (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 1 @@ -771,55 +982,3033 @@ i32.store end ) - (func $wit_bindgen::rt::run_ctors_once (;12;) (type 4) - block ;; label = @1 - i32.const 0 - i32.load8_u offset=1048581 - br_if 0 (;@1;) - call $__wasm_call_ctors - i32.const 0 - i32.const 1 - i32.store8 offset=1048581 - end + (func $core::ptr::drop_in_place (;21;) (type 2) (param i32)) + (func $core::ptr::drop_in_place (;22;) (type 2) (param i32)) + (func $core::panicking::panic_fmt (;23;) (type 10) (param i32 i32) + (local i32) + global.get $__stack_pointer + i32.const 32 + i32.sub + local.tee 2 + global.set $__stack_pointer + local.get 2 + i32.const 1 + i32.store16 offset=28 + local.get 2 + local.get 1 + i32.store offset=24 + local.get 2 + local.get 0 + i32.store offset=20 + local.get 2 + i32.const 1048696 + i32.store offset=16 + local.get 2 + i32.const 1 + i32.store offset=12 + local.get 2 + i32.const 12 + i32.add + call $rust_begin_unwind + unreachable + ) + (func $core::slice::index::slice_start_index_len_fail (;24;) (type 7) (param i32 i32 i32) + local.get 0 + local.get 1 + local.get 2 + call $core::slice::index::slice_start_index_len_fail_rt + unreachable + ) + (func $core::panicking::panic_bounds_check (;25;) (type 7) (param i32 i32 i32) + (local i32 i64) + global.get $__stack_pointer + i32.const 48 + i32.sub + local.tee 3 + global.set $__stack_pointer + local.get 3 + local.get 1 + i32.store offset=4 + local.get 3 + local.get 0 + i32.store + local.get 3 + i32.const 2 + i32.store offset=12 + local.get 3 + i32.const 1048764 + i32.store offset=8 + local.get 3 + i64.const 2 + i64.store offset=20 align=4 + local.get 3 + i32.const 7 + i64.extend_i32_u + i64.const 32 + i64.shl + local.tee 4 + local.get 3 + i64.extend_i32_u + i64.or + i64.store offset=40 + local.get 3 + local.get 4 + local.get 3 + i32.const 4 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=32 + local.get 3 + local.get 3 + i32.const 32 + i32.add + i32.store offset=16 + local.get 3 + i32.const 8 + i32.add + local.get 2 + call $core::panicking::panic_fmt + unreachable ) - (func $cabi_realloc (;13;) (type 6) (param i32 i32 i32 i32) (result i32) + (func $core::fmt::Formatter::pad (;26;) (type 0) (param i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32) block ;; label = @1 + local.get 0 + i32.load + local.tee 3 + local.get 0 + i32.load offset=8 + local.tee 4 + i32.or + i32.eqz + br_if 0 (;@1;) block ;; label = @2 + local.get 4 + i32.eqz + br_if 0 (;@2;) + local.get 1 + local.get 2 + i32.add + local.set 5 block ;; label = @3 + block ;; label = @4 + local.get 0 + i32.load offset=12 + local.tee 6 + br_if 0 (;@4;) + i32.const 0 + local.set 7 + local.get 1 + local.set 8 + br 1 (;@3;) + end + i32.const 0 + local.set 7 local.get 1 + local.set 8 + loop ;; label = @4 + local.get 8 + local.tee 4 + local.get 5 + i32.eq + br_if 2 (;@2;) + block ;; label = @5 + block ;; label = @6 + local.get 4 + i32.load8_s + local.tee 8 + i32.const -1 + i32.le_s + br_if 0 (;@6;) + local.get 4 + i32.const 1 + i32.add + local.set 8 + br 1 (;@5;) + end + block ;; label = @6 + local.get 8 + i32.const -32 + i32.ge_u + br_if 0 (;@6;) + local.get 4 + i32.const 2 + i32.add + local.set 8 + br 1 (;@5;) + end + block ;; label = @6 + local.get 8 + i32.const -16 + i32.ge_u + br_if 0 (;@6;) + local.get 4 + i32.const 3 + i32.add + local.set 8 + br 1 (;@5;) + end + local.get 4 + i32.load8_u offset=2 + i32.const 63 + i32.and + i32.const 6 + i32.shl + local.get 4 + i32.load8_u offset=1 + i32.const 63 + i32.and + i32.const 12 + i32.shl + i32.or + local.get 4 + i32.load8_u offset=3 + i32.const 63 + i32.and + i32.or + local.get 8 + i32.const 255 + i32.and + i32.const 18 + i32.shl + i32.const 1835008 + i32.and + i32.or + i32.const 1114112 + i32.eq + br_if 3 (;@2;) + local.get 4 + i32.const 4 + i32.add + local.set 8 + end + local.get 7 + local.get 4 + i32.sub + local.get 8 + i32.add + local.set 7 + local.get 6 + i32.const -1 + i32.add + local.tee 6 + br_if 0 (;@4;) + end + end + local.get 8 + local.get 5 + i32.eq + br_if 0 (;@2;) + block ;; label = @3 + local.get 8 + i32.load8_s + local.tee 4 + i32.const -1 + i32.gt_s br_if 0 (;@3;) - local.get 3 + local.get 4 + i32.const -32 + i32.lt_u + br_if 0 (;@3;) + local.get 4 + i32.const -16 + i32.lt_u + br_if 0 (;@3;) + local.get 8 + i32.load8_u offset=2 + i32.const 63 + i32.and + i32.const 6 + i32.shl + local.get 8 + i32.load8_u offset=1 + i32.const 63 + i32.and + i32.const 12 + i32.shl + i32.or + local.get 8 + i32.load8_u offset=3 + i32.const 63 + i32.and + i32.or + local.get 4 + i32.const 255 + i32.and + i32.const 18 + i32.shl + i32.const 1835008 + i32.and + i32.or + i32.const 1114112 + i32.eq + br_if 1 (;@2;) + end + block ;; label = @3 + local.get 7 + i32.eqz + br_if 0 (;@3;) + block ;; label = @4 + local.get 7 + local.get 2 + i32.lt_u + br_if 0 (;@4;) + local.get 7 + local.get 2 + i32.eq + br_if 1 (;@3;) + br 2 (;@2;) + end + local.get 1 + local.get 7 + i32.add + i32.load8_s + i32.const -64 + i32.lt_s + br_if 1 (;@2;) + end + local.get 7 + local.set 2 + end + block ;; label = @2 + local.get 3 + br_if 0 (;@2;) + local.get 0 + i32.load offset=20 + local.get 1 + local.get 2 + local.get 0 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + return + end + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + block ;; label = @3 + local.get 2 + i32.const 16 + i32.lt_u + br_if 0 (;@3;) + local.get 1 + local.get 2 + call $core::str::count::do_count_chars + local.set 4 + br 1 (;@2;) + end + block ;; label = @3 + local.get 2 + br_if 0 (;@3;) + i32.const 0 + local.set 4 + br 1 (;@2;) + end + local.get 2 + i32.const 3 + i32.and + local.set 6 + block ;; label = @3 + block ;; label = @4 + local.get 2 + i32.const 4 + i32.ge_u + br_if 0 (;@4;) + i32.const 0 + local.set 4 + i32.const 0 + local.set 7 + br 1 (;@3;) + end + local.get 2 + i32.const 12 + i32.and + local.set 5 + i32.const 0 + local.set 4 + i32.const 0 + local.set 7 + loop ;; label = @4 + local.get 4 + local.get 1 + local.get 7 + i32.add + local.tee 8 + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 8 + i32.const 1 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 8 + i32.const 2 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 8 + i32.const 3 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.set 4 + local.get 5 + local.get 7 + i32.const 4 + i32.add + local.tee 7 + i32.ne + br_if 0 (;@4;) + end + end + local.get 6 + i32.eqz + br_if 0 (;@2;) + local.get 1 + local.get 7 + i32.add + local.set 8 + loop ;; label = @3 + local.get 4 + local.get 8 + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.set 4 + local.get 8 + i32.const 1 + i32.add + local.set 8 + local.get 6 + i32.const -1 + i32.add + local.tee 6 + br_if 0 (;@3;) + end + end + block ;; label = @2 + block ;; label = @3 + local.get 3 + local.get 4 + i32.le_u + br_if 0 (;@3;) + local.get 3 + local.get 4 + i32.sub + local.set 5 + i32.const 0 + local.set 4 + block ;; label = @4 + block ;; label = @5 + block ;; label = @6 + local.get 0 + i32.load8_u offset=32 + br_table 2 (;@4;) 0 (;@6;) 1 (;@5;) 2 (;@4;) 2 (;@4;) + end + local.get 5 + local.set 4 + i32.const 0 + local.set 5 + br 1 (;@4;) + end + local.get 5 + i32.const 1 + i32.shr_u + local.set 4 + local.get 5 + i32.const 1 + i32.add + i32.const 1 + i32.shr_u + local.set 5 + end + local.get 4 + i32.const 1 + i32.add + local.set 4 + local.get 0 + i32.load offset=16 + local.set 6 + local.get 0 + i32.load offset=24 + local.set 8 + local.get 0 + i32.load offset=20 + local.set 7 + loop ;; label = @4 + local.get 4 + i32.const -1 + i32.add + local.tee 4 + i32.eqz + br_if 2 (;@2;) + local.get 7 + local.get 6 + local.get 8 + i32.load offset=16 + call_indirect (type 1) + i32.eqz + br_if 0 (;@4;) + end + i32.const 1 + return + end + local.get 0 + i32.load offset=20 + local.get 1 + local.get 2 + local.get 0 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + return + end + i32.const 1 + local.set 4 + block ;; label = @2 + local.get 7 + local.get 1 + local.get 2 + local.get 8 + i32.load offset=12 + call_indirect (type 0) + br_if 0 (;@2;) + i32.const 0 + local.set 4 + block ;; label = @3 + loop ;; label = @4 + block ;; label = @5 + local.get 5 + local.get 4 + i32.ne + br_if 0 (;@5;) + local.get 5 + local.set 4 + br 2 (;@3;) + end + local.get 4 + i32.const 1 + i32.add + local.set 4 + local.get 7 + local.get 6 + local.get 8 + i32.load offset=16 + call_indirect (type 1) + i32.eqz + br_if 0 (;@4;) + end + local.get 4 + i32.const -1 + i32.add + local.set 4 + end + local.get 4 + local.get 5 + i32.lt_u + local.set 4 + end + local.get 4 + return + end + local.get 0 + i32.load offset=20 + local.get 1 + local.get 2 + local.get 0 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + ) + (func $core::fmt::num::imp::::fmt (;27;) (type 1) (param i32 i32) (result i32) + local.get 0 + i64.load32_u + i32.const 1 + local.get 1 + call $core::fmt::num::imp::fmt_u64 + ) + (func $core::fmt::write (;28;) (type 0) (param i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) + global.get $__stack_pointer + i32.const 48 + i32.sub + local.tee 3 + global.set $__stack_pointer + local.get 3 + i32.const 3 + i32.store8 offset=44 + local.get 3 + i32.const 32 + i32.store offset=28 + i32.const 0 + local.set 4 + local.get 3 + i32.const 0 + i32.store offset=40 + local.get 3 + local.get 1 + i32.store offset=36 + local.get 3 + local.get 0 + i32.store offset=32 + local.get 3 + i32.const 0 + i32.store offset=20 + local.get 3 + i32.const 0 + i32.store offset=12 + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + block ;; label = @4 + block ;; label = @5 + local.get 2 + i32.load offset=16 + local.tee 5 + br_if 0 (;@5;) + local.get 2 + i32.load offset=12 + local.tee 0 + i32.eqz + br_if 1 (;@4;) + local.get 2 + i32.load offset=8 + local.set 1 + local.get 0 + i32.const 3 + i32.shl + local.set 6 + local.get 0 + i32.const -1 + i32.add + i32.const 536870911 + i32.and + i32.const 1 + i32.add + local.set 4 + local.get 2 + i32.load + local.set 0 + loop ;; label = @6 + block ;; label = @7 + local.get 0 + i32.const 4 + i32.add + i32.load + local.tee 7 + i32.eqz + br_if 0 (;@7;) + local.get 3 + i32.load offset=32 + local.get 0 + i32.load + local.get 7 + local.get 3 + i32.load offset=36 + i32.load offset=12 + call_indirect (type 0) + br_if 4 (;@3;) + end + local.get 1 + i32.load + local.get 3 + i32.const 12 + i32.add + local.get 1 + i32.load offset=4 + call_indirect (type 1) + br_if 3 (;@3;) + local.get 1 + i32.const 8 + i32.add + local.set 1 + local.get 0 + i32.const 8 + i32.add + local.set 0 + local.get 6 + i32.const -8 + i32.add + local.tee 6 + br_if 0 (;@6;) + br 2 (;@4;) + end + end + local.get 2 + i32.load offset=20 + local.tee 1 + i32.eqz + br_if 0 (;@4;) + local.get 1 + i32.const 5 + i32.shl + local.set 8 + local.get 1 + i32.const -1 + i32.add + i32.const 134217727 + i32.and + i32.const 1 + i32.add + local.set 4 + local.get 2 + i32.load offset=8 + local.set 9 + local.get 2 + i32.load + local.set 0 + i32.const 0 + local.set 6 + loop ;; label = @5 + block ;; label = @6 + local.get 0 + i32.const 4 + i32.add + i32.load + local.tee 1 + i32.eqz + br_if 0 (;@6;) + local.get 3 + i32.load offset=32 + local.get 0 + i32.load + local.get 1 + local.get 3 + i32.load offset=36 + i32.load offset=12 + call_indirect (type 0) + br_if 3 (;@3;) + end + local.get 3 + local.get 5 + local.get 6 + i32.add + local.tee 1 + i32.const 16 + i32.add + i32.load + i32.store offset=28 + local.get 3 + local.get 1 + i32.const 28 + i32.add + i32.load8_u + i32.store8 offset=44 + local.get 3 + local.get 1 + i32.const 24 + i32.add + i32.load + i32.store offset=40 + local.get 1 + i32.const 12 + i32.add + i32.load + local.set 7 + i32.const 0 + local.set 10 + i32.const 0 + local.set 11 + block ;; label = @6 + block ;; label = @7 + block ;; label = @8 + local.get 1 + i32.const 8 + i32.add + i32.load + br_table 1 (;@7;) 0 (;@8;) 2 (;@6;) 1 (;@7;) + end + local.get 7 + i32.const 3 + i32.shl + local.set 12 + i32.const 0 + local.set 11 + local.get 9 + local.get 12 + i32.add + local.tee 12 + i32.load offset=4 + br_if 1 (;@6;) + local.get 12 + i32.load + local.set 7 + end + i32.const 1 + local.set 11 + end + local.get 3 + local.get 7 + i32.store offset=16 + local.get 3 + local.get 11 + i32.store offset=12 + local.get 1 + i32.const 4 + i32.add + i32.load + local.set 7 + block ;; label = @6 + block ;; label = @7 + block ;; label = @8 + local.get 1 + i32.load + br_table 1 (;@7;) 0 (;@8;) 2 (;@6;) 1 (;@7;) + end + local.get 7 + i32.const 3 + i32.shl + local.set 11 + local.get 9 + local.get 11 + i32.add + local.tee 11 + i32.load offset=4 + br_if 1 (;@6;) + local.get 11 + i32.load + local.set 7 + end + i32.const 1 + local.set 10 + end + local.get 3 + local.get 7 + i32.store offset=24 + local.get 3 + local.get 10 + i32.store offset=20 + local.get 9 + local.get 1 + i32.const 20 + i32.add + i32.load + i32.const 3 + i32.shl + i32.add + local.tee 1 + i32.load + local.get 3 + i32.const 12 + i32.add + local.get 1 + i32.load offset=4 + call_indirect (type 1) + br_if 2 (;@3;) + local.get 0 + i32.const 8 + i32.add + local.set 0 + local.get 8 + local.get 6 + i32.const 32 + i32.add + local.tee 6 + i32.ne + br_if 0 (;@5;) + end + end + local.get 4 + local.get 2 + i32.load offset=4 + i32.ge_u + br_if 1 (;@2;) + local.get 3 + i32.load offset=32 + local.get 2 + i32.load + local.get 4 + i32.const 3 + i32.shl + i32.add + local.tee 1 + i32.load + local.get 1 + i32.load offset=4 + local.get 3 + i32.load offset=36 + i32.load offset=12 + call_indirect (type 0) + i32.eqz + br_if 1 (;@2;) + end + i32.const 1 + local.set 1 + br 1 (;@1;) + end + i32.const 0 + local.set 1 + end + local.get 3 + i32.const 48 + i32.add + global.set $__stack_pointer + local.get 1 + ) + (func $::type_id (;29;) (type 10) (param i32 i32) + local.get 0 + i64.const 5799598635382251841 + i64.store offset=8 + local.get 0 + i64.const 3885382061309546557 + i64.store + ) + (func $core::fmt::builders::DebugStruct::field (;30;) (type 11) (param i32 i32 i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i64) + global.get $__stack_pointer + i32.const 64 + i32.sub + local.tee 5 + global.set $__stack_pointer + i32.const 1 + local.set 6 + block ;; label = @1 + local.get 0 + i32.load8_u offset=4 + br_if 0 (;@1;) + local.get 0 + i32.load8_u offset=5 + local.set 7 + block ;; label = @2 + local.get 0 + i32.load + local.tee 8 + i32.load offset=28 + local.tee 9 + i32.const 4 + i32.and + br_if 0 (;@2;) + i32.const 1 + local.set 6 + local.get 8 + i32.load offset=20 + i32.const 1048959 + i32.const 1048956 + local.get 7 + i32.const 255 + i32.and + local.tee 7 + select + i32.const 2 + i32.const 3 + local.get 7 + select + local.get 8 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + br_if 1 (;@1;) + i32.const 1 + local.set 6 + local.get 8 + i32.load offset=20 + local.get 1 + local.get 2 + local.get 8 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + br_if 1 (;@1;) + i32.const 1 + local.set 6 + local.get 8 + i32.load offset=20 + i32.const 1048924 + i32.const 2 + local.get 8 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + br_if 1 (;@1;) + local.get 3 + local.get 8 + local.get 4 + i32.load offset=12 + call_indirect (type 1) + local.set 6 + br 1 (;@1;) + end + block ;; label = @2 + local.get 7 + i32.const 255 + i32.and + br_if 0 (;@2;) + i32.const 1 + local.set 6 + local.get 8 + i32.load offset=20 + i32.const 1048961 + i32.const 3 + local.get 8 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + br_if 1 (;@1;) + local.get 8 + i32.load offset=28 + local.set 9 + end + i32.const 1 + local.set 6 + local.get 5 + i32.const 1 + i32.store8 offset=27 + local.get 5 + local.get 8 + i64.load offset=20 align=4 + i64.store offset=12 align=4 + local.get 5 + i32.const 1048928 + i32.store offset=52 + local.get 5 + local.get 5 + i32.const 27 + i32.add + i32.store offset=20 + local.get 5 + local.get 8 + i64.load offset=8 align=4 + i64.store offset=36 align=4 + local.get 8 + i64.load align=4 + local.set 10 + local.get 5 + local.get 9 + i32.store offset=56 + local.get 5 + local.get 8 + i32.load offset=16 + i32.store offset=44 + local.get 5 + local.get 8 + i32.load8_u offset=32 + i32.store8 offset=60 + local.get 5 + local.get 10 + i64.store offset=28 align=4 + local.get 5 + local.get 5 + i32.const 12 + i32.add + i32.store offset=48 + local.get 5 + i32.const 12 + i32.add + local.get 1 + local.get 2 + call $::write_str + br_if 0 (;@1;) + local.get 5 + i32.const 12 + i32.add + i32.const 1048924 + i32.const 2 + call $::write_str + br_if 0 (;@1;) + local.get 3 + local.get 5 + i32.const 28 + i32.add + local.get 4 + i32.load offset=12 + call_indirect (type 1) + br_if 0 (;@1;) + local.get 5 + i32.load offset=48 + i32.const 1048964 + i32.const 2 + local.get 5 + i32.load offset=52 + i32.load offset=12 + call_indirect (type 0) + local.set 6 + end + local.get 0 + i32.const 1 + i32.store8 offset=5 + local.get 0 + local.get 6 + i32.store8 offset=4 + local.get 5 + i32.const 64 + i32.add + global.set $__stack_pointer + local.get 0 + ) + (func $<&T as core::fmt::Display>::fmt (;31;) (type 1) (param i32 i32) (result i32) + local.get 1 + local.get 0 + i32.load + local.get 0 + i32.load offset=4 + call $core::fmt::Formatter::pad + ) + (func $core::panicking::assert_failed_inner (;32;) (type 12) (param i32 i32 i32 i32 i32 i32 i32) + (local i32 i64) + global.get $__stack_pointer + i32.const 112 + i32.sub + local.tee 7 + global.set $__stack_pointer + local.get 7 + local.get 2 + i32.store offset=12 + local.get 7 + local.get 1 + i32.store offset=8 + local.get 7 + local.get 4 + i32.store offset=20 + local.get 7 + local.get 3 + i32.store offset=16 + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + block ;; label = @4 + local.get 0 + i32.const 255 + i32.and + br_table 0 (;@4;) 1 (;@3;) 2 (;@2;) 0 (;@4;) + end + local.get 7 + i32.const 1048780 + i32.store offset=24 + i32.const 2 + local.set 2 + br 2 (;@1;) + end + local.get 7 + i32.const 1048782 + i32.store offset=24 + i32.const 2 + local.set 2 + br 1 (;@1;) + end + local.get 7 + i32.const 1048784 + i32.store offset=24 + i32.const 7 + local.set 2 + end + local.get 7 + local.get 2 + i32.store offset=28 + block ;; label = @1 + local.get 5 + i32.load + br_if 0 (;@1;) + local.get 7 + i32.const 3 + i32.store offset=92 + local.get 7 + i32.const 1048840 + i32.store offset=88 + local.get 7 + i64.const 3 + i64.store offset=100 align=4 + local.get 7 + i32.const 8 + i64.extend_i32_u + i64.const 32 + i64.shl + local.tee 8 + local.get 7 + i32.const 16 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=72 + local.get 7 + local.get 8 + local.get 7 + i32.const 8 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=64 + local.get 7 + i32.const 9 + i64.extend_i32_u + i64.const 32 + i64.shl + local.get 7 + i32.const 24 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=56 + local.get 7 + local.get 7 + i32.const 56 + i32.add + i32.store offset=96 + local.get 7 + i32.const 88 + i32.add + local.get 6 + call $core::panicking::panic_fmt + unreachable + end + local.get 7 + i32.const 32 + i32.add + i32.const 16 + i32.add + local.get 5 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get 7 + i32.const 32 + i32.add + i32.const 8 + i32.add + local.get 5 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get 7 + local.get 5 + i64.load align=4 + i64.store offset=32 + local.get 7 + i32.const 4 + i32.store offset=92 + local.get 7 + i32.const 1048892 + i32.store offset=88 + local.get 7 + i64.const 4 + i64.store offset=100 align=4 + local.get 7 + i32.const 8 + i64.extend_i32_u + i64.const 32 + i64.shl + local.tee 8 + local.get 7 + i32.const 16 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=80 + local.get 7 + local.get 8 + local.get 7 + i32.const 8 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=72 + local.get 7 + i32.const 10 + i64.extend_i32_u + i64.const 32 + i64.shl + local.get 7 + i32.const 32 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=64 + local.get 7 + i32.const 9 + i64.extend_i32_u + i64.const 32 + i64.shl + local.get 7 + i32.const 24 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=56 + local.get 7 + local.get 7 + i32.const 56 + i32.add + i32.store offset=96 + local.get 7 + i32.const 88 + i32.add + local.get 6 + call $core::panicking::panic_fmt + unreachable + ) + (func $<&T as core::fmt::Debug>::fmt (;33;) (type 1) (param i32 i32) (result i32) + local.get 0 + i32.load + local.get 1 + local.get 0 + i32.load offset=4 + i32.load offset=12 + call_indirect (type 1) + ) + (func $::fmt (;34;) (type 1) (param i32 i32) (result i32) + local.get 1 + i32.load offset=20 + local.get 1 + i32.load offset=24 + local.get 0 + call $core::fmt::write + ) + (func $::write_str (;35;) (type 0) (param i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) + local.get 1 + i32.const -1 + i32.add + local.set 3 + local.get 0 + i32.load offset=4 + local.set 4 + local.get 0 + i32.load + local.set 5 + local.get 0 + i32.load offset=8 + local.set 6 + i32.const 0 + local.set 7 + i32.const 0 + local.set 8 + loop ;; label = @1 + block ;; label = @2 + block ;; label = @3 + local.get 7 + local.get 2 + i32.gt_u + br_if 0 (;@3;) + loop ;; label = @4 + local.get 1 + local.get 7 + i32.add + local.set 9 + block ;; label = @5 + block ;; label = @6 + block ;; label = @7 + local.get 2 + local.get 7 + i32.sub + local.tee 10 + i32.const 8 + i32.lt_u + br_if 0 (;@7;) + block ;; label = @8 + block ;; label = @9 + local.get 9 + i32.const 3 + i32.add + i32.const -4 + i32.and + local.tee 11 + local.get 9 + i32.sub + local.tee 12 + i32.eqz + br_if 0 (;@9;) + i32.const 0 + local.set 0 + loop ;; label = @10 + local.get 9 + local.get 0 + i32.add + i32.load8_u + i32.const 10 + i32.eq + br_if 5 (;@5;) + local.get 12 + local.get 0 + i32.const 1 + i32.add + local.tee 0 + i32.ne + br_if 0 (;@10;) + end + local.get 12 + local.get 10 + i32.const -8 + i32.add + local.tee 13 + i32.le_u + br_if 1 (;@8;) + br 3 (;@6;) + end + local.get 10 + i32.const -8 + i32.add + local.set 13 + end + loop ;; label = @8 + local.get 11 + i32.const 4 + i32.add + i32.load + local.tee 0 + i32.const 168430090 + i32.xor + i32.const -16843009 + i32.add + local.get 0 + i32.const -1 + i32.xor + i32.and + local.get 11 + i32.load + local.tee 0 + i32.const 168430090 + i32.xor + i32.const -16843009 + i32.add + local.get 0 + i32.const -1 + i32.xor + i32.and + i32.or + i32.const -2139062144 + i32.and + br_if 2 (;@6;) + local.get 11 + i32.const 8 + i32.add + local.set 11 + local.get 12 + i32.const 8 + i32.add + local.tee 12 + local.get 13 + i32.le_u + br_if 0 (;@8;) + br 2 (;@6;) + end + end + block ;; label = @7 + local.get 2 + local.get 7 + i32.ne + br_if 0 (;@7;) + local.get 2 + local.set 7 + br 4 (;@3;) + end + i32.const 0 + local.set 0 + loop ;; label = @7 + local.get 9 + local.get 0 + i32.add + i32.load8_u + i32.const 10 + i32.eq + br_if 2 (;@5;) + local.get 10 + local.get 0 + i32.const 1 + i32.add + local.tee 0 + i32.ne + br_if 0 (;@7;) + end + local.get 2 + local.set 7 + br 3 (;@3;) + end + block ;; label = @6 + local.get 10 + local.get 12 + i32.ne + br_if 0 (;@6;) + local.get 2 + local.set 7 + br 3 (;@3;) + end + loop ;; label = @6 + block ;; label = @7 + local.get 9 + local.get 12 + i32.add + i32.load8_u + i32.const 10 + i32.ne + br_if 0 (;@7;) + local.get 12 + local.set 0 + br 2 (;@5;) + end + local.get 10 + local.get 12 + i32.const 1 + i32.add + local.tee 12 + i32.ne + br_if 0 (;@6;) + end + local.get 2 + local.set 7 + br 2 (;@3;) + end + local.get 0 + local.get 7 + i32.add + local.tee 12 + i32.const 1 + i32.add + local.set 7 + block ;; label = @5 + local.get 12 + local.get 2 + i32.ge_u + br_if 0 (;@5;) + local.get 9 + local.get 0 + i32.add + i32.load8_u + i32.const 10 + i32.ne + br_if 0 (;@5;) + i32.const 0 + local.set 9 + local.get 7 + local.set 11 + local.get 7 + local.set 0 + br 3 (;@2;) + end + local.get 7 + local.get 2 + i32.le_u + br_if 0 (;@4;) + end + end + i32.const 1 + local.set 9 + local.get 8 + local.set 11 + local.get 2 + local.set 0 + local.get 8 + local.get 2 + i32.ne + br_if 0 (;@2;) + i32.const 0 + return + end + block ;; label = @2 + local.get 6 + i32.load8_u + i32.eqz + br_if 0 (;@2;) + local.get 5 + i32.const 1048952 + i32.const 4 + local.get 4 + i32.load offset=12 + call_indirect (type 0) + i32.eqz + br_if 0 (;@2;) + i32.const 1 + return + end + local.get 0 + local.get 8 + i32.sub + local.set 10 + i32.const 0 + local.set 12 + block ;; label = @2 + local.get 0 + local.get 8 + i32.eq + br_if 0 (;@2;) + local.get 3 + local.get 0 + i32.add + i32.load8_u + i32.const 10 + i32.eq + local.set 12 + end + local.get 1 + local.get 8 + i32.add + local.set 0 + local.get 6 + local.get 12 + i32.store8 + local.get 11 + local.set 8 + local.get 5 + local.get 0 + local.get 10 + local.get 4 + i32.load offset=12 + call_indirect (type 0) + local.tee 0 + local.get 9 + i32.or + i32.eqz + br_if 0 (;@1;) + end + local.get 0 + ) + (func $::write_char (;36;) (type 1) (param i32 i32) (result i32) + (local i32 i32) + local.get 0 + i32.load offset=4 + local.set 2 + local.get 0 + i32.load + local.set 3 + block ;; label = @1 + local.get 0 + i32.load offset=8 + local.tee 0 + i32.load8_u + i32.eqz + br_if 0 (;@1;) + local.get 3 + i32.const 1048952 + i32.const 4 + local.get 2 + i32.load offset=12 + call_indirect (type 0) + i32.eqz + br_if 0 (;@1;) + i32.const 1 + return + end + local.get 0 + local.get 1 + i32.const 10 + i32.eq + i32.store8 + local.get 3 + local.get 1 + local.get 2 + i32.load offset=16 + call_indirect (type 1) + ) + (func $core::fmt::builders::DebugStruct::finish (;37;) (type 13) (param i32) (result i32) + (local i32 i32) + local.get 0 + i32.load8_u offset=4 + local.set 1 + block ;; label = @1 + local.get 0 + i32.load8_u offset=5 + br_if 0 (;@1;) + local.get 1 + i32.const 255 + i32.and + i32.const 0 + i32.ne + return + end + i32.const 1 + local.set 2 + block ;; label = @1 + local.get 1 + i32.const 255 + i32.and + br_if 0 (;@1;) + block ;; label = @2 + local.get 0 + i32.load + local.tee 1 + i32.load8_u offset=28 + i32.const 4 + i32.and + br_if 0 (;@2;) + local.get 0 + local.get 1 + i32.load offset=20 + i32.const 1048967 + i32.const 2 + local.get 1 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + local.tee 1 + i32.store8 offset=4 + local.get 1 + return + end + local.get 1 + i32.load offset=20 + i32.const 1048966 + i32.const 1 + local.get 1 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + local.set 2 + end + local.get 0 + local.get 2 + i32.store8 offset=4 + local.get 2 + ) + (func $core::fmt::Formatter::pad_integral (;38;) (type 14) (param i32 i32 i32 i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32) + block ;; label = @1 + block ;; label = @2 + local.get 1 + br_if 0 (;@2;) + local.get 5 + i32.const 1 + i32.add + local.set 6 + local.get 0 + i32.load offset=28 + local.set 7 + i32.const 45 + local.set 8 + br 1 (;@1;) + end + i32.const 43 + i32.const 1114112 + local.get 0 + i32.load offset=28 + local.tee 7 + i32.const 1 + i32.and + local.tee 1 + select + local.set 8 + local.get 1 + local.get 5 + i32.add + local.set 6 + end + block ;; label = @1 + block ;; label = @2 + local.get 7 + i32.const 4 + i32.and + br_if 0 (;@2;) + i32.const 0 + local.set 2 + br 1 (;@1;) + end + block ;; label = @2 + block ;; label = @3 + local.get 3 + i32.const 16 + i32.lt_u + br_if 0 (;@3;) + local.get 2 + local.get 3 + call $core::str::count::do_count_chars + local.set 1 + br 1 (;@2;) + end + block ;; label = @3 + local.get 3 + br_if 0 (;@3;) + i32.const 0 + local.set 1 + br 1 (;@2;) + end + local.get 3 + i32.const 3 + i32.and + local.set 9 + block ;; label = @3 + block ;; label = @4 + local.get 3 + i32.const 4 + i32.ge_u + br_if 0 (;@4;) + i32.const 0 + local.set 1 + i32.const 0 + local.set 10 + br 1 (;@3;) + end + local.get 3 + i32.const 12 + i32.and + local.set 11 + i32.const 0 + local.set 1 + i32.const 0 + local.set 10 + loop ;; label = @4 + local.get 1 + local.get 2 + local.get 10 + i32.add + local.tee 12 + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 12 + i32.const 1 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 12 + i32.const 2 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 12 + i32.const 3 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.set 1 + local.get 11 + local.get 10 + i32.const 4 + i32.add + local.tee 10 + i32.ne + br_if 0 (;@4;) + end + end + local.get 9 + i32.eqz + br_if 0 (;@2;) + local.get 2 + local.get 10 + i32.add + local.set 12 + loop ;; label = @3 + local.get 1 + local.get 12 + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.set 1 + local.get 12 + i32.const 1 + i32.add + local.set 12 + local.get 9 + i32.const -1 + i32.add + local.tee 9 + br_if 0 (;@3;) + end + end + local.get 1 + local.get 6 + i32.add + local.set 6 + end + block ;; label = @1 + block ;; label = @2 + local.get 0 + i32.load + br_if 0 (;@2;) + i32.const 1 + local.set 1 + local.get 0 + i32.load offset=20 + local.tee 12 + local.get 0 + i32.load offset=24 + local.tee 10 + local.get 8 + local.get 2 + local.get 3 + call $core::fmt::Formatter::pad_integral::write_prefix + br_if 1 (;@1;) + local.get 12 + local.get 4 + local.get 5 + local.get 10 + i32.load offset=12 + call_indirect (type 0) + return + end + block ;; label = @2 + local.get 0 + i32.load offset=4 + local.tee 9 + local.get 6 + i32.gt_u + br_if 0 (;@2;) + i32.const 1 + local.set 1 + local.get 0 + i32.load offset=20 + local.tee 12 + local.get 0 + i32.load offset=24 + local.tee 10 + local.get 8 + local.get 2 + local.get 3 + call $core::fmt::Formatter::pad_integral::write_prefix + br_if 1 (;@1;) + local.get 12 + local.get 4 + local.get 5 + local.get 10 + i32.load offset=12 + call_indirect (type 0) + return + end + block ;; label = @2 + local.get 7 + i32.const 8 + i32.and + i32.eqz + br_if 0 (;@2;) + local.get 0 + i32.load offset=16 + local.set 11 + local.get 0 + i32.const 48 + i32.store offset=16 + local.get 0 + i32.load8_u offset=32 + local.set 7 + i32.const 1 + local.set 1 + local.get 0 + i32.const 1 + i32.store8 offset=32 + local.get 0 + i32.load offset=20 + local.tee 12 + local.get 0 + i32.load offset=24 + local.tee 10 + local.get 8 + local.get 2 + local.get 3 + call $core::fmt::Formatter::pad_integral::write_prefix + br_if 1 (;@1;) + local.get 9 + local.get 6 + i32.sub + i32.const 1 + i32.add + local.set 1 + block ;; label = @3 + loop ;; label = @4 + local.get 1 + i32.const -1 + i32.add + local.tee 1 + i32.eqz + br_if 1 (;@3;) + local.get 12 + i32.const 48 + local.get 10 + i32.load offset=16 + call_indirect (type 1) + i32.eqz + br_if 0 (;@4;) + end + i32.const 1 + return + end + i32.const 1 + local.set 1 + local.get 12 + local.get 4 + local.get 5 + local.get 10 + i32.load offset=12 + call_indirect (type 0) + br_if 1 (;@1;) + local.get 0 + local.get 7 + i32.store8 offset=32 + local.get 0 + local.get 11 + i32.store offset=16 + i32.const 0 + local.set 1 + br 1 (;@1;) + end + local.get 9 + local.get 6 + i32.sub + local.set 6 + block ;; label = @2 + block ;; label = @3 + block ;; label = @4 + local.get 0 + i32.load8_u offset=32 + local.tee 1 + br_table 2 (;@2;) 0 (;@4;) 1 (;@3;) 0 (;@4;) 2 (;@2;) + end + local.get 6 + local.set 1 + i32.const 0 + local.set 6 + br 1 (;@2;) + end + local.get 6 + i32.const 1 + i32.shr_u + local.set 1 + local.get 6 + i32.const 1 + i32.add + i32.const 1 + i32.shr_u + local.set 6 + end + local.get 1 + i32.const 1 + i32.add + local.set 1 + local.get 0 + i32.load offset=16 + local.set 9 + local.get 0 + i32.load offset=24 + local.set 12 + local.get 0 + i32.load offset=20 + local.set 10 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const -1 + i32.add + local.tee 1 + i32.eqz + br_if 1 (;@2;) + local.get 10 + local.get 9 + local.get 12 + i32.load offset=16 + call_indirect (type 1) + i32.eqz + br_if 0 (;@3;) + end + i32.const 1 + return + end + i32.const 1 + local.set 1 + local.get 10 + local.get 12 + local.get 8 + local.get 2 + local.get 3 + call $core::fmt::Formatter::pad_integral::write_prefix + br_if 0 (;@1;) + local.get 10 + local.get 4 + local.get 5 + local.get 12 + i32.load offset=12 + call_indirect (type 0) + br_if 0 (;@1;) + i32.const 0 + local.set 1 + loop ;; label = @2 + block ;; label = @3 + local.get 6 + local.get 1 + i32.ne + br_if 0 (;@3;) + local.get 6 + local.get 6 + i32.lt_u + return + end + local.get 1 + i32.const 1 + i32.add + local.set 1 + local.get 10 + local.get 9 + local.get 12 + i32.load offset=16 + call_indirect (type 1) + i32.eqz + br_if 0 (;@2;) + end + local.get 1 + i32.const -1 + i32.add + local.get 6 + i32.lt_u + return + end + local.get 1 + ) + (func $core::fmt::Write::write_fmt (;39;) (type 1) (param i32 i32) (result i32) + local.get 0 + i32.const 1048928 + local.get 1 + call $core::fmt::write + ) + (func $core::str::count::do_count_chars (;40;) (type 1) (param i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32 i32) + block ;; label = @1 + block ;; label = @2 + local.get 1 + local.get 0 + i32.const 3 + i32.add + i32.const -4 + i32.and + local.tee 2 + local.get 0 + i32.sub + local.tee 3 + i32.lt_u + br_if 0 (;@2;) + local.get 1 + local.get 3 + i32.sub + local.tee 4 + i32.const 4 + i32.lt_u + br_if 0 (;@2;) + local.get 4 + i32.const 3 + i32.and + local.set 5 + i32.const 0 + local.set 6 + i32.const 0 + local.set 1 + block ;; label = @3 + local.get 2 + local.get 0 + i32.eq + local.tee 7 + br_if 0 (;@3;) + i32.const 0 + local.set 1 + block ;; label = @4 + block ;; label = @5 + local.get 0 + local.get 2 + i32.sub + local.tee 8 + i32.const -4 + i32.le_u + br_if 0 (;@5;) + i32.const 0 + local.set 9 + br 1 (;@4;) + end + i32.const 0 + local.set 9 + loop ;; label = @5 + local.get 1 + local.get 0 + local.get 9 + i32.add + local.tee 2 + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 2 + i32.const 1 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 2 + i32.const 2 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 2 + i32.const 3 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.set 1 + local.get 9 + i32.const 4 + i32.add + local.tee 9 + br_if 0 (;@5;) + end + end + local.get 7 + br_if 0 (;@3;) + local.get 0 + local.get 9 + i32.add + local.set 2 + loop ;; label = @4 + local.get 1 + local.get 2 + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.set 1 + local.get 2 + i32.const 1 + i32.add + local.set 2 + local.get 8 + i32.const 1 + i32.add + local.tee 8 + br_if 0 (;@4;) + end + end + local.get 0 + local.get 3 + i32.add + local.set 9 + block ;; label = @3 + local.get 5 + i32.eqz + br_if 0 (;@3;) + local.get 9 + local.get 4 + i32.const -4 + i32.and + i32.add + local.tee 2 + i32.load8_s + i32.const -65 + i32.gt_s + local.set 6 + local.get 5 + i32.const 1 + i32.eq + br_if 0 (;@3;) + local.get 6 + local.get 2 + i32.load8_s offset=1 + i32.const -65 + i32.gt_s + i32.add + local.set 6 + local.get 5 + i32.const 2 + i32.eq + br_if 0 (;@3;) + local.get 6 + local.get 2 + i32.load8_s offset=2 + i32.const -65 + i32.gt_s + i32.add + local.set 6 + end + local.get 4 + i32.const 2 + i32.shr_u + local.set 3 + local.get 6 + local.get 1 + i32.add + local.set 8 + loop ;; label = @3 + local.get 9 + local.set 4 + local.get 3 i32.eqz br_if 2 (;@1;) + local.get 3 + i32.const 192 + local.get 3 + i32.const 192 + i32.lt_u + select + local.tee 6 + i32.const 3 + i32.and + local.set 7 + local.get 6 + i32.const 2 + i32.shl + local.set 5 + i32.const 0 + local.set 2 + block ;; label = @4 + local.get 3 + i32.const 4 + i32.lt_u + br_if 0 (;@4;) + local.get 4 + local.get 5 + i32.const 1008 + i32.and + i32.add + local.set 0 + i32.const 0 + local.set 2 + local.get 4 + local.set 1 + loop ;; label = @5 + local.get 1 + i32.load offset=12 + local.tee 9 + i32.const -1 + i32.xor + i32.const 7 + i32.shr_u + local.get 9 + i32.const 6 + i32.shr_u + i32.or + i32.const 16843009 + i32.and + local.get 1 + i32.load offset=8 + local.tee 9 + i32.const -1 + i32.xor + i32.const 7 + i32.shr_u + local.get 9 + i32.const 6 + i32.shr_u + i32.or + i32.const 16843009 + i32.and + local.get 1 + i32.load offset=4 + local.tee 9 + i32.const -1 + i32.xor + i32.const 7 + i32.shr_u + local.get 9 + i32.const 6 + i32.shr_u + i32.or + i32.const 16843009 + i32.and + local.get 1 + i32.load + local.tee 9 + i32.const -1 + i32.xor + i32.const 7 + i32.shr_u + local.get 9 + i32.const 6 + i32.shr_u + i32.or + i32.const 16843009 + i32.and + local.get 2 + i32.add + i32.add + i32.add + i32.add + local.set 2 + local.get 1 + i32.const 16 + i32.add + local.tee 1 + local.get 0 + i32.ne + br_if 0 (;@5;) + end + end + local.get 3 + local.get 6 + i32.sub + local.set 3 + local.get 4 + local.get 5 + i32.add + local.set 9 + local.get 2 + i32.const 8 + i32.shr_u + i32.const 16711935 + i32.and + local.get 2 + i32.const 16711935 + i32.and + i32.add + i32.const 65537 + i32.mul + i32.const 16 + i32.shr_u + local.get 8 + i32.add + local.set 8 + local.get 7 + i32.eqz + br_if 0 (;@3;) + end + local.get 4 + local.get 6 + i32.const 252 + i32.and + i32.const 2 + i32.shl + i32.add + local.tee 2 + i32.load + local.tee 1 + i32.const -1 + i32.xor + i32.const 7 + i32.shr_u + local.get 1 + i32.const 6 + i32.shr_u + i32.or + i32.const 16843009 + i32.and + local.set 1 + block ;; label = @3 + local.get 7 + i32.const 1 + i32.eq + br_if 0 (;@3;) + local.get 2 + i32.load offset=4 + local.tee 9 + i32.const -1 + i32.xor + i32.const 7 + i32.shr_u + local.get 9 + i32.const 6 + i32.shr_u + i32.or + i32.const 16843009 + i32.and + local.get 1 + i32.add + local.set 1 + local.get 7 + i32.const 2 + i32.eq + br_if 0 (;@3;) + local.get 2 + i32.load offset=8 + local.tee 2 + i32.const -1 + i32.xor + i32.const 7 + i32.shr_u + local.get 2 + i32.const 6 + i32.shr_u + i32.or + i32.const 16843009 + i32.and + local.get 1 + i32.add + local.set 1 + end + local.get 1 + i32.const 8 + i32.shr_u + i32.const 459007 + i32.and + local.get 1 + i32.const 16711935 + i32.and + i32.add + i32.const 65537 + i32.mul + i32.const 16 + i32.shr_u + local.get 8 + i32.add + return + end + block ;; label = @2 + local.get 1 + br_if 0 (;@2;) + i32.const 0 + return + end + local.get 1 + i32.const 3 + i32.and + local.set 9 + block ;; label = @2 + block ;; label = @3 + local.get 1 + i32.const 4 + i32.ge_u + br_if 0 (;@3;) + i32.const 0 + local.set 8 i32.const 0 - i32.load8_u offset=1048580 - drop + local.set 2 + br 1 (;@2;) + end + local.get 1 + i32.const -4 + i32.and + local.set 3 + i32.const 0 + local.set 8 + i32.const 0 + local.set 2 + loop ;; label = @3 + local.get 8 + local.get 0 + local.get 2 + i32.add + local.tee 1 + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 1 + i32.const 1 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 1 + i32.const 2 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.get 1 + i32.const 3 + i32.add + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.set 8 local.get 3 local.get 2 - call $__rust_alloc - local.set 2 - br 1 (;@2;) + i32.const 4 + i32.add + local.tee 2 + i32.ne + br_if 0 (;@3;) + end + end + local.get 9 + i32.eqz + br_if 0 (;@1;) + local.get 0 + local.get 2 + i32.add + local.set 1 + loop ;; label = @2 + local.get 8 + local.get 1 + i32.load8_s + i32.const -65 + i32.gt_s + i32.add + local.set 8 + local.get 1 + i32.const 1 + i32.add + local.set 1 + local.get 9 + i32.const -1 + i32.add + local.tee 9 + br_if 0 (;@2;) + end + end + local.get 8 + ) + (func $core::fmt::Formatter::pad_integral::write_prefix (;41;) (type 11) (param i32 i32 i32 i32 i32) (result i32) + (local i32) + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + local.get 2 + i32.const 1114112 + i32.eq + br_if 0 (;@3;) + i32.const 1 + local.set 5 + local.get 0 + local.get 2 + local.get 1 + i32.load offset=16 + call_indirect (type 1) + br_if 1 (;@2;) end + local.get 3 + br_if 1 (;@1;) + i32.const 0 + local.set 5 + end + local.get 5 + return + end + local.get 0 + local.get 3 + local.get 4 + local.get 1 + i32.load offset=12 + call_indirect (type 0) + ) + (func $core::fmt::Formatter::debug_struct (;42;) (type 9) (param i32 i32 i32 i32) + local.get 1 + i32.load offset=20 + local.get 2 + local.get 3 + local.get 1 + i32.load offset=24 + i32.load offset=12 + call_indirect (type 0) + local.set 3 + local.get 0 + i32.const 0 + i32.store8 offset=5 + local.get 0 + local.get 3 + i32.store8 offset=4 + local.get 0 + local.get 1 + i32.store + ) + (func $core::slice::index::slice_start_index_len_fail_rt (;43;) (type 7) (param i32 i32 i32) + (local i32 i64) + global.get $__stack_pointer + i32.const 48 + i32.sub + local.tee 3 + global.set $__stack_pointer + local.get 3 + local.get 1 + i32.store offset=4 + local.get 3 + local.get 0 + i32.store + local.get 3 + i32.const 2 + i32.store offset=12 + local.get 3 + i32.const 1049268 + i32.store offset=8 + local.get 3 + i64.const 2 + i64.store offset=20 align=4 + local.get 3 + i32.const 7 + i64.extend_i32_u + i64.const 32 + i64.shl + local.tee 4 + local.get 3 + i32.const 4 + i32.add + i64.extend_i32_u + i64.or + i64.store offset=40 + local.get 3 + local.get 4 + local.get 3 + i64.extend_i32_u + i64.or + i64.store offset=32 + local.get 3 + local.get 3 + i32.const 32 + i32.add + i32.store offset=16 + local.get 3 + i32.const 8 + i32.add + local.get 2 + call $core::panicking::panic_fmt + unreachable + ) + (func $core::fmt::num::imp::::fmt (;44;) (type 1) (param i32 i32) (result i32) + local.get 0 + i64.load + i32.const 1 + local.get 1 + call $core::fmt::num::imp::fmt_u64 + ) + (func $core::fmt::num::imp::fmt_u64 (;45;) (type 15) (param i64 i32 i32) (result i32) + (local i32 i32 i64 i32 i32 i32) + global.get $__stack_pointer + i32.const 48 + i32.sub + local.tee 3 + global.set $__stack_pointer + i32.const 39 + local.set 4 + block ;; label = @1 + block ;; label = @2 local.get 0 - local.get 1 - local.get 2 + i64.const 10000 + i64.ge_u + br_if 0 (;@2;) + local.get 0 + local.set 5 + br 1 (;@1;) + end + i32.const 39 + local.set 4 + loop ;; label = @2 local.get 3 - call $__rust_realloc - local.set 2 + i32.const 9 + i32.add + local.get 4 + i32.add + local.tee 6 + i32.const -4 + i32.add + local.get 0 + local.get 0 + i64.const 10000 + i64.div_u + local.tee 5 + i64.const 10000 + i64.mul + i64.sub + i32.wrap_i64 + local.tee 7 + i32.const 65535 + i32.and + i32.const 100 + i32.div_u + local.tee 8 + i32.const 1 + i32.shl + i32.const 1049014 + i32.add + i32.load16_u align=1 + i32.store16 align=1 + local.get 6 + i32.const -2 + i32.add + local.get 7 + local.get 8 + i32.const 100 + i32.mul + i32.sub + i32.const 65535 + i32.and + i32.const 1 + i32.shl + i32.const 1049014 + i32.add + i32.load16_u align=1 + i32.store16 align=1 + local.get 4 + i32.const -4 + i32.add + local.set 4 + local.get 0 + i64.const 99999999 + i64.gt_u + local.set 6 + local.get 5 + local.set 0 + local.get 6 + br_if 0 (;@2;) + end + end + block ;; label = @1 + local.get 5 + i32.wrap_i64 + local.tee 6 + i32.const 99 + i32.le_u + br_if 0 (;@1;) + local.get 3 + i32.const 9 + i32.add + local.get 4 + i32.const -2 + i32.add + local.tee 4 + i32.add + local.get 5 + i32.wrap_i64 + local.tee 6 + local.get 6 + i32.const 65535 + i32.and + i32.const 100 + i32.div_u + local.tee 6 + i32.const 100 + i32.mul + i32.sub + i32.const 65535 + i32.and + i32.const 1 + i32.shl + i32.const 1049014 + i32.add + i32.load16_u align=1 + i32.store16 align=1 + end + block ;; label = @1 + block ;; label = @2 + local.get 6 + i32.const 10 + i32.lt_u + br_if 0 (;@2;) + local.get 3 + i32.const 9 + i32.add + local.get 4 + i32.const -2 + i32.add + local.tee 4 + i32.add + local.get 6 + i32.const 1 + i32.shl + i32.const 1049014 + i32.add + i32.load16_u align=1 + i32.store16 align=1 + br 1 (;@1;) end + local.get 3 + i32.const 9 + i32.add + local.get 4 + i32.const -1 + i32.add + local.tee 4 + i32.add + local.get 6 + i32.const 48 + i32.or + i32.store8 + end + local.get 2 + local.get 1 + i32.const 1 + i32.const 0 + local.get 3 + i32.const 9 + i32.add + local.get 4 + i32.add + i32.const 39 + local.get 4 + i32.sub + call $core::fmt::Formatter::pad_integral + local.set 4 + local.get 3 + i32.const 48 + i32.add + global.set $__stack_pointer + local.get 4 + ) + (func $core::fmt::num::::fmt (;46;) (type 1) (param i32 i32) (result i32) + (local i32 i64 i32) + global.get $__stack_pointer + i32.const 128 + i32.sub + local.tee 2 + global.set $__stack_pointer + local.get 0 + i64.load + local.set 3 + i32.const 0 + local.set 0 + loop ;; label = @1 local.get 2 + local.get 0 + i32.add + i32.const 127 + i32.add + local.get 3 + i32.wrap_i64 + i32.const 15 + i32.and + local.tee 4 + i32.const 48 + i32.or + local.get 4 + i32.const 87 + i32.add + local.get 4 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get 0 + i32.const -1 + i32.add + local.set 0 + local.get 3 + i64.const 16 + i64.lt_u + local.set 4 + local.get 3 + i64.const 4 + i64.shr_u + local.set 3 + local.get 4 + i32.eqz + br_if 0 (;@1;) + end + block ;; label = @1 + local.get 0 + i32.const 128 + i32.add + local.tee 4 + i32.const 129 + i32.lt_u br_if 0 (;@1;) + local.get 4 + i32.const 128 + i32.const 1048996 + call $core::slice::index::slice_start_index_len_fail unreachable + end + local.get 1 + i32.const 1 + i32.const 1049012 + i32.const 2 + local.get 2 + local.get 0 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get 0 + i32.sub + call $core::fmt::Formatter::pad_integral + local.set 0 + local.get 2 + i32.const 128 + i32.add + global.set $__stack_pointer + local.get 0 + ) + (func $core::fmt::num::::fmt (;47;) (type 1) (param i32 i32) (result i32) + (local i32 i64 i32) + global.get $__stack_pointer + i32.const 128 + i32.sub + local.tee 2 + global.set $__stack_pointer + local.get 0 + i64.load + local.set 3 + i32.const 0 + local.set 0 + loop ;; label = @1 + local.get 2 + local.get 0 + i32.add + i32.const 127 + i32.add + local.get 3 + i32.wrap_i64 + i32.const 15 + i32.and + local.tee 4 + i32.const 48 + i32.or + local.get 4 + i32.const 55 + i32.add + local.get 4 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get 0 + i32.const -1 + i32.add + local.set 0 + local.get 3 + i64.const 16 + i64.lt_u + local.set 4 + local.get 3 + i64.const 4 + i64.shr_u + local.set 3 + local.get 4 + i32.eqz + br_if 0 (;@1;) + end + block ;; label = @1 + local.get 0 + i32.const 128 + i32.add + local.tee 4 + i32.const 129 + i32.lt_u + br_if 0 (;@1;) + local.get 4 + i32.const 128 + i32.const 1048996 + call $core::slice::index::slice_start_index_len_fail unreachable end + local.get 1 + i32.const 1 + i32.const 1049012 + i32.const 2 + local.get 2 + local.get 0 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get 0 + i32.sub + call $core::fmt::Formatter::pad_integral + local.set 0 local.get 2 + i32.const 128 + i32.add + global.set $__stack_pointer + local.get 0 + ) + (func $cabi_realloc (;48;) (type 8) (param i32 i32 i32 i32) (result i32) + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $cabi_realloc_wit_bindgen_0_28_0 ) - (table (;0;) 1 1 funcref) + (table (;0;) 17 17 funcref) (memory (;0;) 17) (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) (export "memory" (memory 0)) (export "miden:base/note-script@1.0.0#note-script" (func $miden:base/note-script@1.0.0#note-script)) + (export "cabi_realloc_wit_bindgen_0_28_0" (func $cabi_realloc_wit_bindgen_0_28_0)) (export "cabi_realloc" (func $cabi_realloc)) + (elem (;0;) (i32.const 1) func $core::ptr::drop_in_place<&basic_wallet_p2id_note::bindings::miden::base::core_types::AccountId> $<&T as core::fmt::Debug>::fmt $core::ptr::drop_in_place $core::fmt::num::::fmt $::fmt $cabi_realloc $core::fmt::num::imp::::fmt $<&T as core::fmt::Debug>::fmt $<&T as core::fmt::Display>::fmt $::fmt $core::ptr::drop_in_place $::type_id $core::ptr::drop_in_place $::write_str $::write_char $core::fmt::Write::write_fmt) + (data $.rodata (;0;) (i32.const 1048576) "\01\00\00\00\04\00\00\00\04\00\00\00\02\00\00\00Feltinner\00\00\00\03\00\00\00\08\00\00\00\08\00\00\00\04\00\00\00AccountId\00\00\00\03\00\00\00\08\00\00\00\08\00\00\00\05\00\00\00src/lib.rs\00\00H\00\10\00\0a\00\00\00!\00\00\00,\00\00\00H\00\10\00\0a\00\00\00$\00\00\00\09\00\00\00\06\00\00\00\0b\00\00\00\00\00\00\00\01\00\00\00\0c\00\00\00index out of bounds: the len is but the index is \00\00\88\00\10\00 \00\00\00\a8\00\10\00\12\00\00\00==!=matchesassertion `left right` failed\0a left: \0a right: \00\d7\00\10\00\10\00\00\00\e7\00\10\00\17\00\00\00\fe\00\10\00\09\00\00\00 right` failed: \0a left: \00\00\00\d7\00\10\00\10\00\00\00 \01\10\00\10\00\00\000\01\10\00\09\00\00\00\fe\00\10\00\09\00\00\00: \00\00\0d\00\00\00\0c\00\00\00\04\00\00\00\0e\00\00\00\0f\00\00\00\10\00\00\00 { , {\0a,\0a} }library/core/src/fmt/num.rs\89\01\10\00\1b\00\00\00i\00\00\00\17\00\00\000x00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899range start index out of range for slice of length \00\00~\02\10\00\12\00\00\00\90\02\10\00\22\00\00\00") ) (core module (;1;) (type (;0;) (func (param i32))) diff --git a/tests/integration/expected/wit_sdk_basic_wallet/miden_sdk.wat b/tests/integration/expected/wit_sdk_basic_wallet/miden_sdk.wat index 8b7f2843..6d205f87 100644 --- a/tests/integration/expected/wit_sdk_basic_wallet/miden_sdk.wat +++ b/tests/integration/expected/wit_sdk_basic_wallet/miden_sdk.wat @@ -1,38 +1,32 @@ (component (core module (;0;) (type (;0;) (func)) - (type (;1;) (func (param i64) (result i64))) - (type (;2;) (func (param i64 i64 i64 i64) (result i32))) - (type (;3;) (func (param i32 i64 i64 i64 i64) (result i32))) - (type (;4;) (func (param i32 i32) (result i32))) - (type (;5;) (func (param i32 i32 i32 i32) (result i32))) - (type (;6;) (func (param i32 i32 i32) (result i32))) - (type (;7;) (func (param i32 i32 i32 i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32 i32 i32) (result i32))) + (type (;4;) (func (param i64) (result i64))) + (type (;5;) (func (param i64 i64 i64 i64) (result i32))) + (type (;6;) (func (param i32 i64 i64 i64 i64) (result i32))) + (type (;7;) (func (param i32 i32 i32) (result i32))) + (type (;8;) (func (param i32 i32 i32 i32))) + (type (;9;) (func (param i32 i32))) + (type (;10;) (func (param i32 i32 i32))) (func $__wasm_call_ctors (;0;) (type 0)) - (func $miden:base/core-types@1.0.0#account-id-from-felt (;1;) (type 1) (param i64) (result i64) - call $wit_bindgen::rt::run_ctors_once - local.get 0 - ) - (func $miden:base/types@1.0.0#from-core-asset (;2;) (type 2) (param i64 i64 i64 i64) (result i32) - call $wit_bindgen::rt::run_ctors_once - unreachable - unreachable - ) - (func $miden:base/types@1.0.0#to-core-asset (;3;) (type 3) (param i32 i64 i64 i64 i64) (result i32) - call $wit_bindgen::rt::run_ctors_once - unreachable - unreachable + (func $rust_begin_unwind (;1;) (type 1) (param i32) + loop ;; label = @1 + br 0 (;@1;) + end ) - (func $__rust_alloc (;4;) (type 4) (param i32 i32) (result i32) - i32.const 1048576 + (func $__rust_alloc (;2;) (type 2) (param i32 i32) (result i32) + i32.const 1048660 local.get 1 local.get 0 call $::alloc ) - (func $__rust_realloc (;5;) (type 5) (param i32 i32 i32 i32) (result i32) + (func $__rust_realloc (;3;) (type 3) (param i32 i32 i32 i32) (result i32) (local i32) block ;; label = @1 - i32.const 1048576 + i32.const 1048660 local.get 2 local.get 3 call $::alloc @@ -48,7 +42,7 @@ i32.lt_u select memory.copy - i32.const 1048576 + i32.const 1048660 local.get 0 local.get 2 local.get 1 @@ -56,309 +50,379 @@ end local.get 4 ) - (func $wee_alloc::alloc_first_fit (;6;) (type 6) (param i32 i32 i32) (result i32) - (local i32 i32 i32 i32 i32 i32) + (func $miden:base/core-types@1.0.0#account-id-from-felt (;4;) (type 4) (param i64) (result i64) + call $wit_bindgen_rt::run_ctors_once + local.get 0 + ) + (func $miden:base/types@1.0.0#from-core-asset (;5;) (type 5) (param i64 i64 i64 i64) (result i32) + call $wit_bindgen_rt::run_ctors_once + i32.const 1048576 + i32.const 19 + i32.const 1048608 + call $core::panicking::panic + unreachable + ) + (func $miden:base/types@1.0.0#to-core-asset (;6;) (type 6) (param i32 i64 i64 i64 i64) (result i32) + call $wit_bindgen_rt::run_ctors_once + i32.const 1048576 + i32.const 19 + i32.const 1048624 + call $core::panicking::panic + unreachable + ) + (func $cabi_realloc_wit_bindgen_0_28_0 (;7;) (type 3) (param i32 i32 i32 i32) (result i32) + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + block ;; label = @4 + local.get 1 + br_if 0 (;@4;) + local.get 3 + i32.eqz + br_if 2 (;@2;) + i32.const 0 + i32.load8_u offset=1048664 + drop + local.get 3 + local.get 2 + call $__rust_alloc + local.set 2 + br 1 (;@3;) + end + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $__rust_realloc + local.set 2 + end + local.get 2 + i32.eqz + br_if 1 (;@1;) + end + local.get 2 + return + end + unreachable + unreachable + ) + (func $wit_bindgen_rt::run_ctors_once (;8;) (type 0) + block ;; label = @1 + i32.const 0 + i32.load8_u offset=1048665 + br_if 0 (;@1;) + call $__wasm_call_ctors + i32.const 0 + i32.const 1 + i32.store8 offset=1048665 + end + ) + (func $wee_alloc::alloc_first_fit (;9;) (type 7) (param i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 2 i32.load local.tee 3 - i32.eqz br_if 0 (;@1;) - local.get 1 - i32.const -1 - i32.add - local.set 4 i32.const 0 - local.get 1 - i32.sub - local.set 5 - local.get 0 - i32.const 2 - i32.shl - local.set 6 - loop ;; label = @2 - local.get 3 - i32.const 8 - i32.add - local.set 7 + return + end + local.get 1 + i32.const -1 + i32.add + local.set 4 + i32.const 0 + local.get 1 + i32.sub + local.set 5 + local.get 0 + i32.const 2 + i32.shl + local.set 6 + loop ;; label = @1 + block ;; label = @2 block ;; label = @3 + local.get 3 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) + local.get 3 + i32.const 8 + i32.add + local.set 0 + br 1 (;@2;) + end + loop ;; label = @3 + local.get 3 + local.get 1 + i32.const -2 + i32.and + i32.store offset=8 block ;; label = @4 - local.get 3 - i32.load offset=8 - local.tee 0 + block ;; label = @5 + local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 + i32.and + local.tee 0 + br_if 0 (;@5;) + i32.const 0 + local.set 8 + br 1 (;@4;) + end + i32.const 0 + local.get 0 + local.get 0 + i32.load8_u i32.const 1 i32.and - br_if 0 (;@4;) - local.get 3 - local.set 1 - br 1 (;@3;) + select + local.set 8 end - loop ;; label = @4 - local.get 7 - local.get 0 - i32.const -2 - i32.and - i32.store + block ;; label = @4 local.get 3 - i32.load offset=4 + i32.load + local.tee 1 i32.const -4 i32.and - local.tee 1 - i32.load - local.set 7 - block ;; label = @5 - block ;; label = @6 - block ;; label = @7 - local.get 3 - i32.load - local.tee 8 - i32.const -4 - i32.and - local.tee 0 - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - block ;; label = @7 - local.get 8 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@7;) - local.get 1 - local.set 8 - br 1 (;@6;) - end - local.get 0 - local.get 0 - i32.load offset=4 - i32.const 3 - i32.and - local.get 1 - i32.or - i32.store offset=4 - local.get 3 - i32.load - local.set 0 - local.get 3 - i32.load offset=4 - local.tee 7 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 1 (;@5;) - local.get 0 - i32.const -4 - i32.and - local.set 0 - local.get 8 - i32.load - local.set 7 - end - local.get 8 - local.get 7 - i32.const 3 - i32.and - local.get 0 - i32.or - i32.store - local.get 3 - i32.load offset=4 - local.set 7 - local.get 3 - i32.load - local.set 0 - end - local.get 3 - local.get 7 + local.tee 9 + i32.eqz + br_if 0 (;@4;) + local.get 1 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 9 + local.get 9 + i32.load offset=4 i32.const 3 i32.and + local.get 0 + i32.or i32.store offset=4 local.get 3 + i32.load offset=4 + local.tee 7 + i32.const -4 + i32.and + local.set 0 + local.get 3 + i32.load + local.set 1 + end + block ;; label = @4 local.get 0 + i32.eqz + br_if 0 (;@4;) + local.get 0 + local.get 0 + i32.load i32.const 3 i32.and - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - i32.eqz - br_if 0 (;@5;) - local.get 1 - local.get 1 - i32.load - i32.const 2 - i32.or - i32.store - end - local.get 2 local.get 1 + i32.const -4 + i32.and + i32.or i32.store - local.get 1 - i32.const 8 - i32.add + local.get 3 + i32.load offset=4 local.set 7 + local.get 3 + i32.load + local.set 1 + end + local.get 3 + local.get 7 + i32.const 3 + i32.and + i32.store offset=4 + local.get 3 + local.get 1 + i32.const 3 + i32.and + i32.store + block ;; label = @4 local.get 1 - local.set 3 - local.get 1 - i32.load offset=8 - local.tee 0 - i32.const 1 + i32.const 2 i32.and + i32.eqz br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load + i32.const 2 + i32.or + i32.store end + local.get 2 + local.get 8 + i32.store + local.get 8 + local.set 3 + local.get 8 + i32.load offset=8 + local.tee 1 + i32.const 1 + i32.and + br_if 0 (;@3;) end + local.get 8 + i32.const 8 + i32.add + local.set 0 + local.get 8 + local.set 3 + end + block ;; label = @2 + local.get 3 + i32.load + i32.const -4 + i32.and + local.tee 8 + local.get 0 + i32.sub + local.get 6 + i32.lt_u + br_if 0 (;@2;) block ;; label = @3 + block ;; label = @4 + local.get 0 + i32.const 72 + i32.add + local.get 8 + local.get 6 + i32.sub + local.get 5 + i32.and + local.tee 8 + i32.le_u + br_if 0 (;@4;) + local.get 4 + local.get 0 + i32.and + br_if 2 (;@2;) + local.get 2 + local.get 1 + i32.const -4 + i32.and + i32.store + local.get 3 + i32.load + local.set 0 + local.get 3 + local.set 1 + br 1 (;@3;) + end + i32.const 0 + local.set 7 + local.get 8 + i32.const 0 + i32.store + local.get 8 + i32.const -8 + i32.add + local.tee 1 + i64.const 0 + i64.store align=4 local.get 1 + local.get 3 i32.load i32.const -4 i32.and - local.tee 3 - local.get 7 - i32.sub - local.get 6 - i32.lt_u - br_if 0 (;@3;) + i32.store block ;; label = @4 - block ;; label = @5 - local.get 7 - i32.const 72 - i32.add - local.get 3 - local.get 6 - i32.sub - local.get 5 - i32.and - local.tee 3 - i32.le_u - br_if 0 (;@5;) - local.get 4 - local.get 7 - i32.and - br_if 2 (;@3;) - local.get 2 - local.get 0 - i32.const -4 - i32.and - i32.store - local.get 1 - i32.load - local.set 0 - local.get 1 - local.set 3 - br 1 (;@4;) - end - i32.const 0 - local.set 0 - local.get 3 - i32.const 0 - i32.store - local.get 3 - i32.const -8 - i32.add - local.tee 3 - i64.const 0 - i64.store align=4 local.get 3 - local.get 1 i32.load + local.tee 9 i32.const -4 i32.and - i32.store - block ;; label = @5 - local.get 1 - i32.load - local.tee 2 - i32.const -4 - i32.and - local.tee 8 - i32.eqz - br_if 0 (;@5;) - local.get 2 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 8 - local.get 8 - i32.load offset=4 - i32.const 3 - i32.and - local.get 3 - i32.or - i32.store offset=4 - local.get 3 - i32.load offset=4 - i32.const 3 - i32.and - local.set 0 - end - local.get 3 - local.get 0 - local.get 1 - i32.or - i32.store offset=4 - local.get 7 - local.get 7 - i32.load - i32.const -2 + local.tee 8 + i32.eqz + br_if 0 (;@4;) + local.get 9 + i32.const 2 i32.and - i32.store - local.get 1 - local.get 1 - i32.load - local.tee 0 + br_if 0 (;@4;) + local.get 8 + local.get 8 + i32.load offset=4 i32.const 3 i32.and - local.get 3 + local.get 1 i32.or - local.tee 7 - i32.store - block ;; label = @5 - local.get 0 - i32.const 2 - i32.and - br_if 0 (;@5;) - local.get 3 - i32.load - local.set 0 - br 1 (;@4;) - end + i32.store offset=4 local.get 1 - local.get 7 - i32.const -3 + i32.load offset=4 + i32.const 3 i32.and - i32.store - local.get 3 - i32.load - i32.const 2 - i32.or - local.set 0 + local.set 7 end + local.get 1 + local.get 7 local.get 3 + i32.or + i32.store offset=4 local.get 0 - i32.const 1 + local.get 0 + i32.load + i32.const -2 + i32.and + i32.store + local.get 3 + local.get 3 + i32.load + local.tee 0 + i32.const 3 + i32.and + local.get 1 i32.or + local.tee 8 i32.store + block ;; label = @4 + local.get 0 + i32.const 2 + i32.and + br_if 0 (;@4;) + local.get 1 + i32.load + local.set 0 + br 1 (;@3;) + end local.get 3 - i32.const 8 - i32.add - return + local.get 8 + i32.const -3 + i32.and + i32.store + local.get 1 + i32.load + i32.const 2 + i32.or + local.set 0 end - local.get 2 + local.get 1 local.get 0 + i32.const 1 + i32.or i32.store - local.get 0 - local.set 3 - local.get 0 - br_if 0 (;@2;) + local.get 1 + i32.const 8 + i32.add + return end + local.get 2 + local.get 1 + i32.store + local.get 1 + local.set 3 + local.get 1 + br_if 0 (;@1;) end i32.const 0 ) - (func $::alloc (;7;) (type 6) (param i32 i32 i32) (result i32) + (func $::alloc (;10;) (type 7) (param i32 i32 i32) (result i32) (local i32 i32 i32) global.get $__stack_pointer i32.const 16 @@ -462,7 +526,7 @@ global.set $__stack_pointer local.get 2 ) - (func $::dealloc (;8;) (type 7) (param i32 i32 i32 i32) + (func $::dealloc (;11;) (type 8) (param i32 i32 i32 i32) (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 1 @@ -635,57 +699,93 @@ i32.store end ) - (func $wit_bindgen::rt::run_ctors_once (;9;) (type 0) - block ;; label = @1 - i32.const 0 - i32.load8_u offset=1048581 - br_if 0 (;@1;) - call $__wasm_call_ctors - i32.const 0 - i32.const 1 - i32.store8 offset=1048581 - end + (func $core::ptr::drop_in_place (;12;) (type 1) (param i32)) + (func $core::panicking::panic_fmt (;13;) (type 9) (param i32 i32) + (local i32) + global.get $__stack_pointer + i32.const 32 + i32.sub + local.tee 2 + global.set $__stack_pointer + local.get 2 + i32.const 1 + i32.store16 offset=28 + local.get 2 + local.get 1 + i32.store offset=24 + local.get 2 + local.get 0 + i32.store offset=20 + local.get 2 + i32.const 1048644 + i32.store offset=16 + local.get 2 + i32.const 1 + i32.store offset=12 + local.get 2 + i32.const 12 + i32.add + call $rust_begin_unwind + unreachable ) - (func $cabi_realloc (;10;) (type 5) (param i32 i32 i32 i32) (result i32) - block ;; label = @1 - block ;; label = @2 - block ;; label = @3 - local.get 1 - br_if 0 (;@3;) - local.get 3 - i32.eqz - br_if 2 (;@1;) - i32.const 0 - i32.load8_u offset=1048580 - drop - local.get 3 - local.get 2 - call $__rust_alloc - local.set 2 - br 1 (;@2;) - end - local.get 0 - local.get 1 - local.get 2 - local.get 3 - call $__rust_realloc - local.set 2 - end - local.get 2 - br_if 0 (;@1;) - unreachable - unreachable - end + (func $core::panicking::panic (;14;) (type 10) (param i32 i32 i32) + (local i32) + global.get $__stack_pointer + i32.const 32 + i32.sub + local.tee 3 + global.set $__stack_pointer + local.get 3 + i32.const 0 + i32.store offset=16 + local.get 3 + i32.const 1 + i32.store offset=4 + local.get 3 + i64.const 4 + i64.store offset=8 align=4 + local.get 3 + local.get 1 + i32.store offset=28 + local.get 3 + local.get 0 + i32.store offset=24 + local.get 3 + local.get 3 + i32.const 24 + i32.add + i32.store + local.get 3 + local.get 2 + call $core::panicking::panic_fmt + unreachable + ) + (func $::type_id (;15;) (type 9) (param i32 i32) + local.get 0 + i64.const 5799598635382251841 + i64.store offset=8 + local.get 0 + i64.const 3885382061309546557 + i64.store + ) + (func $cabi_realloc (;16;) (type 3) (param i32 i32 i32 i32) (result i32) + local.get 0 + local.get 1 local.get 2 + local.get 3 + call $cabi_realloc_wit_bindgen_0_28_0 ) - (table (;0;) 1 1 funcref) + (table (;0;) 4 4 funcref) (memory (;0;) 17) (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) (export "memory" (memory 0)) (export "miden:base/core-types@1.0.0#account-id-from-felt" (func $miden:base/core-types@1.0.0#account-id-from-felt)) (export "miden:base/types@1.0.0#from-core-asset" (func $miden:base/types@1.0.0#from-core-asset)) (export "miden:base/types@1.0.0#to-core-asset" (func $miden:base/types@1.0.0#to-core-asset)) + (export "cabi_realloc_wit_bindgen_0_28_0" (func $cabi_realloc_wit_bindgen_0_28_0)) (export "cabi_realloc" (func $cabi_realloc)) + (elem (;0;) (i32.const 1) func $cabi_realloc $core::ptr::drop_in_place $::type_id) + (data $.rodata (;0;) (i32.const 1048576) "not yet implementedsrc/lib.rs\00\00\00\13\00\10\00\0a\00\00\00!\00\00\00\09\00\00\00\13\00\10\00\0a\00\00\00%\00\00\00\09\00\00\00\01\00\00\00\02\00\00\00\00\00\00\00\01\00\00\00\03\00\00\00") ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) diff --git a/tests/integration/expected/xor_bool.hir b/tests/integration/expected/xor_bool.hir index 5e5e6043..fe223934 100644 --- a/tests/integration/expected/xor_bool.hir +++ b/tests/integration/expected/xor_bool.hir @@ -1,6 +1,6 @@ (component ;; Modules - (module #test_rust_dcd67ec43bbcd9107cffbbb7423564fd0a2cb122c842d7b8f810e5d557615869 + (module #test_rust_bf1daa4716c09a8fc6f8362a72042139765ebe6efcfdd17e817a70b2a495f6b1 ;; Constants (const (id 0) 0x00100000) diff --git a/tests/integration/expected/xor_bool.masm b/tests/integration/expected/xor_bool.masm index b414c43b..746d91b1 100644 --- a/tests/integration/expected/xor_bool.masm +++ b/tests/integration/expected/xor_bool.masm @@ -1,10 +1,7 @@ -# mod test_rust_dcd67ec43bbcd9107cffbbb7423564fd0a2cb122c842d7b8f810e5d557615869 +# mod test_rust_bf1daa4716c09a8fc6f8362a72042139765ebe6efcfdd17e817a70b2a495f6b1 export.entrypoint swap.1 u32xor end -begin - exec.::test_rust_dcd67ec43bbcd9107cffbbb7423564fd0a2cb122c842d7b8f810e5d557615869::entrypoint -end \ No newline at end of file diff --git a/tests/integration/expected/xor_bool.wat b/tests/integration/expected/xor_bool.wat index 0d835965..f4e93507 100644 --- a/tests/integration/expected/xor_bool.wat +++ b/tests/integration/expected/xor_bool.wat @@ -1,4 +1,4 @@ -(module $test_rust_dcd67ec43bbcd9107cffbbb7423564fd0a2cb122c842d7b8f810e5d557615869.wasm +(module $test_rust_bf1daa4716c09a8fc6f8362a72042139765ebe6efcfdd17e817a70b2a495f6b1.wasm (type (;0;) (func (param i32 i32) (result i32))) (func $entrypoint (;0;) (type 0) (param i32 i32) (result i32) local.get 0 diff --git a/tests/integration/src/cargo_proj/mod.rs b/tests/integration/src/cargo_proj/mod.rs index 31561b0c..d58feef0 100644 --- a/tests/integration/src/cargo_proj/mod.rs +++ b/tests/integration/src/cargo_proj/mod.rs @@ -44,7 +44,6 @@ pub fn panic_error(what: &str, err: impl Into) -> ! { pub mod paths; use self::paths::CargoPathExt; -use crate::compiler_test::skip_rust_compilation; /* * @@ -207,7 +206,8 @@ impl ProjectBuilder { pub fn build(mut self) -> Project { let last_path_component = self.root.root().file_name().unwrap().to_string_lossy().to_string(); - if skip_rust_compilation(&self.root(), &last_path_component) { + + if self.skip_rust_compilation(&last_path_component) { // Return the root directory without re-creating any files return self.root; } @@ -249,6 +249,22 @@ impl ProjectBuilder { fn rm_root(&self) { self.root.root().rm_rf() } + + fn skip_rust_compilation(&self, artifact_name: &str) -> bool { + let computed_artifact_path = self + .root() + .join("target") + .join("wasm32-unknown-unknown") + .join("release") + .join(artifact_name) + .with_extension("wasm"); + if std::env::var("SKIP_RUST").is_ok() && computed_artifact_path.exists() { + eprintln!("Skipping Rust compilation"); + true + } else { + false + } + } } impl Project { @@ -465,9 +481,6 @@ pub fn is_nightly() -> bool { /// Returns `true` if the local filesystem has low-resolution mtimes. pub fn is_coarse_mtime() -> bool { - // If the filetime crate is being used to emulate HFS then - // return `true`, without looking at the actual hardware. - cfg!(emulate_second_only_system) || // This should actually be a test that `$CARGO_TARGET_DIR` is on an HFS // filesystem, (or any filesystem with low-resolution mtimes). However, // that's tricky to detect, so for now just deal with CI. diff --git a/tests/integration/src/compiler_test.rs b/tests/integration/src/compiler_test.rs index 55804d26..751987f6 100644 --- a/tests/integration/src/compiler_test.rs +++ b/tests/integration/src/compiler_test.rs @@ -2,55 +2,24 @@ use core::panic; use std::{ - fmt::Write, - fs, + borrow::Cow, + fmt, fs, io::Read, path::{Path, PathBuf}, process::{Command, Stdio}, + rc::Rc, sync::Arc, }; -use miden_assembly::{ast::ModuleKind, diagnostics::Report, Assembler, LibraryPath}; -use miden_diagnostics::SourceSpan; -use miden_stdlib::StdLibrary; +use miden_assembly::LibraryPath; use midenc_frontend_wasm::{translate, WasmTranslationConfig}; -use midenc_hir::{FunctionIdent, Ident, Symbol}; -use midenc_session::{ - InputFile, InputType, Options, OutputType, OutputTypeSpec, OutputTypes, ProjectType, Session, -}; +use midenc_hir::{demangle, FunctionIdent, Ident, Symbol}; +use midenc_session::{InputFile, InputType, Session}; use crate::cargo_proj::project; type LinkMasmModules = Vec<(LibraryPath, String)>; -pub enum CompilerTestSource { - Rust(String), - RustCargo { - cargo_project_folder_name: String, - artifact_name: String, - }, - RustCargoLib { - artifact_name: String, - }, - RustCargoComponent { - artifact_name: String, - }, -} - -impl CompilerTestSource { - pub fn artifact_name(&self) -> String { - match self { - CompilerTestSource::RustCargo { - cargo_project_folder_name: _, - artifact_name, - } => artifact_name.clone(), - CompilerTestSource::RustCargoLib { artifact_name } => artifact_name.clone(), - CompilerTestSource::RustCargoComponent { artifact_name } => artifact_name.clone(), - _ => panic!("Not a Rust Cargo project"), - } - } -} - #[derive(derive_more::From)] pub enum HirArtifact { Program(Box), @@ -81,156 +50,369 @@ impl HirArtifact { } } -/// Compile to different stages (e.g. Wasm, IR, MASM) and compare the results against expected -/// output -pub struct CompilerTest { - /// The Wasm translation configuration - pub config: WasmTranslationConfig, - /// The compiler session - pub session: Arc, - /// The source code used to compile the test - pub source: CompilerTestSource, - /// The entrypoint function to use when building the IR - entrypoint: Option, - /// The extra MASM modules to link to the compiled MASM program - pub link_masm_modules: LinkMasmModules, - /// The compiled IR - hir: Option, - /// The MASM source code - masm_src: Option, - /// The compiled IR MASM program - ir_masm_program: Option, String>>, - /// The compiled VM program - vm_masm_program: Option, String>>, +/// Configuration for tests which use as input, the artifact produced by a Cargo build +pub struct CargoTest { + project_dir: PathBuf, + manifest_path: Option>, + target_dir: Option, + name: Cow<'static, str>, + target: Cow<'static, str>, + entrypoint: Option>, + build_std: bool, + build_alloc: bool, } - -impl Default for CompilerTest { - fn default() -> Self { +impl CargoTest { + /// Create a new `cargo` test with the given name, and project directory + pub fn new(name: impl Into>, project_dir: PathBuf) -> Self { Self { - config: WasmTranslationConfig::default(), - session: Arc::new(dummy_session()), - source: CompilerTestSource::Rust(String::new()), + project_dir, + manifest_path: None, + target_dir: None, + name: name.into(), + target: "wasm32-wasip1".into(), entrypoint: None, - link_masm_modules: Vec::new(), - hir: None, - masm_src: None, - ir_masm_program: None, - vm_masm_program: None, + build_std: false, + build_alloc: false, } } + + /// Specify whether to build the entire standard library as part of the crate graph + #[inline] + pub fn with_build_std(mut self, build_std: bool) -> Self { + self.build_std = build_std; + self + } + + /// Specify whether to build libcore and liballoc as part of the crate graph (implied by + /// `with_build_std`) + #[inline] + pub fn with_build_alloc(mut self, build_alloc: bool) -> Self { + self.build_alloc = build_alloc; + self + } + + /// Specify the target triple to pass to Cargo + #[inline] + pub fn with_target(mut self, target: impl Into>) -> Self { + self.target = target.into(); + self + } + + /// Specify the target directory for Cargo + #[inline] + pub fn with_target_dir(mut self, target_dir: impl Into) -> Self { + self.target_dir = Some(target_dir.into()); + self + } + + /// Specify the name of the entrypoint function (just the function name, no namespace) + #[inline] + pub fn with_entrypoint(mut self, entrypoint: impl Into>) -> Self { + self.entrypoint = Some(entrypoint.into()); + self + } + + /// Override the Cargo manifest path + #[inline] + pub fn with_manifest_path(mut self, manifest_path: impl Into>) -> Self { + self.manifest_path = Some(manifest_path.into()); + self + } + + /// Get a [PathBuf] representing the path to the expected Cargo artifact + pub fn wasm_artifact_path(&self) -> PathBuf { + self.project_dir + .join("target") + .join(self.target.as_ref()) + .join("release") + .join(self.name.as_ref()) + .with_extension("wasm") + } } -impl CompilerTest { - /// Compile the Wasm component from a Rust Cargo project using cargo-component - pub fn rust_source_cargo_component( - cargo_project_folder: PathBuf, - config: WasmTranslationConfig, +/// Configuration for tests which use as input, the artifact produced by an invocation of `rustc` +pub struct RustcTest { + target_dir: Option, + name: Cow<'static, str>, + target: Cow<'static, str>, + output_name: Option>, + source_code: Cow<'static, str>, + rustflags: Vec>, +} +impl RustcTest { + /// Construct a new `rustc` input with the given name and source code content + pub fn new( + name: impl Into>, + source_code: impl Into>, ) -> Self { - let manifest_path = cargo_project_folder.join("Cargo.toml"); - let mut cargo_build_cmd = Command::new("cargo"); - let compiler_workspace_dir = get_workspace_dir(); - // Enable Wasm bulk-memory proposal (uses Wasm `memory.copy` op instead of `memcpy` import) - // Remap the compiler workspace directory to `~` to have a reproducible build that does not - // have the absolute local path baked into the Wasm binary - cargo_build_cmd.env( - "RUSTFLAGS", - format!( - "-C target-feature=+bulk-memory --remap-path-prefix {compiler_workspace_dir}=~" - ), - ); - cargo_build_cmd - .arg("component") - .arg("build") - .arg("--manifest-path") - .arg(manifest_path) - .arg("--release") - // compile std as part of crate graph compilation - // https://doc.rust-lang.org/cargo/reference/unstable.html#build-std - .arg("-Z") - .arg("build-std=std,core,alloc,panic_abort") - .arg("-Z") - // abort on panic without message formatting (core::fmt uses call_indirect) - .arg("build-std-features=panic_immediate_abort"); - let mut child = cargo_build_cmd - .arg("--message-format=json-render-diagnostics") - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|_| { - panic!( - "Failed to execute cargo build {}.", - cargo_build_cmd - .get_args() - .map(|arg| format!("'{}'", arg.to_str().unwrap())) - .collect::>() - .join(" ") - ) - }); - let wasm_artifacts = find_wasm_artifacts(&mut child); - let output = child.wait().expect("Couldn't get cargo's exit status"); - if !output.success() { - report_cargo_error(child); + Self { + target_dir: None, + name: name.into(), + target: "wasm32-unknown-unknown".into(), + output_name: None, + source_code: source_code.into(), + // Always use spec-compliant C ABI behavior + rustflags: vec!["-Z".into(), "wasm_c_abi=spec".into()], + } + } +} + +/// The various types of input artifacts that can be used to drive compiler tests +pub enum CompilerTestInputType { + /// A project that uses `cargo component build` to produce a Wasm module to use as input + CargoComponent(CargoTest), + /// A project that uses `cargo build` to produce a core Wasm module to use as input + Cargo(CargoTest), + /// A project that uses `rustc` to produce a core Wasm module to use as input + Rustc(RustcTest), +} +impl From for CompilerTestInputType { + fn from(config: CargoTest) -> Self { + Self::Cargo(config) + } +} +impl From for CompilerTestInputType { + fn from(config: RustcTest) -> Self { + Self::Rustc(config) + } +} + +/// [CompilerTestBuilder] is used to obtain a [CompilerTest], and subsequently run that test. +/// +/// Testing the compiler involves orchestrating a number of complex components. First, we must +/// obtain the input we wish to feed into `midenc` for the test. Typically, we have some Rust +/// source code, or a Cargo project, and we must compile that first, in order to get the Wasm +/// module/component which will be passed to `midenc`. This first phase requires some configuration, +/// and that configuration affects later phases (such as the name of the artifact produced). +/// +/// Secondly, we need to prepare the [midenc_session::Session] object for the compiler. This is +/// where we specify inputs, and various bits of configuration that are important to the test, or +/// which are needed in order to obtain useful diagnostic output. This phase requires us to +/// construct the base configuration here, but make it possible to extend/alter in each specific +/// test. +/// +/// Lastly, we must run the test, and in order to do this, we must know where our inputs and outputs +/// are, so that we can fetch files/data/etc. as needed; know the names of things to be called, and +/// more. +pub struct CompilerTestBuilder { + /// The Wasm translation configuration + config: WasmTranslationConfig, + /// The source code used to compile the test + source: CompilerTestInputType, + /// The entrypoint function to use when building the IR + entrypoint: Option, + /// The extra MASM modules to link to the compiled MASM program + link_masm_modules: LinkMasmModules, + /// Extra flags to pass to the midenc driver + midenc_flags: Vec>, + /// Extra RUSTFLAGS to set when compiling Rust code + rustflags: Vec>, + /// The cargo workspace directory of the compiler + workspace_dir: String, +} +impl CompilerTestBuilder { + /// Construct a new [CompilerTestBuilder] for the given source type configuration + pub fn new(source: impl Into) -> Self { + let workspace_dir = get_workspace_dir(); + let mut source = source.into(); + let mut rustflags = match source { + CompilerTestInputType::Rustc(ref mut config) => core::mem::take(&mut config.rustflags), + _ => vec![], + }; + let entrypoint = match source { + CompilerTestInputType::Cargo(ref mut config) => config.entrypoint.take(), + CompilerTestInputType::CargoComponent(ref mut config) => config.entrypoint.take(), + CompilerTestInputType::Rustc(_) => None, + }; + let name = match source { + CompilerTestInputType::Cargo(ref mut config) => config.name.as_ref(), + CompilerTestInputType::CargoComponent(ref mut config) => config.name.as_ref(), + CompilerTestInputType::Rustc(ref mut config) => config.name.as_ref(), + }; + let entrypoint = entrypoint.as_deref().map(|entry| FunctionIdent { + module: Ident::with_empty_span(Symbol::intern(name)), + function: Ident::with_empty_span(Symbol::intern(entry)), + }); + rustflags.extend([ + // Enable bulk-memory features (e.g. native memcpy/memset instructions) + "-C".into(), + "target-feature=+bulk-memory".into(), + // Remap the compiler workspace to `.` so that build outputs do not embed user- + // specific paths, which would cause expect tests to break + "--remap-path-prefix".into(), + format!("{workspace_dir}=../../").into(), + ]); + let mut midenc_flags = vec!["--debug".into(), "--verbose".into()]; + if let Some(entrypoint) = entrypoint { + midenc_flags + .extend(["--entrypoint".into(), format!("{}", entrypoint.display()).into()]); } - assert!(output.success()); - assert_eq!(wasm_artifacts.len(), 1, "Expected one Wasm artifact"); - let wasm_comp_path = &wasm_artifacts.first().unwrap(); - let artifact_name = wasm_comp_path.file_stem().unwrap().to_str().unwrap().to_string(); - let input_file = InputFile::from_path(wasm_comp_path).unwrap(); Self { - config, - session: default_session(input_file), - source: CompilerTestSource::RustCargoComponent { artifact_name }, - ..Default::default() + config: Default::default(), + source, + entrypoint, + link_masm_modules: vec![], + midenc_flags, + rustflags, + workspace_dir, } } - /// Set the Rust source code to compile a library Cargo project to Wasm module - pub fn rust_source_cargo_lib( - cargo_project_folder: PathBuf, - artifact_name: &str, - is_build_std: bool, - entry_func_name: Option, - ) -> Self { - let expected_wasm_artifact_path = wasm_artifact_path(&cargo_project_folder, artifact_name); - // dbg!(&wasm_artifact_path); - let wasm_artifact_path = if !skip_rust_compilation(&cargo_project_folder, artifact_name) - || !expected_wasm_artifact_path.exists() - { - let manifest_path = cargo_project_folder.join("Cargo.toml"); - let mut cargo_build_cmd = Command::new("cargo"); - let compiler_workspace_dir = get_workspace_dir(); - // Enable Wasm bulk-memory proposal (uses Wasm `memory.copy` op instead of `memcpy` - // import) Remap the compiler workspace directory to `~` to have a - // reproducible build that does not have the absolute local path baked into - // the Wasm binary - cargo_build_cmd.env( - "RUSTFLAGS", - format!( - "-C target-feature=+bulk-memory --remap-path-prefix {compiler_workspace_dir}=~" - ), + /// Override the default [WasmTranslationConfig] for the test + pub fn with_wasm_translation_config(&mut self, config: WasmTranslationConfig) -> &mut Self { + self.config = config; + self + } + + /// Specify the entrypoint function to call during the test + pub fn with_entrypoint(&mut self, entrypoint: FunctionIdent) -> &mut Self { + match self.entrypoint.replace(entrypoint) { + Some(prev) if prev == entrypoint => return self, + Some(prev) => { + // Remove the previous --entrypoint ID flag + let index = self + .midenc_flags + .iter() + .position(|flag| flag == "--entrypoint") + .unwrap_or_else(|| { + panic!( + "entrypoint was changed from '{}' -> '{}', but previous entrypoint \ + had been set without passing --entrypoint to midenc", + prev.display(), + entrypoint.display() + ) + }); + self.midenc_flags.remove(index); + self.midenc_flags.remove(index); + } + None => (), + } + self.midenc_flags + .extend(["--entrypoint".into(), format!("{}", entrypoint.display()).into()]); + self + } + + /// Append additional `midenc` compiler flags + pub fn with_midenc_flags( + &mut self, + flags: impl IntoIterator>, + ) -> &mut Self { + self.midenc_flags.extend(flags); + self + } + + /// Append additional flags to the value of `RUSTFLAGS` used when invoking `cargo` or `rustc` + pub fn with_rustflags( + &mut self, + flags: impl IntoIterator>, + ) -> &mut Self { + self.rustflags.extend(flags); + self + } + + /// Add additional Miden Assembly module sources, to be linked with the program under test. + pub fn link_with_masm_module( + &mut self, + fully_qualified_name: impl AsRef, + source: impl Into, + ) -> &mut Self { + let name = fully_qualified_name.as_ref(); + let path = LibraryPath::new(name) + .unwrap_or_else(|err| panic!("invalid miden assembly module name '{name}': {err}")); + self.link_masm_modules.push((path, source.into())); + self + } + + /// Consume the builder, invoke any tools required to obtain the inputs for the test, and if + /// successful, return a [CompilerTest], ready for evaluation. + pub fn build(self) -> CompilerTest { + // Set up the command used to compile the test inputs (typically Rust -> Wasm) + let mut command = match self.source { + CompilerTestInputType::CargoComponent(_) => { + let mut cmd = Command::new("cargo"); + cmd.arg("component").arg("build"); + cmd + } + CompilerTestInputType::Cargo(_) => { + let mut cmd = Command::new("cargo"); + cmd.arg("build"); + cmd + } + CompilerTestInputType::Rustc(_) => Command::new("rustc"), + }; + + // Extract the directory in which source code is presumed to exist (or will be placed) + let project_dir = match self.source { + CompilerTestInputType::CargoComponent(CargoTest { + ref project_dir, .. + }) + | CompilerTestInputType::Cargo(CargoTest { + ref project_dir, .. + }) => Cow::Borrowed(project_dir.as_path()), + CompilerTestInputType::Rustc(RustcTest { ref target_dir, .. }) => target_dir + .as_deref() + .map(Cow::Borrowed) + .unwrap_or_else(|| Cow::Owned(std::env::temp_dir())), + }; + + // Cargo-based source types share a lot of configuration in common + match self.source { + CompilerTestInputType::CargoComponent(ref config) + | CompilerTestInputType::Cargo(ref config) => { + let manifest_path = project_dir.join("Cargo.toml"); + command + .arg("--manifest-path") + .arg(manifest_path) + .arg("--release") + .arg("--target") + .arg(config.target.as_ref()); + + if config.build_std { + // compile std as part of crate graph compilation + // https://doc.rust-lang.org/cargo/reference/unstable.html#build-std + command.arg("-Z").arg("build-std=core,alloc,std,panic_abort"); + + // abort on panic without message formatting (core::fmt uses call_indirect) + command.arg("-Z").arg("build-std-features=panic_immediate_abort"); + } else if config.build_alloc { + // compile libcore and liballoc as part of crate graph compilation + // https://doc.rust-lang.org/cargo/reference/unstable.html#build-std + command.arg("-Z").arg("build-std=core,alloc"); + + // abort on panic without message formatting (core::fmt uses call_indirect) + command.arg("-Z").arg("build-std-features=panic_immediate_abort"); + } + + // Render Cargo output as JSON + command.arg("--message-format=json-render-diagnostics"); + } + _ => (), + } + + // All test source types support custom RUSTFLAGS + if !self.rustflags.is_empty() { + let mut flags = String::with_capacity( + self.rustflags.iter().map(|flag| flag.len()).sum::() + self.rustflags.len(), ); - cargo_build_cmd - .arg("build") - .arg("--manifest-path") - .arg(manifest_path) - .arg("--release") - .arg("--target=wasm32-wasi"); - if is_build_std { - // compile std as part of crate graph compilation - // https://doc.rust-lang.org/cargo/reference/unstable.html#build-std - cargo_build_cmd.arg("-Z") - .arg("build-std=std,core,alloc,panic_abort") - .arg("-Z") - // abort on panic without message formatting (core::fmt uses call_indirect) - .arg("build-std-features=panic_immediate_abort"); + for (i, flag) in self.rustflags.iter().enumerate() { + if i > 0 { + flags.push(' '); + } + flags.push_str(flag.as_ref()); } - let mut child = cargo_build_cmd - .arg("--message-format=json-render-diagnostics") - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|_| { + command.env("RUSTFLAGS", flags); + } + + // Pipe output of command to terminal + command.stdout(Stdio::piped()); + + // Build test + match self.source { + CompilerTestInputType::CargoComponent(_) => { + let mut child = command.spawn().unwrap_or_else(|_| { panic!( - "Failed to execute cargo build {}.", - cargo_build_cmd + "Failed to execute command: {}", + command .get_args() .map(|arg| format!("'{}'", arg.to_str().unwrap())) .collect::>() @@ -238,111 +420,224 @@ impl CompilerTest { ) }); - // Find the Wasm artifacts from the cargo build output for debugging purposes - let mut wasm_artifacts = find_wasm_artifacts(&mut child); - let output = child.wait().expect("Couldn't get cargo's exit status"); - if !output.success() { - report_cargo_error(child); + let wasm_artifacts = find_wasm_artifacts(&mut child); + let output = child.wait().expect("Couldn't get cargo's exit status"); + if !output.success() { + report_cargo_error(child); + } + assert!(output.success()); + assert_eq!(wasm_artifacts.len(), 1, "Expected one Wasm artifact"); + let wasm_comp_path = &wasm_artifacts.first().unwrap(); + let artifact_name = + wasm_comp_path.file_stem().unwrap().to_str().unwrap().to_string(); + let input_file = InputFile::from_path(wasm_comp_path).unwrap(); + let mut inputs = vec![input_file]; + inputs.extend(self.link_masm_modules.into_iter().map(|(path, content)| { + let path = path.to_string(); + InputFile::new( + midenc_session::FileType::Masm, + InputType::Stdin { + name: path.into(), + input: content.into_bytes(), + }, + ) + })); + + CompilerTest { + config: self.config, + session: default_session(inputs, &self.midenc_flags), + artifact_name: artifact_name.into(), + entrypoint: self.entrypoint, + ..Default::default() + } } - assert!(output.success()); - // filter out dependencies - wasm_artifacts.retain(|path| { - let path_str = path.to_str().unwrap(); - !path_str.contains("release/deps") - }); - dbg!(&wasm_artifacts); - assert_eq!(wasm_artifacts.len(), 1, "Expected one Wasm artifact"); - wasm_artifacts.first().unwrap().to_path_buf() - } else { - expected_wasm_artifact_path - }; + CompilerTestInputType::Cargo(config) => { + let expected_wasm_artifact_path = config.wasm_artifact_path(); + let skip_rust_compilation = + std::env::var("SKIP_RUST").is_ok() && expected_wasm_artifact_path.exists(); + let wasm_artifact_path = if !skip_rust_compilation { + let mut child = command.spawn().unwrap_or_else(|_| { + panic!( + "Failed to execute command: {}", + command + .get_args() + .map(|arg| format!("'{}'", arg.to_str().unwrap())) + .collect::>() + .join(" ") + ) + }); + // Find the Wasm artifacts from the cargo build output for debugging purposes + let mut wasm_artifacts = find_wasm_artifacts(&mut child); + let output = child.wait().expect("Couldn't get cargo's exit status"); + if !output.success() { + report_cargo_error(child); + } + assert!(output.success()); + // filter out dependencies + wasm_artifacts.retain(|path| { + let path_str = path.to_str().unwrap(); + !path_str.contains("release/deps") + }); + dbg!(&wasm_artifacts); + assert_eq!(wasm_artifacts.len(), 1, "Expected one Wasm artifact"); + wasm_artifacts.swap_remove(0) + } else { + drop(command); + expected_wasm_artifact_path + }; + + let input_file = InputFile::from_path(wasm_artifact_path).unwrap(); + let mut inputs = vec![input_file]; + inputs.extend(self.link_masm_modules.into_iter().map(|(path, content)| { + let path = path.to_string(); + InputFile::new( + midenc_session::FileType::Masm, + InputType::Stdin { + name: path.into(), + input: content.into_bytes(), + }, + ) + })); + CompilerTest { + config: self.config, + session: default_session(inputs, &self.midenc_flags), + artifact_name: config.name, + entrypoint: self.entrypoint, + ..Default::default() + } + } + CompilerTestInputType::Rustc(config) => { + // Ensure we have a fresh working directory prepared + let working_dir = config + .target_dir + .clone() + .unwrap_or_else(|| std::env::temp_dir().join(config.name.as_ref())); + if working_dir.exists() { + fs::remove_dir_all(&working_dir).unwrap(); + } + fs::create_dir_all(&working_dir).unwrap(); + + // Prepare inputs + let basename = working_dir.join(config.name.as_ref()); + let input_file = basename.with_extension("rs"); + fs::write(&input_file, config.source_code.as_ref()).unwrap(); + + // Output is the same name as the input, just with a different extension + let output_file = basename.with_extension("wasm"); + + let output = command + .args(["-C", "opt-level=z"]) // optimize for size + .arg("--target") + .arg(config.target.as_ref()) + .arg("-o") + .arg(&output_file) + .arg(&input_file) + .output() + .expect("rustc invocation failed"); + if !output.status.success() { + eprintln!("pwd: {:?}", std::env::current_dir().unwrap()); + eprintln!("{}", String::from_utf8_lossy(&output.stderr)); + panic!("Rust to Wasm compilation failed!"); + } + let input_file = InputFile::from_path(output_file).unwrap(); + let mut inputs = vec![input_file]; + inputs.extend(self.link_masm_modules.into_iter().map(|(path, content)| { + let path = path.to_string(); + InputFile::new( + midenc_session::FileType::Masm, + InputType::Stdin { + name: path.into(), + input: content.into_bytes(), + }, + ) + })); + CompilerTest { + config: self.config, + session: default_session(inputs, &self.midenc_flags), + artifact_name: config.name, + entrypoint: self.entrypoint, + ..Default::default() + } + } + } + } +} + +/// Convenience builders +impl CompilerTestBuilder { + /// Compile the Wasm component from a Rust Cargo project using cargo-component + pub fn rust_source_cargo_component( + cargo_project_folder: impl AsRef, + config: WasmTranslationConfig, + ) -> Self { + let name = cargo_project_folder + .as_ref() + .file_stem() + .map(|name| name.to_string_lossy().into_owned()) + .unwrap_or("".to_string()); + let mut builder = CompilerTestBuilder::new(CompilerTestInputType::CargoComponent( + CargoTest::new(name, cargo_project_folder.as_ref().to_path_buf()), + )); + builder.with_wasm_translation_config(config); + builder + } - let entrypoint = entry_func_name.map(|func_name| FunctionIdent { - module: Ident::new(Symbol::intern(artifact_name), SourceSpan::default()), - function: Ident::new(Symbol::intern(func_name.to_string()), SourceSpan::default()), + /// Set the Rust source code to compile a library Cargo project to Wasm module + pub fn rust_source_cargo_lib( + cargo_project_folder: impl AsRef, + artifact_name: impl Into>, + is_build_std: bool, + entry_func_name: Option>, + midenc_flags: impl IntoIterator>, + ) -> Self { + let cargo_project_folder = cargo_project_folder.as_ref().to_path_buf(); + let config = + CargoTest::new(artifact_name, cargo_project_folder).with_build_std(is_build_std); + let mut builder = CompilerTestBuilder::new(match entry_func_name { + Some(entry) => config.with_entrypoint(entry), + None => config, }); - let input_file = InputFile::from_path(wasm_artifact_path).unwrap(); - Self { - config: WasmTranslationConfig::default(), - session: default_session(input_file), - source: CompilerTestSource::RustCargoLib { - artifact_name: artifact_name.to_string(), - }, - entrypoint, - ..Default::default() - } + builder.with_midenc_flags(midenc_flags); + builder } /// Set the Rust source code to compile using a Cargo project and binary bundle name pub fn rust_source_cargo( - cargo_project_folder: &str, - artifact_name: &str, - entrypoint: &str, + cargo_project_folder: impl AsRef, + artifact_name: impl Into>, + entrypoint: impl Into>, ) -> Self { - let manifest_path = format!("../rust-apps-wasm/{}/Cargo.toml", cargo_project_folder); - // dbg!(&pwd); let temp_dir = std::env::temp_dir(); - let target_dir = temp_dir.join(cargo_project_folder); - let output = Command::new("cargo") - .arg("build") - .arg("--manifest-path") - .arg(manifest_path) - .arg("--release") - // .arg("--bins") - .arg("--target=wasm32-unknown-unknown") - // .arg("--features=wasm-target") - .arg("--target-dir") - .arg(target_dir.clone()) - // compile std as part of crate graph compilation - // https://doc.rust-lang.org/cargo/reference/unstable.html#build-std - .arg("-Z") - .arg("build-std=core,alloc") - .arg("-Z") - // abort on panic without message formatting (core::fmt uses call_indirect) - .arg("build-std-features=panic_immediate_abort") - .output() - .expect("Failed to execute cargo build."); - if !output.status.success() { - eprintln!("pwd: {:?}", std::env::current_dir().unwrap()); - eprintln!("{}", String::from_utf8_lossy(&output.stderr)); - panic!("Rust to Wasm compilation failed!"); - } - let target_bin_file_path = Path::new(&target_dir) - .join("wasm32-unknown-unknown") - .join("release") - .join(artifact_name) - .with_extension("wasm"); - - let input_file = InputFile::from_path(target_bin_file_path).unwrap(); - let session = default_session(input_file); - let entrypoint = FunctionIdent { - module: Ident::new(Symbol::intern(artifact_name), SourceSpan::default()), - function: Ident::new(Symbol::intern(entrypoint.to_string()), SourceSpan::default()), - }; - CompilerTest { - session, - source: CompilerTestSource::RustCargo { - cargo_project_folder_name: cargo_project_folder.to_string(), - artifact_name: artifact_name.to_string(), - }, - entrypoint: Some(entrypoint), - ..Default::default() - } + let target_dir = temp_dir.join(cargo_project_folder.as_ref()); + let project_dir = Path::new("../rust-apps-wasm") + .join(cargo_project_folder.as_ref()) + .canonicalize() + .unwrap_or_else(|_| { + panic!( + "unknown project folder: ../rust-apps-wasm/{}", + cargo_project_folder.as_ref().display() + ) + }); + let config = CargoTest::new(artifact_name, project_dir) + .with_build_alloc(true) + .with_target_dir(target_dir) + .with_target("wasm32-unknown-unknown") + .with_entrypoint(entrypoint); + CompilerTestBuilder::new(config) } /// Set the Rust source code to compile - pub fn rust_source_program(rust_source: &str) -> Self { - let wasm_file = compile_rust_file(rust_source); - let session = default_session(wasm_file); - CompilerTest { - session, - source: CompilerTestSource::Rust(rust_source.to_string()), - ..Default::default() - } + pub fn rust_source_program(rust_source: impl Into>) -> Self { + let rust_source = rust_source.into(); + let name = format!("test_rust_{}", hash_string(&rust_source)); + CompilerTestBuilder::new(RustcTest::new(name, rust_source)) } /// Set the Rust source code to compile and add a binary operation test - pub fn rust_fn_body(rust_source: &str) -> Self { + pub fn rust_fn_body( + rust_source: &str, + midenc_flags: impl IntoIterator>, + ) -> Self { let rust_source = format!( r#" #![no_std] @@ -350,7 +645,7 @@ impl CompilerTest { #[panic_handler] fn my_panic(_info: &core::panic::PanicInfo) -> ! {{ - loop {{}} + core::arch::wasm32::unreachable() }} #[no_mangle] @@ -358,32 +653,26 @@ impl CompilerTest { "#, rust_source ); - let wasm_file = compile_rust_file(&rust_source); - let wasm_filestem = wasm_file.filestem().to_string(); - let session = default_session(wasm_file); - let entrypoint = FunctionIdent { - module: Ident { - name: Symbol::intern(wasm_filestem), - span: SourceSpan::default(), - }, - function: Ident { - name: Symbol::intern("entrypoint"), - span: SourceSpan::default(), - }, - }; - - CompilerTest { - session, - source: CompilerTestSource::Rust(rust_source.to_string()), - entrypoint: Some(entrypoint), - ..Default::default() - } + let name = format!("test_rust_{}", hash_string(&rust_source)); + let module_name = Ident::with_empty_span(Symbol::intern(&name)); + let mut builder = CompilerTestBuilder::new(RustcTest::new(name, rust_source)); + builder.with_midenc_flags(midenc_flags).with_entrypoint(FunctionIdent { + module: module_name, + function: Ident::with_empty_span(Symbol::intern("entrypoint")), + }); + builder } /// Set the Rust source code to compile with `miden-stdlib-sys` (stdlib + intrinsics) - pub fn rust_fn_body_with_stdlib_sys(name: &str, rust_source: &str, is_build_std: bool) -> Self { - let miden_stdlib_sys_path_str = stdlib_sys_crate_path(); - let proj = project(name) + pub fn rust_fn_body_with_stdlib_sys( + name: impl Into>, + source: &str, + is_build_std: bool, + midenc_flags: impl IntoIterator>, + ) -> Self { + let name = name.into(); + let stdlib_sys_path = stdlib_sys_crate_path(); + let proj = project(name.as_ref()) .file( "Cargo.toml", format!( @@ -396,7 +685,7 @@ impl CompilerTest { [dependencies] wee_alloc = {{ version = "0.4.5", default-features = false}} - miden-stdlib-sys = {{ path = "{miden_stdlib_sys_path_str}" }} + miden-stdlib-sys = {{ path = "{stdlib_sys_path}" }} [lib] crate-type = ["cdylib"] @@ -405,7 +694,9 @@ impl CompilerTest { panic = "abort" # optimize for size opt-level = "z" - "# + debug = true + "#, + stdlib_sys_path = stdlib_sys_path.display(), ) .as_str(), ) @@ -418,7 +709,7 @@ impl CompilerTest { #[panic_handler] fn my_panic(_info: &core::panic::PanicInfo) -> ! {{ - loop {{}} + core::arch::wasm32::unreachable() }} @@ -431,88 +722,303 @@ impl CompilerTest { #[no_mangle] pub extern "C" fn entrypoint{} "#, - rust_source + source ) .as_str(), ) .build(); - Self::rust_source_cargo_lib(proj.root(), name, is_build_std, Some("entrypoint".to_string())) + Self::rust_source_cargo_lib( + proj.root(), + name, + is_build_std, + Some("entrypoint".into()), + midenc_flags, + ) } - /// Set the Rust source code to compile with `miden-stdlib-sys` (stdlib + intrinsics) - pub fn rust_fn_body_with_sdk(name: &str, rust_source: &str, is_build_std: bool) -> Self { - let cwd = std::env::current_dir().unwrap(); - let miden_sdk_path = cwd.parent().unwrap().parent().unwrap().join("sdk").join("sdk"); - let miden_sdk_path_str = miden_sdk_path.to_str().unwrap(); - let proj = project(name) + /// Set the Rust source code to compile with `miden-sdk` (sdk + intrinsics) + pub fn rust_source_with_sdk( + name: impl Into>, + source: &str, + is_build_std: bool, + entrypoint: Option>, + midenc_flags: impl IntoIterator>, + ) -> Self { + let name = name.into(); + let sdk_path = sdk_crate_path(); + let proj = project(name.as_ref()) .file( "Cargo.toml", format!( - r#" - [package] - name = "{name}" - version = "0.0.1" - edition = "2015" - authors = [] - - [dependencies] - wee_alloc = {{ version = "0.4.5", default-features = false}} - miden-sdk = {{ path = "{miden_sdk_path_str}" }} - - [lib] - crate-type = ["cdylib"] - - [profile.release] - panic = "abort" - # optimize for size - opt-level = "z" - "# + r#"[package] +name = "{name}" +version = "0.0.1" +edition = "2021" +authors = [] + +[dependencies] +wee_alloc = {{ version = "0.4.5", default-features = false}} +miden-sdk = {{ path = "{sdk_path}" }} + +[lib] +crate-type = ["cdylib"] + +[profile.release] +panic = "abort" +# optimize for size +opt-level = "z" +debug = true +"#, + sdk_path = sdk_path.display(), ) .as_str(), ) .file( "src/lib.rs", format!( - r#" - #![no_std] - #![no_main] + r#"#![no_std] +#![no_main] - #[panic_handler] - fn my_panic(_info: &core::panic::PanicInfo) -> ! {{ - loop {{}} - }} +#[panic_handler] +fn my_panic(_info: &core::panic::PanicInfo) -> ! {{ + core::arch::wasm32::unreachable() +}} - #[global_allocator] - static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; +#[global_allocator] +static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; - extern crate miden_sdk; - use miden_sdk::*; +extern crate miden_sdk; +use miden_sdk::*; - extern crate alloc; - use alloc::vec::Vec; +extern crate alloc; +use alloc::vec::Vec; - #[no_mangle] - pub extern "C" fn entrypoint{} - "#, - rust_source +{} +"#, + source ) .as_str(), ) .build(); - Self::rust_source_cargo_lib(proj.root(), name, is_build_std, Some("entrypoint".to_string())) + Self::rust_source_cargo_lib(proj.root(), name, is_build_std, entrypoint, midenc_flags) + } + + /// Like `rust_source_with_sdk`, but expects the source code to be the body of a function + /// which will be used as the entrypoint. + pub fn rust_fn_body_with_sdk( + name: impl Into>, + source: &str, + is_build_std: bool, + midenc_flags: impl IntoIterator>, + ) -> Self { + let source = format!("#[no_mangle]\npub extern \"C\" fn entrypoint{source}"); + Self::rust_source_with_sdk( + name, + &source, + is_build_std, + Some("entrypoint".into()), + midenc_flags, + ) + } +} + +/// Compile to different stages (e.g. Wasm, IR, MASM) and compare the results against expected +/// output +pub struct CompilerTest { + /// The Wasm translation configuration + pub config: WasmTranslationConfig, + /// The compiler session + pub session: Rc, + /// The artifact name from which this test is derived + artifact_name: Cow<'static, str>, + /// The entrypoint function to use when building the IR + entrypoint: Option, + /// The compiled IR + hir: Option, + /// The MASM source code + masm_src: Option, + /// The compiled IR MASM program + ir_masm_program: Option, String>>, + /// The compiled VM program + vm_masm_program: Option, String>>, +} + +impl fmt::Debug for CompilerTest { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("CompilerTest") + .field("config", &self.config) + .field("session", &self.session) + .field("artifact_name", &self.artifact_name) + .field("entrypoint", &self.entrypoint) + .field_with("hir", |f| match self.hir.as_ref() { + None => f.debug_tuple("None").finish(), + Some(HirArtifact::Module(module)) => f + .debug_struct("Module") + .field("name", &module.name) + .field("entrypoint", &module.entrypoint()) + .field("is_kernel", &module.is_kernel()) + .field_with("functions", |f| { + f.debug_list() + .entries(module.functions().map(|fun| &fun.signature)) + .finish() + }) + .field_with("globals", |f| { + f.debug_list().entries(module.globals().iter()).finish() + }) + .finish_non_exhaustive(), + Some(HirArtifact::Program(program)) => f + .debug_struct("Program") + .field("is_executable", &program.is_executable()) + .field_with("modules", |f| { + f.debug_list().entries(program.modules().iter().map(|m| m.name)).finish() + }) + .field_with("libraries", |f| { + let mut map = f.debug_map(); + for (digest, lib) in program.libraries().iter() { + map.key(digest).value_with(|f| { + f.debug_list() + .entries(lib.exports().map(|proc| proc.to_string())) + .finish() + }); + } + map.finish() + }) + .finish_non_exhaustive(), + Some(HirArtifact::Component(component)) => f + .debug_struct("Component") + .field_with("exports", |f| { + f.debug_map().entries(component.exports().iter()).finish() + }) + .finish_non_exhaustive(), + }) + .finish_non_exhaustive() + } +} + +impl Default for CompilerTest { + fn default() -> Self { + Self { + config: WasmTranslationConfig::default(), + session: dummy_session(&[]), + artifact_name: "unknown".into(), + entrypoint: None, + hir: None, + masm_src: None, + ir_masm_program: None, + vm_masm_program: None, + } + } +} + +impl CompilerTest { + /// Return the name of the artifact this test is derived from + pub fn artifact_name(&self) -> &str { + self.artifact_name.as_ref() + } + + /// Compile the Wasm component from a Rust Cargo project using cargo-component + pub fn rust_source_cargo_component( + cargo_project_folder: impl AsRef, + config: WasmTranslationConfig, + ) -> Self { + CompilerTestBuilder::rust_source_cargo_component(cargo_project_folder, config).build() + } + + /// Set the Rust source code to compile a library Cargo project to Wasm module + pub fn rust_source_cargo_lib( + cargo_project_folder: impl AsRef, + artifact_name: impl Into>, + is_build_std: bool, + entry_func_name: Option>, + midenc_flags: impl IntoIterator>, + ) -> Self { + CompilerTestBuilder::rust_source_cargo_lib( + cargo_project_folder, + artifact_name, + is_build_std, + entry_func_name, + midenc_flags, + ) + .build() + } + + /// Set the Rust source code to compile using a Cargo project and binary bundle name + pub fn rust_source_cargo( + cargo_project_folder: &str, + artifact_name: impl Into>, + entrypoint: impl Into>, + ) -> Self { + CompilerTestBuilder::rust_source_cargo(cargo_project_folder, artifact_name, entrypoint) + .build() + } + + /// Set the Rust source code to compile + pub fn rust_source_program(rust_source: impl Into>) -> Self { + CompilerTestBuilder::rust_source_program(rust_source).build() + } + + /// Set the Rust source code to compile and add a binary operation test + pub fn rust_fn_body( + source: &str, + midenc_flags: impl IntoIterator>, + ) -> Self { + CompilerTestBuilder::rust_fn_body(source, midenc_flags).build() + } + + /// Set the Rust source code to compile with `miden-stdlib-sys` (stdlib + intrinsics) + pub fn rust_fn_body_with_stdlib_sys( + name: impl Into>, + source: &str, + is_build_std: bool, + midenc_flags: impl IntoIterator>, + ) -> Self { + CompilerTestBuilder::rust_fn_body_with_stdlib_sys(name, source, is_build_std, midenc_flags) + .build() + } + + /// Set the Rust source code to compile with `miden-sdk` (sdk + intrinsics) + pub fn rust_source_with_sdk( + name: impl Into>, + source: &str, + is_build_std: bool, + entrypoint: Option>, + midenc_flags: impl IntoIterator>, + ) -> Self { + CompilerTestBuilder::rust_source_with_sdk( + name, + source, + is_build_std, + entrypoint, + midenc_flags, + ) + .build() + } + + /// Like [Self::rust_source_with_sdk], but expects the source code to be a function parameter + /// list and body, rather than arbitrary source code. + /// + /// NOTE: It is valid to append additional sources _after_ the closing brace of the function + /// body. + pub fn rust_fn_body_with_sdk( + name: impl Into>, + source: &str, + is_build_std: bool, + midenc_flags: impl IntoIterator>, + ) -> Self { + CompilerTestBuilder::rust_fn_body_with_sdk(name, source, is_build_std, midenc_flags).build() } /// Compare the compiled Wasm against the expected output pub fn expect_wasm(&self, expected_wat_file: expect_test::ExpectFile) { let wasm_bytes = self.wasm_bytes(); - let wat = demangle(&wasm_to_wat(&wasm_bytes)); + let wat = demangle(wasm_to_wat(&wasm_bytes)); expected_wat_file.assert_eq(&wat); } fn wasm_to_ir(&self) -> HirArtifact { - let ir_component = translate(&self.wasm_bytes(), &self.config, &self.session.diagnostics) + let ir_component = translate(&self.wasm_bytes(), &self.config, &self.session) .expect("Failed to translate Wasm binary to IR component"); Box::new(ir_component).into() } @@ -529,26 +1035,30 @@ impl CompilerTest { pub fn expect_ir(&mut self, expected_hir_file: expect_test::ExpectFile) { match self.hir() { HirArtifact::Program(hir_program) => { - // Program does not implement pretty printer yet, use the first module - let ir_module = demangle( - hir_program - .modules() - .iter() - .take(1) - .collect::>() - .first() - .expect("no module in IR program") - .to_string() - .as_str(), - ); + // Program does not implement pretty printer yet, use the module containing the + // entrypoint function, or the first module found if no entrypoint is set + let ir_module = hir_program + .entrypoint() + .map(|entry| { + hir_program + .modules() + .find(&entry.module) + .get() + .expect("missing entrypoint module") + }) + .unwrap_or_else(|| { + hir_program.modules().iter().next().expect("expected at least one module") + }) + .to_string(); + let ir_module = demangle(ir_module); expected_hir_file.assert_eq(&ir_module); } HirArtifact::Component(hir_component) => { - let ir_component = demangle(&hir_component.to_string()); + let ir_component = demangle(hir_component.to_string()); expected_hir_file.assert_eq(&ir_component); } HirArtifact::Module(hir_module) => { - let ir_module = demangle(&hir_module.to_string()); + let ir_module = demangle(hir_module.to_string()); expected_hir_file.assert_eq(&ir_module); } } @@ -592,7 +1102,7 @@ impl CompilerTest { /// The compiled Wasm component/module fn wasm_bytes(&self) -> Vec { - match &self.session.input.file { + match &self.session.inputs[0].file { InputType::Real(file_path) => fs::read(file_path) .unwrap_or_else(|_| panic!("Failed to read Wasm file: {}", file_path.display())), InputType::Stdin { name: _, input } => input.clone(), @@ -600,23 +1110,36 @@ impl CompilerTest { } pub(crate) fn compile_wasm_to_masm_program(&mut self) { - match midenc_compile::compile_to_memory(self.session.clone()).unwrap() { - midenc_compile::Compiled::Program(_p) => todo!("Program compilation not yet supported"), - midenc_compile::Compiled::Modules(modules) => { - let src = expected_masm_prog_source_from_modules( - &modules, - self.entrypoint, - &self.link_masm_modules, - ); - self.masm_src = Some(src); - let vm_prog = - vm_masm_prog_from_modules(&modules, self.entrypoint, &self.link_masm_modules); - self.vm_masm_program = Some(vm_prog.map_err(format_report)); - let ir_prog = - ir_masm_prog_from_modules(modules, self.entrypoint, &self.link_masm_modules); - self.ir_masm_program = Some(ir_prog.map_err(format_report)); - } - } + use midenc_codegen_masm::MasmArtifact; + use midenc_compile::compile_to_memory_with_pre_assembly_stage; + use midenc_hir::pass::AnalysisManager; + + let mut src = None; + let mut masm_program = None; + let mut stage = + |artifact: MasmArtifact, _analyses: &mut AnalysisManager, _session: &Session| { + match artifact { + MasmArtifact::Executable(ref program) => { + src = Some(program.to_string()); + masm_program = Some(Arc::from(program.clone())); + } + MasmArtifact::Library(ref lib) => { + src = Some(lib.to_string()); + } + } + Ok(artifact) + }; + let mast_program = + compile_to_memory_with_pre_assembly_stage(self.session.clone(), &mut stage as _) + .map_err(format_report) + .unwrap_or_else(|err| panic!("{err}")) + .unwrap_mast() + .unwrap_program(); + assert!(src.is_some(), "failed to pretty print masm artifact"); + assert!(masm_program.is_some(), "failed to capture masm artifact"); + self.masm_src = src; + self.ir_masm_program = masm_program.map(Ok); + self.vm_masm_program = Some(Ok(mast_program)); } } @@ -626,146 +1149,16 @@ fn format_report(report: miden_assembly::diagnostics::Report) -> String { PrintDiagnostic::new(report).to_string() } -fn wasm_artifact_path(cargo_project_folder: &Path, artifact_name: &str) -> PathBuf { - cargo_project_folder - .to_path_buf() - .join("target") - .join("wasm32-wasi") - .join("release") - .join(artifact_name) - .with_extension("wasm") -} - -/// Directs if we should do the Rust compilation step or not -pub fn skip_rust_compilation(cargo_project_folder: &Path, artifact_name: &str) -> bool { - let expected_wasm_artifact_path = wasm_artifact_path(cargo_project_folder, artifact_name); - let skip_rust = std::env::var("SKIP_RUST").is_ok() && expected_wasm_artifact_path.exists(); - if skip_rust { - eprintln!("Skipping Rust compilation"); - }; - skip_rust -} - -#[allow(clippy::vec_box)] -fn ir_masm_prog_from_modules( - modules: Vec>, - entrypoint: Option, - link_masm_modules: &LinkMasmModules, -) -> Result, Report> { - let mut p = midenc_codegen_masm::Program::empty(); - for (_path, _src) in link_masm_modules { - // TODO: implement linking of MASM source code - } - for module in modules.into_iter() { - p.insert(module); - } - p.entrypoint = entrypoint; - Ok(Box::new(p).freeze()) -} - -// Assemble the VM MASM program from the compiled IR MASM modules -fn vm_masm_prog_from_modules( - modules: &[Box], - entrypoint: Option, - link_masm_modules: &LinkMasmModules, -) -> Result, Report> { - let mut assembler = Assembler::default().with_library(&StdLibrary::default())?; - for (path, src) in link_masm_modules { - let options = miden_assembly::CompileOptions { - kind: ModuleKind::Library, - warnings_as_errors: false, - path: Some(path.clone()), - }; - assembler.add_module_with_options(src, options)?; - } - for module in modules { - let module_src = format!("{}", module); - //eprintln!("### {}\n", module.id); - //eprintln!("{}", &module_src); - let path = module.id.as_str().to_string(); - let library_path = LibraryPath::new(path).unwrap(); - // dbg!(&library_path); - let options = miden_assembly::CompileOptions { - kind: ModuleKind::Library, - warnings_as_errors: false, - path: Some(library_path), - }; - assembler.add_module_with_options(module_src, options)?; - } - if let Some(entrypoint) = entrypoint { - let prog_source = masm_prog_source(entrypoint); - assembler.assemble(prog_source).map(Arc::new) - } else { - todo!() - } -} - -// Generate the MASM program source code from the compiled IR MASM modules -fn expected_masm_prog_source_from_modules( - modules: &[Box], - entrypoint: Option, - link_masm_modules: &LinkMasmModules, -) -> String { - let mut src = String::new(); - for (path, module_src) in link_masm_modules { - writeln!(src, "# mod {path}\n").unwrap(); - writeln!(src, "{module_src}").unwrap(); - } - for module in modules { - let module_src = format!("{}", module); - let path = module.id.as_str().to_string(); - if !path.contains("intrinsic") { - // print only user modules and not intrinsic modules - writeln!(src, "# mod {path}\n").unwrap(); - write!(src, "{module_src}").unwrap(); - } - } - if let Some(entrypoint) = entrypoint { - let prog_source = masm_prog_source(entrypoint); - src.push_str(&prog_source); - } else { - todo!() - } - src -} - -// Generate the MASM program source code (call the entrypoint function) -fn masm_prog_source(entrypoint: FunctionIdent) -> String { - let module_name = entrypoint.module.as_str(); - let function_name = entrypoint.function.as_str(); - format!( - r#" -begin - exec.::{module_name}::{function_name} -end"#, - ) -} - -fn stdlib_sys_crate_path() -> String { +fn stdlib_sys_crate_path() -> PathBuf { let cwd = std::env::current_dir().unwrap(); - cwd.parent() - .unwrap() - .parent() - .unwrap() - .join("sdk") - .join("stdlib-sys") - .to_str() - .unwrap() - .to_string() + cwd.parent().unwrap().parent().unwrap().join("sdk").join("stdlib-sys") } -pub fn sdk_crate_path() -> String { +pub fn sdk_crate_path() -> PathBuf { let cwd = std::env::current_dir().unwrap(); - cwd.parent() - .unwrap() - .parent() - .unwrap() - .join("sdk") - .join("sdk") - .to_str() - .unwrap() - .to_string() + cwd.parent().unwrap().parent().unwrap().join("sdk").join("sdk") } + /// Get the directory for the top-level workspace fn get_workspace_dir() -> String { // Get the directory for the integration test suite project @@ -805,14 +1198,6 @@ fn find_wasm_artifacts(child: &mut std::process::Child) -> Vec String { - let mut input = name.as_bytes(); - let mut demangled = Vec::new(); - let include_hash = false; - rustc_demangle::demangle_stream(&mut input, &mut demangled, include_hash).unwrap(); - String::from_utf8(demangled).unwrap() -} - fn wasm_to_wat(wasm_bytes: &[u8]) -> String { let mut wasm_printer = wasmprinter::Printer::new(); // disable printing of the "producers" section because it contains a rustc version @@ -821,71 +1206,28 @@ fn wasm_to_wat(wasm_bytes: &[u8]) -> String { let wat = wasm_printer.print(wasm_bytes.as_ref()).unwrap(); wat } -fn compile_rust_file(rust_source: &str) -> InputFile { - let rustc_opts = [ - "-C", - "opt-level=z", // optimize for size - "--target", - "wasm32-unknown-unknown", - ]; - let file_name = format!("test_rust_{}", hash_string(rust_source)); - let proj_dir = std::env::temp_dir().join(&file_name); - if proj_dir.exists() { - fs::remove_dir_all(&proj_dir).unwrap(); - fs::create_dir_all(&proj_dir).unwrap(); - } else { - fs::create_dir_all(&proj_dir).unwrap(); - } - let input_file = proj_dir.join(format!("{file_name}.rs")); - let output_file = proj_dir.join(format!("{file_name}.wasm")); - fs::write(&input_file, rust_source).unwrap(); - let output = Command::new("rustc") - .args(rustc_opts) - .arg(&input_file) - .arg("-o") - .arg(&output_file) - .output() - .expect("Failed to execute rustc."); - if !output.status.success() { - eprintln!("{}", String::from_utf8_lossy(&output.stderr)); - panic!("Rust to Wasm compilation failed!"); - } - InputFile::from_path(output_file).unwrap() -} -fn dummy_session() -> Session { - let output_type = OutputType::Masm; - let output_types = OutputTypes::new(vec![OutputTypeSpec { - output_type, - path: None, - }]); - let options = Options::default().with_output_types(output_types); - Session::new( - Default::default(), - InputFile::from_path(PathBuf::from("dummy.wasm")).unwrap(), - None, - None, - None, - options, - None, - ) - .with_project_type(ProjectType::Library) +fn dummy_session(flags: &[&str]) -> Rc { + let dummy = InputFile::from_path(PathBuf::from("dummy.wasm")).unwrap(); + default_session([dummy], flags) } /// Create a default session for testing -pub fn default_session(input_file: InputFile) -> Arc { - let default_session = dummy_session(); - let session = Session::new( - Default::default(), - input_file, - None, - None, - None, - default_session.options, - None, - ) - .with_project_type(ProjectType::Library); - Arc::new(session) +pub fn default_session(inputs: I, argv: &[S]) -> Rc +where + I: IntoIterator, + S: AsRef, +{ + use midenc_hir::diagnostics::reporting::{self, ReportHandlerOpts}; + + let result = reporting::set_hook(Box::new(|_| Box::new(ReportHandlerOpts::new().build()))); + if result.is_ok() { + reporting::set_panic_hook(); + } + + let argv = argv.iter().map(|arg| arg.as_ref()); + let session = midenc_compile::Compiler::new_session(inputs, None, argv); + Rc::new(session) } fn hash_string(inputs: &str) -> String { diff --git a/tests/integration/src/exec_emulator.rs b/tests/integration/src/exec_emulator.rs index 6b58bfc9..ee40028f 100644 --- a/tests/integration/src/exec_emulator.rs +++ b/tests/integration/src/exec_emulator.rs @@ -1,10 +1,9 @@ use std::sync::Arc; use midenc_codegen_masm::{Emulator, Program}; +use midenc_debug::TestFelt; use midenc_hir::{Felt, Stack}; -use crate::felt_conversion::TestFelt; - /// Execute the module using the emulator with the given arguments /// Arguments are expected to be in the order they are passed to the entrypoint function pub fn execute_emulator(program: Arc, args: &[Felt]) -> Vec { diff --git a/tests/integration/src/exec_vm.rs b/tests/integration/src/exec_vm.rs deleted file mode 100644 index ca2a950b..00000000 --- a/tests/integration/src/exec_vm.rs +++ /dev/null @@ -1,43 +0,0 @@ -use miden_core::{Program, StackInputs}; -use miden_processor::{DefaultHost, ExecutionError, ExecutionOptions}; -use midenc_hir::Felt; - -use crate::felt_conversion::TestFelt; - -/// Execute the program using the VM with the given arguments -/// Arguments are expected to be in the order they are passed to the entrypoint function -pub fn execute_vm(program: &Program, args: &[Felt]) -> Vec { - // Reverse the arguments to counteract the StackInputs::new() reversing them into a stack - let stack_inputs = StackInputs::new(args.to_vec()).expect("invalid stack inputs"); - dbg!(&stack_inputs); - let trace = miden_processor::execute( - program, - stack_inputs, - DefaultHost::default(), - ExecutionOptions::default(), - ) - .expect("failed to execute program on VM"); - trace.stack_outputs().stack().iter().map(|i| TestFelt(*i)).collect() -} - -/// Execute the program using the VM with the given arguments -/// Prints the trace (VM state) after each step to stdout -/// Arguments are expected to be in the order they are passed to the entrypoint function -#[allow(unused)] -pub fn execute_vm_tracing( - program: &Program, - args: &[Felt], -) -> Result, ExecutionError> { - // Reverse the arguments to counteract the StackInputs::new() reversing them into a stack - let args_reversed = args.iter().copied().rev().collect(); - let stack_inputs = StackInputs::new(args_reversed).expect("invalid stack inputs"); - let vm_state_iterator = - miden_processor::execute_iter(program, stack_inputs, DefaultHost::default()); - let mut last_stack = Vec::new(); - for vm_state in vm_state_iterator { - let vm_state = vm_state?; - eprintln!("{}", vm_state); - last_stack.clone_from(&vm_state.stack); - } - Ok(last_stack.into_iter().map(TestFelt).collect()) -} diff --git a/tests/integration/src/felt_conversion.rs b/tests/integration/src/felt_conversion.rs deleted file mode 100644 index ef5ac737..00000000 --- a/tests/integration/src/felt_conversion.rs +++ /dev/null @@ -1,340 +0,0 @@ -use std::collections::VecDeque; - -use miden_core::Felt; -use proptest::{ - arbitrary::Arbitrary, - strategy::{BoxedStrategy, Strategy}, -}; - -pub trait PushToStack: Sized { - fn try_push(&self, stack: &mut Vec) { - let mut ptr = self as *const Self as *const u8; - let mut num_bytes = core::mem::size_of::(); - let mut buf = Vec::with_capacity(num_bytes / core::mem::size_of::()); - while num_bytes > 0 { - let mut next = [0u8; 4]; - let consume = core::cmp::min(4, num_bytes); - unsafe { - ptr.copy_to_nonoverlapping(next.as_mut_ptr(), consume); - ptr = ptr.byte_add(consume); - } - num_bytes -= consume; - buf.push(Felt::new(u32::from_be_bytes(next) as u64)); - } - - for item in buf.into_iter().rev() { - stack.push(item); - } - } -} - -pub trait PopFromStack: Sized { - fn try_pop(stack: &mut VecDeque) -> Result { - use core::mem::MaybeUninit; - - let mut num_bytes = core::mem::size_of::(); - let mut result = MaybeUninit::::uninit(); - let mut ptr = result.as_mut_ptr() as *mut u8; - while num_bytes > 0 { - let next = stack.pop_front().expect("expected more operand stack elements"); - let next_bytes = (next.0.as_int() as u32).to_be_bytes(); - let consume = core::cmp::min(4, num_bytes); - unsafe { - next_bytes.as_ptr().copy_to_nonoverlapping(ptr, consume); - ptr = ptr.byte_add(consume); - } - num_bytes -= consume; - } - Ok(unsafe { result.assume_init() }) - } -} - -impl PushToStack for bool { - fn try_push(&self, stack: &mut Vec) { - stack.push(Felt::new(*self as u64)) - } -} -impl PopFromStack for bool { - fn try_pop(stack: &mut VecDeque) -> Result { - Ok(stack.pop_front().unwrap().0.as_int() != 0) - } -} - -impl PushToStack for u8 { - fn try_push(&self, stack: &mut Vec) { - stack.push(Felt::new(*self as u64)) - } -} -impl PopFromStack for u8 { - fn try_pop(stack: &mut VecDeque) -> Result { - Ok(stack.pop_front().unwrap().0.as_int() as u8) - } -} - -impl PushToStack for i8 { - fn try_push(&self, stack: &mut Vec) { - stack.push(Felt::new(*self as u8 as u64)) - } -} -impl PopFromStack for i8 { - fn try_pop(stack: &mut VecDeque) -> Result { - Ok(stack.pop_front().unwrap().0.as_int() as i8) - } -} - -impl PushToStack for u16 { - fn try_push(&self, stack: &mut Vec) { - stack.push(Felt::new(*self as u64)) - } -} -impl PopFromStack for u16 { - fn try_pop(stack: &mut VecDeque) -> Result { - Ok(stack.pop_front().unwrap().0.as_int() as u16) - } -} - -impl PushToStack for i16 { - fn try_push(&self, stack: &mut Vec) { - stack.push(Felt::new(*self as u16 as u64)) - } -} -impl PopFromStack for i16 { - fn try_pop(stack: &mut VecDeque) -> Result { - Ok(stack.pop_front().unwrap().0.as_int() as i16) - } -} - -impl PushToStack for u32 { - fn try_push(&self, stack: &mut Vec) { - stack.push(Felt::new(*self as u64)) - } -} -impl PopFromStack for u32 { - fn try_pop(stack: &mut VecDeque) -> Result { - Ok(stack.pop_front().unwrap().0.as_int() as u32) - } -} - -impl PushToStack for i32 { - fn try_push(&self, stack: &mut Vec) { - stack.push(Felt::new(*self as u32 as u64)) - } -} -impl PopFromStack for i32 { - fn try_pop(stack: &mut VecDeque) -> Result { - Ok(stack.pop_front().unwrap().0.as_int() as i32) - } -} - -impl PushToStack for u64 { - fn try_push(&self, stack: &mut Vec) { - let lo = self.rem_euclid(2u64.pow(32)); - let hi = self.div_euclid(2u64.pow(32)); - dbg!(hi, lo); - stack.push(Felt::new(lo)); - stack.push(Felt::new(hi)); - } -} -impl PopFromStack for u64 { - fn try_pop(stack: &mut VecDeque) -> Result { - dbg!(&stack); - let hi = stack.pop_front().unwrap().0.as_int() * 2u64.pow(32); - let lo = stack.pop_front().unwrap().0.as_int(); - dbg!(hi, lo); - Ok(hi + lo) - } -} - -impl PushToStack for i64 { - fn try_push(&self, stack: &mut Vec) { - (*self as u64).try_push(stack) - } -} -impl PopFromStack for i64 { - fn try_pop(stack: &mut VecDeque) -> Result { - u64::try_pop(stack).map(|value| value as i64) - } -} - -impl PushToStack for u128 { - fn try_push(&self, stack: &mut Vec) { - let lo = self.rem_euclid(2u128.pow(64)); - let hi = self.div_euclid(2u128.pow(64)); - (lo as u64).try_push(stack); - (hi as u64).try_push(stack); - } -} -impl PopFromStack for u128 { - fn try_pop(stack: &mut VecDeque) -> Result { - let hi = (u64::try_pop(stack).unwrap() as u128) * 2u128.pow(64); - let lo = u64::try_pop(stack).unwrap() as u128; - Ok(hi + lo) - } -} - -impl PushToStack for i128 { - fn try_push(&self, stack: &mut Vec) { - (*self as u128).try_push(stack) - } -} -impl PopFromStack for i128 { - fn try_pop(stack: &mut VecDeque) -> Result { - u128::try_pop(stack).map(|value| value as i128) - } -} - -impl PushToStack for Felt { - #[inline(always)] - fn try_push(&self, stack: &mut Vec) { - stack.push(*self); - } -} -impl PopFromStack for Felt { - #[inline(always)] - fn try_pop(stack: &mut VecDeque) -> Result { - Ok(stack.pop_front().ok_or(())?.0) - } -} - -impl PushToStack for TestFelt { - #[inline(always)] - fn try_push(&self, stack: &mut Vec) { - stack.push(self.0); - } -} -impl PopFromStack for TestFelt { - #[inline(always)] - fn try_pop(stack: &mut VecDeque) -> Result { - stack.pop_front().ok_or(()) - } -} - -/// Wrapper around `Felt` that implements `From` for a bunch of types that are want to support in -/// tests -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct TestFelt(pub Felt); - -impl From for Felt { - fn from(f: TestFelt) -> Self { - f.0 - } -} - -impl From for TestFelt { - fn from(b: bool) -> Self { - Self(Felt::from(b as u32)) - } -} - -impl From for TestFelt { - fn from(t: u8) -> Self { - Self(t.into()) - } -} - -impl From for TestFelt { - fn from(t: i8) -> Self { - Self((t as u8).into()) - } -} - -impl From for TestFelt { - fn from(t: i16) -> Self { - Self((t as u16).into()) - } -} - -impl From for TestFelt { - fn from(t: u16) -> Self { - Self(t.into()) - } -} - -impl From for TestFelt { - fn from(t: i32) -> Self { - Self((t as u32).into()) - } -} - -impl From for TestFelt { - fn from(t: u32) -> Self { - Self(t.into()) - } -} - -impl From for TestFelt { - fn from(t: u64) -> Self { - Self(Felt::new(t)) - } -} - -impl From for TestFelt { - fn from(t: i64) -> Self { - Self(Felt::new(t as u64)) - } -} - -// Reverse TestFelt to Rust types conversion - -impl From for bool { - fn from(f: TestFelt) -> Self { - f.0.as_int() != 0 - } -} - -impl From for u8 { - fn from(f: TestFelt) -> Self { - f.0.as_int() as u8 - } -} - -impl From for i8 { - fn from(f: TestFelt) -> Self { - f.0.as_int() as i8 - } -} - -impl From for u16 { - fn from(f: TestFelt) -> Self { - f.0.as_int() as u16 - } -} - -impl From for i16 { - fn from(f: TestFelt) -> Self { - f.0.as_int() as i16 - } -} - -impl From for u32 { - fn from(f: TestFelt) -> Self { - f.0.as_int() as u32 - } -} - -impl From for i32 { - fn from(f: TestFelt) -> Self { - f.0.as_int() as i32 - } -} - -impl From for u64 { - fn from(f: TestFelt) -> Self { - f.0.as_int() - } -} - -impl From for i64 { - fn from(f: TestFelt) -> Self { - f.0.as_int() as i64 - } -} - -impl Arbitrary for TestFelt { - type Parameters = (); - type Strategy = BoxedStrategy; - - fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { - (0u64..u64::MAX).prop_map(|v| TestFelt(Felt::new(v))).boxed() - } -} diff --git a/tests/integration/src/lib.rs b/tests/integration/src/lib.rs index 9eaf01ea..bdaf6190 100644 --- a/tests/integration/src/lib.rs +++ b/tests/integration/src/lib.rs @@ -1,17 +1,15 @@ //! Compilation and semantic tests for the whole compiler pipeline - -#![deny(warnings)] +#![feature(iter_array_chunks)] +#![feature(debug_closure_helpers)] +//#![deny(warnings)] #![deny(missing_docs)] mod cargo_proj; mod compiler_test; mod exec_emulator; -mod exec_vm; -pub(crate) mod felt_conversion; -pub use compiler_test::{default_session, CompilerTest}; +pub use compiler_test::{default_session, CargoTest, CompilerTest, CompilerTestBuilder, RustcTest}; pub use exec_emulator::execute_emulator; -pub use exec_vm::execute_vm; #[cfg(test)] mod rust_masm_tests; diff --git a/tests/integration/src/rust_masm_tests/abi_transform/stdlib.rs b/tests/integration/src/rust_masm_tests/abi_transform/stdlib.rs index 34e5e049..96d0d91f 100644 --- a/tests/integration/src/rust_masm_tests/abi_transform/stdlib.rs +++ b/tests/integration/src/rust_masm_tests/abi_transform/stdlib.rs @@ -1,7 +1,9 @@ use core::panic; +use std::collections::VecDeque; use expect_test::expect_file; use miden_core::utils::group_slice_elements; +use midenc_debug::{Executor, PopFromStack, PushToStack, TestFelt}; use midenc_hir::Felt; use proptest::{ arbitrary::any, @@ -9,38 +11,62 @@ use proptest::{ test_runner::{TestError, TestRunner}, }; -use crate::{execute_vm, felt_conversion::TestFelt, CompilerTest}; +use crate::CompilerTest; -#[ignore = "until the VM stack overflow during the MASM generation is fixed"] #[test] +#[ignore = "pending rodata fixes"] fn test_blake3_hash() { - let main_fn = "(a: [u8; 32], b: [u8; 32]) -> [u8; 32] { miden_stdlib_sys::blake3_hash_2to1(a, \ - b) }" - .to_string(); + let main_fn = + "(a: [u8; 32]) -> [u8; 32] { miden_stdlib_sys::blake3_hash_1to1(a) }".to_string(); let artifact_name = "abi_transform_stdlib_blake3_hash"; - let mut test = CompilerTest::rust_fn_body_with_stdlib_sys(artifact_name, &main_fn, true); + let mut test = CompilerTest::rust_fn_body_with_stdlib_sys( + artifact_name, + &main_fn, + true, + ["--test-harness".into()], + ); // Test expected compilation artifacts test.expect_wasm(expect_file![format!("../../../expected/{artifact_name}.wat")]); test.expect_ir(expect_file![format!("../../../expected/{artifact_name}.hir")]); test.expect_masm(expect_file![format!("../../../expected/{artifact_name}.masm")]); + let ir_program = test.ir_masm_program(); let vm_program = test.vm_masm_program(); + let advice_inputs = ir_program.advice_inputs(); + + println!("{ir_program}"); + // Run the Rust and compiled MASM code against a bunch of random inputs and compare the results - let res = TestRunner::default().run(&any::<[u8; 64]>(), move |ibytes| { + let res = TestRunner::default().run(&any::<[u8; 32]>(), move |ibytes| { let hash_bytes = blake3::hash(&ibytes); let rs_out = hash_bytes.as_bytes(); - let rs_ofelts = group_slice_elements::(rs_out) - .iter() - .map(|&bytes| u32::from_le_bytes(bytes).into()) - .collect::>(); - let ifelts = group_slice_elements::(&ibytes) - .iter() - .map(|&bytes| u32::from_le_bytes(bytes).into()) - .collect::>(); - let vm_out = execute_vm(&vm_program, &ifelts); - prop_assert_eq!(rs_ofelts, vm_out, "VM output mismatch"); + let mut frame = Vec::::default(); + PushToStack::try_push(&ibytes, &mut frame); // words + PushToStack::try_push(&2u32, &mut frame); // num_words + PushToStack::try_push(&0u32, &mut frame); // dest_ptr + //let rs_ofelts = group_slice_elements::(rs_out) + // .iter() + // .map(|&bytes| u32::from_le_bytes(bytes).into()) + // .collect::>(); + //let ifelts = group_slice_elements::(&ibytes) + // .iter() + // .map(|&bytes| u32::from_le_bytes(bytes).into()) + // .collect::>(); + dbg!(&ibytes, &frame, rs_out); + // Arguments are: [hash_input_ptr, hash_output_ptr] + let mut exec = Executor::new(vec![Felt::new(0), Felt::new(128 * 1024)]); + let mut advice_inputs = advice_inputs.clone(); + advice_inputs.extend_stack(frame); + exec.with_advice_inputs(advice_inputs); + let trace = exec.execute(&vm_program, &test.session); + let vm_out: [u8; 32] = trace + .read_from_rust_memory(128 * 1024) + .expect("expected memory to have been written"); + dbg!(&vm_out); + prop_assert_eq!(rs_out, &vm_out, "VM output mismatch"); Ok(()) }); + match res { Err(TestError::Fail(_, value)) => { panic!("Found minimal(shrinked) failing case: {:?}", value); diff --git a/tests/integration/src/rust_masm_tests/abi_transform/tx_kernel.rs b/tests/integration/src/rust_masm_tests/abi_transform/tx_kernel.rs index 0af3771b..87b47dd3 100644 --- a/tests/integration/src/rust_masm_tests/abi_transform/tx_kernel.rs +++ b/tests/integration/src/rust_masm_tests/abi_transform/tx_kernel.rs @@ -4,8 +4,9 @@ use expect_test::expect_file; use miden_assembly::LibraryPath; use miden_core::{Felt, FieldElement}; use miden_processor::ExecutionError; +use midenc_debug::Executor; -use crate::{exec_vm::execute_vm_tracing, execute_emulator, execute_vm, CompilerTest}; +use crate::{execute_emulator, CompilerTestBuilder}; #[allow(unused)] fn setup_log() { @@ -17,32 +18,35 @@ fn setup_log() { .try_init(); } +#[test] +#[ignore = "pending rodata fixes"] +fn test_get_inputs_4() { + test_get_inputs("4", vec![u32::MAX.into(), Felt::ONE, Felt::ZERO, u32::MAX.into()]); +} + fn test_get_inputs(test_name: &str, expected_inputs: Vec) { assert!(expected_inputs.len() == 4, "for now only word-sized inputs are supported"); - let mut main_fn = String::new(); - writeln!(main_fn, "() -> Vec {{\n").unwrap(); - writeln!(main_fn, " let inputs = get_inputs();").unwrap(); - // for (_i, _expected_input) in expected_inputs.iter().enumerate() { - // TODO: use miden asserts once they are implemented - // writeln!(main_fn, " assert_eq!(inputs[{i}], {expected_input});").unwrap(); - // } - writeln!(main_fn, " inputs").unwrap(); - writeln!(main_fn, "}}").unwrap(); - + let masm = format!( + " +export.get_inputs + push.{expect1}.{expect2}.{expect3}.{expect4} + # write word to memory, leaving the pointer on the stack + dup.4 mem_storew dropw + # push the inputs len on the stack + push.4 +end +", + expect1 = expected_inputs.first().map(|i| i.as_int()).unwrap_or(0), + expect2 = expected_inputs.get(1).map(|i| i.as_int()).unwrap_or(0), + expect3 = expected_inputs.get(2).map(|i| i.as_int()).unwrap_or(0), + expect4 = expected_inputs.get(3).map(|i| i.as_int()).unwrap_or(0), + ); + let main_fn = "() -> Vec { get_inputs() }"; let artifact_name = format!("abi_transform_tx_kernel_get_inputs_{}", test_name); - let mut test = CompilerTest::rust_fn_body_with_sdk(&artifact_name, &main_fn, true); - let mut masm = String::new(); - writeln!(masm, "export.get_inputs").unwrap(); - for expected_input in expected_inputs.iter() { - writeln!(masm, " push.{expected_input}").unwrap(); - } - // copy the pointer to the top of the stack - writeln!(masm, " dup.4").unwrap(); - writeln!(masm, " mem_storew").unwrap(); - // push the inputs len on the stack - writeln!(masm, " push.{}", expected_inputs.len()).unwrap(); - writeln!(masm, " end").unwrap(); - test.link_masm_modules = vec![(LibraryPath::new("miden::note").unwrap(), masm)]; + let mut test_builder = + CompilerTestBuilder::rust_fn_body_with_sdk(artifact_name.clone(), main_fn, true, None); + test_builder.link_with_masm_module("miden::note", masm); + let mut test = test_builder.build(); // Test expected compilation artifacts test.expect_wasm(expect_file![format!("../../../expected/{artifact_name}.wat")]); @@ -50,13 +54,12 @@ fn test_get_inputs(test_name: &str, expected_inputs: Vec) { test.expect_masm(expect_file![format!("../../../expected/{artifact_name}.masm")]); let vm_program = test.vm_masm_program(); - // let vm_out = execute_vm_tracing(&vm_program, &[]).unwrap(); + + let exec = Executor::new(vec![]); + let trace = exec.execute(&vm_program, &test.session); + let vm_out = trace.into_outputs(); + dbg!(&vm_out); // let ir_program = test.ir_masm_program(); // let emul_out = execute_emulator(ir_program.clone(), &[]); } - -#[test] -fn test_get_inputs_4() { - test_get_inputs("4", vec![u32::MAX.into(), Felt::ONE, Felt::ZERO, u32::MAX.into()]); -} diff --git a/tests/integration/src/rust_masm_tests/apps.rs b/tests/integration/src/rust_masm_tests/apps.rs index 02df1f3c..559ac2a6 100644 --- a/tests/integration/src/rust_masm_tests/apps.rs +++ b/tests/integration/src/rust_masm_tests/apps.rs @@ -1,14 +1,11 @@ use std::collections::VecDeque; use expect_test::expect_file; +use midenc_debug::{Executor, PopFromStack, PushToStack}; use midenc_hir::Felt; use proptest::{prelude::*, test_runner::TestRunner}; -use crate::{ - execute_vm, - felt_conversion::{PopFromStack, PushToStack}, - CompilerTest, -}; +use crate::CompilerTest; #[test] fn fib() { @@ -28,10 +25,10 @@ fn fib() { let mut args = Vec::::default(); PushToStack::try_push(&a, &mut args); - let mut out = VecDeque::from(execute_vm(vm_program, &args)); - dbg!(&out); - let vm_out = u32::try_pop(&mut out).expect("invalid result"); - prop_assert_eq!(rust_out, vm_out); + let exec = Executor::new(args); + let output: u32 = exec.execute_into(vm_program, &test.session); + dbg!(output); + prop_assert_eq!(rust_out, output); // args.reverse(); // let emul_out: u32 = // execute_emulator(ir_masm.clone(), &args).first().unwrap().clone().into(); diff --git a/tests/integration/src/rust_masm_tests/components.rs b/tests/integration/src/rust_masm_tests/components.rs index 17f4db4a..e48bedbc 100644 --- a/tests/integration/src/rust_masm_tests/components.rs +++ b/tests/integration/src/rust_masm_tests/components.rs @@ -20,7 +20,7 @@ fn wcm_no_imports() { authors = [] [dependencies] - wit-bindgen = { version = "0.17.0", default-features = false, features = ["realloc"] } + wit-bindgen-rt = "0.28" wee_alloc = { version = "0.4.5", default-features = false} [lib] @@ -46,7 +46,7 @@ fn wcm_no_imports() { loop {} } - extern crate wit_bindgen; + bindings::export!(Component with_types_in bindings); mod bindings; @@ -77,7 +77,7 @@ fn wcm_no_imports() { ) .build(); let mut test = CompilerTest::rust_source_cargo_component(proj.root(), config); - let artifact_name = test.source.artifact_name(); + let artifact_name = test.artifact_name(); test.expect_wasm(expect_file![format!("../../expected/components/{artifact_name}.wat")]); test.expect_ir(expect_file![format!("../../expected/components/{artifact_name}.hir")]); } @@ -136,7 +136,7 @@ fn wcm_import() { authors = [] [dependencies] - wit-bindgen = { version = "0.17.0", default-features = false, features = ["realloc"] } + wit-bindgen-rt = "0.28" wee_alloc = { version = "0.4.5", default-features = false} [lib] @@ -165,7 +165,7 @@ fn wcm_import() { loop {} } - extern crate wit_bindgen; + bindings::export!(Component with_types_in bindings); mod bindings; @@ -196,7 +196,8 @@ fn wcm_import() { .build(); let mut test = CompilerTest::rust_source_cargo_component(proj.root(), config); - let artifact_name = test.source.artifact_name(); + dbg!(&test); + let artifact_name = test.artifact_name(); test.expect_wasm(expect_file![format!("../../expected/components/{artifact_name}.wat")]); test.expect_ir(expect_file![format!("../../expected/components/{artifact_name}.hir")]); diff --git a/tests/integration/src/rust_masm_tests/instructions.rs b/tests/integration/src/rust_masm_tests/instructions.rs index 4d9ff3db..c5be8c04 100644 --- a/tests/integration/src/rust_masm_tests/instructions.rs +++ b/tests/integration/src/rust_masm_tests/instructions.rs @@ -1,11 +1,12 @@ use expect_test::expect_file; +use midenc_debug::PushToStack; use proptest::{ prelude::*, test_runner::{TestError, TestRunner}, }; use super::run_masm_vs_rust; -use crate::{felt_conversion::PushToStack, CompilerTest}; +use crate::CompilerTest; macro_rules! test_bin_op { ($name:ident, $op:tt, $op_ty:ty, $res_ty:ty, $a_range:expr, $b_range:expr) => { @@ -21,7 +22,7 @@ macro_rules! test_bin_op { let b_ty_str = stringify!($b_ty); let res_ty_str = stringify!($res_ty); let main_fn = format!("(a: {a_ty_str}, b: {b_ty_str}) -> {res_ty_str} {{ a {op_str} b }}"); - let mut test = CompilerTest::rust_fn_body(&main_fn); + let mut test = CompilerTest::rust_fn_body(&main_fn, None); // Test expected compilation artifacts let artifact_name = format!("{}_{}", stringify!($name), stringify!($a_ty)); test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]); @@ -39,7 +40,7 @@ macro_rules! test_bin_op { let mut args = Vec::::default(); PushToStack::try_push(&b, &mut args); PushToStack::try_push(&a, &mut args); - run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args) + run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args, &test.session) }); match res { Err(TestError::Fail(_, value)) => { @@ -62,7 +63,7 @@ macro_rules! test_unary_op { let op_ty_str = stringify!($op_ty); let res_ty_str = stringify!($op_ty); let main_fn = format!("(a: {op_ty_str}) -> {res_ty_str} {{ {op_str}a }}"); - let mut test = CompilerTest::rust_fn_body(&main_fn); + let mut test = CompilerTest::rust_fn_body(&main_fn, None); // Test expected compilation artifacts let artifact_name = format!("{}_{}", stringify!($name), stringify!($op_ty)); test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]); @@ -78,7 +79,7 @@ macro_rules! test_unary_op { dbg!(&rs_out); let mut args = Vec::::default(); a.try_push(&mut args); - run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args) + run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args, &test.session) }); match res { Err(TestError::Fail(_, value)) => { @@ -102,7 +103,7 @@ macro_rules! test_func_two_arg { let b_ty_str = stringify!($b_ty); let res_ty_str = stringify!($res_ty); let main_fn = format!("(a: {a_ty_str}, b: {b_ty_str}) -> {res_ty_str} {{ {func_name_str}(a, b) }}"); - let mut test = CompilerTest::rust_fn_body(&main_fn); + let mut test = CompilerTest::rust_fn_body(&main_fn, None); // Test expected compilation artifacts let artifact_name = format!("{}_{}_{}", stringify!($func), stringify!($a_ty), stringify!($b_ty)); test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]); @@ -119,7 +120,7 @@ macro_rules! test_func_two_arg { let mut args = Vec::::default(); b.try_push(&mut args); a.try_push(&mut args); - run_masm_vs_rust(rust_out, &vm_program, ir_masm.clone(), &args) + run_masm_vs_rust(rust_out, &vm_program, ir_masm.clone(), &args, &test.session) }); match res { Err(TestError::Fail(_, value)) => { diff --git a/tests/integration/src/rust_masm_tests/intrinsics.rs b/tests/integration/src/rust_masm_tests/intrinsics.rs index 65188a68..68d94cd8 100644 --- a/tests/integration/src/rust_masm_tests/intrinsics.rs +++ b/tests/integration/src/rust_masm_tests/intrinsics.rs @@ -2,16 +2,13 @@ use core::panic; use expect_test::expect_file; use miden_core::Felt; +use midenc_debug::{PushToStack, TestFelt}; use proptest::{ arbitrary::any, test_runner::{TestError, TestRunner}, }; -use crate::{ - felt_conversion::{PushToStack, TestFelt}, - rust_masm_tests::run_masm_vs_rust, - CompilerTest, -}; +use crate::{rust_masm_tests::run_masm_vs_rust, CompilerTest}; /// Compiles, runs VM vs. Rust fuzzing the inputs via proptest macro_rules! test_bin_op { @@ -24,7 +21,7 @@ macro_rules! test_bin_op { let res_ty_str = stringify!($res_ty); let main_fn = format!("(a: {op_ty_str}, b: {op_ty_str}) -> {res_ty_str} {{ a {op_str} b }}"); let artifact_name = format!("{}_{}", stringify!($name), stringify!($op_ty).to_lowercase()); - let mut test = CompilerTest::rust_fn_body_with_stdlib_sys(&artifact_name, &main_fn, false); + let mut test = CompilerTest::rust_fn_body_with_stdlib_sys(artifact_name.clone(), &main_fn, false, None); // Test expected compilation artifacts test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]); test.expect_ir(expect_file![format!("../../expected/{artifact_name}.hir")]); @@ -43,7 +40,7 @@ macro_rules! test_bin_op { let mut args = Vec::::default(); PushToStack::try_push(&b, &mut args); PushToStack::try_push(&a, &mut args); - run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args) + run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args, &test.session) }); match res { Err(TestError::Fail(_, value)) => { @@ -66,7 +63,7 @@ macro_rules! test_compile_comparison_op { let op_str = stringify!($op); let main_fn = format!("(a: Felt, b: Felt) -> bool {{ a {op_str} b }}"); let artifact_name = format!("{}_felt", stringify!($name)); - let mut test = CompilerTest::rust_fn_body_with_stdlib_sys(&artifact_name, &main_fn, false); + let mut test = CompilerTest::rust_fn_body_with_stdlib_sys(artifact_name.clone(), &main_fn, false, None); // Test expected compilation artifacts test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]); test.expect_ir(expect_file![format!("../../expected/{artifact_name}.hir")]); diff --git a/tests/integration/src/rust_masm_tests/mod.rs b/tests/integration/src/rust_masm_tests/mod.rs index 79ac7deb..6154e4b7 100644 --- a/tests/integration/src/rust_masm_tests/mod.rs +++ b/tests/integration/src/rust_masm_tests/mod.rs @@ -4,9 +4,11 @@ use std::{collections::VecDeque, sync::Arc}; use miden_core::Felt; +use midenc_debug::{Executor, PopFromStack}; +use midenc_session::Session; use proptest::{prop_assert_eq, test_runner::TestCaseError}; -use crate::{execute_emulator, execute_vm, felt_conversion::PopFromStack}; +use crate::execute_emulator; mod abi_transform; mod apps; @@ -21,14 +23,17 @@ pub fn run_masm_vs_rust( vm_program: &miden_core::Program, ir_program: Arc, args: &[Felt], + session: &Session, ) -> Result<(), TestCaseError> where T: Clone + PopFromStack + std::cmp::PartialEq + std::fmt::Debug, { - let mut out = VecDeque::from(execute_vm(vm_program, args)); - let vm_out = T::try_pop(&mut out).expect("invalid result"); - dbg!(&vm_out); - prop_assert_eq!(rust_out.clone(), vm_out, "VM output mismatch"); + let mut exec = Executor::new(args.to_vec()); + for lib in ir_program.link_libraries() { + exec.with_library(lib); + } + let output = exec.execute_into(vm_program, session); + prop_assert_eq!(rust_out.clone(), output, "VM output mismatch"); // TODO: Uncomment after https://github.com/0xPolygonMiden/compiler/issues/228 is fixed // let emul_out: T = (*execute_emulator(ir_program.clone(), args).first().unwrap()).into(); // prop_assert_eq!(rust_out, emul_out, "Emulator output mismatch"); diff --git a/tests/integration/src/rust_masm_tests/rust_sdk.rs b/tests/integration/src/rust_masm_tests/rust_sdk.rs index c2b34dc0..2e369a48 100644 --- a/tests/integration/src/rust_masm_tests/rust_sdk.rs +++ b/tests/integration/src/rust_masm_tests/rust_sdk.rs @@ -8,10 +8,11 @@ use crate::{cargo_proj::project, compiler_test::sdk_crate_path, CompilerTest}; fn account() { let artifact_name = "miden_sdk_account_test"; let mut test = CompilerTest::rust_source_cargo_lib( - PathBuf::from("../rust-apps-wasm/rust-sdk/account-test"), + "../rust-apps-wasm/rust-sdk/account-test", artifact_name, true, None, + None, ); test.expect_wasm(expect_file![format!( "../../expected/rust_sdk_account_test/{artifact_name}.wat" @@ -26,68 +27,27 @@ fn account() { #[test] fn basic_wallet() { - let sdk_crate_path = sdk_crate_path(); let project_name = "rust_sdk_basic_wallet"; - let proj = project(project_name) - .file( - "Cargo.toml", - format!( - r#" - - [package] - name = "{project_name}" - version = "0.0.1" - edition = "2021" - authors = [] - - [dependencies] - wee_alloc = {{ version = "0.4.5", default-features = false}} - miden-sdk = {{ path = "{sdk_crate_path}" }} - - [lib] - crate-type = ["cdylib"] - - [profile.release] - panic = "abort" - # optimize for size - opt-level = "z" - "#).as_str() - ) - .file( - "src/lib.rs", - r#" - #![no_std] + let source = r#" - #[panic_handler] - fn my_panic(_info: &core::panic::PanicInfo) -> ! { - loop {} - } +pub struct Account; - #[global_allocator] - static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; +impl Account { + #[no_mangle] + pub fn receive_asset(asset: CoreAsset) { + add_asset(asset); + } - use miden_sdk::*; - - pub struct Account; - - impl Account { - #[no_mangle] - pub fn receive_asset(asset: CoreAsset) { - add_asset(asset); - } - - #[no_mangle] - pub fn send_asset(asset: CoreAsset, tag: Tag, note_type: NoteType, recipient: Recipient) { - let asset = remove_asset(asset); - create_note(asset, tag, note_type, recipient); - } - } - "#, - ) - .build(); + #[no_mangle] + pub fn send_asset(asset: CoreAsset, tag: Tag, note_type: NoteType, recipient: Recipient) { + let asset = remove_asset(asset); + create_note(asset, tag, note_type, recipient); + } +} +"#; - let mut test = CompilerTest::rust_source_cargo_lib(proj.root(), project_name, true, None); - let artifact_name = test.source.artifact_name(); + let mut test = CompilerTest::rust_source_with_sdk(project_name, source, true, None, None); + let artifact_name = test.artifact_name(); test.expect_wasm(expect_file![format!("../../expected/{project_name}/{artifact_name}.wat")]); test.expect_ir(expect_file![format!("../../expected/{project_name}/{artifact_name}.hir")]); // TODO: fix flaky test, "exec."_ZN19miden_sdk_tx_kernel9add_asset17h6f4cff304c095ffc" is diff --git a/tests/integration/src/rust_masm_tests/wit_sdk.rs b/tests/integration/src/rust_masm_tests/wit_sdk.rs index f2ddf44a..b2f0781e 100644 --- a/tests/integration/src/rust_masm_tests/wit_sdk.rs +++ b/tests/integration/src/rust_masm_tests/wit_sdk.rs @@ -10,10 +10,10 @@ use crate::CompilerTest; #[test] fn sdk() { let test = CompilerTest::rust_source_cargo_component( - PathBuf::from_str("../rust-apps-wasm/wit-sdk/sdk").unwrap(), + "../rust-apps-wasm/wit-sdk/sdk", Default::default(), ); - let artifact_name = test.source.artifact_name(); + let artifact_name = test.artifact_name(); test.expect_wasm(expect_file![format!( "../../expected/wit_sdk_basic_wallet/{artifact_name}.wat" )]); @@ -63,11 +63,9 @@ fn sdk_basic_wallet() { import_metadata: import_metadata.clone(), ..Default::default() }; - let mut test = CompilerTest::rust_source_cargo_component( - PathBuf::from_str("../rust-apps-wasm/wit-sdk/basic-wallet").unwrap(), - config, - ); - let artifact_name = test.source.artifact_name(); + let mut test = + CompilerTest::rust_source_cargo_component("../rust-apps-wasm/wit-sdk/basic-wallet", config); + let artifact_name = test.artifact_name(); test.expect_wasm(expect_file![format!( "../../expected/wit_sdk_basic_wallet/{artifact_name}.wat" )]); @@ -144,11 +142,9 @@ fn sdk_basic_wallet_p2id_note() { import_metadata: import_metadata.clone(), ..Default::default() }; - let mut test = CompilerTest::rust_source_cargo_component( - PathBuf::from_str("../rust-apps-wasm/wit-sdk/p2id-note").unwrap(), - config, - ); - let artifact_name = test.source.artifact_name(); + let mut test = + CompilerTest::rust_source_cargo_component("../rust-apps-wasm/wit-sdk/p2id-note", config); + let artifact_name = test.artifact_name(); test.expect_wasm(expect_file![format!( "../../expected/wit_sdk_basic_wallet/{artifact_name}.wat" )]); diff --git a/tests/rust-apps-wasm/fib/Cargo.toml b/tests/rust-apps-wasm/fib/Cargo.toml index 38bb21e1..b975b3f1 100644 --- a/tests/rust-apps-wasm/fib/Cargo.toml +++ b/tests/rust-apps-wasm/fib/Cargo.toml @@ -7,8 +7,9 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -dlmalloc = { version = "0.2.4", features = ["global"]} +dlmalloc = { version = "0.2.4", features = ["global"] } miden-integration-tests-rust-fib = { path = "../../rust-apps/fib" } [profile.release] -opt-level = "z" \ No newline at end of file +opt-level = "z" +debug = true diff --git a/tests/rust-apps-wasm/rust-sdk/account-test/Cargo.lock b/tests/rust-apps-wasm/rust-sdk/account-test/Cargo.lock index 07621571..ed1e5395 100644 --- a/tests/rust-apps-wasm/rust-sdk/account-test/Cargo.lock +++ b/tests/rust-apps-wasm/rust-sdk/account-test/Cargo.lock @@ -2,58 +2,1520 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "arrayref" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "blake3" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if 1.0.0", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549" +dependencies = [ + "jobserver", + "libc", +] + [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dissimilar" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "generator" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "979f00864edc7516466d6b3157706e06c032f22715700ddd878228a91d02bc56" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "log", + "rustversion", + "windows", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_ci" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lalrpop" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax 0.8.4", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if 1.0.0", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + +[[package]] +name = "miden-assembly" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3aefae8d99d66c3f8666e917cb3ef976edb39247099311f695e5ba57305616d" +dependencies = [ + "aho-corasick", + "lalrpop", + "lalrpop-util", + "miden-core", + "miden-miette", + "miden-thiserror", + "rustc_version 0.4.0", + "smallvec", + "tracing", + "unicode-width", +] + +[[package]] +name = "miden-base-sys" +version = "0.0.0" +dependencies = [ + "miden-assembly", + "miden-stdlib-sys", +] + +[[package]] +name = "miden-core" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e46df4105dc2ec15aa14182ce6de299720991bfb83a9b6aa9293c6ee2b12b18" +dependencies = [ + "lock_api", + "loom", + "memchr", + "miden-crypto", + "miden-formatting", + "miden-miette", + "miden-thiserror", + "num-derive", + "num-traits", + "parking_lot", + "winter-math", + "winter-utils", +] + +[[package]] +name = "miden-crypto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6fad06fc3af260ed3c4235821daa2132813d993f96d446856036ae97e9606dd" +dependencies = [ + "blake3", + "cc", + "glob", + "num", + "num-complex", + "rand", + "rand_core", + "sha3", + "winter-crypto", + "winter-math", + "winter-utils", +] + +[[package]] +name = "miden-formatting" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e392e0a8c34b32671012b439de35fa8987bf14f0f8aac279b97f8b8cc6e263b" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "miden-miette" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c532250422d933f15b148fb81e4522a5d649c178ab420d0d596c86228da35570" +dependencies = [ + "backtrace", + "backtrace-ext", + "cfg-if 1.0.0", + "futures", + "indenter", + "lazy_static", + "miden-miette-derive", + "miden-thiserror", + "owo-colors", + "regex", + "rustc_version 0.2.3", + "rustversion", + "serde_json", + "spin", + "strip-ansi-escapes", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "syn", + "terminal_size", + "textwrap", + "trybuild", + "unicode-width", +] + +[[package]] +name = "miden-miette-derive" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cc759f0a2947acae217a2f32f722105cacc57d17d5f93bc16362142943a4edd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "miden-sdk" +version = "0.0.1" +dependencies = [ + "miden-base-sys", + "miden-stdlib-sys", +] + +[[package]] +name = "miden-sdk-account-test" +version = "0.0.0" +dependencies = [ + "miden-sdk", + "wee_alloc", +] + +[[package]] +name = "miden-stdlib-sys" +version = "0.0.1" + +[[package]] +name = "miden-thiserror" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183ff8de338956ecfde3a38573241eb7a6f3d44d73866c210e5629c07fa00253" +dependencies = [ + "miden-thiserror-impl", +] + +[[package]] +name = "miden-thiserror-impl" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee4176a0f2e7d29d2a8ee7e60b6deb14ce67a20e94c3e2c7275cdb8804e1862" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[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" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "object" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.205" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.205" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strip-ansi-escapes" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa" +dependencies = [ + "vte", +] + +[[package]] +name = "supports-color" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9829b314621dfc575df4e409e79f9d6a66a3bd707ab73f23cb4aa3a854ac854f" +dependencies = [ + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c0a1e5168041f5f3ff68ff7d95dcb9c8749df29f6e7e89ada40dd4c9de404ee" + +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" + +[[package]] +name = "syn" +version = "2.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] [[package]] -name = "libc" -version = "0.2.153" +name = "termcolor" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] [[package]] -name = "memory_units" -version = "0.4.0" +name = "terminal_size" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] [[package]] -name = "miden-sdk" -version = "0.0.1" +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" dependencies = [ - "miden-stdlib-sys", - "miden-tx-kernel-sys", + "smawk", + "unicode-linebreak", + "unicode-width", ] [[package]] -name = "miden-sdk-account-test" -version = "0.0.0" +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ - "miden-sdk", - "wee_alloc", + "thiserror-impl", ] [[package]] -name = "miden-stdlib-sys" -version = "0.0.1" +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "miden-tx-kernel-sys" -version = "0.0.1" +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ - "miden-stdlib-sys", + "cfg-if 1.0.0", + "once_cell", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trybuild" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" +dependencies = [ + "dissimilar", + "glob", + "serde", + "serde_derive", + "serde_json", + "termcolor", + "toml", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-width" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vte" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" +dependencies = [ + "utf8parse", + "vte_generate_state_changes", +] + +[[package]] +name = "vte_generate_state_changes" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wee_alloc" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "memory_units", "winapi", @@ -75,8 +1537,286 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + +[[package]] +name = "winter-crypto" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00fbb724d2d9fbfd3aa16ea27f5e461d4fe1d74b0c9e0ed1bf79e9e2a955f4d5" +dependencies = [ + "blake3", + "sha3", + "winter-math", + "winter-utils", +] + +[[package]] +name = "winter-math" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "004f85bb051ce986ec0b9a2bd90aaf81b83e3c67464becfdf7db31f14c1019ba" +dependencies = [ + "winter-utils", +] + +[[package]] +name = "winter-utils" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0568612a95bcae3c94fb14da2686f8279ca77723dbdf1e97cf3673798faf6485" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/tests/rust-apps-wasm/rust-sdk/account-test/Cargo.toml b/tests/rust-apps-wasm/rust-sdk/account-test/Cargo.toml index ea2f77d1..2b8a9e19 100644 --- a/tests/rust-apps-wasm/rust-sdk/account-test/Cargo.toml +++ b/tests/rust-apps-wasm/rust-sdk/account-test/Cargo.toml @@ -9,9 +9,10 @@ crate-type = ["cdylib", "rlib"] [dependencies] miden-sdk = { path = "../../../../sdk/sdk" } -wee_alloc = { version = "0.4.5", default-features = false} +wee_alloc = { version = "0.4.5", default-features = false } [profile.release] panic = "abort" # optimize for size -opt-level = "z" \ No newline at end of file +opt-level = "z" +debug = true diff --git a/tests/rust-apps-wasm/rust-sdk/account-test/src/lib.rs b/tests/rust-apps-wasm/rust-sdk/account-test/src/lib.rs index 81e8b966..a1dcd74f 100644 --- a/tests/rust-apps-wasm/rust-sdk/account-test/src/lib.rs +++ b/tests/rust-apps-wasm/rust-sdk/account-test/src/lib.rs @@ -67,8 +67,8 @@ pub fn test_blake3_hash_1to1(input: [u8; 32]) -> [u8; 32] { } #[no_mangle] -pub fn test_blake3_hash_2to1(input1: [u8; 32], input2: [u8; 32]) -> [u8; 32] { - blake3_hash_2to1(input1, input2) +pub fn test_blake3_hash_2to1(input: [u8; 64]) -> [u8; 32] { + blake3_hash_2to1(input) } #[no_mangle] diff --git a/tests/rust-apps-wasm/wit-sdk/basic-wallet/Cargo.lock b/tests/rust-apps-wasm/wit-sdk/basic-wallet/Cargo.lock index dcc21871..e48ef947 100644 --- a/tests/rust-apps-wasm/wit-sdk/basic-wallet/Cargo.lock +++ b/tests/rust-apps-wasm/wit-sdk/basic-wallet/Cargo.lock @@ -7,15 +7,9 @@ name = "basic-wallet" version = "0.0.0" dependencies = [ "wee_alloc", - "wit-bindgen", + "wit-bindgen-rt", ] -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - [[package]] name = "cfg-if" version = "0.1.10" @@ -69,10 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "wit-bindgen" -version = "0.17.0" +name = "wit-bindgen-rt" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6237168d93497b26dacdab157b08ad2787d74cdce10f89735f791b2a225eba4d" -dependencies = [ - "bitflags", -] +checksum = "d7a37bd9274cb2d4754b915d624447ec0dce9105d174361841c0826efc79ceb9" diff --git a/tests/rust-apps-wasm/wit-sdk/basic-wallet/Cargo.toml b/tests/rust-apps-wasm/wit-sdk/basic-wallet/Cargo.toml index 841a8b84..736b4688 100644 --- a/tests/rust-apps-wasm/wit-sdk/basic-wallet/Cargo.toml +++ b/tests/rust-apps-wasm/wit-sdk/basic-wallet/Cargo.toml @@ -12,8 +12,8 @@ edition = "2021" publish = false [dependencies] -wit-bindgen = { version = "0.17.0", default-features = false, features = ["realloc"] } -wee_alloc = { version = "0.4.5", default-features = false} +wit-bindgen-rt = "0.28" +wee_alloc = { version = "0.4.5", default-features = false } [lib] crate-type = ["cdylib"] @@ -27,4 +27,5 @@ package = "miden:basic-wallet" "miden:base" = { path = "../sdk/wit" } [profile.release] -panic = "abort" \ No newline at end of file +panic = "abort" +debug = true diff --git a/tests/rust-apps-wasm/wit-sdk/basic-wallet/src/bindings.rs b/tests/rust-apps-wasm/wit-sdk/basic-wallet/src/bindings.rs index 7e2ed5fc..9477639c 100644 --- a/tests/rust-apps-wasm/wit-sdk/basic-wallet/src/bindings.rs +++ b/tests/rust-apps-wasm/wit-sdk/basic-wallet/src/bindings.rs @@ -1,1051 +1,1240 @@ -// Generated by `wit-bindgen` 0.16.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.25.0. DO NOT EDIT! +// Options used: +#[allow(dead_code)] pub mod miden { - pub mod base { - - #[allow(clippy::all)] - pub mod core_types { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; - /// Represents base field element in the field using Montgomery representation. - /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). - /// The backing type is `f64` but the internal values are always integer in the range [0, M). - /// Field modulus M = 2^64 - 2^32 + 1 - #[repr(C)] - #[derive(Clone, Copy)] - pub struct Felt { - /// We plan to use f64 as the backing type for the field element. It has the size that we need and - /// we don't plan to support floating point arithmetic in programs for Miden VM. - /// - /// For now its u64 - pub inner: u64, - } - impl ::core::fmt::Debug for Felt { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Felt").field("inner", &self.inner).finish() - } - } - /// A group of four field elements in the Miden base field. - pub type Word = (Felt,Felt,Felt,Felt,); - /// Unique identifier of an account. - /// - /// Account ID consists of 1 field element (~64 bits). This field element uniquely identifies a - /// single account and also specifies the type of the underlying account. Specifically: - /// - The two most significant bits of the ID specify the type of the account: - /// - 00 - regular account with updatable code. - /// - 01 - regular account with immutable code. - /// - 10 - fungible asset faucet with immutable code. - /// - 11 - non-fungible asset faucet with immutable code. - /// - The third most significant bit of the ID specifies whether the account data is stored on-chain: - /// - 0 - full account data is stored on-chain. - /// - 1 - only the account hash is stored on-chain which serves as a commitment to the account state. - /// As such the three most significant bits fully describes the type of the account. - #[repr(C)] - #[derive(Clone, Copy)] - pub struct AccountId { - pub inner: Felt, - } - impl ::core::fmt::Debug for AccountId { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("AccountId").field("inner", &self.inner).finish() - } - } - /// Recipient of the note, i.e., hash(hash(hash(serial_num, [0; 4]), note_script_hash), input_hash) - #[repr(C)] - #[derive(Clone, Copy)] - pub struct Recipient { - pub inner: Word, - } - impl ::core::fmt::Debug for Recipient { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Recipient").field("inner", &self.inner).finish() - } - } - #[repr(C)] - #[derive(Clone, Copy)] - pub struct Tag { - pub inner: Felt, - } - impl ::core::fmt::Debug for Tag { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Tag").field("inner", &self.inner).finish() - } - } - /// A fungible or a non-fungible asset. - /// - /// All assets are encoded using a single word (4 elements) such that it is easy to determine the - /// type of an asset both inside and outside Miden VM. Specifically: - /// Element 1 will be: - /// - ZERO for a fungible asset - /// - non-ZERO for a non-fungible asset - /// The most significant bit will be: - /// - ONE for a fungible asset - /// - ZERO for a non-fungible asset - /// - /// The above properties guarantee that there can never be a collision between a fungible and a - /// non-fungible asset. - /// - /// The methodology for constructing fungible and non-fungible assets is described below. - /// - /// # Fungible assets - /// The most significant element of a fungible asset is set to the ID of the faucet which issued - /// the asset. This guarantees the properties described above (the first bit is ONE). - /// - /// The least significant element is set to the amount of the asset. This amount cannot be greater - /// than 2^63 - 1 and thus requires 63-bits to store. - /// - /// Elements 1 and 2 are set to ZERO. - /// - /// It is impossible to find a collision between two fungible assets issued by different faucets as - /// the faucet_id is included in the description of the asset and this is guaranteed to be different - /// for each faucet as per the faucet creation logic. - /// - /// # Non-fungible assets - /// The 4 elements of non-fungible assets are computed as follows: - /// - First the asset data is hashed. This compresses an asset of an arbitrary length to 4 field - /// elements: [d0, d1, d2, d3]. - /// - d1 is then replaced with the faucet_id which issues the asset: [d0, faucet_id, d2, d3]. - /// - Lastly, the most significant bit of d3 is set to ZERO. - /// - /// It is impossible to find a collision between two non-fungible assets issued by different faucets - /// as the faucet_id is included in the description of the non-fungible asset and this is guaranteed - /// to be different as per the faucet creation logic. Collision resistance for non-fungible assets - /// issued by the same faucet is ~2^95. - #[repr(C)] - #[derive(Clone, Copy)] - pub struct CoreAsset { - pub inner: Word, - } - impl ::core::fmt::Debug for CoreAsset { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("CoreAsset").field("inner", &self.inner).finish() - } - } - /// Account nonce - #[repr(C)] - #[derive(Clone, Copy)] - pub struct Nonce { - pub inner: Felt, - } - impl ::core::fmt::Debug for Nonce { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Nonce").field("inner", &self.inner).finish() - } - } - /// Account hash - #[repr(C)] - #[derive(Clone, Copy)] - pub struct AccountHash { - pub inner: Word, - } - impl ::core::fmt::Debug for AccountHash { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("AccountHash").field("inner", &self.inner).finish() - } - } - /// Block hash - #[repr(C)] - #[derive(Clone, Copy)] - pub struct BlockHash { - pub inner: Word, - } - impl ::core::fmt::Debug for BlockHash { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("BlockHash").field("inner", &self.inner).finish() - } - } - /// Storage value - #[repr(C)] - #[derive(Clone, Copy)] - pub struct StorageValue { - pub inner: Word, - } - impl ::core::fmt::Debug for StorageValue { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("StorageValue").field("inner", &self.inner).finish() - } - } - /// Account storage root - #[repr(C)] - #[derive(Clone, Copy)] - pub struct StorageRoot { - pub inner: Word, - } - impl ::core::fmt::Debug for StorageRoot { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("StorageRoot").field("inner", &self.inner).finish() - } - } - /// Account code root - #[repr(C)] - #[derive(Clone, Copy)] - pub struct AccountCodeRoot { - pub inner: Word, - } - impl ::core::fmt::Debug for AccountCodeRoot { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("AccountCodeRoot").field("inner", &self.inner).finish() - } - } - /// Commitment to the account vault - #[repr(C)] - #[derive(Clone, Copy)] - pub struct VaultCommitment { - pub inner: Word, - } - impl ::core::fmt::Debug for VaultCommitment { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("VaultCommitment").field("inner", &self.inner).finish() + #[allow(dead_code)] + pub mod base { + #[allow(dead_code, clippy::all)] + pub mod core_types { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + /// Represents base field element in the field using Montgomery representation. + /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). + /// The backing type is `f64` but the internal values are always integer in the range + /// [0, M). Field modulus M = 2^64 - 2^32 + 1 + #[repr(C)] + #[derive(Clone, Copy)] + pub struct Felt { + /// We plan to use f64 as the backing type for the field element. It has the size + /// that we need and we don't plan to support floating point + /// arithmetic in programs for Miden VM. + /// + /// For now its u64 + pub inner: u64, + } + impl ::core::fmt::Debug for Felt { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Felt").field("inner", &self.inner).finish() + } + } + /// A group of four field elements in the Miden base field. + pub type Word = (Felt, Felt, Felt, Felt); + /// Unique identifier of an account. + /// + /// Account ID consists of 1 field element (~64 bits). This field element uniquely + /// identifies a single account and also specifies the type of the + /// underlying account. Specifically: + /// - The two most significant bits of the ID specify the type of the account: + /// - 00 - regular account with updatable code. + /// - 01 - regular account with immutable code. + /// - 10 - fungible asset faucet with immutable code. + /// - 11 - non-fungible asset faucet with immutable code. + /// - The third most significant bit of the ID specifies whether the account data is + /// stored on-chain: + /// - 0 - full account data is stored on-chain. + /// - 1 - only the account hash is stored on-chain which serves as a commitment to the + /// account state. + /// As such the three most significant bits fully describes the type of the account. + #[repr(C)] + #[derive(Clone, Copy)] + pub struct AccountId { + pub inner: Felt, + } + impl ::core::fmt::Debug for AccountId { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("AccountId").field("inner", &self.inner).finish() + } + } + /// Recipient of the note, i.e., hash(hash(hash(serial_num, [0; 4]), note_script_hash), + /// input_hash) + #[repr(C)] + #[derive(Clone, Copy)] + pub struct Recipient { + pub inner: Word, + } + impl ::core::fmt::Debug for Recipient { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Recipient").field("inner", &self.inner).finish() + } + } + #[repr(C)] + #[derive(Clone, Copy)] + pub struct Tag { + pub inner: Felt, + } + impl ::core::fmt::Debug for Tag { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Tag").field("inner", &self.inner).finish() + } + } + /// A fungible or a non-fungible asset. + /// + /// All assets are encoded using a single word (4 elements) such that it is easy to + /// determine the type of an asset both inside and outside Miden VM. + /// Specifically: Element 1 will be: + /// - ZERO for a fungible asset + /// - non-ZERO for a non-fungible asset + /// The most significant bit will be: + /// - ONE for a fungible asset + /// - ZERO for a non-fungible asset + /// + /// The above properties guarantee that there can never be a collision between a + /// fungible and a non-fungible asset. + /// + /// The methodology for constructing fungible and non-fungible assets is described + /// below. + /// + /// # Fungible assets + /// The most significant element of a fungible asset is set to the ID of the faucet + /// which issued the asset. This guarantees the properties described above + /// (the first bit is ONE). + /// + /// The least significant element is set to the amount of the asset. This amount cannot + /// be greater than 2^63 - 1 and thus requires 63-bits to store. + /// + /// Elements 1 and 2 are set to ZERO. + /// + /// It is impossible to find a collision between two fungible assets issued by different + /// faucets as the faucet_id is included in the description of the asset and + /// this is guaranteed to be different for each faucet as per the faucet + /// creation logic. + /// + /// # Non-fungible assets + /// The 4 elements of non-fungible assets are computed as follows: + /// - First the asset data is hashed. This compresses an asset of an arbitrary length to + /// 4 field + /// elements: [d0, d1, d2, d3]. + /// - d1 is then replaced with the faucet_id which issues the asset: [d0, faucet_id, d2, + /// d3]. + /// - Lastly, the most significant bit of d3 is set to ZERO. + /// + /// It is impossible to find a collision between two non-fungible assets issued by + /// different faucets as the faucet_id is included in the description of the + /// non-fungible asset and this is guaranteed to be different as per the + /// faucet creation logic. Collision resistance for non-fungible assets + /// issued by the same faucet is ~2^95. + #[repr(C)] + #[derive(Clone, Copy)] + pub struct CoreAsset { + pub inner: Word, + } + impl ::core::fmt::Debug for CoreAsset { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("CoreAsset").field("inner", &self.inner).finish() + } + } + /// Account nonce + #[repr(C)] + #[derive(Clone, Copy)] + pub struct Nonce { + pub inner: Felt, + } + impl ::core::fmt::Debug for Nonce { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Nonce").field("inner", &self.inner).finish() + } + } + /// Account hash + #[repr(C)] + #[derive(Clone, Copy)] + pub struct AccountHash { + pub inner: Word, + } + impl ::core::fmt::Debug for AccountHash { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("AccountHash").field("inner", &self.inner).finish() + } + } + /// Block hash + #[repr(C)] + #[derive(Clone, Copy)] + pub struct BlockHash { + pub inner: Word, + } + impl ::core::fmt::Debug for BlockHash { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("BlockHash").field("inner", &self.inner).finish() + } + } + /// Storage value + #[repr(C)] + #[derive(Clone, Copy)] + pub struct StorageValue { + pub inner: Word, + } + impl ::core::fmt::Debug for StorageValue { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("StorageValue").field("inner", &self.inner).finish() + } + } + /// Account storage root + #[repr(C)] + #[derive(Clone, Copy)] + pub struct StorageRoot { + pub inner: Word, + } + impl ::core::fmt::Debug for StorageRoot { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("StorageRoot").field("inner", &self.inner).finish() + } + } + /// Account code root + #[repr(C)] + #[derive(Clone, Copy)] + pub struct AccountCodeRoot { + pub inner: Word, + } + impl ::core::fmt::Debug for AccountCodeRoot { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("AccountCodeRoot").field("inner", &self.inner).finish() + } + } + /// Commitment to the account vault + #[repr(C)] + #[derive(Clone, Copy)] + pub struct VaultCommitment { + pub inner: Word, + } + impl ::core::fmt::Debug for VaultCommitment { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("VaultCommitment").field("inner", &self.inner).finish() + } + } + /// An id of the created note + #[repr(C)] + #[derive(Clone, Copy)] + pub struct NoteId { + pub inner: Felt, + } + impl ::core::fmt::Debug for NoteId { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("NoteId").field("inner", &self.inner).finish() + } + } + #[allow(unused_unsafe, clippy::all)] + /// Creates a new account ID from a field element. + pub fn account_id_from_felt(felt: Felt) -> AccountId { + unsafe { + let Felt { inner: inner0 } = felt; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/core-types@1.0.0")] + extern "C" { + #[link_name = "account-id-from-felt"] + fn wit_import(_: i64) -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64) -> i64 { + unreachable!() + } + let ret = wit_import(_rt::as_i64(inner0)); + AccountId { + inner: Felt { inner: ret as u64 }, + } + } + } } - } - /// An id of the created note - #[repr(C)] - #[derive(Clone, Copy)] - pub struct NoteId { - pub inner: Felt, - } - impl ::core::fmt::Debug for NoteId { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("NoteId").field("inner", &self.inner).finish() + + #[allow(dead_code, clippy::all)] + pub mod account { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Felt = super::super::super::miden::base::core_types::Felt; + pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; + pub type AccountId = super::super::super::miden::base::core_types::AccountId; + pub type Nonce = super::super::super::miden::base::core_types::Nonce; + pub type AccountHash = super::super::super::miden::base::core_types::AccountHash; + pub type StorageValue = super::super::super::miden::base::core_types::StorageValue; + pub type StorageRoot = super::super::super::miden::base::core_types::StorageRoot; + pub type AccountCodeRoot = + super::super::super::miden::base::core_types::AccountCodeRoot; + pub type VaultCommitment = + super::super::super::miden::base::core_types::VaultCommitment; + #[allow(unused_unsafe, clippy::all)] + /// Get the id of the currently executing account + pub fn get_id() -> AccountId { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-id"] + fn wit_import() -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import() -> i64 { + unreachable!() + } + let ret = wit_import(); + super::super::super::miden::base::core_types::AccountId { + inner: super::super::super::miden::base::core_types::Felt { + inner: ret as u64, + }, + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Return the account nonce + pub fn get_nonce() -> Nonce { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-nonce"] + fn wit_import() -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import() -> i64 { + unreachable!() + } + let ret = wit_import(); + super::super::super::miden::base::core_types::Nonce { + inner: super::super::super::miden::base::core_types::Felt { + inner: ret as u64, + }, + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Get the initial hash of the currently executing account + pub fn get_initial_hash() -> AccountHash { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-initial-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + super::super::super::miden::base::core_types::AccountHash { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Get the current hash of the account data stored in memory + pub fn get_current_hash() -> AccountHash { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-current-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + super::super::super::miden::base::core_types::AccountHash { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Increment the account nonce by the specified value. + /// value can be at most 2^32 - 1 otherwise this procedure panics + pub fn incr_nonce(value: Felt) { + unsafe { + let super::super::super::miden::base::core_types::Felt { inner: inner0 } = + value; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "incr-nonce"] + fn wit_import(_: i64); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64) { + unreachable!() + } + wit_import(_rt::as_i64(inner0)); + } + } + #[allow(unused_unsafe, clippy::all)] + /// Get the value of the specified key in the account storage + pub fn get_item(index: Felt) -> StorageValue { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let super::super::super::miden::base::core_types::Felt { inner: inner0 } = + index; + let ptr1 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-item"] + fn wit_import(_: i64, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: *mut u8) { + unreachable!() + } + wit_import(_rt::as_i64(inner0), ptr1); + let l2 = *ptr1.add(0).cast::(); + let l3 = *ptr1.add(8).cast::(); + let l4 = *ptr1.add(16).cast::(); + let l5 = *ptr1.add(24).cast::(); + super::super::super::miden::base::core_types::StorageValue { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l5 as u64 }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Set the value of the specified key in the account storage + /// Returns the old value of the key and the new storage root + pub fn set_item(index: Felt, value: StorageValue) -> (StorageRoot, StorageValue) { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 64]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 64]); + let super::super::super::miden::base::core_types::Felt { inner: inner0 } = + index; + let super::super::super::miden::base::core_types::StorageValue { + inner: inner1, + } = value; + let (t2_0, t2_1, t2_2, t2_3) = inner1; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t2_0; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t2_1; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t2_2; + let super::super::super::miden::base::core_types::Felt { inner: inner6 } = t2_3; + let ptr7 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "set-item"] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: *mut u8) { + unreachable!() + } + wit_import( + _rt::as_i64(inner0), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + _rt::as_i64(inner6), + ptr7, + ); + let l8 = *ptr7.add(0).cast::(); + let l9 = *ptr7.add(8).cast::(); + let l10 = *ptr7.add(16).cast::(); + let l11 = *ptr7.add(24).cast::(); + let l12 = *ptr7.add(32).cast::(); + let l13 = *ptr7.add(40).cast::(); + let l14 = *ptr7.add(48).cast::(); + let l15 = *ptr7.add(56).cast::(); + ( + super::super::super::miden::base::core_types::StorageRoot { + inner: ( + super::super::super::miden::base::core_types::Felt { + inner: l8 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l9 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l10 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l11 as u64, + }, + ), + }, + super::super::super::miden::base::core_types::StorageValue { + inner: ( + super::super::super::miden::base::core_types::Felt { + inner: l12 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l13 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l14 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l15 as u64, + }, + ), + }, + ) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Sets the code of the account the transaction is being executed against. + /// This procedure can only be executed on regular accounts with updatable + /// code. Otherwise, this procedure fails. code is the hash of the code + /// to set. + pub fn set_code(code_root: AccountCodeRoot) { + unsafe { + let super::super::super::miden::base::core_types::AccountCodeRoot { + inner: inner0, + } = code_root; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "set-code"] + fn wit_import(_: i64, _: i64, _: i64, _: i64); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64) { + unreachable!() + } + wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ); + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the balance of a fungible asset associated with a account_id. + /// Panics if the asset is not a fungible asset. account_id is the faucet id + /// of the fungible asset of interest. balance is the vault balance of the + /// fungible asset. + pub fn get_balance(account_id: AccountId) -> Felt { + unsafe { + let super::super::super::miden::base::core_types::AccountId { inner: inner0 } = + account_id; + let super::super::super::miden::base::core_types::Felt { inner: inner1 } = + inner0; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-balance"] + fn wit_import(_: i64) -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64) -> i64 { + unreachable!() + } + let ret = wit_import(_rt::as_i64(inner1)); + super::super::super::miden::base::core_types::Felt { inner: ret as u64 } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns a boolean indicating whether the non-fungible asset is present + /// in the vault. Panics if the asset is a fungible asset. asset is the + /// non-fungible asset of interest. has_asset is a boolean indicating + /// whether the account vault has the asset of interest. + pub fn has_non_fungible_asset(asset: CoreAsset) -> bool { + unsafe { + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "has-non-fungible-asset"] + fn wit_import(_: i64, _: i64, _: i64, _: i64) -> i32; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64) -> i32 { + unreachable!() + } + let ret = wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ); + _rt::bool_lift(ret as u8) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Add the specified asset to the vault. Panics under various conditions. + /// Returns the final asset in the account vault defined as follows: If asset is + /// a non-fungible asset, then returns the same as asset. If asset is a + /// fungible asset, then returns the total fungible asset in the account + /// vault after asset was added to it. + pub fn add_asset(asset: CoreAsset) -> CoreAsset { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + let ptr6 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "add-asset"] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: *mut u8) { + unreachable!() + } + wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ptr6, + ); + let l7 = *ptr6.add(0).cast::(); + let l8 = *ptr6.add(8).cast::(); + let l9 = *ptr6.add(16).cast::(); + let l10 = *ptr6.add(24).cast::(); + super::super::super::miden::base::core_types::CoreAsset { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l7 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l8 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l9 as u64 }, + super::super::super::miden::base::core_types::Felt { + inner: l10 as u64, + }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Remove the specified asset from the vault + pub fn remove_asset(asset: CoreAsset) -> CoreAsset { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + let ptr6 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "remove-asset"] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: *mut u8) { + unreachable!() + } + wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ptr6, + ); + let l7 = *ptr6.add(0).cast::(); + let l8 = *ptr6.add(8).cast::(); + let l9 = *ptr6.add(16).cast::(); + let l10 = *ptr6.add(24).cast::(); + super::super::super::miden::base::core_types::CoreAsset { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l7 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l8 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l9 as u64 }, + super::super::super::miden::base::core_types::Felt { + inner: l10 as u64, + }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the commitment to the account vault. + pub fn get_vault_commitment() -> VaultCommitment { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-vault-commitment"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + super::super::super::miden::base::core_types::VaultCommitment { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ), + } + } + } } - } - #[allow(unused_unsafe, clippy::all)] - /// Creates a new account ID from a field element. - pub fn account_id_from_felt(felt: Felt,) -> AccountId{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let Felt{ inner:inner0, } = felt; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/core-types@1.0.0")] - extern "C" { - #[link_name = "account-id-from-felt"] - fn wit_import(_: i64, ) -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, ) -> i64{ unreachable!() } - let ret = wit_import(wit_bindgen::rt::as_i64(inner0)); - AccountId{ - inner: Felt{ - inner: ret as u64, - }, - } + + #[allow(dead_code, clippy::all)] + pub mod tx { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Felt = super::super::super::miden::base::core_types::Felt; + pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; + pub type Tag = super::super::super::miden::base::core_types::Tag; + pub type Recipient = super::super::super::miden::base::core_types::Recipient; + pub type BlockHash = super::super::super::miden::base::core_types::BlockHash; + pub type Word = super::super::super::miden::base::core_types::Word; + pub type NoteId = super::super::super::miden::base::core_types::NoteId; + #[allow(unused_unsafe, clippy::all)] + /// Returns the block number of the last known block at the time of transaction + /// execution. + pub fn get_block_number() -> Felt { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "get-block-number"] + fn wit_import() -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import() -> i64 { + unreachable!() + } + let ret = wit_import(); + super::super::super::miden::base::core_types::Felt { inner: ret as u64 } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the block hash of the last known block at the time of transaction execution. + pub fn get_block_hash() -> BlockHash { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "get-block-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + super::super::super::miden::base::core_types::BlockHash { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the input notes hash. This is computed as a sequential hash of + /// (nullifier, script_root) tuples over all input notes. + pub fn get_input_notes_hash() -> Word { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "get-input-notes-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the output notes hash. This is computed as a sequential hash of + /// (note_hash, note_metadata) tuples over all output notes. + pub fn get_output_notes_hash() -> Word { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "get-output-notes-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Creates a new note. + /// asset is the asset to be included in the note. + /// tag is the tag to be included in the note. + /// recipient is the recipient of the note. + /// Returns the id of the created note. + pub fn create_note(asset: CoreAsset, tag: Tag, recipient: Recipient) -> NoteId { + unsafe { + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + let super::super::super::miden::base::core_types::Tag { inner: inner6 } = tag; + let super::super::super::miden::base::core_types::Felt { inner: inner7 } = + inner6; + let super::super::super::miden::base::core_types::Recipient { inner: inner8 } = + recipient; + let (t9_0, t9_1, t9_2, t9_3) = inner8; + let super::super::super::miden::base::core_types::Felt { inner: inner10 } = + t9_0; + let super::super::super::miden::base::core_types::Felt { inner: inner11 } = + t9_1; + let super::super::super::miden::base::core_types::Felt { inner: inner12 } = + t9_2; + let super::super::super::miden::base::core_types::Felt { inner: inner13 } = + t9_3; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "create-note"] + fn wit_import( + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + ) -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import( + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + ) -> i64 { + unreachable!() + } + let ret = wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + _rt::as_i64(inner7), + _rt::as_i64(inner10), + _rt::as_i64(inner11), + _rt::as_i64(inner12), + _rt::as_i64(inner13), + ); + super::super::super::miden::base::core_types::NoteId { + inner: super::super::super::miden::base::core_types::Felt { + inner: ret as u64, + }, + } + } + } } - } - } - - - #[allow(clippy::all)] - pub mod account { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; - pub type Felt = super::super::super::miden::base::core_types::Felt; - pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; - pub type AccountId = super::super::super::miden::base::core_types::AccountId; - pub type Nonce = super::super::super::miden::base::core_types::Nonce; - pub type AccountHash = super::super::super::miden::base::core_types::AccountHash; - pub type StorageValue = super::super::super::miden::base::core_types::StorageValue; - pub type StorageRoot = super::super::super::miden::base::core_types::StorageRoot; - pub type AccountCodeRoot = super::super::super::miden::base::core_types::AccountCodeRoot; - pub type VaultCommitment = super::super::super::miden::base::core_types::VaultCommitment; - #[allow(unused_unsafe, clippy::all)] - /// Get the id of the currently executing account - pub fn get_id() -> AccountId{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-id"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64{ unreachable!() } - let ret = wit_import(); - super::super::super::miden::base::core_types::AccountId{ - inner: super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - }, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Return the account nonce - pub fn get_nonce() -> Nonce{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-nonce"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64{ unreachable!() } - let ret = wit_import(); - super::super::super::miden::base::core_types::Nonce{ - inner: super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - }, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the initial hash of the currently executing account - pub fn get_initial_hash() -> AccountHash{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-initial-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - super::super::super::miden::base::core_types::AccountHash{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the current hash of the account data stored in memory - pub fn get_current_hash() -> AccountHash{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-current-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - super::super::super::miden::base::core_types::AccountHash{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Increment the account nonce by the specified value. - /// value can be at most 2^32 - 1 otherwise this procedure panics - pub fn incr_nonce(value: Felt,){ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::Felt{ inner:inner0, } = value; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "incr-nonce"] - fn wit_import(_: i64, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner0)); - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the value of the specified key in the account storage - pub fn get_item(index: Felt,) -> StorageValue{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let super::super::super::miden::base::core_types::Felt{ inner:inner0, } = index; - let ptr1 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-item"] - fn wit_import(_: i64, _: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i32, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner0), ptr1); - let l2 = *((ptr1 + 0) as *const i64); - let l3 = *((ptr1 + 8) as *const i64); - let l4 = *((ptr1 + 16) as *const i64); - let l5 = *((ptr1 + 24) as *const i64); - super::super::super::miden::base::core_types::StorageValue{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l5 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Set the value of the specified key in the account storage - /// Returns the old value of the key and the new storage root - pub fn set_item(index: Felt,value: StorageValue,) -> (StorageRoot,StorageValue,){ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 64]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let super::super::super::miden::base::core_types::Felt{ inner:inner0, } = index; - let super::super::super::miden::base::core_types::StorageValue{ inner:inner1, } = value; - let (t2_0, t2_1, t2_2, t2_3, ) = inner1; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t2_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t2_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t2_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner6, } = t2_3; - let ptr7 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "set-item"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i32, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner0), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), wit_bindgen::rt::as_i64(inner6), ptr7); - let l8 = *((ptr7 + 0) as *const i64); - let l9 = *((ptr7 + 8) as *const i64); - let l10 = *((ptr7 + 16) as *const i64); - let l11 = *((ptr7 + 24) as *const i64); - let l12 = *((ptr7 + 32) as *const i64); - let l13 = *((ptr7 + 40) as *const i64); - let l14 = *((ptr7 + 48) as *const i64); - let l15 = *((ptr7 + 56) as *const i64); - (super::super::super::miden::base::core_types::StorageRoot{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l8 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l9 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l10 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l11 as u64, - }), - }, super::super::super::miden::base::core_types::StorageValue{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l12 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l13 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l14 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l15 as u64, - }), - }) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Sets the code of the account the transaction is being executed against. - /// This procedure can only be executed on regular accounts with updatable - /// code. Otherwise, this procedure fails. code is the hash of the code - /// to set. - pub fn set_code(code_root: AccountCodeRoot,){ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::AccountCodeRoot{ inner:inner0, } = code_root; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "set-code"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5)); - } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the balance of a fungible asset associated with a account_id. - /// Panics if the asset is not a fungible asset. account_id is the faucet id - /// of the fungible asset of interest. balance is the vault balance of the - /// fungible asset. - pub fn get_balance(account_id: AccountId,) -> Felt{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::AccountId{ inner:inner0, } = account_id; - let super::super::super::miden::base::core_types::Felt{ inner:inner1, } = inner0; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-balance"] - fn wit_import(_: i64, ) -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, ) -> i64{ unreachable!() } - let ret = wit_import(wit_bindgen::rt::as_i64(inner1)); - super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns a boolean indicating whether the non-fungible asset is present - /// in the vault. Panics if the asset is a fungible asset. asset is the - /// non-fungible asset of interest. has_asset is a boolean indicating - /// whether the account vault has the asset of interest. - pub fn has_non_fungible_asset(asset: CoreAsset,) -> bool{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "has-non-fungible-asset"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ) -> i32{ unreachable!() } - let ret = wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5)); - wit_bindgen::rt::bool_lift(ret as u8) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Add the specified asset to the vault. Panics under various conditions. - /// Returns the final asset in the account vault defined as follows: If asset is - /// a non-fungible asset, then returns the same as asset. If asset is a - /// fungible asset, then returns the total fungible asset in the account - /// vault after asset was added to it. - pub fn add_asset(asset: CoreAsset,) -> CoreAsset{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - let ptr6 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "add-asset"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i32, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), ptr6); - let l7 = *((ptr6 + 0) as *const i64); - let l8 = *((ptr6 + 8) as *const i64); - let l9 = *((ptr6 + 16) as *const i64); - let l10 = *((ptr6 + 24) as *const i64); - super::super::super::miden::base::core_types::CoreAsset{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l7 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l8 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l9 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l10 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Remove the specified asset from the vault - pub fn remove_asset(asset: CoreAsset,) -> CoreAsset{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - let ptr6 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "remove-asset"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i32, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), ptr6); - let l7 = *((ptr6 + 0) as *const i64); - let l8 = *((ptr6 + 8) as *const i64); - let l9 = *((ptr6 + 16) as *const i64); - let l10 = *((ptr6 + 24) as *const i64); - super::super::super::miden::base::core_types::CoreAsset{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l7 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l8 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l9 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l10 as u64, - }), - } +} +#[allow(dead_code)] +pub mod exports { + #[allow(dead_code)] + pub mod miden { + #[allow(dead_code)] + pub mod basic_wallet { + #[allow(dead_code, clippy::all)] + pub mod basic_wallet { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::super::__link_custom_section_describing_imports; + use super::super::super::super::_rt; + pub type CoreAsset = super::super::super::super::miden::base::core_types::CoreAsset; + pub type Tag = super::super::super::super::miden::base::core_types::Tag; + pub type Recipient = super::super::super::super::miden::base::core_types::Recipient; + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_receive_asset_cabi( + arg0: i64, + arg1: i64, + arg2: i64, + arg3: i64, + ) { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + T::receive_asset( + super::super::super::super::miden::base::core_types::CoreAsset { + inner: ( + super::super::super::super::miden::base::core_types::Felt { + inner: arg0 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg1 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg2 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg3 as u64, + }, + ), + }, + ); + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_send_asset_cabi( + arg0: i64, + arg1: i64, + arg2: i64, + arg3: i64, + arg4: i64, + arg5: i64, + arg6: i64, + arg7: i64, + arg8: i64, + ) { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + T::send_asset( + super::super::super::super::miden::base::core_types::CoreAsset { + inner: ( + super::super::super::super::miden::base::core_types::Felt { + inner: arg0 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg1 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg2 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg3 as u64, + }, + ), + }, + super::super::super::super::miden::base::core_types::Tag { + inner: super::super::super::super::miden::base::core_types::Felt { + inner: arg4 as u64, + }, + }, + super::super::super::super::miden::base::core_types::Recipient { + inner: ( + super::super::super::super::miden::base::core_types::Felt { + inner: arg5 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg6 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg7 as u64, + }, + super::super::super::super::miden::base::core_types::Felt { + inner: arg8 as u64, + }, + ), + }, + ); + } + pub trait Guest { + fn receive_asset(core_asset: CoreAsset); + fn send_asset(core_asset: CoreAsset, tag: Tag, recipient: Recipient); + } + #[doc(hidden)] + + macro_rules! __export_miden_basic_wallet_basic_wallet_1_0_0_cabi{ + ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { + + #[export_name = "miden:basic-wallet/basic-wallet@1.0.0#receive-asset"] + unsafe extern "C" fn export_receive_asset(arg0: i64,arg1: i64,arg2: i64,arg3: i64,) { + $($path_to_types)*::_export_receive_asset_cabi::<$ty>(arg0, arg1, arg2, arg3) } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the commitment to the account vault. - pub fn get_vault_commitment() -> VaultCommitment{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-vault-commitment"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - super::super::super::miden::base::core_types::VaultCommitment{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }), - } + #[export_name = "miden:basic-wallet/basic-wallet@1.0.0#send-asset"] + unsafe extern "C" fn export_send_asset(arg0: i64,arg1: i64,arg2: i64,arg3: i64,arg4: i64,arg5: i64,arg6: i64,arg7: i64,arg8: i64,) { + $($path_to_types)*::_export_send_asset_cabi::<$ty>(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } - } - + };); } - - - #[allow(clippy::all)] - pub mod tx { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; - pub type Felt = super::super::super::miden::base::core_types::Felt; - pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; - pub type Tag = super::super::super::miden::base::core_types::Tag; - pub type Recipient = super::super::super::miden::base::core_types::Recipient; - pub type BlockHash = super::super::super::miden::base::core_types::BlockHash; - pub type Word = super::super::super::miden::base::core_types::Word; - pub type NoteId = super::super::super::miden::base::core_types::NoteId; - #[allow(unused_unsafe, clippy::all)] - /// Returns the block number of the last known block at the time of transaction execution. - pub fn get_block_number() -> Felt{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "get-block-number"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64{ unreachable!() } - let ret = wit_import(); - super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the block hash of the last known block at the time of transaction execution. - pub fn get_block_hash() -> BlockHash{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "get-block-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - super::super::super::miden::base::core_types::BlockHash{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }), - } + #[doc(hidden)] + pub(crate) use __export_miden_basic_wallet_basic_wallet_1_0_0_cabi; + } } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the input notes hash. This is computed as a sequential hash of - /// (nullifier, script_root) tuples over all input notes. - pub fn get_input_notes_hash() -> Word{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "get-input-notes-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }) + } +} +mod _rt { + + pub fn as_i64(t: T) -> i64 { + t.as_i64() + } + + pub trait AsI64 { + fn as_i64(self) -> i64; + } + + impl<'a, T: Copy + AsI64> AsI64 for &'a T { + fn as_i64(self) -> i64 { + (*self).as_i64() } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the output notes hash. This is computed as a sequential hash of - /// (note_hash, note_metadata) tuples over all output notes. - pub fn get_output_notes_hash() -> Word{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "get-output-notes-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }) + } + + impl AsI64 for i64 { + #[inline] + fn as_i64(self) -> i64 { + self as i64 } - } - #[allow(unused_unsafe, clippy::all)] - /// Creates a new note. - /// asset is the asset to be included in the note. - /// tag is the tag to be included in the note. - /// recipient is the recipient of the note. - /// Returns the id of the created note. - pub fn create_note(asset: CoreAsset,tag: Tag,recipient: Recipient,) -> NoteId{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - let super::super::super::miden::base::core_types::Tag{ inner:inner6, } = tag; - let super::super::super::miden::base::core_types::Felt{ inner:inner7, } = inner6; - let super::super::super::miden::base::core_types::Recipient{ inner:inner8, } = recipient; - let (t9_0, t9_1, t9_2, t9_3, ) = inner8; - let super::super::super::miden::base::core_types::Felt{ inner:inner10, } = t9_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner11, } = t9_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner12, } = t9_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner13, } = t9_3; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "create-note"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, ) -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, ) -> i64{ unreachable!() } - let ret = wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), wit_bindgen::rt::as_i64(inner7), wit_bindgen::rt::as_i64(inner10), wit_bindgen::rt::as_i64(inner11), wit_bindgen::rt::as_i64(inner12), wit_bindgen::rt::as_i64(inner13)); - super::super::super::miden::base::core_types::NoteId{ - inner: super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - }, - } + } + + impl AsI64 for u64 { + #[inline] + fn as_i64(self) -> i64 { + self as i64 } - } - } - - } -} -pub mod exports { - pub mod miden { - pub mod basic_wallet { - - #[allow(clippy::all)] - pub mod basic_wallet { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_section; - pub type CoreAsset = super::super::super::super::miden::base::core_types::CoreAsset; - pub type Tag = super::super::super::super::miden::base::core_types::Tag; - pub type Recipient = super::super::super::super::miden::base::core_types::Recipient; - const _: () = { - - #[doc(hidden)] - #[export_name = "miden:basic-wallet/basic-wallet@1.0.0#receive-asset"] - #[allow(non_snake_case)] - unsafe extern "C" fn __export_receive_asset(arg0: i64,arg1: i64,arg2: i64,arg3: i64,) { - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - - // Before executing any other code, use this function to run all static - // constructors, if they have not yet been run. This is a hack required - // to work around wasi-libc ctors calling import functions to initialize - // the environment. - // - // This functionality will be removed once rust 1.69.0 is stable, at which - // point wasi-libc will no longer have this behavior. - // - // See - // https://github.com/bytecodealliance/preview2-prototyping/issues/99 - // for more details. - #[cfg(target_arch="wasm32")] - wit_bindgen::rt::run_ctors_once(); - - <_GuestImpl as Guest>::receive_asset(super::super::super::super::miden::base::core_types::CoreAsset{ - inner: (super::super::super::super::miden::base::core_types::Felt{ - inner: arg0 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg1 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg2 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg3 as u64, - }), - }); - } - }; - const _: () = { - - #[doc(hidden)] - #[export_name = "miden:basic-wallet/basic-wallet@1.0.0#send-asset"] - #[allow(non_snake_case)] - unsafe extern "C" fn __export_send_asset(arg0: i64,arg1: i64,arg2: i64,arg3: i64,arg4: i64,arg5: i64,arg6: i64,arg7: i64,arg8: i64,) { - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - - // Before executing any other code, use this function to run all static - // constructors, if they have not yet been run. This is a hack required - // to work around wasi-libc ctors calling import functions to initialize - // the environment. - // - // This functionality will be removed once rust 1.69.0 is stable, at which - // point wasi-libc will no longer have this behavior. - // - // See - // https://github.com/bytecodealliance/preview2-prototyping/issues/99 - // for more details. - #[cfg(target_arch="wasm32")] - wit_bindgen::rt::run_ctors_once(); - - <_GuestImpl as Guest>::send_asset(super::super::super::super::miden::base::core_types::CoreAsset{ - inner: (super::super::super::super::miden::base::core_types::Felt{ - inner: arg0 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg1 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg2 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg3 as u64, - }), - }, super::super::super::super::miden::base::core_types::Tag{ - inner: super::super::super::super::miden::base::core_types::Felt{ - inner: arg4 as u64, - }, - }, super::super::super::super::miden::base::core_types::Recipient{ - inner: (super::super::super::super::miden::base::core_types::Felt{ - inner: arg5 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg6 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg7 as u64, - }, super::super::super::super::miden::base::core_types::Felt{ - inner: arg8 as u64, - }), - }); - } - }; - use super::super::super::super::super::Component as _GuestImpl; - pub trait Guest { - fn receive_asset(core_asset: CoreAsset,); - fn send_asset(core_asset: CoreAsset,tag: Tag,recipient: Recipient,); + pub unsafe fn bool_lift(val: u8) -> bool { + if cfg!(debug_assertions) { + match val { + 0 => false, + 1 => true, + _ => panic!("invalid bool discriminant"), + } + } else { + val != 0 } - - } - } - } + + #[cfg(target_arch = "wasm32")] + pub fn run_ctors_once() { + wit_bindgen_rt::run_ctors_once(); + } } +/// Generates `#[no_mangle]` functions to export the specified type as the +/// root implementation of all generated traits. +/// +/// For more information see the documentation of `wit_bindgen::generate!`. +/// +/// ```rust +/// # macro_rules! export{ ($($t:tt)*) => (); } +/// # trait Guest {} +/// struct MyType; +/// +/// impl Guest for MyType { +/// // ... +/// } +/// +/// export!(MyType); +/// ``` +#[allow(unused_macros)] +#[doc(hidden)] + +macro_rules! __export_basic_wallet_world_impl { + ($ty:ident) => (self::export!($ty with_types_in self);); + ($ty:ident with_types_in $($path_to_types_root:tt)*) => ( + $($path_to_types_root)*::exports::miden::basic_wallet::basic_wallet::__export_miden_basic_wallet_basic_wallet_1_0_0_cabi!($ty with_types_in $($path_to_types_root)*::exports::miden::basic_wallet::basic_wallet); + ) +} +#[doc(inline)] +pub(crate) use __export_basic_wallet_world_impl as export; + #[cfg(target_arch = "wasm32")] -#[link_section = "component-type:basic-wallet-world"] +#[link_section = "component-type:wit-bindgen:0.25.0:basic-wallet-world:encoded world"] #[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 2717] = [3, 0, 18, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 45, 119, 111, 114, 108, 100, 0, 97, 115, 109, 13, 0, 1, 0, 7, 227, 4, 1, 65, 7, 1, 66, 28, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 2, 3, 0, 0, 3, 116, 97, 103, 2, 3, 0, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 1, 66, 10, 2, 3, 2, 1, 1, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 3, 116, 97, 103, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 4, 1, 64, 1, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 1, 0, 4, 0, 13, 114, 101, 99, 101, 105, 118, 101, 45, 97, 115, 115, 101, 116, 1, 6, 1, 64, 3, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 3, 116, 97, 103, 3, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 5, 1, 0, 4, 0, 10, 115, 101, 110, 100, 45, 97, 115, 115, 101, 116, 1, 7, 4, 1, 37, 109, 105, 100, 101, 110, 58, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 47, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 64, 49, 46, 48, 46, 48, 5, 4, 11, 18, 1, 0, 12, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 3, 0, 0, 7, 143, 15, 1, 65, 2, 1, 65, 22, 1, 66, 30, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 1, 64, 1, 4, 102, 101, 108, 116, 1, 0, 5, 4, 0, 20, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 45, 102, 114, 111, 109, 45, 102, 101, 108, 116, 1, 28, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 2, 3, 0, 0, 3, 116, 97, 103, 2, 3, 0, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 5, 110, 111, 110, 99, 101, 2, 3, 0, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 2, 3, 0, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 2, 3, 0, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 1, 66, 47, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 1, 64, 0, 0, 9, 4, 0, 6, 103, 101, 116, 45, 105, 100, 1, 22, 1, 64, 0, 0, 11, 4, 0, 9, 103, 101, 116, 45, 110, 111, 110, 99, 101, 1, 23, 1, 64, 0, 0, 13, 4, 0, 16, 103, 101, 116, 45, 105, 110, 105, 116, 105, 97, 108, 45, 104, 97, 115, 104, 1, 24, 4, 0, 16, 103, 101, 116, 45, 99, 117, 114, 114, 101, 110, 116, 45, 104, 97, 115, 104, 1, 24, 1, 64, 1, 5, 118, 97, 108, 117, 101, 1, 1, 0, 4, 0, 10, 105, 110, 99, 114, 45, 110, 111, 110, 99, 101, 1, 25, 1, 64, 1, 5, 105, 110, 100, 101, 120, 1, 0, 15, 4, 0, 8, 103, 101, 116, 45, 105, 116, 101, 109, 1, 26, 1, 111, 2, 17, 15, 1, 64, 2, 5, 105, 110, 100, 101, 120, 1, 5, 118, 97, 108, 117, 101, 15, 0, 27, 4, 0, 8, 115, 101, 116, 45, 105, 116, 101, 109, 1, 28, 1, 64, 1, 9, 99, 111, 100, 101, 45, 114, 111, 111, 116, 19, 1, 0, 4, 0, 8, 115, 101, 116, 45, 99, 111, 100, 101, 1, 29, 1, 64, 1, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 9, 0, 1, 4, 0, 11, 103, 101, 116, 45, 98, 97, 108, 97, 110, 99, 101, 1, 30, 1, 64, 1, 5, 97, 115, 115, 101, 116, 3, 0, 127, 4, 0, 22, 104, 97, 115, 45, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 1, 31, 1, 64, 1, 5, 97, 115, 115, 101, 116, 3, 0, 3, 4, 0, 9, 97, 100, 100, 45, 97, 115, 115, 101, 116, 1, 32, 4, 0, 12, 114, 101, 109, 111, 118, 101, 45, 97, 115, 115, 101, 116, 1, 32, 1, 64, 0, 0, 21, 4, 0, 20, 103, 101, 116, 45, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 1, 33, 3, 1, 24, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 97, 99, 99, 111, 117, 110, 116, 64, 49, 46, 48, 46, 48, 5, 12, 2, 3, 0, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 2, 3, 0, 0, 4, 119, 111, 114, 100, 2, 3, 0, 0, 7, 110, 111, 116, 101, 45, 105, 100, 1, 66, 37, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 2, 3, 2, 1, 13, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 22, 2, 3, 2, 1, 14, 4, 0, 4, 119, 111, 114, 100, 3, 0, 24, 2, 3, 2, 1, 15, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 1, 64, 0, 0, 1, 4, 0, 16, 103, 101, 116, 45, 98, 108, 111, 99, 107, 45, 110, 117, 109, 98, 101, 114, 1, 28, 1, 64, 0, 0, 23, 4, 0, 14, 103, 101, 116, 45, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 1, 29, 1, 64, 0, 0, 25, 4, 0, 20, 103, 101, 116, 45, 105, 110, 112, 117, 116, 45, 110, 111, 116, 101, 115, 45, 104, 97, 115, 104, 1, 30, 4, 0, 21, 103, 101, 116, 45, 111, 117, 116, 112, 117, 116, 45, 110, 111, 116, 101, 115, 45, 104, 97, 115, 104, 1, 30, 1, 64, 3, 5, 97, 115, 115, 101, 116, 3, 3, 116, 97, 103, 5, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 7, 0, 27, 4, 0, 11, 99, 114, 101, 97, 116, 101, 45, 110, 111, 116, 101, 1, 31, 3, 1, 19, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 116, 120, 64, 49, 46, 48, 46, 48, 5, 16, 1, 66, 10, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 0, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 2, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 4, 1, 64, 1, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 1, 0, 4, 0, 13, 114, 101, 99, 101, 105, 118, 101, 45, 97, 115, 115, 101, 116, 1, 6, 1, 64, 3, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 3, 116, 97, 103, 3, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 5, 1, 0, 4, 0, 10, 115, 101, 110, 100, 45, 97, 115, 115, 101, 116, 1, 7, 4, 1, 37, 109, 105, 100, 101, 110, 58, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 47, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 64, 49, 46, 48, 46, 48, 5, 17, 4, 1, 43, 109, 105, 100, 101, 110, 58, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 47, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 45, 119, 111, 114, 108, 100, 64, 49, 46, 48, 46, 48, 4, 0, 11, 24, 1, 0, 18, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 45, 119, 111, 114, 108, 100, 3, 2, 0, 0, 16, 12, 112, 97, 99, 107, 97, 103, 101, 45, 100, 111, 99, 115, 0, 123, 125, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 49, 56, 46, 50, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 54, 46, 48]; +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 2072] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\x8f\x0f\x01A\x02\x01\ +A\x16\x01B\x1e\x01r\x01\x05innerw\x04\0\x04felt\x03\0\0\x01o\x04\x01\x01\x01\x01\ +\x04\0\x04word\x03\0\x02\x01r\x01\x05inner\x01\x04\0\x0aaccount-id\x03\0\x04\x01\ +r\x01\x05inner\x03\x04\0\x09recipient\x03\0\x06\x01r\x01\x05inner\x01\x04\0\x03t\ +ag\x03\0\x08\x01r\x01\x05inner\x03\x04\0\x0acore-asset\x03\0\x0a\x01r\x01\x05inn\ +er\x01\x04\0\x05nonce\x03\0\x0c\x01r\x01\x05inner\x03\x04\0\x0caccount-hash\x03\0\ +\x0e\x01r\x01\x05inner\x03\x04\0\x0ablock-hash\x03\0\x10\x01r\x01\x05inner\x03\x04\ +\0\x0dstorage-value\x03\0\x12\x01r\x01\x05inner\x03\x04\0\x0cstorage-root\x03\0\x14\ +\x01r\x01\x05inner\x03\x04\0\x11account-code-root\x03\0\x16\x01r\x01\x05inner\x03\ +\x04\0\x10vault-commitment\x03\0\x18\x01r\x01\x05inner\x01\x04\0\x07note-id\x03\0\ +\x1a\x01@\x01\x04felt\x01\0\x05\x04\0\x14account-id-from-felt\x01\x1c\x03\x01\x1b\ +miden:base/core-types@1.0.0\x05\0\x02\x03\0\0\x04felt\x02\x03\0\0\x0acore-asset\x02\ +\x03\0\0\x03tag\x02\x03\0\0\x09recipient\x02\x03\0\0\x0aaccount-id\x02\x03\0\0\x05\ +nonce\x02\x03\0\0\x0caccount-hash\x02\x03\0\0\x0dstorage-value\x02\x03\0\0\x0cst\ +orage-root\x02\x03\0\0\x11account-code-root\x02\x03\0\0\x10vault-commitment\x01B\ +/\x02\x03\x02\x01\x01\x04\0\x04felt\x03\0\0\x02\x03\x02\x01\x02\x04\0\x0acore-as\ +set\x03\0\x02\x02\x03\x02\x01\x03\x04\0\x03tag\x03\0\x04\x02\x03\x02\x01\x04\x04\ +\0\x09recipient\x03\0\x06\x02\x03\x02\x01\x05\x04\0\x0aaccount-id\x03\0\x08\x02\x03\ +\x02\x01\x06\x04\0\x05nonce\x03\0\x0a\x02\x03\x02\x01\x07\x04\0\x0caccount-hash\x03\ +\0\x0c\x02\x03\x02\x01\x08\x04\0\x0dstorage-value\x03\0\x0e\x02\x03\x02\x01\x09\x04\ +\0\x0cstorage-root\x03\0\x10\x02\x03\x02\x01\x0a\x04\0\x11account-code-root\x03\0\ +\x12\x02\x03\x02\x01\x0b\x04\0\x10vault-commitment\x03\0\x14\x01@\0\0\x09\x04\0\x06\ +get-id\x01\x16\x01@\0\0\x0b\x04\0\x09get-nonce\x01\x17\x01@\0\0\x0d\x04\0\x10get\ +-initial-hash\x01\x18\x04\0\x10get-current-hash\x01\x18\x01@\x01\x05value\x01\x01\ +\0\x04\0\x0aincr-nonce\x01\x19\x01@\x01\x05index\x01\0\x0f\x04\0\x08get-item\x01\ +\x1a\x01o\x02\x11\x0f\x01@\x02\x05index\x01\x05value\x0f\0\x1b\x04\0\x08set-item\ +\x01\x1c\x01@\x01\x09code-root\x13\x01\0\x04\0\x08set-code\x01\x1d\x01@\x01\x0aa\ +ccount-id\x09\0\x01\x04\0\x0bget-balance\x01\x1e\x01@\x01\x05asset\x03\0\x7f\x04\ +\0\x16has-non-fungible-asset\x01\x1f\x01@\x01\x05asset\x03\0\x03\x04\0\x09add-as\ +set\x01\x20\x04\0\x0cremove-asset\x01\x20\x01@\0\0\x15\x04\0\x14get-vault-commit\ +ment\x01!\x03\x01\x18miden:base/account@1.0.0\x05\x0c\x02\x03\0\0\x0ablock-hash\x02\ +\x03\0\0\x04word\x02\x03\0\0\x07note-id\x01B%\x02\x03\x02\x01\x01\x04\0\x04felt\x03\ +\0\0\x02\x03\x02\x01\x02\x04\0\x0acore-asset\x03\0\x02\x02\x03\x02\x01\x03\x04\0\ +\x03tag\x03\0\x04\x02\x03\x02\x01\x04\x04\0\x09recipient\x03\0\x06\x02\x03\x02\x01\ +\x05\x04\0\x0aaccount-id\x03\0\x08\x02\x03\x02\x01\x06\x04\0\x05nonce\x03\0\x0a\x02\ +\x03\x02\x01\x07\x04\0\x0caccount-hash\x03\0\x0c\x02\x03\x02\x01\x08\x04\0\x0dst\ +orage-value\x03\0\x0e\x02\x03\x02\x01\x09\x04\0\x0cstorage-root\x03\0\x10\x02\x03\ +\x02\x01\x0a\x04\0\x11account-code-root\x03\0\x12\x02\x03\x02\x01\x0b\x04\0\x10v\ +ault-commitment\x03\0\x14\x02\x03\x02\x01\x0d\x04\0\x0ablock-hash\x03\0\x16\x02\x03\ +\x02\x01\x0e\x04\0\x04word\x03\0\x18\x02\x03\x02\x01\x0f\x04\0\x07note-id\x03\0\x1a\ +\x01@\0\0\x01\x04\0\x10get-block-number\x01\x1c\x01@\0\0\x17\x04\0\x0eget-block-\ +hash\x01\x1d\x01@\0\0\x19\x04\0\x14get-input-notes-hash\x01\x1e\x04\0\x15get-out\ +put-notes-hash\x01\x1e\x01@\x03\x05asset\x03\x03tag\x05\x09recipient\x07\0\x1b\x04\ +\0\x0bcreate-note\x01\x1f\x03\x01\x13miden:base/tx@1.0.0\x05\x10\x01B\x0a\x02\x03\ +\x02\x01\x02\x04\0\x0acore-asset\x03\0\0\x02\x03\x02\x01\x03\x04\0\x03tag\x03\0\x02\ +\x02\x03\x02\x01\x04\x04\0\x09recipient\x03\0\x04\x01@\x01\x0acore-asset\x01\x01\ +\0\x04\0\x0dreceive-asset\x01\x06\x01@\x03\x0acore-asset\x01\x03tag\x03\x09recip\ +ient\x05\x01\0\x04\0\x0asend-asset\x01\x07\x04\x01%miden:basic-wallet/basic-wall\ +et@1.0.0\x05\x11\x04\x01+miden:basic-wallet/basic-wallet-world@1.0.0\x04\0\x0b\x18\ +\x01\0\x12basic-wallet-world\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0d\ +wit-component\x070.208.1\x10wit-bindgen-rust\x060.25.0"; #[inline(never)] #[doc(hidden)] #[cfg(target_arch = "wasm32")] -pub fn __link_section() {} +pub fn __link_custom_section_describing_imports() { + wit_bindgen_rt::maybe_link_cabi_realloc(); +} diff --git a/tests/rust-apps-wasm/wit-sdk/basic-wallet/src/lib.rs b/tests/rust-apps-wasm/wit-sdk/basic-wallet/src/lib.rs index cf97ce09..0b83b2c9 100644 --- a/tests/rust-apps-wasm/wit-sdk/basic-wallet/src/lib.rs +++ b/tests/rust-apps-wasm/wit-sdk/basic-wallet/src/lib.rs @@ -8,12 +8,18 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! { loop {} } +bindings::export!(Component with_types_in bindings); + #[allow(dead_code)] mod bindings; -use bindings::exports::miden::basic_wallet::basic_wallet::{CoreAsset, Guest, Recipient, Tag}; -use bindings::miden::base::account::{add_asset, remove_asset}; -use bindings::miden::base::tx::create_note; +use bindings::{ + exports::miden::basic_wallet::basic_wallet::{CoreAsset, Guest, Recipient, Tag}, + miden::base::{ + account::{add_asset, remove_asset}, + tx::create_note, + }, +}; struct Component; diff --git a/tests/rust-apps-wasm/wit-sdk/p2id-note/Cargo.lock b/tests/rust-apps-wasm/wit-sdk/p2id-note/Cargo.lock index b44ec7e7..79bc8a1f 100644 --- a/tests/rust-apps-wasm/wit-sdk/p2id-note/Cargo.lock +++ b/tests/rust-apps-wasm/wit-sdk/p2id-note/Cargo.lock @@ -7,15 +7,9 @@ name = "basic-wallet-p2id-note" version = "0.0.0" dependencies = [ "wee_alloc", - "wit-bindgen", + "wit-bindgen-rt", ] -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - [[package]] name = "cfg-if" version = "0.1.10" @@ -69,10 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "wit-bindgen" -version = "0.17.0" +name = "wit-bindgen-rt" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6237168d93497b26dacdab157b08ad2787d74cdce10f89735f791b2a225eba4d" -dependencies = [ - "bitflags", -] +checksum = "d7a37bd9274cb2d4754b915d624447ec0dce9105d174361841c0826efc79ceb9" diff --git a/tests/rust-apps-wasm/wit-sdk/p2id-note/Cargo.toml b/tests/rust-apps-wasm/wit-sdk/p2id-note/Cargo.toml index 62adb695..f891ee73 100644 --- a/tests/rust-apps-wasm/wit-sdk/p2id-note/Cargo.toml +++ b/tests/rust-apps-wasm/wit-sdk/p2id-note/Cargo.toml @@ -15,8 +15,8 @@ publish = false crate-type = ["cdylib"] [dependencies] -wit-bindgen = { version = "0.17.0", default-features = false, features = ["realloc"] } -wee_alloc = { version = "0.4.5", default-features = false} +wit-bindgen-rt = "0.28" +wee_alloc = { version = "0.4.5", default-features = false } [package.metadata.component] package = "miden:basic-wallet-p2id-note" @@ -31,4 +31,5 @@ package = "miden:basic-wallet-p2id-note" derives = ["PartialEq"] [profile.release] -panic = "abort" \ No newline at end of file +panic = "abort" +debug = true diff --git a/tests/rust-apps-wasm/wit-sdk/p2id-note/src/bindings.rs b/tests/rust-apps-wasm/wit-sdk/p2id-note/src/bindings.rs index b175a5d7..1e6fc85c 100644 --- a/tests/rust-apps-wasm/wit-sdk/p2id-note/src/bindings.rs +++ b/tests/rust-apps-wasm/wit-sdk/p2id-note/src/bindings.rs @@ -1,1154 +1,1370 @@ -// Generated by `wit-bindgen` 0.16.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.25.0. DO NOT EDIT! +// Options used: +// * additional derives ["PartialEq"] +#[allow(dead_code)] pub mod miden { - pub mod base { - - #[allow(clippy::all)] - pub mod core_types { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; - /// Represents base field element in the field using Montgomery representation. - /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). - /// The backing type is `f64` but the internal values are always integer in the range [0, M). - /// Field modulus M = 2^64 - 2^32 + 1 - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct Felt { - /// We plan to use f64 as the backing type for the field element. It has the size that we need and - /// we don't plan to support floating point arithmetic in programs for Miden VM. - /// - /// For now its u64 - pub inner: u64, - } - impl ::core::fmt::Debug for Felt { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Felt").field("inner", &self.inner).finish() - } - } - /// A group of four field elements in the Miden base field. - pub type Word = (Felt,Felt,Felt,Felt,); - /// Unique identifier of an account. - /// - /// Account ID consists of 1 field element (~64 bits). This field element uniquely identifies a - /// single account and also specifies the type of the underlying account. Specifically: - /// - The two most significant bits of the ID specify the type of the account: - /// - 00 - regular account with updatable code. - /// - 01 - regular account with immutable code. - /// - 10 - fungible asset faucet with immutable code. - /// - 11 - non-fungible asset faucet with immutable code. - /// - The third most significant bit of the ID specifies whether the account data is stored on-chain: - /// - 0 - full account data is stored on-chain. - /// - 1 - only the account hash is stored on-chain which serves as a commitment to the account state. - /// As such the three most significant bits fully describes the type of the account. - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct AccountId { - pub inner: Felt, - } - impl ::core::fmt::Debug for AccountId { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("AccountId").field("inner", &self.inner).finish() - } - } - /// Recipient of the note, i.e., hash(hash(hash(serial_num, [0; 4]), note_script_hash), input_hash) - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct Recipient { - pub inner: Word, - } - impl ::core::fmt::Debug for Recipient { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Recipient").field("inner", &self.inner).finish() - } - } - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct Tag { - pub inner: Felt, - } - impl ::core::fmt::Debug for Tag { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Tag").field("inner", &self.inner).finish() - } - } - /// A fungible or a non-fungible asset. - /// - /// All assets are encoded using a single word (4 elements) such that it is easy to determine the - /// type of an asset both inside and outside Miden VM. Specifically: - /// Element 1 will be: - /// - ZERO for a fungible asset - /// - non-ZERO for a non-fungible asset - /// The most significant bit will be: - /// - ONE for a fungible asset - /// - ZERO for a non-fungible asset - /// - /// The above properties guarantee that there can never be a collision between a fungible and a - /// non-fungible asset. - /// - /// The methodology for constructing fungible and non-fungible assets is described below. - /// - /// # Fungible assets - /// The most significant element of a fungible asset is set to the ID of the faucet which issued - /// the asset. This guarantees the properties described above (the first bit is ONE). - /// - /// The least significant element is set to the amount of the asset. This amount cannot be greater - /// than 2^63 - 1 and thus requires 63-bits to store. - /// - /// Elements 1 and 2 are set to ZERO. - /// - /// It is impossible to find a collision between two fungible assets issued by different faucets as - /// the faucet_id is included in the description of the asset and this is guaranteed to be different - /// for each faucet as per the faucet creation logic. - /// - /// # Non-fungible assets - /// The 4 elements of non-fungible assets are computed as follows: - /// - First the asset data is hashed. This compresses an asset of an arbitrary length to 4 field - /// elements: [d0, d1, d2, d3]. - /// - d1 is then replaced with the faucet_id which issues the asset: [d0, faucet_id, d2, d3]. - /// - Lastly, the most significant bit of d3 is set to ZERO. - /// - /// It is impossible to find a collision between two non-fungible assets issued by different faucets - /// as the faucet_id is included in the description of the non-fungible asset and this is guaranteed - /// to be different as per the faucet creation logic. Collision resistance for non-fungible assets - /// issued by the same faucet is ~2^95. - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct CoreAsset { - pub inner: Word, - } - impl ::core::fmt::Debug for CoreAsset { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("CoreAsset").field("inner", &self.inner).finish() - } - } - /// Account nonce - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct Nonce { - pub inner: Felt, - } - impl ::core::fmt::Debug for Nonce { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Nonce").field("inner", &self.inner).finish() - } - } - /// Account hash - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct AccountHash { - pub inner: Word, - } - impl ::core::fmt::Debug for AccountHash { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("AccountHash").field("inner", &self.inner).finish() - } - } - /// Block hash - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct BlockHash { - pub inner: Word, - } - impl ::core::fmt::Debug for BlockHash { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("BlockHash").field("inner", &self.inner).finish() - } - } - /// Storage value - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct StorageValue { - pub inner: Word, - } - impl ::core::fmt::Debug for StorageValue { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("StorageValue").field("inner", &self.inner).finish() - } - } - /// Account storage root - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct StorageRoot { - pub inner: Word, - } - impl ::core::fmt::Debug for StorageRoot { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("StorageRoot").field("inner", &self.inner).finish() - } - } - /// Account code root - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct AccountCodeRoot { - pub inner: Word, - } - impl ::core::fmt::Debug for AccountCodeRoot { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("AccountCodeRoot").field("inner", &self.inner).finish() + #[allow(dead_code)] + pub mod base { + #[allow(dead_code, clippy::all)] + pub mod core_types { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + /// Represents base field element in the field using Montgomery representation. + /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). + /// The backing type is `f64` but the internal values are always integer in the range + /// [0, M). Field modulus M = 2^64 - 2^32 + 1 + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct Felt { + /// We plan to use f64 as the backing type for the field element. It has the size + /// that we need and we don't plan to support floating point + /// arithmetic in programs for Miden VM. + /// + /// For now its u64 + pub inner: u64, + } + impl ::core::fmt::Debug for Felt { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Felt").field("inner", &self.inner).finish() + } + } + /// A group of four field elements in the Miden base field. + pub type Word = (Felt, Felt, Felt, Felt); + /// Unique identifier of an account. + /// + /// Account ID consists of 1 field element (~64 bits). This field element uniquely + /// identifies a single account and also specifies the type of the + /// underlying account. Specifically: + /// - The two most significant bits of the ID specify the type of the account: + /// - 00 - regular account with updatable code. + /// - 01 - regular account with immutable code. + /// - 10 - fungible asset faucet with immutable code. + /// - 11 - non-fungible asset faucet with immutable code. + /// - The third most significant bit of the ID specifies whether the account data is + /// stored on-chain: + /// - 0 - full account data is stored on-chain. + /// - 1 - only the account hash is stored on-chain which serves as a commitment to the + /// account state. + /// As such the three most significant bits fully describes the type of the account. + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct AccountId { + pub inner: Felt, + } + impl ::core::fmt::Debug for AccountId { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("AccountId").field("inner", &self.inner).finish() + } + } + /// Recipient of the note, i.e., hash(hash(hash(serial_num, [0; 4]), note_script_hash), + /// input_hash) + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct Recipient { + pub inner: Word, + } + impl ::core::fmt::Debug for Recipient { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Recipient").field("inner", &self.inner).finish() + } + } + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct Tag { + pub inner: Felt, + } + impl ::core::fmt::Debug for Tag { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Tag").field("inner", &self.inner).finish() + } + } + /// A fungible or a non-fungible asset. + /// + /// All assets are encoded using a single word (4 elements) such that it is easy to + /// determine the type of an asset both inside and outside Miden VM. + /// Specifically: Element 1 will be: + /// - ZERO for a fungible asset + /// - non-ZERO for a non-fungible asset + /// The most significant bit will be: + /// - ONE for a fungible asset + /// - ZERO for a non-fungible asset + /// + /// The above properties guarantee that there can never be a collision between a + /// fungible and a non-fungible asset. + /// + /// The methodology for constructing fungible and non-fungible assets is described + /// below. + /// + /// # Fungible assets + /// The most significant element of a fungible asset is set to the ID of the faucet + /// which issued the asset. This guarantees the properties described above + /// (the first bit is ONE). + /// + /// The least significant element is set to the amount of the asset. This amount cannot + /// be greater than 2^63 - 1 and thus requires 63-bits to store. + /// + /// Elements 1 and 2 are set to ZERO. + /// + /// It is impossible to find a collision between two fungible assets issued by different + /// faucets as the faucet_id is included in the description of the asset and + /// this is guaranteed to be different for each faucet as per the faucet + /// creation logic. + /// + /// # Non-fungible assets + /// The 4 elements of non-fungible assets are computed as follows: + /// - First the asset data is hashed. This compresses an asset of an arbitrary length to + /// 4 field + /// elements: [d0, d1, d2, d3]. + /// - d1 is then replaced with the faucet_id which issues the asset: [d0, faucet_id, d2, + /// d3]. + /// - Lastly, the most significant bit of d3 is set to ZERO. + /// + /// It is impossible to find a collision between two non-fungible assets issued by + /// different faucets as the faucet_id is included in the description of the + /// non-fungible asset and this is guaranteed to be different as per the + /// faucet creation logic. Collision resistance for non-fungible assets + /// issued by the same faucet is ~2^95. + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct CoreAsset { + pub inner: Word, + } + impl ::core::fmt::Debug for CoreAsset { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("CoreAsset").field("inner", &self.inner).finish() + } + } + /// Account nonce + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct Nonce { + pub inner: Felt, + } + impl ::core::fmt::Debug for Nonce { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Nonce").field("inner", &self.inner).finish() + } + } + /// Account hash + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct AccountHash { + pub inner: Word, + } + impl ::core::fmt::Debug for AccountHash { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("AccountHash").field("inner", &self.inner).finish() + } + } + /// Block hash + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct BlockHash { + pub inner: Word, + } + impl ::core::fmt::Debug for BlockHash { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("BlockHash").field("inner", &self.inner).finish() + } + } + /// Storage value + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct StorageValue { + pub inner: Word, + } + impl ::core::fmt::Debug for StorageValue { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("StorageValue").field("inner", &self.inner).finish() + } + } + /// Account storage root + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct StorageRoot { + pub inner: Word, + } + impl ::core::fmt::Debug for StorageRoot { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("StorageRoot").field("inner", &self.inner).finish() + } + } + /// Account code root + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct AccountCodeRoot { + pub inner: Word, + } + impl ::core::fmt::Debug for AccountCodeRoot { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("AccountCodeRoot").field("inner", &self.inner).finish() + } + } + /// Commitment to the account vault + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct VaultCommitment { + pub inner: Word, + } + impl ::core::fmt::Debug for VaultCommitment { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("VaultCommitment").field("inner", &self.inner).finish() + } + } + /// An id of the created note + #[repr(C)] + #[derive(Clone, Copy, PartialEq)] + pub struct NoteId { + pub inner: Felt, + } + impl ::core::fmt::Debug for NoteId { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("NoteId").field("inner", &self.inner).finish() + } + } + #[allow(unused_unsafe, clippy::all)] + /// Creates a new account ID from a field element. + pub fn account_id_from_felt(felt: Felt) -> AccountId { + unsafe { + let Felt { inner: inner0 } = felt; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/core-types@1.0.0")] + extern "C" { + #[link_name = "account-id-from-felt"] + fn wit_import(_: i64) -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64) -> i64 { + unreachable!() + } + let ret = wit_import(_rt::as_i64(inner0)); + AccountId { + inner: Felt { inner: ret as u64 }, + } + } + } } - } - /// Commitment to the account vault - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct VaultCommitment { - pub inner: Word, - } - impl ::core::fmt::Debug for VaultCommitment { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("VaultCommitment").field("inner", &self.inner).finish() + + #[allow(dead_code, clippy::all)] + pub mod tx { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Felt = super::super::super::miden::base::core_types::Felt; + pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; + pub type Tag = super::super::super::miden::base::core_types::Tag; + pub type Recipient = super::super::super::miden::base::core_types::Recipient; + pub type BlockHash = super::super::super::miden::base::core_types::BlockHash; + pub type Word = super::super::super::miden::base::core_types::Word; + pub type NoteId = super::super::super::miden::base::core_types::NoteId; + #[allow(unused_unsafe, clippy::all)] + /// Returns the block number of the last known block at the time of transaction + /// execution. + pub fn get_block_number() -> Felt { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "get-block-number"] + fn wit_import() -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import() -> i64 { + unreachable!() + } + let ret = wit_import(); + super::super::super::miden::base::core_types::Felt { inner: ret as u64 } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the block hash of the last known block at the time of transaction execution. + pub fn get_block_hash() -> BlockHash { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "get-block-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + super::super::super::miden::base::core_types::BlockHash { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the input notes hash. This is computed as a sequential hash of + /// (nullifier, script_root) tuples over all input notes. + pub fn get_input_notes_hash() -> Word { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "get-input-notes-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the output notes hash. This is computed as a sequential hash of + /// (note_hash, note_metadata) tuples over all output notes. + pub fn get_output_notes_hash() -> Word { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "get-output-notes-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Creates a new note. + /// asset is the asset to be included in the note. + /// tag is the tag to be included in the note. + /// recipient is the recipient of the note. + /// Returns the id of the created note. + pub fn create_note(asset: CoreAsset, tag: Tag, recipient: Recipient) -> NoteId { + unsafe { + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + let super::super::super::miden::base::core_types::Tag { inner: inner6 } = tag; + let super::super::super::miden::base::core_types::Felt { inner: inner7 } = + inner6; + let super::super::super::miden::base::core_types::Recipient { inner: inner8 } = + recipient; + let (t9_0, t9_1, t9_2, t9_3) = inner8; + let super::super::super::miden::base::core_types::Felt { inner: inner10 } = + t9_0; + let super::super::super::miden::base::core_types::Felt { inner: inner11 } = + t9_1; + let super::super::super::miden::base::core_types::Felt { inner: inner12 } = + t9_2; + let super::super::super::miden::base::core_types::Felt { inner: inner13 } = + t9_3; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/tx@1.0.0")] + extern "C" { + #[link_name = "create-note"] + fn wit_import( + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + ) -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import( + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + ) -> i64 { + unreachable!() + } + let ret = wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + _rt::as_i64(inner7), + _rt::as_i64(inner10), + _rt::as_i64(inner11), + _rt::as_i64(inner12), + _rt::as_i64(inner13), + ); + super::super::super::miden::base::core_types::NoteId { + inner: super::super::super::miden::base::core_types::Felt { + inner: ret as u64, + }, + } + } + } } - } - /// An id of the created note - #[repr(C)] - #[derive(Clone, Copy, PartialEq)] - pub struct NoteId { - pub inner: Felt, - } - impl ::core::fmt::Debug for NoteId { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("NoteId").field("inner", &self.inner).finish() + + #[allow(dead_code, clippy::all)] + pub mod account { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Felt = super::super::super::miden::base::core_types::Felt; + pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; + pub type AccountId = super::super::super::miden::base::core_types::AccountId; + pub type Nonce = super::super::super::miden::base::core_types::Nonce; + pub type AccountHash = super::super::super::miden::base::core_types::AccountHash; + pub type StorageValue = super::super::super::miden::base::core_types::StorageValue; + pub type StorageRoot = super::super::super::miden::base::core_types::StorageRoot; + pub type AccountCodeRoot = + super::super::super::miden::base::core_types::AccountCodeRoot; + pub type VaultCommitment = + super::super::super::miden::base::core_types::VaultCommitment; + #[allow(unused_unsafe, clippy::all)] + /// Get the id of the currently executing account + pub fn get_id() -> AccountId { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-id"] + fn wit_import() -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import() -> i64 { + unreachable!() + } + let ret = wit_import(); + super::super::super::miden::base::core_types::AccountId { + inner: super::super::super::miden::base::core_types::Felt { + inner: ret as u64, + }, + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Return the account nonce + pub fn get_nonce() -> Nonce { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-nonce"] + fn wit_import() -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import() -> i64 { + unreachable!() + } + let ret = wit_import(); + super::super::super::miden::base::core_types::Nonce { + inner: super::super::super::miden::base::core_types::Felt { + inner: ret as u64, + }, + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Get the initial hash of the currently executing account + pub fn get_initial_hash() -> AccountHash { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-initial-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + super::super::super::miden::base::core_types::AccountHash { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Get the current hash of the account data stored in memory + pub fn get_current_hash() -> AccountHash { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-current-hash"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + super::super::super::miden::base::core_types::AccountHash { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Increment the account nonce by the specified value. + /// value can be at most 2^32 - 1 otherwise this procedure panics + pub fn incr_nonce(value: Felt) { + unsafe { + let super::super::super::miden::base::core_types::Felt { inner: inner0 } = + value; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "incr-nonce"] + fn wit_import(_: i64); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64) { + unreachable!() + } + wit_import(_rt::as_i64(inner0)); + } + } + #[allow(unused_unsafe, clippy::all)] + /// Get the value of the specified key in the account storage + pub fn get_item(index: Felt) -> StorageValue { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let super::super::super::miden::base::core_types::Felt { inner: inner0 } = + index; + let ptr1 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-item"] + fn wit_import(_: i64, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: *mut u8) { + unreachable!() + } + wit_import(_rt::as_i64(inner0), ptr1); + let l2 = *ptr1.add(0).cast::(); + let l3 = *ptr1.add(8).cast::(); + let l4 = *ptr1.add(16).cast::(); + let l5 = *ptr1.add(24).cast::(); + super::super::super::miden::base::core_types::StorageValue { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l5 as u64 }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Set the value of the specified key in the account storage + /// Returns the old value of the key and the new storage root + pub fn set_item(index: Felt, value: StorageValue) -> (StorageRoot, StorageValue) { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 64]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 64]); + let super::super::super::miden::base::core_types::Felt { inner: inner0 } = + index; + let super::super::super::miden::base::core_types::StorageValue { + inner: inner1, + } = value; + let (t2_0, t2_1, t2_2, t2_3) = inner1; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t2_0; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t2_1; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t2_2; + let super::super::super::miden::base::core_types::Felt { inner: inner6 } = t2_3; + let ptr7 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "set-item"] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: *mut u8) { + unreachable!() + } + wit_import( + _rt::as_i64(inner0), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + _rt::as_i64(inner6), + ptr7, + ); + let l8 = *ptr7.add(0).cast::(); + let l9 = *ptr7.add(8).cast::(); + let l10 = *ptr7.add(16).cast::(); + let l11 = *ptr7.add(24).cast::(); + let l12 = *ptr7.add(32).cast::(); + let l13 = *ptr7.add(40).cast::(); + let l14 = *ptr7.add(48).cast::(); + let l15 = *ptr7.add(56).cast::(); + ( + super::super::super::miden::base::core_types::StorageRoot { + inner: ( + super::super::super::miden::base::core_types::Felt { + inner: l8 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l9 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l10 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l11 as u64, + }, + ), + }, + super::super::super::miden::base::core_types::StorageValue { + inner: ( + super::super::super::miden::base::core_types::Felt { + inner: l12 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l13 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l14 as u64, + }, + super::super::super::miden::base::core_types::Felt { + inner: l15 as u64, + }, + ), + }, + ) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Sets the code of the account the transaction is being executed against. + /// This procedure can only be executed on regular accounts with updatable + /// code. Otherwise, this procedure fails. code is the hash of the code + /// to set. + pub fn set_code(code_root: AccountCodeRoot) { + unsafe { + let super::super::super::miden::base::core_types::AccountCodeRoot { + inner: inner0, + } = code_root; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "set-code"] + fn wit_import(_: i64, _: i64, _: i64, _: i64); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64) { + unreachable!() + } + wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ); + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the balance of a fungible asset associated with a account_id. + /// Panics if the asset is not a fungible asset. account_id is the faucet id + /// of the fungible asset of interest. balance is the vault balance of the + /// fungible asset. + pub fn get_balance(account_id: AccountId) -> Felt { + unsafe { + let super::super::super::miden::base::core_types::AccountId { inner: inner0 } = + account_id; + let super::super::super::miden::base::core_types::Felt { inner: inner1 } = + inner0; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-balance"] + fn wit_import(_: i64) -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64) -> i64 { + unreachable!() + } + let ret = wit_import(_rt::as_i64(inner1)); + super::super::super::miden::base::core_types::Felt { inner: ret as u64 } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns a boolean indicating whether the non-fungible asset is present + /// in the vault. Panics if the asset is a fungible asset. asset is the + /// non-fungible asset of interest. has_asset is a boolean indicating + /// whether the account vault has the asset of interest. + pub fn has_non_fungible_asset(asset: CoreAsset) -> bool { + unsafe { + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "has-non-fungible-asset"] + fn wit_import(_: i64, _: i64, _: i64, _: i64) -> i32; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64) -> i32 { + unreachable!() + } + let ret = wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ); + _rt::bool_lift(ret as u8) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Add the specified asset to the vault. Panics under various conditions. + /// Returns the final asset in the account vault defined as follows: If asset is + /// a non-fungible asset, then returns the same as asset. If asset is a + /// fungible asset, then returns the total fungible asset in the account + /// vault after asset was added to it. + pub fn add_asset(asset: CoreAsset) -> CoreAsset { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + let ptr6 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "add-asset"] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: *mut u8) { + unreachable!() + } + wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ptr6, + ); + let l7 = *ptr6.add(0).cast::(); + let l8 = *ptr6.add(8).cast::(); + let l9 = *ptr6.add(16).cast::(); + let l10 = *ptr6.add(24).cast::(); + super::super::super::miden::base::core_types::CoreAsset { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l7 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l8 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l9 as u64 }, + super::super::super::miden::base::core_types::Felt { + inner: l10 as u64, + }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Remove the specified asset from the vault + pub fn remove_asset(asset: CoreAsset) -> CoreAsset { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + let ptr6 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "remove-asset"] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64, _: *mut u8) { + unreachable!() + } + wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ptr6, + ); + let l7 = *ptr6.add(0).cast::(); + let l8 = *ptr6.add(8).cast::(); + let l9 = *ptr6.add(16).cast::(); + let l10 = *ptr6.add(24).cast::(); + super::super::super::miden::base::core_types::CoreAsset { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l7 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l8 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l9 as u64 }, + super::super::super::miden::base::core_types::Felt { + inner: l10 as u64, + }, + ), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Returns the commitment to the account vault. + pub fn get_vault_commitment() -> VaultCommitment { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 32]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 32]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/account@1.0.0")] + extern "C" { + #[link_name = "get-vault-commitment"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::(); + let l2 = *ptr0.add(8).cast::(); + let l3 = *ptr0.add(16).cast::(); + let l4 = *ptr0.add(24).cast::(); + super::super::super::miden::base::core_types::VaultCommitment { + inner: ( + super::super::super::miden::base::core_types::Felt { inner: l1 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l2 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l3 as u64 }, + super::super::super::miden::base::core_types::Felt { inner: l4 as u64 }, + ), + } + } + } } - } - #[allow(unused_unsafe, clippy::all)] - /// Creates a new account ID from a field element. - pub fn account_id_from_felt(felt: Felt,) -> AccountId{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let Felt{ inner:inner0, } = felt; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/core-types@1.0.0")] - extern "C" { - #[link_name = "account-id-from-felt"] - fn wit_import(_: i64, ) -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, ) -> i64{ unreachable!() } - let ret = wit_import(wit_bindgen::rt::as_i64(inner0)); - AccountId{ - inner: Felt{ - inner: ret as u64, - }, - } + + #[allow(dead_code, clippy::all)] + pub mod note { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Felt = super::super::super::miden::base::core_types::Felt; + pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; + pub type AccountId = super::super::super::miden::base::core_types::AccountId; + #[allow(unused_unsafe, clippy::all)] + /// Get the inputs of the currently executed note + pub fn get_inputs() -> _rt::Vec { + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/note@1.0.0")] + extern "C" { + #[link_name = "get-inputs"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::<*mut u8>(); + let l2 = *ptr0.add(4).cast::(); + let len3 = l2; + _rt::Vec::from_raw_parts(l1.cast(), len3, len3) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Get the assets of the currently executing note + pub fn get_assets() -> _rt::Vec { + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/note@1.0.0")] + extern "C" { + #[link_name = "get-assets"] + fn wit_import(_: *mut u8); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8) { + unreachable!() + } + wit_import(ptr0); + let l1 = *ptr0.add(0).cast::<*mut u8>(); + let l2 = *ptr0.add(4).cast::(); + let len3 = l2; + _rt::Vec::from_raw_parts(l1.cast(), len3, len3) + } + } + #[allow(unused_unsafe, clippy::all)] + /// Get the sender of the currently executing note + pub fn get_sender() -> AccountId { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:base/note@1.0.0")] + extern "C" { + #[link_name = "get-sender"] + fn wit_import() -> i64; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import() -> i64 { + unreachable!() + } + let ret = wit_import(); + super::super::super::miden::base::core_types::AccountId { + inner: super::super::super::miden::base::core_types::Felt { + inner: ret as u64, + }, + } + } + } } - } - } - - - #[allow(clippy::all)] - pub mod tx { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; - pub type Felt = super::super::super::miden::base::core_types::Felt; - pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; - pub type Tag = super::super::super::miden::base::core_types::Tag; - pub type Recipient = super::super::super::miden::base::core_types::Recipient; - pub type BlockHash = super::super::super::miden::base::core_types::BlockHash; - pub type Word = super::super::super::miden::base::core_types::Word; - pub type NoteId = super::super::super::miden::base::core_types::NoteId; - #[allow(unused_unsafe, clippy::all)] - /// Returns the block number of the last known block at the time of transaction execution. - pub fn get_block_number() -> Felt{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "get-block-number"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64{ unreachable!() } - let ret = wit_import(); - super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the block hash of the last known block at the time of transaction execution. - pub fn get_block_hash() -> BlockHash{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "get-block-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - super::super::super::miden::base::core_types::BlockHash{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the input notes hash. This is computed as a sequential hash of - /// (nullifier, script_root) tuples over all input notes. - pub fn get_input_notes_hash() -> Word{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "get-input-notes-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the output notes hash. This is computed as a sequential hash of - /// (note_hash, note_metadata) tuples over all output notes. - pub fn get_output_notes_hash() -> Word{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "get-output-notes-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Creates a new note. - /// asset is the asset to be included in the note. - /// tag is the tag to be included in the note. - /// recipient is the recipient of the note. - /// Returns the id of the created note. - pub fn create_note(asset: CoreAsset,tag: Tag,recipient: Recipient,) -> NoteId{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - let super::super::super::miden::base::core_types::Tag{ inner:inner6, } = tag; - let super::super::super::miden::base::core_types::Felt{ inner:inner7, } = inner6; - let super::super::super::miden::base::core_types::Recipient{ inner:inner8, } = recipient; - let (t9_0, t9_1, t9_2, t9_3, ) = inner8; - let super::super::super::miden::base::core_types::Felt{ inner:inner10, } = t9_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner11, } = t9_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner12, } = t9_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner13, } = t9_3; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/tx@1.0.0")] - extern "C" { - #[link_name = "create-note"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, ) -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, ) -> i64{ unreachable!() } - let ret = wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), wit_bindgen::rt::as_i64(inner7), wit_bindgen::rt::as_i64(inner10), wit_bindgen::rt::as_i64(inner11), wit_bindgen::rt::as_i64(inner12), wit_bindgen::rt::as_i64(inner13)); - super::super::super::miden::base::core_types::NoteId{ - inner: super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - }, - } + #[allow(dead_code)] + pub mod basic_wallet { + #[allow(dead_code, clippy::all)] + pub mod basic_wallet { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; + pub type Tag = super::super::super::miden::base::core_types::Tag; + pub type Recipient = super::super::super::miden::base::core_types::Recipient; + #[allow(unused_unsafe, clippy::all)] + pub fn receive_asset(core_asset: CoreAsset) { + unsafe { + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + core_asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:basic-wallet/basic-wallet@1.0.0")] + extern "C" { + #[link_name = "receive-asset"] + fn wit_import(_: i64, _: i64, _: i64, _: i64); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i64, _: i64, _: i64, _: i64) { + unreachable!() + } + wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + ); + } + } + #[allow(unused_unsafe, clippy::all)] + pub fn send_asset(core_asset: CoreAsset, tag: Tag, recipient: Recipient) { + unsafe { + let super::super::super::miden::base::core_types::CoreAsset { inner: inner0 } = + core_asset; + let (t1_0, t1_1, t1_2, t1_3) = inner0; + let super::super::super::miden::base::core_types::Felt { inner: inner2 } = t1_0; + let super::super::super::miden::base::core_types::Felt { inner: inner3 } = t1_1; + let super::super::super::miden::base::core_types::Felt { inner: inner4 } = t1_2; + let super::super::super::miden::base::core_types::Felt { inner: inner5 } = t1_3; + let super::super::super::miden::base::core_types::Tag { inner: inner6 } = tag; + let super::super::super::miden::base::core_types::Felt { inner: inner7 } = + inner6; + let super::super::super::miden::base::core_types::Recipient { inner: inner8 } = + recipient; + let (t9_0, t9_1, t9_2, t9_3) = inner8; + let super::super::super::miden::base::core_types::Felt { inner: inner10 } = + t9_0; + let super::super::super::miden::base::core_types::Felt { inner: inner11 } = + t9_1; + let super::super::super::miden::base::core_types::Felt { inner: inner12 } = + t9_2; + let super::super::super::miden::base::core_types::Felt { inner: inner13 } = + t9_3; + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:basic-wallet/basic-wallet@1.0.0")] + extern "C" { + #[link_name = "send-asset"] + fn wit_import( + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import( + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + _: i64, + ) { + unreachable!() + } + wit_import( + _rt::as_i64(inner2), + _rt::as_i64(inner3), + _rt::as_i64(inner4), + _rt::as_i64(inner5), + _rt::as_i64(inner7), + _rt::as_i64(inner10), + _rt::as_i64(inner11), + _rt::as_i64(inner12), + _rt::as_i64(inner13), + ); + } + } } - } - } - - - #[allow(clippy::all)] - pub mod account { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; - pub type Felt = super::super::super::miden::base::core_types::Felt; - pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; - pub type AccountId = super::super::super::miden::base::core_types::AccountId; - pub type Nonce = super::super::super::miden::base::core_types::Nonce; - pub type AccountHash = super::super::super::miden::base::core_types::AccountHash; - pub type StorageValue = super::super::super::miden::base::core_types::StorageValue; - pub type StorageRoot = super::super::super::miden::base::core_types::StorageRoot; - pub type AccountCodeRoot = super::super::super::miden::base::core_types::AccountCodeRoot; - pub type VaultCommitment = super::super::super::miden::base::core_types::VaultCommitment; - #[allow(unused_unsafe, clippy::all)] - /// Get the id of the currently executing account - pub fn get_id() -> AccountId{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-id"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64{ unreachable!() } - let ret = wit_import(); - super::super::super::miden::base::core_types::AccountId{ - inner: super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - }, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Return the account nonce - pub fn get_nonce() -> Nonce{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-nonce"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64{ unreachable!() } - let ret = wit_import(); - super::super::super::miden::base::core_types::Nonce{ - inner: super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - }, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the initial hash of the currently executing account - pub fn get_initial_hash() -> AccountHash{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-initial-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - super::super::super::miden::base::core_types::AccountHash{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the current hash of the account data stored in memory - pub fn get_current_hash() -> AccountHash{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-current-hash"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - super::super::super::miden::base::core_types::AccountHash{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Increment the account nonce by the specified value. - /// value can be at most 2^32 - 1 otherwise this procedure panics - pub fn incr_nonce(value: Felt,){ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::Felt{ inner:inner0, } = value; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "incr-nonce"] - fn wit_import(_: i64, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner0)); - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the value of the specified key in the account storage - pub fn get_item(index: Felt,) -> StorageValue{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let super::super::super::miden::base::core_types::Felt{ inner:inner0, } = index; - let ptr1 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-item"] - fn wit_import(_: i64, _: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i32, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner0), ptr1); - let l2 = *((ptr1 + 0) as *const i64); - let l3 = *((ptr1 + 8) as *const i64); - let l4 = *((ptr1 + 16) as *const i64); - let l5 = *((ptr1 + 24) as *const i64); - super::super::super::miden::base::core_types::StorageValue{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l5 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Set the value of the specified key in the account storage - /// Returns the old value of the key and the new storage root - pub fn set_item(index: Felt,value: StorageValue,) -> (StorageRoot,StorageValue,){ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 64]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let super::super::super::miden::base::core_types::Felt{ inner:inner0, } = index; - let super::super::super::miden::base::core_types::StorageValue{ inner:inner1, } = value; - let (t2_0, t2_1, t2_2, t2_3, ) = inner1; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t2_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t2_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t2_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner6, } = t2_3; - let ptr7 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "set-item"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i32, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner0), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), wit_bindgen::rt::as_i64(inner6), ptr7); - let l8 = *((ptr7 + 0) as *const i64); - let l9 = *((ptr7 + 8) as *const i64); - let l10 = *((ptr7 + 16) as *const i64); - let l11 = *((ptr7 + 24) as *const i64); - let l12 = *((ptr7 + 32) as *const i64); - let l13 = *((ptr7 + 40) as *const i64); - let l14 = *((ptr7 + 48) as *const i64); - let l15 = *((ptr7 + 56) as *const i64); - (super::super::super::miden::base::core_types::StorageRoot{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l8 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l9 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l10 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l11 as u64, - }), - }, super::super::super::miden::base::core_types::StorageValue{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l12 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l13 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l14 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l15 as u64, - }), - }) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Sets the code of the account the transaction is being executed against. - /// This procedure can only be executed on regular accounts with updatable - /// code. Otherwise, this procedure fails. code is the hash of the code - /// to set. - pub fn set_code(code_root: AccountCodeRoot,){ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::AccountCodeRoot{ inner:inner0, } = code_root; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "set-code"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5)); - } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns the balance of a fungible asset associated with a account_id. - /// Panics if the asset is not a fungible asset. account_id is the faucet id - /// of the fungible asset of interest. balance is the vault balance of the - /// fungible asset. - pub fn get_balance(account_id: AccountId,) -> Felt{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::AccountId{ inner:inner0, } = account_id; - let super::super::super::miden::base::core_types::Felt{ inner:inner1, } = inner0; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-balance"] - fn wit_import(_: i64, ) -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, ) -> i64{ unreachable!() } - let ret = wit_import(wit_bindgen::rt::as_i64(inner1)); - super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Returns a boolean indicating whether the non-fungible asset is present - /// in the vault. Panics if the asset is a fungible asset. asset is the - /// non-fungible asset of interest. has_asset is a boolean indicating - /// whether the account vault has the asset of interest. - pub fn has_non_fungible_asset(asset: CoreAsset,) -> bool{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "has-non-fungible-asset"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ) -> i32{ unreachable!() } - let ret = wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5)); - wit_bindgen::rt::bool_lift(ret as u8) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Add the specified asset to the vault. Panics under various conditions. - /// Returns the final asset in the account vault defined as follows: If asset is - /// a non-fungible asset, then returns the same as asset. If asset is a - /// fungible asset, then returns the total fungible asset in the account - /// vault after asset was added to it. - pub fn add_asset(asset: CoreAsset,) -> CoreAsset{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - let ptr6 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "add-asset"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i32, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), ptr6); - let l7 = *((ptr6 + 0) as *const i64); - let l8 = *((ptr6 + 8) as *const i64); - let l9 = *((ptr6 + 16) as *const i64); - let l10 = *((ptr6 + 24) as *const i64); - super::super::super::miden::base::core_types::CoreAsset{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l7 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l8 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l9 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l10 as u64, - }), - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Remove the specified asset from the vault - pub fn remove_asset(asset: CoreAsset,) -> CoreAsset{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - let ptr6 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "remove-asset"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i32, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), ptr6); - let l7 = *((ptr6 + 0) as *const i64); - let l8 = *((ptr6 + 8) as *const i64); - let l9 = *((ptr6 + 16) as *const i64); - let l10 = *((ptr6 + 24) as *const i64); - super::super::super::miden::base::core_types::CoreAsset{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l7 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l8 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l9 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l10 as u64, - }), +} +#[allow(dead_code)] +pub mod exports { + #[allow(dead_code)] + pub mod miden { + #[allow(dead_code)] + pub mod base { + #[allow(dead_code, clippy::all)] + pub mod note_script { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::super::__link_custom_section_describing_imports; + use super::super::super::super::_rt; + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_note_script_cabi() { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + T::note_script(); + } + pub trait Guest { + fn note_script(); + } + #[doc(hidden)] + + macro_rules! __export_miden_base_note_script_1_0_0_cabi{ + ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { + + #[export_name = "miden:base/note-script@1.0.0#note-script"] + unsafe extern "C" fn export_note_script() { + $($path_to_types)*::_export_note_script_cabi::<$ty>() } - } + };); } - #[allow(unused_unsafe, clippy::all)] - /// Returns the commitment to the account vault. - pub fn get_vault_commitment() -> VaultCommitment{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(8))] - struct RetArea([u8; 32]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/account@1.0.0")] - extern "C" { - #[link_name = "get-vault-commitment"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i64); - let l2 = *((ptr0 + 8) as *const i64); - let l3 = *((ptr0 + 16) as *const i64); - let l4 = *((ptr0 + 24) as *const i64); - super::super::super::miden::base::core_types::VaultCommitment{ - inner: (super::super::super::miden::base::core_types::Felt{ - inner: l1 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l2 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l3 as u64, - }, super::super::super::miden::base::core_types::Felt{ - inner: l4 as u64, - }), - } + #[doc(hidden)] + pub(crate) use __export_miden_base_note_script_1_0_0_cabi; + } } - } - } - - - #[allow(clippy::all)] - pub mod note { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; - pub type Felt = super::super::super::miden::base::core_types::Felt; - pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; - pub type AccountId = super::super::super::miden::base::core_types::AccountId; - #[allow(unused_unsafe, clippy::all)] - /// Get the inputs of the currently executed note - pub fn get_inputs() -> wit_bindgen::rt::vec::Vec::{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(4))] - struct RetArea([u8; 8]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/note@1.0.0")] - extern "C" { - #[link_name = "get-inputs"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i32); - let l2 = *((ptr0 + 4) as *const i32); - let len3 = l2 as usize; - Vec::from_raw_parts(l1 as *mut _, len3, len3) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the assets of the currently executing note - pub fn get_assets() -> wit_bindgen::rt::vec::Vec::{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[repr(align(4))] - struct RetArea([u8; 8]); - let mut ret_area = ::core::mem::MaybeUninit::::uninit(); - let ptr0 = ret_area.as_mut_ptr() as i32; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/note@1.0.0")] - extern "C" { - #[link_name = "get-assets"] - fn wit_import(_: i32, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, ){ unreachable!() } - wit_import(ptr0); - let l1 = *((ptr0 + 0) as *const i32); - let l2 = *((ptr0 + 4) as *const i32); - let len3 = l2 as usize; - Vec::from_raw_parts(l1 as *mut _, len3, len3) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the sender of the currently executing note - pub fn get_sender() -> AccountId{ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:base/note@1.0.0")] - extern "C" { - #[link_name = "get-sender"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64{ unreachable!() } - let ret = wit_import(); - super::super::super::miden::base::core_types::AccountId{ - inner: super::super::super::miden::base::core_types::Felt{ - inner: ret as u64, - }, - } +} +mod _rt { + + pub fn as_i64(t: T) -> i64 { + t.as_i64() + } + + pub trait AsI64 { + fn as_i64(self) -> i64; + } + + impl<'a, T: Copy + AsI64> AsI64 for &'a T { + fn as_i64(self) -> i64 { + (*self).as_i64() } - } - } - - } - pub mod basic_wallet { - - #[allow(clippy::all)] - pub mod basic_wallet { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; - pub type CoreAsset = super::super::super::miden::base::core_types::CoreAsset; - pub type Tag = super::super::super::miden::base::core_types::Tag; - pub type Recipient = super::super::super::miden::base::core_types::Recipient; - #[allow(unused_unsafe, clippy::all)] - pub fn receive_asset(core_asset: CoreAsset,){ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = core_asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:basic-wallet/basic-wallet@1.0.0")] - extern "C" { - #[link_name = "receive-asset"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5)); + + impl AsI64 for i64 { + #[inline] + fn as_i64(self) -> i64 { + self as i64 } - } - #[allow(unused_unsafe, clippy::all)] - pub fn send_asset(core_asset: CoreAsset,tag: Tag,recipient: Recipient,){ - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - unsafe { - let super::super::super::miden::base::core_types::CoreAsset{ inner:inner0, } = core_asset; - let (t1_0, t1_1, t1_2, t1_3, ) = inner0; - let super::super::super::miden::base::core_types::Felt{ inner:inner2, } = t1_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner3, } = t1_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner4, } = t1_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner5, } = t1_3; - let super::super::super::miden::base::core_types::Tag{ inner:inner6, } = tag; - let super::super::super::miden::base::core_types::Felt{ inner:inner7, } = inner6; - let super::super::super::miden::base::core_types::Recipient{ inner:inner8, } = recipient; - let (t9_0, t9_1, t9_2, t9_3, ) = inner8; - let super::super::super::miden::base::core_types::Felt{ inner:inner10, } = t9_0; - let super::super::super::miden::base::core_types::Felt{ inner:inner11, } = t9_1; - let super::super::super::miden::base::core_types::Felt{ inner:inner12, } = t9_2; - let super::super::super::miden::base::core_types::Felt{ inner:inner13, } = t9_3; - - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "miden:basic-wallet/basic-wallet@1.0.0")] - extern "C" { - #[link_name = "send-asset"] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, _: i64, ){ unreachable!() } - wit_import(wit_bindgen::rt::as_i64(inner2), wit_bindgen::rt::as_i64(inner3), wit_bindgen::rt::as_i64(inner4), wit_bindgen::rt::as_i64(inner5), wit_bindgen::rt::as_i64(inner7), wit_bindgen::rt::as_i64(inner10), wit_bindgen::rt::as_i64(inner11), wit_bindgen::rt::as_i64(inner12), wit_bindgen::rt::as_i64(inner13)); + } + + impl AsI64 for u64 { + #[inline] + fn as_i64(self) -> i64 { + self as i64 } - } - } - - } -} -pub mod exports { - pub mod miden { - pub mod base { - - #[allow(clippy::all)] - pub mod note_script { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_section; - const _: () = { - - #[doc(hidden)] - #[export_name = "miden:base/note-script@1.0.0#note-script"] - #[allow(non_snake_case)] - unsafe extern "C" fn __export_note_script() { - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - - // Before executing any other code, use this function to run all static - // constructors, if they have not yet been run. This is a hack required - // to work around wasi-libc ctors calling import functions to initialize - // the environment. - // - // This functionality will be removed once rust 1.69.0 is stable, at which - // point wasi-libc will no longer have this behavior. - // - // See - // https://github.com/bytecodealliance/preview2-prototyping/issues/99 - // for more details. - #[cfg(target_arch="wasm32")] - wit_bindgen::rt::run_ctors_once(); - - <_GuestImpl as Guest>::note_script(); - } - }; - use super::super::super::super::super::Component as _GuestImpl; - pub trait Guest { - fn note_script(); + pub unsafe fn bool_lift(val: u8) -> bool { + if cfg!(debug_assertions) { + match val { + 0 => false, + 1 => true, + _ => panic!("invalid bool discriminant"), + } + } else { + val != 0 } - - } - } - } + pub use alloc_crate::vec::Vec; + + #[cfg(target_arch = "wasm32")] + pub fn run_ctors_once() { + wit_bindgen_rt::run_ctors_once(); + } + extern crate alloc as alloc_crate; } +/// Generates `#[no_mangle]` functions to export the specified type as the +/// root implementation of all generated traits. +/// +/// For more information see the documentation of `wit_bindgen::generate!`. +/// +/// ```rust +/// # macro_rules! export{ ($($t:tt)*) => (); } +/// # trait Guest {} +/// struct MyType; +/// +/// impl Guest for MyType { +/// // ... +/// } +/// +/// export!(MyType); +/// ``` +#[allow(unused_macros)] +#[doc(hidden)] + +macro_rules! __export_notes_world_impl { + ($ty:ident) => (self::export!($ty with_types_in self);); + ($ty:ident with_types_in $($path_to_types_root:tt)*) => ( + $($path_to_types_root)*::exports::miden::base::note_script::__export_miden_base_note_script_1_0_0_cabi!($ty with_types_in $($path_to_types_root)*::exports::miden::base::note_script); + ) +} +#[doc(inline)] +pub(crate) use __export_notes_world_impl as export; + #[cfg(target_arch = "wasm32")] -#[link_section = "component-type:notes-world"] +#[link_section = "component-type:wit-bindgen:0.25.0:notes-world:encoded world"] #[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 2438] = [3, 0, 11, 110, 111, 116, 101, 115, 45, 119, 111, 114, 108, 100, 0, 97, 115, 109, 13, 0, 1, 0, 7, 128, 18, 1, 65, 2, 1, 65, 26, 1, 66, 30, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 1, 64, 1, 4, 102, 101, 108, 116, 1, 0, 5, 4, 0, 20, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 45, 102, 114, 111, 109, 45, 102, 101, 108, 116, 1, 28, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 2, 3, 0, 0, 3, 116, 97, 103, 2, 3, 0, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 5, 110, 111, 110, 99, 101, 2, 3, 0, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 2, 3, 0, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 2, 3, 0, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 2, 3, 0, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 2, 3, 0, 0, 4, 119, 111, 114, 100, 2, 3, 0, 0, 7, 110, 111, 116, 101, 45, 105, 100, 1, 66, 37, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 2, 3, 2, 1, 12, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 22, 2, 3, 2, 1, 13, 4, 0, 4, 119, 111, 114, 100, 3, 0, 24, 2, 3, 2, 1, 14, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 1, 64, 0, 0, 1, 4, 0, 16, 103, 101, 116, 45, 98, 108, 111, 99, 107, 45, 110, 117, 109, 98, 101, 114, 1, 28, 1, 64, 0, 0, 23, 4, 0, 14, 103, 101, 116, 45, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 1, 29, 1, 64, 0, 0, 25, 4, 0, 20, 103, 101, 116, 45, 105, 110, 112, 117, 116, 45, 110, 111, 116, 101, 115, 45, 104, 97, 115, 104, 1, 30, 4, 0, 21, 103, 101, 116, 45, 111, 117, 116, 112, 117, 116, 45, 110, 111, 116, 101, 115, 45, 104, 97, 115, 104, 1, 30, 1, 64, 3, 5, 97, 115, 115, 101, 116, 3, 3, 116, 97, 103, 5, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 7, 0, 27, 4, 0, 11, 99, 114, 101, 97, 116, 101, 45, 110, 111, 116, 101, 1, 31, 3, 1, 19, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 116, 120, 64, 49, 46, 48, 46, 48, 5, 15, 1, 66, 47, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 1, 64, 0, 0, 9, 4, 0, 6, 103, 101, 116, 45, 105, 100, 1, 22, 1, 64, 0, 0, 11, 4, 0, 9, 103, 101, 116, 45, 110, 111, 110, 99, 101, 1, 23, 1, 64, 0, 0, 13, 4, 0, 16, 103, 101, 116, 45, 105, 110, 105, 116, 105, 97, 108, 45, 104, 97, 115, 104, 1, 24, 4, 0, 16, 103, 101, 116, 45, 99, 117, 114, 114, 101, 110, 116, 45, 104, 97, 115, 104, 1, 24, 1, 64, 1, 5, 118, 97, 108, 117, 101, 1, 1, 0, 4, 0, 10, 105, 110, 99, 114, 45, 110, 111, 110, 99, 101, 1, 25, 1, 64, 1, 5, 105, 110, 100, 101, 120, 1, 0, 15, 4, 0, 8, 103, 101, 116, 45, 105, 116, 101, 109, 1, 26, 1, 111, 2, 17, 15, 1, 64, 2, 5, 105, 110, 100, 101, 120, 1, 5, 118, 97, 108, 117, 101, 15, 0, 27, 4, 0, 8, 115, 101, 116, 45, 105, 116, 101, 109, 1, 28, 1, 64, 1, 9, 99, 111, 100, 101, 45, 114, 111, 111, 116, 19, 1, 0, 4, 0, 8, 115, 101, 116, 45, 99, 111, 100, 101, 1, 29, 1, 64, 1, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 9, 0, 1, 4, 0, 11, 103, 101, 116, 45, 98, 97, 108, 97, 110, 99, 101, 1, 30, 1, 64, 1, 5, 97, 115, 115, 101, 116, 3, 0, 127, 4, 0, 22, 104, 97, 115, 45, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 1, 31, 1, 64, 1, 5, 97, 115, 115, 101, 116, 3, 0, 3, 4, 0, 9, 97, 100, 100, 45, 97, 115, 115, 101, 116, 1, 32, 4, 0, 12, 114, 101, 109, 111, 118, 101, 45, 97, 115, 115, 101, 116, 1, 32, 1, 64, 0, 0, 21, 4, 0, 20, 103, 101, 116, 45, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 1, 33, 3, 1, 24, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 97, 99, 99, 111, 117, 110, 116, 64, 49, 46, 48, 46, 48, 5, 16, 1, 66, 30, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 1, 112, 1, 1, 64, 0, 0, 22, 4, 0, 10, 103, 101, 116, 45, 105, 110, 112, 117, 116, 115, 1, 23, 1, 112, 3, 1, 64, 0, 0, 24, 4, 0, 10, 103, 101, 116, 45, 97, 115, 115, 101, 116, 115, 1, 25, 1, 64, 0, 0, 9, 4, 0, 10, 103, 101, 116, 45, 115, 101, 110, 100, 101, 114, 1, 26, 3, 1, 21, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 110, 111, 116, 101, 64, 49, 46, 48, 46, 48, 5, 17, 1, 66, 10, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 0, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 2, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 4, 1, 64, 1, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 1, 0, 4, 0, 13, 114, 101, 99, 101, 105, 118, 101, 45, 97, 115, 115, 101, 116, 1, 6, 1, 64, 3, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 3, 116, 97, 103, 3, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 5, 1, 0, 4, 0, 10, 115, 101, 110, 100, 45, 97, 115, 115, 101, 116, 1, 7, 3, 1, 37, 109, 105, 100, 101, 110, 58, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 47, 98, 97, 115, 105, 99, 45, 119, 97, 108, 108, 101, 116, 64, 49, 46, 48, 46, 48, 5, 18, 1, 66, 2, 1, 64, 0, 1, 0, 4, 0, 11, 110, 111, 116, 101, 45, 115, 99, 114, 105, 112, 116, 1, 0, 4, 1, 28, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 110, 111, 116, 101, 45, 115, 99, 114, 105, 112, 116, 64, 49, 46, 48, 46, 48, 5, 19, 4, 1, 28, 109, 105, 100, 101, 110, 58, 112, 50, 105, 100, 47, 110, 111, 116, 101, 115, 45, 119, 111, 114, 108, 100, 64, 49, 46, 48, 46, 48, 4, 0, 11, 17, 1, 0, 11, 110, 111, 116, 101, 115, 45, 119, 111, 114, 108, 100, 3, 0, 0, 0, 16, 12, 112, 97, 99, 107, 97, 103, 101, 45, 100, 111, 99, 115, 0, 123, 125, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 49, 56, 46, 50, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 54, 46, 48]; +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 2434] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\x80\x12\x01A\x02\x01\ +A\x1a\x01B\x1e\x01r\x01\x05innerw\x04\0\x04felt\x03\0\0\x01o\x04\x01\x01\x01\x01\ +\x04\0\x04word\x03\0\x02\x01r\x01\x05inner\x01\x04\0\x0aaccount-id\x03\0\x04\x01\ +r\x01\x05inner\x03\x04\0\x09recipient\x03\0\x06\x01r\x01\x05inner\x01\x04\0\x03t\ +ag\x03\0\x08\x01r\x01\x05inner\x03\x04\0\x0acore-asset\x03\0\x0a\x01r\x01\x05inn\ +er\x01\x04\0\x05nonce\x03\0\x0c\x01r\x01\x05inner\x03\x04\0\x0caccount-hash\x03\0\ +\x0e\x01r\x01\x05inner\x03\x04\0\x0ablock-hash\x03\0\x10\x01r\x01\x05inner\x03\x04\ +\0\x0dstorage-value\x03\0\x12\x01r\x01\x05inner\x03\x04\0\x0cstorage-root\x03\0\x14\ +\x01r\x01\x05inner\x03\x04\0\x11account-code-root\x03\0\x16\x01r\x01\x05inner\x03\ +\x04\0\x10vault-commitment\x03\0\x18\x01r\x01\x05inner\x01\x04\0\x07note-id\x03\0\ +\x1a\x01@\x01\x04felt\x01\0\x05\x04\0\x14account-id-from-felt\x01\x1c\x03\x01\x1b\ +miden:base/core-types@1.0.0\x05\0\x02\x03\0\0\x04felt\x02\x03\0\0\x0acore-asset\x02\ +\x03\0\0\x03tag\x02\x03\0\0\x09recipient\x02\x03\0\0\x0aaccount-id\x02\x03\0\0\x05\ +nonce\x02\x03\0\0\x0caccount-hash\x02\x03\0\0\x0dstorage-value\x02\x03\0\0\x0cst\ +orage-root\x02\x03\0\0\x11account-code-root\x02\x03\0\0\x10vault-commitment\x02\x03\ +\0\0\x0ablock-hash\x02\x03\0\0\x04word\x02\x03\0\0\x07note-id\x01B%\x02\x03\x02\x01\ +\x01\x04\0\x04felt\x03\0\0\x02\x03\x02\x01\x02\x04\0\x0acore-asset\x03\0\x02\x02\ +\x03\x02\x01\x03\x04\0\x03tag\x03\0\x04\x02\x03\x02\x01\x04\x04\0\x09recipient\x03\ +\0\x06\x02\x03\x02\x01\x05\x04\0\x0aaccount-id\x03\0\x08\x02\x03\x02\x01\x06\x04\ +\0\x05nonce\x03\0\x0a\x02\x03\x02\x01\x07\x04\0\x0caccount-hash\x03\0\x0c\x02\x03\ +\x02\x01\x08\x04\0\x0dstorage-value\x03\0\x0e\x02\x03\x02\x01\x09\x04\0\x0cstora\ +ge-root\x03\0\x10\x02\x03\x02\x01\x0a\x04\0\x11account-code-root\x03\0\x12\x02\x03\ +\x02\x01\x0b\x04\0\x10vault-commitment\x03\0\x14\x02\x03\x02\x01\x0c\x04\0\x0abl\ +ock-hash\x03\0\x16\x02\x03\x02\x01\x0d\x04\0\x04word\x03\0\x18\x02\x03\x02\x01\x0e\ +\x04\0\x07note-id\x03\0\x1a\x01@\0\0\x01\x04\0\x10get-block-number\x01\x1c\x01@\0\ +\0\x17\x04\0\x0eget-block-hash\x01\x1d\x01@\0\0\x19\x04\0\x14get-input-notes-has\ +h\x01\x1e\x04\0\x15get-output-notes-hash\x01\x1e\x01@\x03\x05asset\x03\x03tag\x05\ +\x09recipient\x07\0\x1b\x04\0\x0bcreate-note\x01\x1f\x03\x01\x13miden:base/tx@1.\ +0.0\x05\x0f\x01B/\x02\x03\x02\x01\x01\x04\0\x04felt\x03\0\0\x02\x03\x02\x01\x02\x04\ +\0\x0acore-asset\x03\0\x02\x02\x03\x02\x01\x03\x04\0\x03tag\x03\0\x04\x02\x03\x02\ +\x01\x04\x04\0\x09recipient\x03\0\x06\x02\x03\x02\x01\x05\x04\0\x0aaccount-id\x03\ +\0\x08\x02\x03\x02\x01\x06\x04\0\x05nonce\x03\0\x0a\x02\x03\x02\x01\x07\x04\0\x0c\ +account-hash\x03\0\x0c\x02\x03\x02\x01\x08\x04\0\x0dstorage-value\x03\0\x0e\x02\x03\ +\x02\x01\x09\x04\0\x0cstorage-root\x03\0\x10\x02\x03\x02\x01\x0a\x04\0\x11accoun\ +t-code-root\x03\0\x12\x02\x03\x02\x01\x0b\x04\0\x10vault-commitment\x03\0\x14\x01\ +@\0\0\x09\x04\0\x06get-id\x01\x16\x01@\0\0\x0b\x04\0\x09get-nonce\x01\x17\x01@\0\ +\0\x0d\x04\0\x10get-initial-hash\x01\x18\x04\0\x10get-current-hash\x01\x18\x01@\x01\ +\x05value\x01\x01\0\x04\0\x0aincr-nonce\x01\x19\x01@\x01\x05index\x01\0\x0f\x04\0\ +\x08get-item\x01\x1a\x01o\x02\x11\x0f\x01@\x02\x05index\x01\x05value\x0f\0\x1b\x04\ +\0\x08set-item\x01\x1c\x01@\x01\x09code-root\x13\x01\0\x04\0\x08set-code\x01\x1d\ +\x01@\x01\x0aaccount-id\x09\0\x01\x04\0\x0bget-balance\x01\x1e\x01@\x01\x05asset\ +\x03\0\x7f\x04\0\x16has-non-fungible-asset\x01\x1f\x01@\x01\x05asset\x03\0\x03\x04\ +\0\x09add-asset\x01\x20\x04\0\x0cremove-asset\x01\x20\x01@\0\0\x15\x04\0\x14get-\ +vault-commitment\x01!\x03\x01\x18miden:base/account@1.0.0\x05\x10\x01B\x1e\x02\x03\ +\x02\x01\x01\x04\0\x04felt\x03\0\0\x02\x03\x02\x01\x02\x04\0\x0acore-asset\x03\0\ +\x02\x02\x03\x02\x01\x03\x04\0\x03tag\x03\0\x04\x02\x03\x02\x01\x04\x04\0\x09rec\ +ipient\x03\0\x06\x02\x03\x02\x01\x05\x04\0\x0aaccount-id\x03\0\x08\x02\x03\x02\x01\ +\x06\x04\0\x05nonce\x03\0\x0a\x02\x03\x02\x01\x07\x04\0\x0caccount-hash\x03\0\x0c\ +\x02\x03\x02\x01\x08\x04\0\x0dstorage-value\x03\0\x0e\x02\x03\x02\x01\x09\x04\0\x0c\ +storage-root\x03\0\x10\x02\x03\x02\x01\x0a\x04\0\x11account-code-root\x03\0\x12\x02\ +\x03\x02\x01\x0b\x04\0\x10vault-commitment\x03\0\x14\x01p\x01\x01@\0\0\x16\x04\0\ +\x0aget-inputs\x01\x17\x01p\x03\x01@\0\0\x18\x04\0\x0aget-assets\x01\x19\x01@\0\0\ +\x09\x04\0\x0aget-sender\x01\x1a\x03\x01\x15miden:base/note@1.0.0\x05\x11\x01B\x0a\ +\x02\x03\x02\x01\x02\x04\0\x0acore-asset\x03\0\0\x02\x03\x02\x01\x03\x04\0\x03ta\ +g\x03\0\x02\x02\x03\x02\x01\x04\x04\0\x09recipient\x03\0\x04\x01@\x01\x0acore-as\ +set\x01\x01\0\x04\0\x0dreceive-asset\x01\x06\x01@\x03\x0acore-asset\x01\x03tag\x03\ +\x09recipient\x05\x01\0\x04\0\x0asend-asset\x01\x07\x03\x01%miden:basic-wallet/b\ +asic-wallet@1.0.0\x05\x12\x01B\x02\x01@\0\x01\0\x04\0\x0bnote-script\x01\0\x04\x01\ +\x1cmiden:base/note-script@1.0.0\x05\x13\x04\x01\x1cmiden:p2id/notes-world@1.0.0\ +\x04\0\x0b\x11\x01\0\x0bnotes-world\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\ +\x0dwit-component\x070.208.1\x10wit-bindgen-rust\x060.25.0"; #[inline(never)] #[doc(hidden)] #[cfg(target_arch = "wasm32")] -pub fn __link_section() {} +pub fn __link_custom_section_describing_imports() { + wit_bindgen_rt::maybe_link_cabi_realloc(); +} diff --git a/tests/rust-apps-wasm/wit-sdk/p2id-note/src/lib.rs b/tests/rust-apps-wasm/wit-sdk/p2id-note/src/lib.rs index 328347a7..702a5e80 100644 --- a/tests/rust-apps-wasm/wit-sdk/p2id-note/src/lib.rs +++ b/tests/rust-apps-wasm/wit-sdk/p2id-note/src/lib.rs @@ -8,15 +8,22 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! { loop {} } +bindings::export!(Component with_types_in bindings); + #[allow(dead_code)] mod bindings; -use bindings::miden::base::account::get_id; -use bindings::miden::base::core_types::account_id_from_felt; -use bindings::miden::base::note::{get_assets, get_inputs}; -use bindings::miden::basic_wallet::basic_wallet::receive_asset; - -use bindings::exports::miden::base::note_script::Guest; +use bindings::{ + exports::miden::base::note_script::Guest, + miden::{ + base::{ + account::get_id, + core_types::account_id_from_felt, + note::{get_assets, get_inputs}, + }, + basic_wallet::basic_wallet::receive_asset, + }, +}; pub struct Component; diff --git a/tests/rust-apps-wasm/wit-sdk/sdk/Cargo.lock b/tests/rust-apps-wasm/wit-sdk/sdk/Cargo.lock index d7955e46..02128e97 100644 --- a/tests/rust-apps-wasm/wit-sdk/sdk/Cargo.lock +++ b/tests/rust-apps-wasm/wit-sdk/sdk/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - [[package]] name = "cfg-if" version = "0.1.10" @@ -31,7 +25,7 @@ name = "miden-sdk" version = "0.0.0" dependencies = [ "wee_alloc", - "wit-bindgen", + "wit-bindgen-rt", ] [[package]] @@ -69,10 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "wit-bindgen" -version = "0.17.0" +name = "wit-bindgen-rt" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6237168d93497b26dacdab157b08ad2787d74cdce10f89735f791b2a225eba4d" -dependencies = [ - "bitflags", -] +checksum = "d7a37bd9274cb2d4754b915d624447ec0dce9105d174361841c0826efc79ceb9" diff --git a/tests/rust-apps-wasm/wit-sdk/sdk/Cargo.toml b/tests/rust-apps-wasm/wit-sdk/sdk/Cargo.toml index deb5b17d..7c9b5c2a 100644 --- a/tests/rust-apps-wasm/wit-sdk/sdk/Cargo.toml +++ b/tests/rust-apps-wasm/wit-sdk/sdk/Cargo.toml @@ -12,8 +12,8 @@ publish = false [workspace] [dependencies] -wit-bindgen = { version = "0.17.0", default-features = false, features = ["realloc"] } -wee_alloc = { version = "0.4.5", default-features = false} +wit-bindgen-rt = "0.28" +wee_alloc = { version = "0.4.5", default-features = false } [lib] @@ -25,4 +25,5 @@ package = "component:miden" [package.metadata.component.dependencies] [profile.release] -panic = "abort" \ No newline at end of file +panic = "abort" +debug = true diff --git a/tests/rust-apps-wasm/wit-sdk/sdk/src/bindings.rs b/tests/rust-apps-wasm/wit-sdk/sdk/src/bindings.rs index 839d9644..e5a194d1 100644 --- a/tests/rust-apps-wasm/wit-sdk/sdk/src/bindings.rs +++ b/tests/rust-apps-wasm/wit-sdk/sdk/src/bindings.rs @@ -1,358 +1,455 @@ -// Generated by `wit-bindgen` 0.16.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.25.0. DO NOT EDIT! +// Options used: +#[allow(dead_code)] pub mod exports { - pub mod miden { - pub mod base { - - #[allow(clippy::all)] - pub mod core_types { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_section; - /// Represents base field element in the field using Montgomery representation. - /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). - /// The backing type is `f64` but the internal values are always integer in the range [0, M). - /// Field modulus M = 2^64 - 2^32 + 1 - #[repr(C)] - #[derive(Clone, Copy)] - pub struct Felt { - /// We plan to use f64 as the backing type for the field element. It has the size that we need and - /// we don't plan to support floating point arithmetic in programs for Miden VM. - /// - /// For now its u64 - pub inner: u64, - } - impl ::core::fmt::Debug for Felt { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Felt").field("inner", &self.inner).finish() - } - } - /// A group of four field elements in the Miden base field. - pub type Word = (Felt,Felt,Felt,Felt,); - /// Unique identifier of an account. - /// - /// Account ID consists of 1 field element (~64 bits). This field element uniquely identifies a - /// single account and also specifies the type of the underlying account. Specifically: - /// - The two most significant bits of the ID specify the type of the account: - /// - 00 - regular account with updatable code. - /// - 01 - regular account with immutable code. - /// - 10 - fungible asset faucet with immutable code. - /// - 11 - non-fungible asset faucet with immutable code. - /// - The third most significant bit of the ID specifies whether the account data is stored on-chain: - /// - 0 - full account data is stored on-chain. - /// - 1 - only the account hash is stored on-chain which serves as a commitment to the account state. - /// As such the three most significant bits fully describes the type of the account. - #[repr(C)] - #[derive(Clone, Copy)] - pub struct AccountId { - pub inner: Felt, - } - impl ::core::fmt::Debug for AccountId { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("AccountId").field("inner", &self.inner).finish() - } - } - /// A fungible or a non-fungible asset. - /// - /// All assets are encoded using a single word (4 elements) such that it is easy to determine the - /// type of an asset both inside and outside Miden VM. Specifically: - /// Element 1 will be: - /// - ZERO for a fungible asset - /// - non-ZERO for a non-fungible asset - /// The most significant bit will be: - /// - ONE for a fungible asset - /// - ZERO for a non-fungible asset - /// - /// The above properties guarantee that there can never be a collision between a fungible and a - /// non-fungible asset. - /// - /// The methodology for constructing fungible and non-fungible assets is described below. - /// - /// # Fungible assets - /// The most significant element of a fungible asset is set to the ID of the faucet which issued - /// the asset. This guarantees the properties described above (the first bit is ONE). - /// - /// The least significant element is set to the amount of the asset. This amount cannot be greater - /// than 2^63 - 1 and thus requires 63-bits to store. - /// - /// Elements 1 and 2 are set to ZERO. - /// - /// It is impossible to find a collision between two fungible assets issued by different faucets as - /// the faucet_id is included in the description of the asset and this is guaranteed to be different - /// for each faucet as per the faucet creation logic. - /// - /// # Non-fungible assets - /// The 4 elements of non-fungible assets are computed as follows: - /// - First the asset data is hashed. This compresses an asset of an arbitrary length to 4 field - /// elements: [d0, d1, d2, d3]. - /// - d1 is then replaced with the faucet_id which issues the asset: [d0, faucet_id, d2, d3]. - /// - Lastly, the most significant bit of d3 is set to ZERO. - /// - /// It is impossible to find a collision between two non-fungible assets issued by different faucets - /// as the faucet_id is included in the description of the non-fungible asset and this is guaranteed - /// to be different as per the faucet creation logic. Collision resistance for non-fungible assets - /// issued by the same faucet is ~2^95. - #[repr(C)] - #[derive(Clone, Copy)] - pub struct CoreAsset { - pub inner: Word, - } - impl ::core::fmt::Debug for CoreAsset { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("CoreAsset").field("inner", &self.inner).finish() - } - } - const _: () = { - - #[doc(hidden)] + #[allow(dead_code)] + pub mod miden { + #[allow(dead_code)] + pub mod base { + #[allow(dead_code, clippy::all)] + pub mod core_types { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::super::__link_custom_section_describing_imports; + use super::super::super::super::_rt; + /// Represents base field element in the field using Montgomery representation. + /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). + /// The backing type is `f64` but the internal values are always integer in the + /// range [0, M). Field modulus M = 2^64 - 2^32 + 1 + #[repr(C)] + #[derive(Clone, Copy)] + pub struct Felt { + /// We plan to use f64 as the backing type for the field element. It has the + /// size that we need and we don't plan to support floating + /// point arithmetic in programs for Miden VM. + /// + /// For now its u64 + pub inner: u64, + } + impl ::core::fmt::Debug for Felt { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Felt").field("inner", &self.inner).finish() + } + } + /// A group of four field elements in the Miden base field. + pub type Word = (Felt, Felt, Felt, Felt); + /// Unique identifier of an account. + /// + /// Account ID consists of 1 field element (~64 bits). This field element uniquely + /// identifies a single account and also specifies the type of the + /// underlying account. Specifically: + /// - The two most significant bits of the ID specify the type of the account: + /// - 00 - regular account with updatable code. + /// - 01 - regular account with immutable code. + /// - 10 - fungible asset faucet with immutable code. + /// - 11 - non-fungible asset faucet with immutable code. + /// - The third most significant bit of the ID specifies whether the account data is + /// stored on-chain: + /// - 0 - full account data is stored on-chain. + /// - 1 - only the account hash is stored on-chain which serves as a commitment to + /// the account state. + /// As such the three most significant bits fully describes the type of the account. + #[repr(C)] + #[derive(Clone, Copy)] + pub struct AccountId { + pub inner: Felt, + } + impl ::core::fmt::Debug for AccountId { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("AccountId").field("inner", &self.inner).finish() + } + } + /// A fungible or a non-fungible asset. + /// + /// All assets are encoded using a single word (4 elements) such that it is easy to + /// determine the type of an asset both inside and outside Miden VM. + /// Specifically: Element 1 will be: + /// - ZERO for a fungible asset + /// - non-ZERO for a non-fungible asset + /// The most significant bit will be: + /// - ONE for a fungible asset + /// - ZERO for a non-fungible asset + /// + /// The above properties guarantee that there can never be a collision between a + /// fungible and a non-fungible asset. + /// + /// The methodology for constructing fungible and non-fungible assets is described + /// below. + /// + /// # Fungible assets + /// The most significant element of a fungible asset is set to the ID of the faucet + /// which issued the asset. This guarantees the properties described + /// above (the first bit is ONE). + /// + /// The least significant element is set to the amount of the asset. This amount + /// cannot be greater than 2^63 - 1 and thus requires 63-bits to + /// store. + /// + /// Elements 1 and 2 are set to ZERO. + /// + /// It is impossible to find a collision between two fungible assets issued by + /// different faucets as the faucet_id is included in the + /// description of the asset and this is guaranteed to be different + /// for each faucet as per the faucet creation logic. + /// + /// # Non-fungible assets + /// The 4 elements of non-fungible assets are computed as follows: + /// - First the asset data is hashed. This compresses an asset of an arbitrary + /// length to 4 field + /// elements: [d0, d1, d2, d3]. + /// - d1 is then replaced with the faucet_id which issues the asset: [d0, faucet_id, + /// d2, d3]. + /// - Lastly, the most significant bit of d3 is set to ZERO. + /// + /// It is impossible to find a collision between two non-fungible assets issued by + /// different faucets as the faucet_id is included in the + /// description of the non-fungible asset and this is guaranteed + /// to be different as per the faucet creation logic. Collision resistance for + /// non-fungible assets issued by the same faucet is ~2^95. + #[repr(C)] + #[derive(Clone, Copy)] + pub struct CoreAsset { + pub inner: Word, + } + impl ::core::fmt::Debug for CoreAsset { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("CoreAsset").field("inner", &self.inner).finish() + } + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_account_id_from_felt_cabi(arg0: i64) -> i64 { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + let result0 = T::account_id_from_felt(Felt { inner: arg0 as u64 }); + let AccountId { inner: inner1 } = result0; + let Felt { inner: inner2 } = inner1; + _rt::as_i64(inner2) + } + pub trait Guest { + /// Creates a new account ID from a field element. + fn account_id_from_felt(felt: Felt) -> AccountId; + } + #[doc(hidden)] + + macro_rules! __export_miden_base_core_types_1_0_0_cabi{ + ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { + #[export_name = "miden:base/core-types@1.0.0#account-id-from-felt"] - #[allow(non_snake_case)] - unsafe extern "C" fn __export_account_id_from_felt(arg0: i64,) -> i64 { - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - - // Before executing any other code, use this function to run all static - // constructors, if they have not yet been run. This is a hack required - // to work around wasi-libc ctors calling import functions to initialize - // the environment. - // - // This functionality will be removed once rust 1.69.0 is stable, at which - // point wasi-libc will no longer have this behavior. - // - // See - // https://github.com/bytecodealliance/preview2-prototyping/issues/99 - // for more details. - #[cfg(target_arch="wasm32")] - wit_bindgen::rt::run_ctors_once(); - - let result0 = <_GuestImpl as Guest>::account_id_from_felt(Felt{ - inner: arg0 as u64, - }); - let AccountId{ inner:inner1, } = result0; - let Felt{ inner:inner2, } = inner1; - wit_bindgen::rt::as_i64(inner2) + unsafe extern "C" fn export_account_id_from_felt(arg0: i64,) -> i64 { + $($path_to_types)*::_export_account_id_from_felt_cabi::<$ty>(arg0) } + };); + } + #[doc(hidden)] + pub(crate) use __export_miden_base_core_types_1_0_0_cabi; + } + + #[allow(dead_code, clippy::all)] + pub mod types { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::super::__link_custom_section_describing_imports; + use super::super::super::super::_rt; + pub type AccountId = + super::super::super::super::exports::miden::base::core_types::AccountId; + pub type Word = super::super::super::super::exports::miden::base::core_types::Word; + pub type CoreAsset = + super::super::super::super::exports::miden::base::core_types::CoreAsset; + /// A fungible asset + #[repr(C)] + #[derive(Clone, Copy)] + pub struct FungibleAsset { + /// Faucet ID of the faucet which issued the asset as well as the asset amount. + pub asset: AccountId, + /// Asset amount is guaranteed to be 2^63 - 1 or smaller. + pub amount: u64, + } + impl ::core::fmt::Debug for FungibleAsset { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("FungibleAsset") + .field("asset", &self.asset) + .field("amount", &self.amount) + .finish() + } + } + /// A commitment to a non-fungible asset. + /// + /// A non-fungible asset consists of 4 field elements which are computed by hashing + /// asset data (which can be of arbitrary length) to produce: [d0, + /// d1, d2, d3]. We then replace d1 with the faucet_id that issued + /// the asset: [d0, faucet_id, d2, d3]. We then set the most significant bit + /// of the most significant element to ZERO. + #[repr(C)] + #[derive(Clone, Copy)] + pub struct NonFungibleAsset { + pub inner: Word, + } + impl ::core::fmt::Debug for NonFungibleAsset { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("NonFungibleAsset").field("inner", &self.inner).finish() + } + } + /// A fungible or a non-fungible asset. + #[derive(Clone, Copy)] + pub enum Asset { + Fungible(FungibleAsset), + NonFungible(NonFungibleAsset), + } + impl ::core::fmt::Debug for Asset { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + Asset::Fungible(e) => { + f.debug_tuple("Asset::Fungible").field(e).finish() + } + Asset::NonFungible(e) => { + f.debug_tuple("Asset::NonFungible").field(e).finish() + } + } + } + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_from_core_asset_cabi( + arg0: i64, + arg1: i64, + arg2: i64, + arg3: i64, + ) -> *mut u8 { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + let result0 = T::from_core_asset(super::super::super::super::exports::miden::base::core_types::CoreAsset{ + inner: (super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg0 as u64, + }, super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg1 as u64, + }, super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg2 as u64, + }, super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg3 as u64, + }), + }); + let ptr1 = _RET_AREA.0.as_mut_ptr().cast::(); + match result0 { + Asset::Fungible(e) => { + *ptr1.add(0).cast::() = (0i32) as u8; + let FungibleAsset { + asset: asset2, + amount: amount2, + } = e; + let super::super::super::super::exports::miden::base::core_types::AccountId{ inner:inner3, } = asset2; + let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner4, } = inner3; + *ptr1.add(8).cast::() = _rt::as_i64(inner4); + *ptr1.add(16).cast::() = _rt::as_i64(amount2); + } + Asset::NonFungible(e) => { + *ptr1.add(0).cast::() = (1i32) as u8; + let NonFungibleAsset { inner: inner5 } = e; + let (t6_0, t6_1, t6_2, t6_3) = inner5; + let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner7, } = t6_0; + *ptr1.add(8).cast::() = _rt::as_i64(inner7); + let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner8, } = t6_1; + *ptr1.add(16).cast::() = _rt::as_i64(inner8); + let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner9, } = t6_2; + *ptr1.add(24).cast::() = _rt::as_i64(inner9); + let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner10, } = t6_3; + *ptr1.add(32).cast::() = _rt::as_i64(inner10); + } + } + ptr1 + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_to_core_asset_cabi( + arg0: i32, + arg1: i64, + arg2: i64, + arg3: i64, + arg4: i64, + ) -> *mut u8 { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + let v0 = match arg0 { + 0 => { + let e0 = FungibleAsset{ + asset: super::super::super::super::exports::miden::base::core_types::AccountId{ + inner: super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg1 as u64, + }, + }, + amount: arg2 as u64, }; - use super::super::super::super::super::Component as _GuestImpl; - pub trait Guest { - /// Creates a new account ID from a field element. - fn account_id_from_felt(felt: Felt,) -> AccountId; - } - + Asset::Fungible(e0) + } + n => { + debug_assert_eq!(n, 1, "invalid enum discriminant"); + let e0 = NonFungibleAsset{ + inner: (super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg1 as u64, + }, super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg2 as u64, + }, super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg3 as u64, + }, super::super::super::super::exports::miden::base::core_types::Felt{ + inner: arg4 as u64, + }), + }; + Asset::NonFungible(e0) + } + }; + let result1 = T::to_core_asset(v0); + let ptr2 = _RET_AREA.0.as_mut_ptr().cast::(); + let super::super::super::super::exports::miden::base::core_types::CoreAsset { + inner: inner3, + } = result1; + let (t4_0, t4_1, t4_2, t4_3) = inner3; + let super::super::super::super::exports::miden::base::core_types::Felt { + inner: inner5, + } = t4_0; + *ptr2.add(0).cast::() = _rt::as_i64(inner5); + let super::super::super::super::exports::miden::base::core_types::Felt { + inner: inner6, + } = t4_1; + *ptr2.add(8).cast::() = _rt::as_i64(inner6); + let super::super::super::super::exports::miden::base::core_types::Felt { + inner: inner7, + } = t4_2; + *ptr2.add(16).cast::() = _rt::as_i64(inner7); + let super::super::super::super::exports::miden::base::core_types::Felt { + inner: inner8, + } = t4_3; + *ptr2.add(24).cast::() = _rt::as_i64(inner8); + ptr2 + } + pub trait Guest { + /// Converts a core asset to a an asset representation. + fn from_core_asset(core_asset: CoreAsset) -> Asset; + /// Converts an asset to a core asset representation. + fn to_core_asset(asset: Asset) -> CoreAsset; + } + #[doc(hidden)] + + macro_rules! __export_miden_base_types_1_0_0_cabi{ + ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { + + #[export_name = "miden:base/types@1.0.0#from-core-asset"] + unsafe extern "C" fn export_from_core_asset(arg0: i64,arg1: i64,arg2: i64,arg3: i64,) -> *mut u8 { + $($path_to_types)*::_export_from_core_asset_cabi::<$ty>(arg0, arg1, arg2, arg3) } - - - #[allow(clippy::all)] - pub mod types { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_section; - pub type AccountId = super::super::super::super::exports::miden::base::core_types::AccountId; - pub type Word = super::super::super::super::exports::miden::base::core_types::Word; - pub type CoreAsset = super::super::super::super::exports::miden::base::core_types::CoreAsset; - /// A fungible asset - #[repr(C)] - #[derive(Clone, Copy)] - pub struct FungibleAsset { - /// Faucet ID of the faucet which issued the asset as well as the asset amount. - pub asset: AccountId, - /// Asset amount is guaranteed to be 2^63 - 1 or smaller. - pub amount: u64, - } - impl ::core::fmt::Debug for FungibleAsset { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("FungibleAsset").field("asset", &self.asset).field("amount", &self.amount).finish() - } - } - /// A commitment to a non-fungible asset. - /// - /// A non-fungible asset consists of 4 field elements which are computed by hashing asset data - /// (which can be of arbitrary length) to produce: [d0, d1, d2, d3]. We then replace d1 with the - /// faucet_id that issued the asset: [d0, faucet_id, d2, d3]. We then set the most significant bit - /// of the most significant element to ZERO. - #[repr(C)] - #[derive(Clone, Copy)] - pub struct NonFungibleAsset { - pub inner: Word, - } - impl ::core::fmt::Debug for NonFungibleAsset { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("NonFungibleAsset").field("inner", &self.inner).finish() - } + #[export_name = "miden:base/types@1.0.0#to-core-asset"] + unsafe extern "C" fn export_to_core_asset(arg0: i32,arg1: i64,arg2: i64,arg3: i64,arg4: i64,) -> *mut u8 { + $($path_to_types)*::_export_to_core_asset_cabi::<$ty>(arg0, arg1, arg2, arg3, arg4) + } + };); + } + #[doc(hidden)] + pub(crate) use __export_miden_base_types_1_0_0_cabi; + #[repr(align(8))] + struct _RetArea([::core::mem::MaybeUninit; 40]); + static mut _RET_AREA: _RetArea = _RetArea([::core::mem::MaybeUninit::uninit(); 40]); + } } - /// A fungible or a non-fungible asset. - #[derive(Clone, Copy)] - pub enum Asset{ - Fungible(FungibleAsset), - NonFungible(NonFungibleAsset), + } +} +mod _rt { + + #[cfg(target_arch = "wasm32")] + pub fn run_ctors_once() { + wit_bindgen_rt::run_ctors_once(); + } + + pub fn as_i64(t: T) -> i64 { + t.as_i64() + } + + pub trait AsI64 { + fn as_i64(self) -> i64; + } + + impl<'a, T: Copy + AsI64> AsI64 for &'a T { + fn as_i64(self) -> i64 { + (*self).as_i64() } - impl ::core::fmt::Debug for Asset { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - Asset::Fungible(e) => { - f.debug_tuple("Asset::Fungible").field(e).finish() - } - Asset::NonFungible(e) => { - f.debug_tuple("Asset::NonFungible").field(e).finish() - } - } - } + } + + impl AsI64 for i64 { + #[inline] + fn as_i64(self) -> i64 { + self as i64 } - const _: () = { - - #[doc(hidden)] - #[export_name = "miden:base/types@1.0.0#from-core-asset"] - #[allow(non_snake_case)] - unsafe extern "C" fn __export_from_core_asset(arg0: i64,arg1: i64,arg2: i64,arg3: i64,) -> i32 { - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - - // Before executing any other code, use this function to run all static - // constructors, if they have not yet been run. This is a hack required - // to work around wasi-libc ctors calling import functions to initialize - // the environment. - // - // This functionality will be removed once rust 1.69.0 is stable, at which - // point wasi-libc will no longer have this behavior. - // - // See - // https://github.com/bytecodealliance/preview2-prototyping/issues/99 - // for more details. - #[cfg(target_arch="wasm32")] - wit_bindgen::rt::run_ctors_once(); - - let result0 = <_GuestImpl as Guest>::from_core_asset(super::super::super::super::exports::miden::base::core_types::CoreAsset{ - inner: (super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg0 as u64, - }, super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg1 as u64, - }, super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg2 as u64, - }, super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg3 as u64, - }), - }); - let ptr1 = _RET_AREA.0.as_mut_ptr() as i32; - match result0 { - Asset::Fungible(e) => { - *((ptr1 + 0) as *mut u8) = (0i32) as u8; - let FungibleAsset{ asset:asset2, amount:amount2, } = e; - let super::super::super::super::exports::miden::base::core_types::AccountId{ inner:inner3, } = asset2; - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner4, } = inner3; - *((ptr1 + 8) as *mut i64) = wit_bindgen::rt::as_i64(inner4); - *((ptr1 + 16) as *mut i64) = wit_bindgen::rt::as_i64(amount2); - }, - Asset::NonFungible(e) => { - *((ptr1 + 0) as *mut u8) = (1i32) as u8; - let NonFungibleAsset{ inner:inner5, } = e; - let (t6_0, t6_1, t6_2, t6_3, ) = inner5; - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner7, } = t6_0; - *((ptr1 + 8) as *mut i64) = wit_bindgen::rt::as_i64(inner7); - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner8, } = t6_1; - *((ptr1 + 16) as *mut i64) = wit_bindgen::rt::as_i64(inner8); - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner9, } = t6_2; - *((ptr1 + 24) as *mut i64) = wit_bindgen::rt::as_i64(inner9); - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner10, } = t6_3; - *((ptr1 + 32) as *mut i64) = wit_bindgen::rt::as_i64(inner10); - }, - } - ptr1 - } - }; - const _: () = { - - #[doc(hidden)] - #[export_name = "miden:base/types@1.0.0#to-core-asset"] - #[allow(non_snake_case)] - unsafe extern "C" fn __export_to_core_asset(arg0: i32,arg1: i64,arg2: i64,arg3: i64,arg4: i64,) -> i32 { - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - - // Before executing any other code, use this function to run all static - // constructors, if they have not yet been run. This is a hack required - // to work around wasi-libc ctors calling import functions to initialize - // the environment. - // - // This functionality will be removed once rust 1.69.0 is stable, at which - // point wasi-libc will no longer have this behavior. - // - // See - // https://github.com/bytecodealliance/preview2-prototyping/issues/99 - // for more details. - #[cfg(target_arch="wasm32")] - wit_bindgen::rt::run_ctors_once(); - - let v0 = match arg0 { - 0 => { - let e0 = FungibleAsset{ - asset: super::super::super::super::exports::miden::base::core_types::AccountId{ - inner: super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg1 as u64, - }, - }, - amount: arg2 as u64, - }; - Asset::Fungible(e0) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - let e0 = NonFungibleAsset{ - inner: (super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg1 as u64, - }, super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg2 as u64, - }, super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg3 as u64, - }, super::super::super::super::exports::miden::base::core_types::Felt{ - inner: arg4 as u64, - }), - }; - Asset::NonFungible(e0) - } - }; - let result1 = <_GuestImpl as Guest>::to_core_asset(v0); - let ptr2 = _RET_AREA.0.as_mut_ptr() as i32; - let super::super::super::super::exports::miden::base::core_types::CoreAsset{ inner:inner3, } = result1; - let (t4_0, t4_1, t4_2, t4_3, ) = inner3; - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner5, } = t4_0; - *((ptr2 + 0) as *mut i64) = wit_bindgen::rt::as_i64(inner5); - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner6, } = t4_1; - *((ptr2 + 8) as *mut i64) = wit_bindgen::rt::as_i64(inner6); - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner7, } = t4_2; - *((ptr2 + 16) as *mut i64) = wit_bindgen::rt::as_i64(inner7); - let super::super::super::super::exports::miden::base::core_types::Felt{ inner:inner8, } = t4_3; - *((ptr2 + 24) as *mut i64) = wit_bindgen::rt::as_i64(inner8); - ptr2 - } - }; - use super::super::super::super::super::Component as _GuestImpl; - pub trait Guest { - /// Converts a core asset to a an asset representation. - fn from_core_asset(core_asset: CoreAsset,) -> Asset; - /// Converts an asset to a core asset representation. - fn to_core_asset(asset: Asset,) -> CoreAsset; + } + + impl AsI64 for u64 { + #[inline] + fn as_i64(self) -> i64 { + self as i64 } - - #[allow(unused_imports)] - use wit_bindgen::rt::{alloc, vec::Vec, string::String}; - - #[repr(align(8))] - struct _RetArea([u8; 40]); - static mut _RET_AREA: _RetArea = _RetArea([0; 40]); - - } - } - } } +/// Generates `#[no_mangle]` functions to export the specified type as the +/// root implementation of all generated traits. +/// +/// For more information see the documentation of `wit_bindgen::generate!`. +/// +/// ```rust +/// # macro_rules! export{ ($($t:tt)*) => (); } +/// # trait Guest {} +/// struct MyType; +/// +/// impl Guest for MyType { +/// // ... +/// } +/// +/// export!(MyType); +/// ``` +#[allow(unused_macros)] +#[doc(hidden)] + +macro_rules! __export_base_world_impl { + ($ty:ident) => (self::export!($ty with_types_in self);); + ($ty:ident with_types_in $($path_to_types_root:tt)*) => ( + $($path_to_types_root)*::exports::miden::base::core_types::__export_miden_base_core_types_1_0_0_cabi!($ty with_types_in $($path_to_types_root)*::exports::miden::base::core_types); + $($path_to_types_root)*::exports::miden::base::types::__export_miden_base_types_1_0_0_cabi!($ty with_types_in $($path_to_types_root)*::exports::miden::base::types); + ) +} +#[doc(inline)] +pub(crate) use __export_base_world_impl as export; + #[cfg(target_arch = "wasm32")] -#[link_section = "component-type:base-world"] +#[link_section = "component-type:wit-bindgen:0.25.0:base-world:encoded world"] #[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 16742] = [3, 0, 10, 98, 97, 115, 101, 45, 119, 111, 114, 108, 100, 0, 97, 115, 109, 13, 0, 1, 0, 7, 171, 3, 1, 65, 2, 1, 66, 30, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 1, 64, 1, 4, 102, 101, 108, 116, 1, 0, 5, 4, 0, 20, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 45, 102, 114, 111, 109, 45, 102, 101, 108, 116, 1, 28, 4, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 11, 16, 1, 0, 10, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 3, 0, 0, 7, 142, 9, 1, 65, 15, 1, 66, 28, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 2, 3, 0, 0, 3, 116, 97, 103, 2, 3, 0, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 5, 110, 111, 110, 99, 101, 2, 3, 0, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 2, 3, 0, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 2, 3, 0, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 1, 66, 47, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 1, 64, 0, 0, 9, 4, 0, 6, 103, 101, 116, 45, 105, 100, 1, 22, 1, 64, 0, 0, 11, 4, 0, 9, 103, 101, 116, 45, 110, 111, 110, 99, 101, 1, 23, 1, 64, 0, 0, 13, 4, 0, 16, 103, 101, 116, 45, 105, 110, 105, 116, 105, 97, 108, 45, 104, 97, 115, 104, 1, 24, 4, 0, 16, 103, 101, 116, 45, 99, 117, 114, 114, 101, 110, 116, 45, 104, 97, 115, 104, 1, 24, 1, 64, 1, 5, 118, 97, 108, 117, 101, 1, 1, 0, 4, 0, 10, 105, 110, 99, 114, 45, 110, 111, 110, 99, 101, 1, 25, 1, 64, 1, 5, 105, 110, 100, 101, 120, 1, 0, 15, 4, 0, 8, 103, 101, 116, 45, 105, 116, 101, 109, 1, 26, 1, 111, 2, 17, 15, 1, 64, 2, 5, 105, 110, 100, 101, 120, 1, 5, 118, 97, 108, 117, 101, 15, 0, 27, 4, 0, 8, 115, 101, 116, 45, 105, 116, 101, 109, 1, 28, 1, 64, 1, 9, 99, 111, 100, 101, 45, 114, 111, 111, 116, 19, 1, 0, 4, 0, 8, 115, 101, 116, 45, 99, 111, 100, 101, 1, 29, 1, 64, 1, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 9, 0, 1, 4, 0, 11, 103, 101, 116, 45, 98, 97, 108, 97, 110, 99, 101, 1, 30, 1, 64, 1, 5, 97, 115, 115, 101, 116, 3, 0, 127, 4, 0, 22, 104, 97, 115, 45, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 1, 31, 1, 64, 1, 5, 97, 115, 115, 101, 116, 3, 0, 3, 4, 0, 9, 97, 100, 100, 45, 97, 115, 115, 101, 116, 1, 32, 4, 0, 12, 114, 101, 109, 111, 118, 101, 45, 97, 115, 115, 101, 116, 1, 32, 1, 64, 0, 0, 21, 4, 0, 20, 103, 101, 116, 45, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 1, 33, 4, 1, 24, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 97, 99, 99, 111, 117, 110, 116, 64, 49, 46, 48, 46, 48, 5, 12, 11, 13, 1, 0, 7, 97, 99, 99, 111, 117, 110, 116, 3, 2, 0, 7, 244, 6, 1, 65, 15, 1, 66, 28, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 2, 3, 0, 0, 3, 116, 97, 103, 2, 3, 0, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 5, 110, 111, 110, 99, 101, 2, 3, 0, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 2, 3, 0, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 2, 3, 0, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 1, 66, 30, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 1, 112, 1, 1, 64, 0, 0, 22, 4, 0, 10, 103, 101, 116, 45, 105, 110, 112, 117, 116, 115, 1, 23, 1, 112, 3, 1, 64, 0, 0, 24, 4, 0, 10, 103, 101, 116, 45, 97, 115, 115, 101, 116, 115, 1, 25, 1, 64, 0, 0, 9, 4, 0, 10, 103, 101, 116, 45, 115, 101, 110, 100, 101, 114, 1, 26, 4, 1, 21, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 110, 111, 116, 101, 64, 49, 46, 48, 46, 48, 5, 12, 11, 10, 1, 0, 4, 110, 111, 116, 101, 3, 4, 0, 7, 160, 8, 1, 65, 18, 1, 66, 28, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 2, 3, 0, 0, 3, 116, 97, 103, 2, 3, 0, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 5, 110, 111, 110, 99, 101, 2, 3, 0, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 2, 3, 0, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 2, 3, 0, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 2, 3, 0, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 2, 3, 0, 0, 4, 119, 111, 114, 100, 2, 3, 0, 0, 7, 110, 111, 116, 101, 45, 105, 100, 1, 66, 37, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 2, 3, 2, 1, 12, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 22, 2, 3, 2, 1, 13, 4, 0, 4, 119, 111, 114, 100, 3, 0, 24, 2, 3, 2, 1, 14, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 1, 64, 0, 0, 1, 4, 0, 16, 103, 101, 116, 45, 98, 108, 111, 99, 107, 45, 110, 117, 109, 98, 101, 114, 1, 28, 1, 64, 0, 0, 23, 4, 0, 14, 103, 101, 116, 45, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 1, 29, 1, 64, 0, 0, 25, 4, 0, 20, 103, 101, 116, 45, 105, 110, 112, 117, 116, 45, 110, 111, 116, 101, 115, 45, 104, 97, 115, 104, 1, 30, 4, 0, 21, 103, 101, 116, 45, 111, 117, 116, 112, 117, 116, 45, 110, 111, 116, 101, 115, 45, 104, 97, 115, 104, 1, 30, 1, 64, 3, 5, 97, 115, 115, 101, 116, 3, 3, 116, 97, 103, 5, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 7, 0, 27, 4, 0, 11, 99, 114, 101, 97, 116, 101, 45, 110, 111, 116, 101, 1, 31, 4, 1, 19, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 116, 120, 64, 49, 46, 48, 46, 48, 5, 15, 11, 8, 1, 0, 2, 116, 120, 3, 6, 0, 7, 173, 8, 1, 65, 17, 1, 66, 28, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 2, 3, 0, 0, 3, 116, 97, 103, 2, 3, 0, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 5, 110, 111, 110, 99, 101, 2, 3, 0, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 2, 3, 0, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 2, 3, 0, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 2, 3, 0, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 2, 3, 0, 0, 4, 119, 111, 114, 100, 1, 66, 34, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 2, 3, 2, 1, 12, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 22, 2, 3, 2, 1, 13, 4, 0, 4, 119, 111, 114, 100, 3, 0, 24, 1, 64, 2, 9, 102, 97, 117, 99, 101, 116, 45, 105, 100, 9, 6, 97, 109, 111, 117, 110, 116, 1, 0, 3, 4, 0, 20, 98, 117, 105, 108, 100, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 1, 26, 1, 64, 1, 6, 97, 109, 111, 117, 110, 116, 1, 0, 3, 4, 0, 21, 99, 114, 101, 97, 116, 101, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 1, 27, 1, 64, 2, 9, 102, 97, 117, 99, 101, 116, 45, 105, 100, 9, 9, 100, 97, 116, 97, 45, 104, 97, 115, 104, 25, 0, 3, 4, 0, 24, 98, 117, 105, 108, 100, 45, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 1, 28, 1, 64, 1, 9, 100, 97, 116, 97, 45, 104, 97, 115, 104, 25, 0, 3, 4, 0, 25, 99, 114, 101, 97, 116, 101, 45, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 1, 29, 4, 1, 22, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 97, 115, 115, 101, 116, 64, 49, 46, 48, 46, 48, 5, 14, 11, 11, 1, 0, 5, 97, 115, 115, 101, 116, 3, 8, 0, 7, 170, 7, 1, 65, 17, 1, 66, 28, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 2, 3, 0, 0, 3, 116, 97, 103, 2, 3, 0, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 5, 110, 111, 110, 99, 101, 2, 3, 0, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 2, 3, 0, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 2, 3, 0, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 2, 3, 0, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 2, 3, 0, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 2, 3, 0, 0, 4, 119, 111, 114, 100, 1, 66, 31, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 3, 116, 97, 103, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 2, 3, 2, 1, 5, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 8, 2, 3, 2, 1, 6, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 10, 2, 3, 2, 1, 7, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 12, 2, 3, 2, 1, 8, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 14, 2, 3, 2, 1, 9, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 16, 2, 3, 2, 1, 10, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 18, 2, 3, 2, 1, 11, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 20, 2, 3, 2, 1, 12, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 22, 2, 3, 2, 1, 13, 4, 0, 4, 119, 111, 114, 100, 3, 0, 24, 1, 64, 1, 5, 97, 115, 115, 101, 116, 3, 0, 3, 4, 0, 4, 109, 105, 110, 116, 1, 26, 4, 0, 4, 98, 117, 114, 110, 1, 26, 1, 64, 0, 0, 1, 4, 0, 18, 103, 101, 116, 45, 116, 111, 116, 97, 108, 45, 105, 115, 115, 117, 97, 110, 99, 101, 1, 27, 4, 1, 23, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 102, 97, 117, 99, 101, 116, 64, 49, 46, 48, 46, 48, 5, 14, 11, 12, 1, 0, 6, 102, 97, 117, 99, 101, 116, 3, 10, 0, 7, 210, 5, 1, 65, 8, 1, 66, 28, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 3, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 4, 119, 111, 114, 100, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 66, 18, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 4, 119, 111, 114, 100, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 6, 1, 114, 2, 5, 97, 115, 115, 101, 116, 3, 6, 97, 109, 111, 117, 110, 116, 119, 4, 0, 14, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 5, 4, 0, 18, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 113, 2, 8, 102, 117, 110, 103, 105, 98, 108, 101, 1, 9, 0, 12, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 1, 11, 0, 4, 0, 5, 97, 115, 115, 101, 116, 3, 0, 12, 1, 64, 1, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 7, 0, 13, 4, 0, 15, 102, 114, 111, 109, 45, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 14, 1, 64, 1, 5, 97, 115, 115, 101, 116, 13, 0, 7, 4, 0, 13, 116, 111, 45, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 15, 4, 1, 22, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 5, 11, 11, 1, 0, 5, 116, 121, 112, 101, 115, 3, 12, 0, 7, 60, 1, 65, 2, 1, 66, 2, 1, 64, 0, 1, 0, 4, 0, 11, 110, 111, 116, 101, 45, 115, 99, 114, 105, 112, 116, 1, 0, 4, 1, 28, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 110, 111, 116, 101, 45, 115, 99, 114, 105, 112, 116, 64, 49, 46, 48, 46, 48, 5, 0, 11, 17, 1, 0, 11, 110, 111, 116, 101, 45, 115, 99, 114, 105, 112, 116, 3, 14, 0, 7, 153, 6, 1, 65, 2, 1, 65, 8, 1, 66, 30, 1, 114, 1, 5, 105, 110, 110, 101, 114, 119, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 1, 111, 4, 1, 1, 1, 1, 4, 0, 4, 119, 111, 114, 100, 3, 0, 2, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 4, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 9, 114, 101, 99, 105, 112, 105, 101, 110, 116, 3, 0, 6, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 3, 116, 97, 103, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 5, 110, 111, 110, 99, 101, 3, 0, 12, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 3, 0, 14, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 10, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 3, 0, 16, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 13, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 3, 0, 18, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 12, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 3, 0, 20, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 17, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 3, 0, 22, 1, 114, 1, 5, 105, 110, 110, 101, 114, 3, 4, 0, 16, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 3, 0, 24, 1, 114, 1, 5, 105, 110, 110, 101, 114, 1, 4, 0, 7, 110, 111, 116, 101, 45, 105, 100, 3, 0, 26, 1, 64, 1, 4, 102, 101, 108, 116, 1, 0, 5, 4, 0, 20, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 45, 102, 114, 111, 109, 45, 102, 101, 108, 116, 1, 28, 4, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 0, 2, 3, 0, 0, 4, 102, 101, 108, 116, 2, 3, 0, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 2, 3, 0, 0, 4, 119, 111, 114, 100, 2, 3, 0, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 66, 18, 2, 3, 2, 1, 1, 4, 0, 4, 102, 101, 108, 116, 3, 0, 0, 2, 3, 2, 1, 2, 4, 0, 10, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 3, 0, 2, 2, 3, 2, 1, 3, 4, 0, 4, 119, 111, 114, 100, 3, 0, 4, 2, 3, 2, 1, 4, 4, 0, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 3, 0, 6, 1, 114, 2, 5, 97, 115, 115, 101, 116, 3, 6, 97, 109, 111, 117, 110, 116, 119, 4, 0, 14, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 3, 0, 8, 1, 114, 1, 5, 105, 110, 110, 101, 114, 5, 4, 0, 18, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 3, 0, 10, 1, 113, 2, 8, 102, 117, 110, 103, 105, 98, 108, 101, 1, 9, 0, 12, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 1, 11, 0, 4, 0, 5, 97, 115, 115, 101, 116, 3, 0, 12, 1, 64, 1, 10, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 7, 0, 13, 4, 0, 15, 102, 114, 111, 109, 45, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 14, 1, 64, 1, 5, 97, 115, 115, 101, 116, 13, 0, 7, 4, 0, 13, 116, 111, 45, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 1, 15, 4, 1, 22, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 116, 121, 112, 101, 115, 64, 49, 46, 48, 46, 48, 5, 5, 4, 1, 27, 109, 105, 100, 101, 110, 58, 98, 97, 115, 101, 47, 98, 97, 115, 101, 45, 119, 111, 114, 108, 100, 64, 49, 46, 48, 46, 48, 4, 0, 11, 16, 1, 0, 10, 98, 97, 115, 101, 45, 119, 111, 114, 108, 100, 3, 16, 0, 0, 157, 73, 12, 112, 97, 99, 107, 97, 103, 101, 45, 100, 111, 99, 115, 0, 123, 34, 105, 110, 116, 101, 114, 102, 97, 99, 101, 115, 34, 58, 123, 34, 99, 111, 114, 101, 45, 116, 121, 112, 101, 115, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 84, 121, 112, 101, 115, 32, 116, 111, 32, 98, 101, 32, 117, 115, 101, 100, 32, 105, 110, 32, 116, 120, 45, 107, 101, 114, 110, 101, 108, 32, 105, 110, 116, 101, 114, 102, 97, 99, 101, 34, 44, 34, 102, 117, 110, 99, 115, 34, 58, 123, 34, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 45, 102, 114, 111, 109, 45, 102, 101, 108, 116, 34, 58, 34, 67, 114, 101, 97, 116, 101, 115, 32, 97, 32, 110, 101, 119, 32, 97, 99, 99, 111, 117, 110, 116, 32, 73, 68, 32, 102, 114, 111, 109, 32, 97, 32, 102, 105, 101, 108, 100, 32, 101, 108, 101, 109, 101, 110, 116, 46, 34, 125, 44, 34, 116, 121, 112, 101, 115, 34, 58, 123, 34, 102, 101, 108, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 82, 101, 112, 114, 101, 115, 101, 110, 116, 115, 32, 98, 97, 115, 101, 32, 102, 105, 101, 108, 100, 32, 101, 108, 101, 109, 101, 110, 116, 32, 105, 110, 32, 116, 104, 101, 32, 102, 105, 101, 108, 100, 32, 117, 115, 105, 110, 103, 32, 77, 111, 110, 116, 103, 111, 109, 101, 114, 121, 32, 114, 101, 112, 114, 101, 115, 101, 110, 116, 97, 116, 105, 111, 110, 46, 92, 110, 73, 110, 116, 101, 114, 110, 97, 108, 32, 118, 97, 108, 117, 101, 115, 32, 114, 101, 112, 114, 101, 115, 101, 110, 116, 32, 120, 32, 42, 32, 82, 32, 109, 111, 100, 32, 77, 32, 119, 104, 101, 114, 101, 32, 82, 32, 61, 32, 50, 94, 54, 52, 32, 109, 111, 100, 32, 77, 32, 97, 110, 100, 32, 120, 32, 105, 110, 32, 91, 48, 44, 32, 77, 41, 46, 92, 110, 84, 104, 101, 32, 98, 97, 99, 107, 105, 110, 103, 32, 116, 121, 112, 101, 32, 105, 115, 32, 96, 102, 54, 52, 96, 32, 98, 117, 116, 32, 116, 104, 101, 32, 105, 110, 116, 101, 114, 110, 97, 108, 32, 118, 97, 108, 117, 101, 115, 32, 97, 114, 101, 32, 97, 108, 119, 97, 121, 115, 32, 105, 110, 116, 101, 103, 101, 114, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 91, 48, 44, 32, 77, 41, 46, 92, 110, 70, 105, 101, 108, 100, 32, 109, 111, 100, 117, 108, 117, 115, 32, 77, 32, 61, 32, 50, 94, 54, 52, 32, 45, 32, 50, 94, 51, 50, 32, 43, 32, 49, 34, 44, 34, 105, 116, 101, 109, 115, 34, 58, 123, 34, 105, 110, 110, 101, 114, 34, 58, 34, 87, 101, 32, 112, 108, 97, 110, 32, 116, 111, 32, 117, 115, 101, 32, 102, 54, 52, 32, 97, 115, 32, 116, 104, 101, 32, 98, 97, 99, 107, 105, 110, 103, 32, 116, 121, 112, 101, 32, 102, 111, 114, 32, 116, 104, 101, 32, 102, 105, 101, 108, 100, 32, 101, 108, 101, 109, 101, 110, 116, 46, 32, 73, 116, 32, 104, 97, 115, 32, 116, 104, 101, 32, 115, 105, 122, 101, 32, 116, 104, 97, 116, 32, 119, 101, 32, 110, 101, 101, 100, 32, 97, 110, 100, 92, 110, 119, 101, 32, 100, 111, 110, 39, 116, 32, 112, 108, 97, 110, 32, 116, 111, 32, 115, 117, 112, 112, 111, 114, 116, 32, 102, 108, 111, 97, 116, 105, 110, 103, 32, 112, 111, 105, 110, 116, 32, 97, 114, 105, 116, 104, 109, 101, 116, 105, 99, 32, 105, 110, 32, 112, 114, 111, 103, 114, 97, 109, 115, 32, 102, 111, 114, 32, 77, 105, 100, 101, 110, 32, 86, 77, 46, 92, 110, 92, 110, 70, 111, 114, 32, 110, 111, 119, 32, 105, 116, 115, 32, 117, 54, 52, 34, 125, 125, 44, 34, 119, 111, 114, 100, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 32, 103, 114, 111, 117, 112, 32, 111, 102, 32, 102, 111, 117, 114, 32, 102, 105, 101, 108, 100, 32, 101, 108, 101, 109, 101, 110, 116, 115, 32, 105, 110, 32, 116, 104, 101, 32, 77, 105, 100, 101, 110, 32, 98, 97, 115, 101, 32, 102, 105, 101, 108, 100, 46, 34, 125, 44, 34, 97, 99, 99, 111, 117, 110, 116, 45, 105, 100, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 85, 110, 105, 113, 117, 101, 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 111, 102, 32, 97, 110, 32, 97, 99, 99, 111, 117, 110, 116, 46, 92, 110, 92, 110, 65, 99, 99, 111, 117, 110, 116, 32, 73, 68, 32, 99, 111, 110, 115, 105, 115, 116, 115, 32, 111, 102, 32, 49, 32, 102, 105, 101, 108, 100, 32, 101, 108, 101, 109, 101, 110, 116, 32, 40, 126, 54, 52, 32, 98, 105, 116, 115, 41, 46, 32, 84, 104, 105, 115, 32, 102, 105, 101, 108, 100, 32, 101, 108, 101, 109, 101, 110, 116, 32, 117, 110, 105, 113, 117, 101, 108, 121, 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, 115, 32, 97, 92, 110, 115, 105, 110, 103, 108, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 97, 110, 100, 32, 97, 108, 115, 111, 32, 115, 112, 101, 99, 105, 102, 105, 101, 115, 32, 116, 104, 101, 32, 116, 121, 112, 101, 32, 111, 102, 32, 116, 104, 101, 32, 117, 110, 100, 101, 114, 108, 121, 105, 110, 103, 32, 97, 99, 99, 111, 117, 110, 116, 46, 32, 83, 112, 101, 99, 105, 102, 105, 99, 97, 108, 108, 121, 58, 92, 110, 45, 32, 84, 104, 101, 32, 116, 119, 111, 32, 109, 111, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 98, 105, 116, 115, 32, 111, 102, 32, 116, 104, 101, 32, 73, 68, 32, 115, 112, 101, 99, 105, 102, 121, 32, 116, 104, 101, 32, 116, 121, 112, 101, 32, 111, 102, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 58, 92, 110, 45, 32, 48, 48, 32, 45, 32, 114, 101, 103, 117, 108, 97, 114, 32, 97, 99, 99, 111, 117, 110, 116, 32, 119, 105, 116, 104, 32, 117, 112, 100, 97, 116, 97, 98, 108, 101, 32, 99, 111, 100, 101, 46, 92, 110, 45, 32, 48, 49, 32, 45, 32, 114, 101, 103, 117, 108, 97, 114, 32, 97, 99, 99, 111, 117, 110, 116, 32, 119, 105, 116, 104, 32, 105, 109, 109, 117, 116, 97, 98, 108, 101, 32, 99, 111, 100, 101, 46, 92, 110, 45, 32, 49, 48, 32, 45, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 102, 97, 117, 99, 101, 116, 32, 119, 105, 116, 104, 32, 105, 109, 109, 117, 116, 97, 98, 108, 101, 32, 99, 111, 100, 101, 46, 92, 110, 45, 32, 49, 49, 32, 45, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 102, 97, 117, 99, 101, 116, 32, 119, 105, 116, 104, 32, 105, 109, 109, 117, 116, 97, 98, 108, 101, 32, 99, 111, 100, 101, 46, 92, 110, 45, 32, 84, 104, 101, 32, 116, 104, 105, 114, 100, 32, 109, 111, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 98, 105, 116, 32, 111, 102, 32, 116, 104, 101, 32, 73, 68, 32, 115, 112, 101, 99, 105, 102, 105, 101, 115, 32, 119, 104, 101, 116, 104, 101, 114, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 100, 97, 116, 97, 32, 105, 115, 32, 115, 116, 111, 114, 101, 100, 32, 111, 110, 45, 99, 104, 97, 105, 110, 58, 92, 110, 45, 32, 48, 32, 45, 32, 102, 117, 108, 108, 32, 97, 99, 99, 111, 117, 110, 116, 32, 100, 97, 116, 97, 32, 105, 115, 32, 115, 116, 111, 114, 101, 100, 32, 111, 110, 45, 99, 104, 97, 105, 110, 46, 92, 110, 45, 32, 49, 32, 45, 32, 111, 110, 108, 121, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 104, 97, 115, 104, 32, 105, 115, 32, 115, 116, 111, 114, 101, 100, 32, 111, 110, 45, 99, 104, 97, 105, 110, 32, 119, 104, 105, 99, 104, 32, 115, 101, 114, 118, 101, 115, 32, 97, 115, 32, 97, 32, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 32, 116, 111, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 115, 116, 97, 116, 101, 46, 92, 110, 65, 115, 32, 115, 117, 99, 104, 32, 116, 104, 101, 32, 116, 104, 114, 101, 101, 32, 109, 111, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 98, 105, 116, 115, 32, 102, 117, 108, 108, 121, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 116, 104, 101, 32, 116, 121, 112, 101, 32, 111, 102, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 46, 34, 125, 44, 34, 114, 101, 99, 105, 112, 105, 101, 110, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 82, 101, 99, 105, 112, 105, 101, 110, 116, 32, 111, 102, 32, 116, 104, 101, 32, 110, 111, 116, 101, 44, 32, 105, 46, 101, 46, 44, 32, 104, 97, 115, 104, 40, 104, 97, 115, 104, 40, 104, 97, 115, 104, 40, 115, 101, 114, 105, 97, 108, 95, 110, 117, 109, 44, 32, 91, 48, 59, 32, 52, 93, 41, 44, 32, 110, 111, 116, 101, 95, 115, 99, 114, 105, 112, 116, 95, 104, 97, 115, 104, 41, 44, 32, 105, 110, 112, 117, 116, 95, 104, 97, 115, 104, 41, 34, 125, 44, 34, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 111, 114, 32, 97, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 46, 92, 110, 92, 110, 65, 108, 108, 32, 97, 115, 115, 101, 116, 115, 32, 97, 114, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 117, 115, 105, 110, 103, 32, 97, 32, 115, 105, 110, 103, 108, 101, 32, 119, 111, 114, 100, 32, 40, 52, 32, 101, 108, 101, 109, 101, 110, 116, 115, 41, 32, 115, 117, 99, 104, 32, 116, 104, 97, 116, 32, 105, 116, 32, 105, 115, 32, 101, 97, 115, 121, 32, 116, 111, 32, 100, 101, 116, 101, 114, 109, 105, 110, 101, 32, 116, 104, 101, 92, 110, 116, 121, 112, 101, 32, 111, 102, 32, 97, 110, 32, 97, 115, 115, 101, 116, 32, 98, 111, 116, 104, 32, 105, 110, 115, 105, 100, 101, 32, 97, 110, 100, 32, 111, 117, 116, 115, 105, 100, 101, 32, 77, 105, 100, 101, 110, 32, 86, 77, 46, 32, 83, 112, 101, 99, 105, 102, 105, 99, 97, 108, 108, 121, 58, 92, 110, 69, 108, 101, 109, 101, 110, 116, 32, 49, 32, 119, 105, 108, 108, 32, 98, 101, 58, 92, 110, 45, 32, 90, 69, 82, 79, 32, 102, 111, 114, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 92, 110, 45, 32, 110, 111, 110, 45, 90, 69, 82, 79, 32, 102, 111, 114, 32, 97, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 92, 110, 84, 104, 101, 32, 109, 111, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 98, 105, 116, 32, 119, 105, 108, 108, 32, 98, 101, 58, 92, 110, 45, 32, 79, 78, 69, 32, 102, 111, 114, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 92, 110, 45, 32, 90, 69, 82, 79, 32, 102, 111, 114, 32, 97, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 92, 110, 92, 110, 84, 104, 101, 32, 97, 98, 111, 118, 101, 32, 112, 114, 111, 112, 101, 114, 116, 105, 101, 115, 32, 103, 117, 97, 114, 97, 110, 116, 101, 101, 32, 116, 104, 97, 116, 32, 116, 104, 101, 114, 101, 32, 99, 97, 110, 32, 110, 101, 118, 101, 114, 32, 98, 101, 32, 97, 32, 99, 111, 108, 108, 105, 115, 105, 111, 110, 32, 98, 101, 116, 119, 101, 101, 110, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 110, 100, 32, 97, 92, 110, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 46, 92, 110, 92, 110, 84, 104, 101, 32, 109, 101, 116, 104, 111, 100, 111, 108, 111, 103, 121, 32, 102, 111, 114, 32, 99, 111, 110, 115, 116, 114, 117, 99, 116, 105, 110, 103, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 110, 100, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 115, 32, 105, 115, 32, 100, 101, 115, 99, 114, 105, 98, 101, 100, 32, 98, 101, 108, 111, 119, 46, 92, 110, 92, 110, 35, 32, 70, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 115, 92, 110, 84, 104, 101, 32, 109, 111, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 101, 108, 101, 109, 101, 110, 116, 32, 111, 102, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 105, 115, 32, 115, 101, 116, 32, 116, 111, 32, 116, 104, 101, 32, 73, 68, 32, 111, 102, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 119, 104, 105, 99, 104, 32, 105, 115, 115, 117, 101, 100, 92, 110, 116, 104, 101, 32, 97, 115, 115, 101, 116, 46, 32, 84, 104, 105, 115, 32, 103, 117, 97, 114, 97, 110, 116, 101, 101, 115, 32, 116, 104, 101, 32, 112, 114, 111, 112, 101, 114, 116, 105, 101, 115, 32, 100, 101, 115, 99, 114, 105, 98, 101, 100, 32, 97, 98, 111, 118, 101, 32, 40, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 98, 105, 116, 32, 105, 115, 32, 79, 78, 69, 41, 46, 92, 110, 92, 110, 84, 104, 101, 32, 108, 101, 97, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 101, 108, 101, 109, 101, 110, 116, 32, 105, 115, 32, 115, 101, 116, 32, 116, 111, 32, 116, 104, 101, 32, 97, 109, 111, 117, 110, 116, 32, 111, 102, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 46, 32, 84, 104, 105, 115, 32, 97, 109, 111, 117, 110, 116, 32, 99, 97, 110, 110, 111, 116, 32, 98, 101, 32, 103, 114, 101, 97, 116, 101, 114, 92, 110, 116, 104, 97, 110, 32, 50, 94, 54, 51, 32, 45, 32, 49, 32, 97, 110, 100, 32, 116, 104, 117, 115, 32, 114, 101, 113, 117, 105, 114, 101, 115, 32, 54, 51, 45, 98, 105, 116, 115, 32, 116, 111, 32, 115, 116, 111, 114, 101, 46, 92, 110, 92, 110, 69, 108, 101, 109, 101, 110, 116, 115, 32, 49, 32, 97, 110, 100, 32, 50, 32, 97, 114, 101, 32, 115, 101, 116, 32, 116, 111, 32, 90, 69, 82, 79, 46, 92, 110, 92, 110, 73, 116, 32, 105, 115, 32, 105, 109, 112, 111, 115, 115, 105, 98, 108, 101, 32, 116, 111, 32, 102, 105, 110, 100, 32, 97, 32, 99, 111, 108, 108, 105, 115, 105, 111, 110, 32, 98, 101, 116, 119, 101, 101, 110, 32, 116, 119, 111, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 115, 32, 105, 115, 115, 117, 101, 100, 32, 98, 121, 32, 100, 105, 102, 102, 101, 114, 101, 110, 116, 32, 102, 97, 117, 99, 101, 116, 115, 32, 97, 115, 92, 110, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 95, 105, 100, 32, 105, 115, 32, 105, 110, 99, 108, 117, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 100, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 97, 110, 100, 32, 116, 104, 105, 115, 32, 105, 115, 32, 103, 117, 97, 114, 97, 110, 116, 101, 101, 100, 32, 116, 111, 32, 98, 101, 32, 100, 105, 102, 102, 101, 114, 101, 110, 116, 92, 110, 102, 111, 114, 32, 101, 97, 99, 104, 32, 102, 97, 117, 99, 101, 116, 32, 97, 115, 32, 112, 101, 114, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 99, 114, 101, 97, 116, 105, 111, 110, 32, 108, 111, 103, 105, 99, 46, 92, 110, 92, 110, 35, 32, 78, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 115, 92, 110, 84, 104, 101, 32, 52, 32, 101, 108, 101, 109, 101, 110, 116, 115, 32, 111, 102, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 115, 32, 97, 114, 101, 32, 99, 111, 109, 112, 117, 116, 101, 100, 32, 97, 115, 32, 102, 111, 108, 108, 111, 119, 115, 58, 92, 110, 45, 32, 70, 105, 114, 115, 116, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 100, 97, 116, 97, 32, 105, 115, 32, 104, 97, 115, 104, 101, 100, 46, 32, 84, 104, 105, 115, 32, 99, 111, 109, 112, 114, 101, 115, 115, 101, 115, 32, 97, 110, 32, 97, 115, 115, 101, 116, 32, 111, 102, 32, 97, 110, 32, 97, 114, 98, 105, 116, 114, 97, 114, 121, 32, 108, 101, 110, 103, 116, 104, 32, 116, 111, 32, 52, 32, 102, 105, 101, 108, 100, 92, 110, 101, 108, 101, 109, 101, 110, 116, 115, 58, 32, 91, 100, 48, 44, 32, 100, 49, 44, 32, 100, 50, 44, 32, 100, 51, 93, 46, 92, 110, 45, 32, 100, 49, 32, 105, 115, 32, 116, 104, 101, 110, 32, 114, 101, 112, 108, 97, 99, 101, 100, 32, 119, 105, 116, 104, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 95, 105, 100, 32, 119, 104, 105, 99, 104, 32, 105, 115, 115, 117, 101, 115, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 58, 32, 91, 100, 48, 44, 32, 102, 97, 117, 99, 101, 116, 95, 105, 100, 44, 32, 100, 50, 44, 32, 100, 51, 93, 46, 92, 110, 45, 32, 76, 97, 115, 116, 108, 121, 44, 32, 116, 104, 101, 32, 109, 111, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 98, 105, 116, 32, 111, 102, 32, 100, 51, 32, 105, 115, 32, 115, 101, 116, 32, 116, 111, 32, 90, 69, 82, 79, 46, 92, 110, 92, 110, 73, 116, 32, 105, 115, 32, 105, 109, 112, 111, 115, 115, 105, 98, 108, 101, 32, 116, 111, 32, 102, 105, 110, 100, 32, 97, 32, 99, 111, 108, 108, 105, 115, 105, 111, 110, 32, 98, 101, 116, 119, 101, 101, 110, 32, 116, 119, 111, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 115, 32, 105, 115, 115, 117, 101, 100, 32, 98, 121, 32, 100, 105, 102, 102, 101, 114, 101, 110, 116, 32, 102, 97, 117, 99, 101, 116, 115, 92, 110, 97, 115, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 95, 105, 100, 32, 105, 115, 32, 105, 110, 99, 108, 117, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 100, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 97, 110, 100, 32, 116, 104, 105, 115, 32, 105, 115, 32, 103, 117, 97, 114, 97, 110, 116, 101, 101, 100, 92, 110, 116, 111, 32, 98, 101, 32, 100, 105, 102, 102, 101, 114, 101, 110, 116, 32, 97, 115, 32, 112, 101, 114, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 99, 114, 101, 97, 116, 105, 111, 110, 32, 108, 111, 103, 105, 99, 46, 32, 67, 111, 108, 108, 105, 115, 105, 111, 110, 32, 114, 101, 115, 105, 115, 116, 97, 110, 99, 101, 32, 102, 111, 114, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 115, 92, 110, 105, 115, 115, 117, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 115, 97, 109, 101, 32, 102, 97, 117, 99, 101, 116, 32, 105, 115, 32, 126, 50, 94, 57, 53, 46, 34, 125, 44, 34, 110, 111, 110, 99, 101, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 99, 99, 111, 117, 110, 116, 32, 110, 111, 110, 99, 101, 34, 125, 44, 34, 97, 99, 99, 111, 117, 110, 116, 45, 104, 97, 115, 104, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 99, 99, 111, 117, 110, 116, 32, 104, 97, 115, 104, 34, 125, 44, 34, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 66, 108, 111, 99, 107, 32, 104, 97, 115, 104, 34, 125, 44, 34, 115, 116, 111, 114, 97, 103, 101, 45, 118, 97, 108, 117, 101, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 83, 116, 111, 114, 97, 103, 101, 32, 118, 97, 108, 117, 101, 34, 125, 44, 34, 115, 116, 111, 114, 97, 103, 101, 45, 114, 111, 111, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 99, 99, 111, 117, 110, 116, 32, 115, 116, 111, 114, 97, 103, 101, 32, 114, 111, 111, 116, 34, 125, 44, 34, 97, 99, 99, 111, 117, 110, 116, 45, 99, 111, 100, 101, 45, 114, 111, 111, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 99, 99, 111, 117, 110, 116, 32, 99, 111, 100, 101, 32, 114, 111, 111, 116, 34, 125, 44, 34, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 67, 111, 109, 109, 105, 116, 109, 101, 110, 116, 32, 116, 111, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 118, 97, 117, 108, 116, 34, 125, 44, 34, 110, 111, 116, 101, 45, 105, 100, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 110, 32, 105, 100, 32, 111, 102, 32, 116, 104, 101, 32, 99, 114, 101, 97, 116, 101, 100, 32, 110, 111, 116, 101, 34, 125, 125, 125, 44, 34, 97, 99, 99, 111, 117, 110, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 99, 99, 111, 117, 110, 116, 45, 114, 101, 108, 97, 116, 101, 100, 32, 102, 117, 110, 99, 116, 105, 111, 110, 115, 34, 44, 34, 102, 117, 110, 99, 115, 34, 58, 123, 34, 103, 101, 116, 45, 105, 100, 34, 58, 34, 71, 101, 116, 32, 116, 104, 101, 32, 105, 100, 32, 111, 102, 32, 116, 104, 101, 32, 99, 117, 114, 114, 101, 110, 116, 108, 121, 32, 101, 120, 101, 99, 117, 116, 105, 110, 103, 32, 97, 99, 99, 111, 117, 110, 116, 34, 44, 34, 103, 101, 116, 45, 110, 111, 110, 99, 101, 34, 58, 34, 82, 101, 116, 117, 114, 110, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 110, 111, 110, 99, 101, 34, 44, 34, 103, 101, 116, 45, 105, 110, 105, 116, 105, 97, 108, 45, 104, 97, 115, 104, 34, 58, 34, 71, 101, 116, 32, 116, 104, 101, 32, 105, 110, 105, 116, 105, 97, 108, 32, 104, 97, 115, 104, 32, 111, 102, 32, 116, 104, 101, 32, 99, 117, 114, 114, 101, 110, 116, 108, 121, 32, 101, 120, 101, 99, 117, 116, 105, 110, 103, 32, 97, 99, 99, 111, 117, 110, 116, 34, 44, 34, 103, 101, 116, 45, 99, 117, 114, 114, 101, 110, 116, 45, 104, 97, 115, 104, 34, 58, 34, 71, 101, 116, 32, 116, 104, 101, 32, 99, 117, 114, 114, 101, 110, 116, 32, 104, 97, 115, 104, 32, 111, 102, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 100, 97, 116, 97, 32, 115, 116, 111, 114, 101, 100, 32, 105, 110, 32, 109, 101, 109, 111, 114, 121, 34, 44, 34, 105, 110, 99, 114, 45, 110, 111, 110, 99, 101, 34, 58, 34, 73, 110, 99, 114, 101, 109, 101, 110, 116, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 110, 111, 110, 99, 101, 32, 98, 121, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, 100, 32, 118, 97, 108, 117, 101, 46, 92, 110, 118, 97, 108, 117, 101, 32, 99, 97, 110, 32, 98, 101, 32, 97, 116, 32, 109, 111, 115, 116, 32, 50, 94, 51, 50, 32, 45, 32, 49, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 32, 116, 104, 105, 115, 32, 112, 114, 111, 99, 101, 100, 117, 114, 101, 32, 112, 97, 110, 105, 99, 115, 34, 44, 34, 103, 101, 116, 45, 105, 116, 101, 109, 34, 58, 34, 71, 101, 116, 32, 116, 104, 101, 32, 118, 97, 108, 117, 101, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, 100, 32, 107, 101, 121, 32, 105, 110, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 115, 116, 111, 114, 97, 103, 101, 34, 44, 34, 115, 101, 116, 45, 105, 116, 101, 109, 34, 58, 34, 83, 101, 116, 32, 116, 104, 101, 32, 118, 97, 108, 117, 101, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, 100, 32, 107, 101, 121, 32, 105, 110, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 115, 116, 111, 114, 97, 103, 101, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 111, 108, 100, 32, 118, 97, 108, 117, 101, 32, 111, 102, 32, 116, 104, 101, 32, 107, 101, 121, 32, 97, 110, 100, 32, 116, 104, 101, 32, 110, 101, 119, 32, 115, 116, 111, 114, 97, 103, 101, 32, 114, 111, 111, 116, 34, 44, 34, 115, 101, 116, 45, 99, 111, 100, 101, 34, 58, 34, 83, 101, 116, 115, 32, 116, 104, 101, 32, 99, 111, 100, 101, 32, 111, 102, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 116, 104, 101, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 105, 115, 32, 98, 101, 105, 110, 103, 32, 101, 120, 101, 99, 117, 116, 101, 100, 32, 97, 103, 97, 105, 110, 115, 116, 46, 92, 110, 84, 104, 105, 115, 32, 112, 114, 111, 99, 101, 100, 117, 114, 101, 32, 99, 97, 110, 32, 111, 110, 108, 121, 32, 98, 101, 32, 101, 120, 101, 99, 117, 116, 101, 100, 32, 111, 110, 32, 114, 101, 103, 117, 108, 97, 114, 32, 97, 99, 99, 111, 117, 110, 116, 115, 32, 119, 105, 116, 104, 32, 117, 112, 100, 97, 116, 97, 98, 108, 101, 92, 110, 99, 111, 100, 101, 46, 32, 79, 116, 104, 101, 114, 119, 105, 115, 101, 44, 32, 116, 104, 105, 115, 32, 112, 114, 111, 99, 101, 100, 117, 114, 101, 32, 102, 97, 105, 108, 115, 46, 32, 99, 111, 100, 101, 32, 105, 115, 32, 116, 104, 101, 32, 104, 97, 115, 104, 32, 111, 102, 32, 116, 104, 101, 32, 99, 111, 100, 101, 92, 110, 116, 111, 32, 115, 101, 116, 46, 34, 44, 34, 103, 101, 116, 45, 98, 97, 108, 97, 110, 99, 101, 34, 58, 34, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 98, 97, 108, 97, 110, 99, 101, 32, 111, 102, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 97, 115, 115, 111, 99, 105, 97, 116, 101, 100, 32, 119, 105, 116, 104, 32, 97, 32, 97, 99, 99, 111, 117, 110, 116, 95, 105, 100, 46, 92, 110, 80, 97, 110, 105, 99, 115, 32, 105, 102, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 105, 115, 32, 110, 111, 116, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 46, 32, 97, 99, 99, 111, 117, 110, 116, 95, 105, 100, 32, 105, 115, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 105, 100, 92, 110, 111, 102, 32, 116, 104, 101, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 111, 102, 32, 105, 110, 116, 101, 114, 101, 115, 116, 46, 32, 98, 97, 108, 97, 110, 99, 101, 32, 105, 115, 32, 116, 104, 101, 32, 118, 97, 117, 108, 116, 32, 98, 97, 108, 97, 110, 99, 101, 32, 111, 102, 32, 116, 104, 101, 92, 110, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 46, 34, 44, 34, 104, 97, 115, 45, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 34, 58, 34, 82, 101, 116, 117, 114, 110, 115, 32, 97, 32, 98, 111, 111, 108, 101, 97, 110, 32, 105, 110, 100, 105, 99, 97, 116, 105, 110, 103, 32, 119, 104, 101, 116, 104, 101, 114, 32, 116, 104, 101, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 105, 115, 32, 112, 114, 101, 115, 101, 110, 116, 92, 110, 105, 110, 32, 116, 104, 101, 32, 118, 97, 117, 108, 116, 46, 32, 80, 97, 110, 105, 99, 115, 32, 105, 102, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 105, 115, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 46, 32, 97, 115, 115, 101, 116, 32, 105, 115, 32, 116, 104, 101, 92, 110, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 111, 102, 32, 105, 110, 116, 101, 114, 101, 115, 116, 46, 32, 104, 97, 115, 95, 97, 115, 115, 101, 116, 32, 105, 115, 32, 97, 32, 98, 111, 111, 108, 101, 97, 110, 32, 105, 110, 100, 105, 99, 97, 116, 105, 110, 103, 92, 110, 119, 104, 101, 116, 104, 101, 114, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 118, 97, 117, 108, 116, 32, 104, 97, 115, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 111, 102, 32, 105, 110, 116, 101, 114, 101, 115, 116, 46, 34, 44, 34, 97, 100, 100, 45, 97, 115, 115, 101, 116, 34, 58, 34, 65, 100, 100, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, 100, 32, 97, 115, 115, 101, 116, 32, 116, 111, 32, 116, 104, 101, 32, 118, 97, 117, 108, 116, 46, 32, 80, 97, 110, 105, 99, 115, 32, 117, 110, 100, 101, 114, 32, 118, 97, 114, 105, 111, 117, 115, 32, 99, 111, 110, 100, 105, 116, 105, 111, 110, 115, 46, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 102, 105, 110, 97, 108, 32, 97, 115, 115, 101, 116, 32, 105, 110, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 118, 97, 117, 108, 116, 32, 100, 101, 102, 105, 110, 101, 100, 32, 97, 115, 32, 102, 111, 108, 108, 111, 119, 115, 58, 32, 73, 102, 32, 97, 115, 115, 101, 116, 32, 105, 115, 92, 110, 97, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 44, 32, 116, 104, 101, 110, 32, 114, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 115, 97, 109, 101, 32, 97, 115, 32, 97, 115, 115, 101, 116, 46, 32, 73, 102, 32, 97, 115, 115, 101, 116, 32, 105, 115, 32, 97, 92, 110, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 44, 32, 116, 104, 101, 110, 32, 114, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 116, 111, 116, 97, 108, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 105, 110, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 92, 110, 118, 97, 117, 108, 116, 32, 97, 102, 116, 101, 114, 32, 97, 115, 115, 101, 116, 32, 119, 97, 115, 32, 97, 100, 100, 101, 100, 32, 116, 111, 32, 105, 116, 46, 34, 44, 34, 114, 101, 109, 111, 118, 101, 45, 97, 115, 115, 101, 116, 34, 58, 34, 82, 101, 109, 111, 118, 101, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, 100, 32, 97, 115, 115, 101, 116, 32, 102, 114, 111, 109, 32, 116, 104, 101, 32, 118, 97, 117, 108, 116, 34, 44, 34, 103, 101, 116, 45, 118, 97, 117, 108, 116, 45, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 34, 58, 34, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 32, 116, 111, 32, 116, 104, 101, 32, 97, 99, 99, 111, 117, 110, 116, 32, 118, 97, 117, 108, 116, 46, 34, 125, 125, 44, 34, 110, 111, 116, 101, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 78, 111, 116, 101, 45, 114, 101, 108, 97, 116, 101, 100, 32, 102, 117, 110, 99, 116, 105, 111, 110, 115, 34, 44, 34, 102, 117, 110, 99, 115, 34, 58, 123, 34, 103, 101, 116, 45, 105, 110, 112, 117, 116, 115, 34, 58, 34, 71, 101, 116, 32, 116, 104, 101, 32, 105, 110, 112, 117, 116, 115, 32, 111, 102, 32, 116, 104, 101, 32, 99, 117, 114, 114, 101, 110, 116, 108, 121, 32, 101, 120, 101, 99, 117, 116, 101, 100, 32, 110, 111, 116, 101, 34, 44, 34, 103, 101, 116, 45, 97, 115, 115, 101, 116, 115, 34, 58, 34, 71, 101, 116, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 115, 32, 111, 102, 32, 116, 104, 101, 32, 99, 117, 114, 114, 101, 110, 116, 108, 121, 32, 101, 120, 101, 99, 117, 116, 105, 110, 103, 32, 110, 111, 116, 101, 34, 44, 34, 103, 101, 116, 45, 115, 101, 110, 100, 101, 114, 34, 58, 34, 71, 101, 116, 32, 116, 104, 101, 32, 115, 101, 110, 100, 101, 114, 32, 111, 102, 32, 116, 104, 101, 32, 99, 117, 114, 114, 101, 110, 116, 108, 121, 32, 101, 120, 101, 99, 117, 116, 105, 110, 103, 32, 110, 111, 116, 101, 34, 125, 125, 44, 34, 116, 120, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 45, 114, 101, 108, 97, 116, 101, 100, 32, 102, 117, 110, 99, 116, 105, 111, 110, 115, 34, 44, 34, 102, 117, 110, 99, 115, 34, 58, 123, 34, 103, 101, 116, 45, 98, 108, 111, 99, 107, 45, 110, 117, 109, 98, 101, 114, 34, 58, 34, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 98, 108, 111, 99, 107, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 116, 104, 101, 32, 108, 97, 115, 116, 32, 107, 110, 111, 119, 110, 32, 98, 108, 111, 99, 107, 32, 97, 116, 32, 116, 104, 101, 32, 116, 105, 109, 101, 32, 111, 102, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 101, 120, 101, 99, 117, 116, 105, 111, 110, 46, 34, 44, 34, 103, 101, 116, 45, 98, 108, 111, 99, 107, 45, 104, 97, 115, 104, 34, 58, 34, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 98, 108, 111, 99, 107, 32, 104, 97, 115, 104, 32, 111, 102, 32, 116, 104, 101, 32, 108, 97, 115, 116, 32, 107, 110, 111, 119, 110, 32, 98, 108, 111, 99, 107, 32, 97, 116, 32, 116, 104, 101, 32, 116, 105, 109, 101, 32, 111, 102, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 101, 120, 101, 99, 117, 116, 105, 111, 110, 46, 34, 44, 34, 103, 101, 116, 45, 105, 110, 112, 117, 116, 45, 110, 111, 116, 101, 115, 45, 104, 97, 115, 104, 34, 58, 34, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 105, 110, 112, 117, 116, 32, 110, 111, 116, 101, 115, 32, 104, 97, 115, 104, 46, 32, 84, 104, 105, 115, 32, 105, 115, 32, 99, 111, 109, 112, 117, 116, 101, 100, 32, 97, 115, 32, 97, 32, 115, 101, 113, 117, 101, 110, 116, 105, 97, 108, 32, 104, 97, 115, 104, 32, 111, 102, 92, 110, 40, 110, 117, 108, 108, 105, 102, 105, 101, 114, 44, 32, 115, 99, 114, 105, 112, 116, 95, 114, 111, 111, 116, 41, 32, 116, 117, 112, 108, 101, 115, 32, 111, 118, 101, 114, 32, 97, 108, 108, 32, 105, 110, 112, 117, 116, 32, 110, 111, 116, 101, 115, 46, 34, 44, 34, 103, 101, 116, 45, 111, 117, 116, 112, 117, 116, 45, 110, 111, 116, 101, 115, 45, 104, 97, 115, 104, 34, 58, 34, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 111, 117, 116, 112, 117, 116, 32, 110, 111, 116, 101, 115, 32, 104, 97, 115, 104, 46, 32, 84, 104, 105, 115, 32, 105, 115, 32, 99, 111, 109, 112, 117, 116, 101, 100, 32, 97, 115, 32, 97, 32, 115, 101, 113, 117, 101, 110, 116, 105, 97, 108, 32, 104, 97, 115, 104, 32, 111, 102, 92, 110, 40, 110, 111, 116, 101, 95, 104, 97, 115, 104, 44, 32, 110, 111, 116, 101, 95, 109, 101, 116, 97, 100, 97, 116, 97, 41, 32, 116, 117, 112, 108, 101, 115, 32, 111, 118, 101, 114, 32, 97, 108, 108, 32, 111, 117, 116, 112, 117, 116, 32, 110, 111, 116, 101, 115, 46, 34, 44, 34, 99, 114, 101, 97, 116, 101, 45, 110, 111, 116, 101, 34, 58, 34, 67, 114, 101, 97, 116, 101, 115, 32, 97, 32, 110, 101, 119, 32, 110, 111, 116, 101, 46, 92, 110, 97, 115, 115, 101, 116, 32, 105, 115, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 116, 111, 32, 98, 101, 32, 105, 110, 99, 108, 117, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 110, 111, 116, 101, 46, 92, 110, 116, 97, 103, 32, 105, 115, 32, 116, 104, 101, 32, 116, 97, 103, 32, 116, 111, 32, 98, 101, 32, 105, 110, 99, 108, 117, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 110, 111, 116, 101, 46, 92, 110, 114, 101, 99, 105, 112, 105, 101, 110, 116, 32, 105, 115, 32, 116, 104, 101, 32, 114, 101, 99, 105, 112, 105, 101, 110, 116, 32, 111, 102, 32, 116, 104, 101, 32, 110, 111, 116, 101, 46, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 105, 100, 32, 111, 102, 32, 116, 104, 101, 32, 99, 114, 101, 97, 116, 101, 100, 32, 110, 111, 116, 101, 46, 34, 125, 125, 44, 34, 97, 115, 115, 101, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 115, 115, 101, 116, 45, 114, 101, 108, 97, 116, 101, 100, 32, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 32, 84, 104, 101, 115, 101, 32, 102, 117, 110, 99, 116, 105, 111, 110, 115, 32, 99, 97, 110, 32, 111, 110, 108, 121, 32, 98, 101, 32, 99, 97, 108, 108, 101, 100, 32, 98, 121, 32, 102, 97, 117, 99, 101, 116, 32, 97, 99, 99, 111, 117, 110, 116, 115, 46, 34, 44, 34, 102, 117, 110, 99, 115, 34, 58, 123, 34, 98, 117, 105, 108, 100, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 34, 58, 34, 66, 117, 105, 108, 100, 115, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 102, 111, 114, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, 100, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 102, 97, 117, 99, 101, 116, 32, 97, 110, 100, 32, 97, 109, 111, 117, 110, 116, 46, 92, 110, 102, 97, 117, 99, 101, 116, 95, 105, 100, 32, 105, 115, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 116, 111, 32, 99, 114, 101, 97, 116, 101, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 102, 111, 114, 46, 92, 110, 97, 109, 111, 117, 110, 116, 32, 105, 115, 32, 116, 104, 101, 32, 97, 109, 111, 117, 110, 116, 32, 111, 102, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 116, 111, 32, 99, 114, 101, 97, 116, 101, 46, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 99, 114, 101, 97, 116, 101, 100, 32, 97, 115, 115, 101, 116, 46, 34, 44, 34, 99, 114, 101, 97, 116, 101, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 34, 58, 34, 67, 114, 101, 97, 116, 101, 115, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 102, 111, 114, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 116, 104, 101, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 105, 115, 32, 98, 101, 105, 110, 103, 92, 110, 101, 120, 101, 99, 117, 116, 101, 100, 32, 97, 103, 97, 105, 110, 115, 116, 46, 92, 110, 97, 109, 111, 117, 110, 116, 32, 105, 115, 32, 116, 104, 101, 32, 97, 109, 111, 117, 110, 116, 32, 111, 102, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 116, 111, 32, 99, 114, 101, 97, 116, 101, 46, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 99, 114, 101, 97, 116, 101, 100, 32, 97, 115, 115, 101, 116, 46, 34, 44, 34, 98, 117, 105, 108, 100, 45, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 34, 58, 34, 66, 117, 105, 108, 100, 115, 32, 97, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 102, 111, 114, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, 100, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 102, 97, 117, 99, 101, 116, 32, 97, 110, 100, 92, 110, 100, 97, 116, 97, 45, 104, 97, 115, 104, 46, 92, 110, 102, 97, 117, 99, 101, 116, 95, 105, 100, 32, 105, 115, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 116, 111, 32, 99, 114, 101, 97, 116, 101, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 102, 111, 114, 46, 92, 110, 100, 97, 116, 97, 45, 104, 97, 115, 104, 32, 105, 115, 32, 116, 104, 101, 32, 100, 97, 116, 97, 32, 104, 97, 115, 104, 32, 111, 102, 32, 116, 104, 101, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 116, 111, 32, 98, 117, 105, 108, 100, 46, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 99, 114, 101, 97, 116, 101, 100, 32, 97, 115, 115, 101, 116, 46, 34, 44, 34, 99, 114, 101, 97, 116, 101, 45, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 34, 58, 34, 67, 114, 101, 97, 116, 101, 115, 32, 97, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 102, 111, 114, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 116, 104, 101, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 105, 115, 32, 98, 101, 105, 110, 103, 32, 101, 120, 101, 99, 117, 116, 101, 100, 32, 97, 103, 97, 105, 110, 115, 116, 46, 92, 110, 100, 97, 116, 97, 45, 104, 97, 115, 104, 32, 105, 115, 32, 116, 104, 101, 32, 100, 97, 116, 97, 32, 104, 97, 115, 104, 32, 111, 102, 32, 116, 104, 101, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 116, 111, 32, 99, 114, 101, 97, 116, 101, 46, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 99, 114, 101, 97, 116, 101, 100, 32, 97, 115, 115, 101, 116, 46, 34, 125, 125, 44, 34, 102, 97, 117, 99, 101, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 70, 97, 117, 99, 101, 116, 45, 114, 101, 108, 97, 116, 101, 100, 32, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 32, 84, 104, 101, 115, 101, 32, 102, 117, 110, 99, 116, 105, 111, 110, 115, 32, 99, 97, 110, 32, 111, 110, 108, 121, 32, 98, 101, 32, 99, 97, 108, 108, 101, 100, 32, 98, 121, 32, 102, 97, 117, 99, 101, 116, 32, 97, 99, 99, 111, 117, 110, 116, 115, 46, 34, 44, 34, 102, 117, 110, 99, 115, 34, 58, 123, 34, 109, 105, 110, 116, 34, 58, 34, 77, 105, 110, 116, 32, 97, 110, 32, 97, 115, 115, 101, 116, 32, 102, 114, 111, 109, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 105, 115, 32, 98, 101, 105, 110, 103, 32, 101, 120, 101, 99, 117, 116, 101, 100, 32, 97, 103, 97, 105, 110, 115, 116, 46, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 109, 105, 110, 116, 101, 100, 32, 97, 115, 115, 101, 116, 46, 34, 44, 34, 98, 117, 114, 110, 34, 58, 34, 66, 117, 114, 110, 32, 97, 110, 32, 97, 115, 115, 101, 116, 32, 102, 114, 111, 109, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 105, 115, 32, 98, 101, 105, 110, 103, 32, 101, 120, 101, 99, 117, 116, 101, 100, 32, 97, 103, 97, 105, 110, 115, 116, 46, 92, 110, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 98, 117, 114, 110, 101, 100, 32, 97, 115, 115, 101, 116, 46, 34, 44, 34, 103, 101, 116, 45, 116, 111, 116, 97, 108, 45, 105, 115, 115, 117, 97, 110, 99, 101, 34, 58, 34, 82, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 116, 111, 116, 97, 108, 32, 105, 115, 115, 117, 97, 110, 99, 101, 32, 111, 102, 32, 116, 104, 101, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 102, 97, 117, 99, 101, 116, 32, 116, 104, 101, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 105, 115, 92, 110, 98, 101, 105, 110, 103, 32, 101, 120, 101, 99, 117, 116, 101, 100, 32, 97, 103, 97, 105, 110, 115, 116, 46, 32, 80, 97, 110, 105, 99, 115, 32, 105, 102, 32, 116, 104, 101, 32, 116, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 105, 115, 32, 110, 111, 116, 32, 98, 101, 105, 110, 103, 32, 101, 120, 101, 99, 117, 116, 101, 100, 92, 110, 97, 103, 97, 105, 110, 115, 116, 32, 97, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 102, 97, 117, 99, 101, 116, 46, 34, 125, 125, 44, 34, 116, 121, 112, 101, 115, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 72, 105, 103, 104, 45, 108, 101, 118, 101, 108, 32, 114, 101, 112, 114, 101, 115, 101, 110, 116, 97, 116, 105, 111, 110, 32, 111, 102, 32, 99, 111, 114, 101, 32, 116, 121, 112, 101, 115, 34, 44, 34, 102, 117, 110, 99, 115, 34, 58, 123, 34, 102, 114, 111, 109, 45, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 34, 58, 34, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 114, 101, 32, 97, 115, 115, 101, 116, 32, 116, 111, 32, 97, 32, 97, 110, 32, 97, 115, 115, 101, 116, 32, 114, 101, 112, 114, 101, 115, 101, 110, 116, 97, 116, 105, 111, 110, 46, 34, 44, 34, 116, 111, 45, 99, 111, 114, 101, 45, 97, 115, 115, 101, 116, 34, 58, 34, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 97, 115, 115, 101, 116, 32, 116, 111, 32, 97, 32, 99, 111, 114, 101, 32, 97, 115, 115, 101, 116, 32, 114, 101, 112, 114, 101, 115, 101, 110, 116, 97, 116, 105, 111, 110, 46, 34, 125, 44, 34, 116, 121, 112, 101, 115, 34, 58, 123, 34, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 34, 44, 34, 105, 116, 101, 109, 115, 34, 58, 123, 34, 97, 115, 115, 101, 116, 34, 58, 34, 70, 97, 117, 99, 101, 116, 32, 73, 68, 32, 111, 102, 32, 116, 104, 101, 32, 102, 97, 117, 99, 101, 116, 32, 119, 104, 105, 99, 104, 32, 105, 115, 115, 117, 101, 100, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 97, 115, 32, 119, 101, 108, 108, 32, 97, 115, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 32, 97, 109, 111, 117, 110, 116, 46, 34, 44, 34, 97, 109, 111, 117, 110, 116, 34, 58, 34, 65, 115, 115, 101, 116, 32, 97, 109, 111, 117, 110, 116, 32, 105, 115, 32, 103, 117, 97, 114, 97, 110, 116, 101, 101, 100, 32, 116, 111, 32, 98, 101, 32, 50, 94, 54, 51, 32, 45, 32, 49, 32, 111, 114, 32, 115, 109, 97, 108, 108, 101, 114, 46, 34, 125, 125, 44, 34, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 45, 97, 115, 115, 101, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 32, 99, 111, 109, 109, 105, 116, 109, 101, 110, 116, 32, 116, 111, 32, 97, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 46, 92, 110, 92, 110, 65, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 99, 111, 110, 115, 105, 115, 116, 115, 32, 111, 102, 32, 52, 32, 102, 105, 101, 108, 100, 32, 101, 108, 101, 109, 101, 110, 116, 115, 32, 119, 104, 105, 99, 104, 32, 97, 114, 101, 32, 99, 111, 109, 112, 117, 116, 101, 100, 32, 98, 121, 32, 104, 97, 115, 104, 105, 110, 103, 32, 97, 115, 115, 101, 116, 32, 100, 97, 116, 97, 92, 110, 40, 119, 104, 105, 99, 104, 32, 99, 97, 110, 32, 98, 101, 32, 111, 102, 32, 97, 114, 98, 105, 116, 114, 97, 114, 121, 32, 108, 101, 110, 103, 116, 104, 41, 32, 116, 111, 32, 112, 114, 111, 100, 117, 99, 101, 58, 32, 91, 100, 48, 44, 32, 100, 49, 44, 32, 100, 50, 44, 32, 100, 51, 93, 46, 32, 32, 87, 101, 32, 116, 104, 101, 110, 32, 114, 101, 112, 108, 97, 99, 101, 32, 100, 49, 32, 119, 105, 116, 104, 32, 116, 104, 101, 92, 110, 102, 97, 117, 99, 101, 116, 95, 105, 100, 32, 116, 104, 97, 116, 32, 105, 115, 115, 117, 101, 100, 32, 116, 104, 101, 32, 97, 115, 115, 101, 116, 58, 32, 91, 100, 48, 44, 32, 102, 97, 117, 99, 101, 116, 95, 105, 100, 44, 32, 100, 50, 44, 32, 100, 51, 93, 46, 32, 87, 101, 32, 116, 104, 101, 110, 32, 115, 101, 116, 32, 116, 104, 101, 32, 109, 111, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 98, 105, 116, 92, 110, 111, 102, 32, 116, 104, 101, 32, 109, 111, 115, 116, 32, 115, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 32, 101, 108, 101, 109, 101, 110, 116, 32, 116, 111, 32, 90, 69, 82, 79, 46, 34, 125, 44, 34, 97, 115, 115, 101, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 65, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 111, 114, 32, 97, 32, 110, 111, 110, 45, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 46, 34, 125, 125, 125, 44, 34, 110, 111, 116, 101, 45, 115, 99, 114, 105, 112, 116, 34, 58, 123, 34, 100, 111, 99, 115, 34, 58, 34, 78, 111, 116, 101, 32, 115, 99, 114, 105, 112, 116, 32, 105, 110, 116, 101, 114, 102, 97, 99, 101, 32, 116, 104, 97, 116, 32, 105, 115, 32, 101, 120, 112, 101, 99, 116, 101, 100, 32, 116, 111, 32, 98, 101, 32, 105, 109, 112, 108, 101, 109, 101, 110, 116, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 110, 111, 116, 101, 32, 115, 99, 114, 105, 112, 116, 46, 34, 125, 125, 125, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 49, 56, 46, 50, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 54, 46, 48]; +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 922] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\x99\x06\x01A\x02\x01\ +A\x08\x01B\x1e\x01r\x01\x05innerw\x04\0\x04felt\x03\0\0\x01o\x04\x01\x01\x01\x01\ +\x04\0\x04word\x03\0\x02\x01r\x01\x05inner\x01\x04\0\x0aaccount-id\x03\0\x04\x01\ +r\x01\x05inner\x03\x04\0\x09recipient\x03\0\x06\x01r\x01\x05inner\x01\x04\0\x03t\ +ag\x03\0\x08\x01r\x01\x05inner\x03\x04\0\x0acore-asset\x03\0\x0a\x01r\x01\x05inn\ +er\x01\x04\0\x05nonce\x03\0\x0c\x01r\x01\x05inner\x03\x04\0\x0caccount-hash\x03\0\ +\x0e\x01r\x01\x05inner\x03\x04\0\x0ablock-hash\x03\0\x10\x01r\x01\x05inner\x03\x04\ +\0\x0dstorage-value\x03\0\x12\x01r\x01\x05inner\x03\x04\0\x0cstorage-root\x03\0\x14\ +\x01r\x01\x05inner\x03\x04\0\x11account-code-root\x03\0\x16\x01r\x01\x05inner\x03\ +\x04\0\x10vault-commitment\x03\0\x18\x01r\x01\x05inner\x01\x04\0\x07note-id\x03\0\ +\x1a\x01@\x01\x04felt\x01\0\x05\x04\0\x14account-id-from-felt\x01\x1c\x04\x01\x1b\ +miden:base/core-types@1.0.0\x05\0\x02\x03\0\0\x04felt\x02\x03\0\0\x0aaccount-id\x02\ +\x03\0\0\x04word\x02\x03\0\0\x0acore-asset\x01B\x12\x02\x03\x02\x01\x01\x04\0\x04\ +felt\x03\0\0\x02\x03\x02\x01\x02\x04\0\x0aaccount-id\x03\0\x02\x02\x03\x02\x01\x03\ +\x04\0\x04word\x03\0\x04\x02\x03\x02\x01\x04\x04\0\x0acore-asset\x03\0\x06\x01r\x02\ +\x05asset\x03\x06amountw\x04\0\x0efungible-asset\x03\0\x08\x01r\x01\x05inner\x05\ +\x04\0\x12non-fungible-asset\x03\0\x0a\x01q\x02\x08fungible\x01\x09\0\x0cnon-fun\ +gible\x01\x0b\0\x04\0\x05asset\x03\0\x0c\x01@\x01\x0acore-asset\x07\0\x0d\x04\0\x0f\ +from-core-asset\x01\x0e\x01@\x01\x05asset\x0d\0\x07\x04\0\x0dto-core-asset\x01\x0f\ +\x04\x01\x16miden:base/types@1.0.0\x05\x05\x04\x01\x1bmiden:base/base-world@1.0.\ +0\x04\0\x0b\x10\x01\0\x0abase-world\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\ +\x0dwit-component\x070.208.1\x10wit-bindgen-rust\x060.25.0"; #[inline(never)] #[doc(hidden)] #[cfg(target_arch = "wasm32")] -pub fn __link_section() {} +pub fn __link_custom_section_describing_imports() { + wit_bindgen_rt::maybe_link_cabi_realloc(); +} diff --git a/tests/rust-apps-wasm/wit-sdk/sdk/src/lib.rs b/tests/rust-apps-wasm/wit-sdk/sdk/src/lib.rs index cd520ed5..d13032ba 100644 --- a/tests/rust-apps-wasm/wit-sdk/sdk/src/lib.rs +++ b/tests/rust-apps-wasm/wit-sdk/sdk/src/lib.rs @@ -8,12 +8,16 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! { loop {} } +bindings::export!(Component with_types_in bindings); + mod bindings; -use bindings::exports::miden::base::core_types; -use bindings::exports::miden::base::core_types::{AccountId, CoreAsset, Felt}; -use bindings::exports::miden::base::types; -use bindings::exports::miden::base::types::Asset; +use bindings::exports::miden::base::{ + core_types, + core_types::{AccountId, CoreAsset, Felt}, + types, + types::Asset, +}; pub struct Component; diff --git a/tests/rust-apps/fib/Cargo.toml b/tests/rust-apps/fib/Cargo.toml index 35afc22e..8f815bf3 100644 --- a/tests/rust-apps/fib/Cargo.toml +++ b/tests/rust-apps/fib/Cargo.toml @@ -3,3 +3,6 @@ name = "miden-integration-tests-rust-fib" version = "0.0.0" edition = "2021" publish = false + +[profile.release] +debug = true diff --git a/tools/cargo-miden/Cargo.toml b/tools/cargo-miden/Cargo.toml index 3d27ed49..3be46957 100644 --- a/tools/cargo-miden/Cargo.toml +++ b/tools/cargo-miden/Cargo.toml @@ -12,7 +12,7 @@ keywords.workspace = true license.workspace = true readme.workspace = true edition.workspace = true -autotests = false # disable autodiscovery of tests +autotests = false # disable autodiscovery of tests [[bin]] name = "cargo-miden" @@ -24,7 +24,6 @@ path = "tests/mod.rs" [dependencies] midenc-compile.workspace = true midenc-session.workspace = true -miden-diagnostics.workspace = true env_logger.workspace = true log.workspace = true clap.workspace = true diff --git a/tools/cargo-miden/README.md b/tools/cargo-miden/README.md index ff37398e..ebac7fab 100644 --- a/tools/cargo-miden/README.md +++ b/tools/cargo-miden/README.md @@ -7,13 +7,13 @@ This crate provides a cargo extension that allows you to compile Rust code to Mi In order to install(build) the extension, you need to have the nightly Rust toolchain installed: ```bash -rustup toolchain install nightly-2024-03-10 +rustup toolchain install nightly-2024-05-07 ``` To install the extension, run: ```bash -cargo +nightly-2024-03-10 install cargo-miden +cargo +nightly-2024-05-07 install cargo-miden ``` ## Usage diff --git a/tools/cargo-miden/src/build.rs b/tools/cargo-miden/src/build.rs index 6ab9777a..2af2a737 100644 --- a/tools/cargo-miden/src/build.rs +++ b/tools/cargo-miden/src/build.rs @@ -1,53 +1,48 @@ use std::{ path::{Path, PathBuf}, - sync::Arc, + rc::Rc, }; -use anyhow::{bail, Context}; -use miden_diagnostics::Verbosity; +use midenc_compile::Compiler; use midenc_session::{ - InputFile, OutputFile, OutputType, OutputTypeSpec, OutputTypes, ProjectType, Session, TargetEnv, + diagnostics::{IntoDiagnostic, Report, WrapErr}, + InputFile, OutputType, }; pub fn build_masm( wasm_file_path: &Path, output_folder: &Path, is_bin: bool, -) -> anyhow::Result { - let project_type = if is_bin { - ProjectType::Program - } else { - ProjectType::Library - }; - +) -> Result { if !output_folder.exists() { - bail!("MASM output folder '{}' does not exist.", output_folder.to_str().unwrap()); + return Err(Report::msg(format!( + "MASM output folder '{}' does not exist.", + output_folder.to_str().unwrap() + ))); } log::debug!( "Compiling '{}' Wasm to '{}' directory with midenc ...", wasm_file_path.to_str().unwrap(), &output_folder.to_str().unwrap() ); - let input = InputFile::from_path(wasm_file_path).context("Invalid input file")?; - let output_file_folder = OutputFile::Real(output_folder.to_path_buf()); - let output_type = OutputType::Masm; - let output_types = OutputTypes::new(vec![OutputTypeSpec { - output_type, - path: Some(output_file_folder.clone()), - }]); - let cwd = std::env::current_dir().context("Failed to get current working directory")?; - let options = midenc_session::Options::new(cwd) - // .with_color(color) - .with_verbosity(Verbosity::Debug) - // .with_warnings(self.warn) - .with_output_types(output_types); - let target = TargetEnv::default(); - let session = Arc::new( - Session::new(target, input, Some(output_folder.to_path_buf()), None, None, options, None) - .with_project_type(project_type), - ); - midenc_compile::compile(session.clone()).context("Wasm to MASM compilation failed!")?; - let mut output_path = output_folder.join(wasm_file_path.file_stem().unwrap()); - output_path.set_extension(output_type.extension()); - Ok(output_path) + let input = InputFile::from_path(wasm_file_path) + .into_diagnostic() + .wrap_err("Invalid input file")?; + let output_file = output_folder + .join(wasm_file_path.file_stem().expect("invalid wasm file path: no file stem")) + .with_extension(OutputType::Mast.extension()); + let project_type = if is_bin { "--exe" } else { "--lib" }; + let args: Vec<&std::ffi::OsStr> = vec![ + "--output-dir".as_ref(), + output_folder.as_os_str(), + "-o".as_ref(), + output_file.as_os_str(), + project_type.as_ref(), + "--verbose".as_ref(), + "--target".as_ref(), + "rollup".as_ref(), + ]; + let session = Rc::new(Compiler::new_session([input], None, args)); + midenc_compile::compile(session.clone())?; + Ok(output_file) } diff --git a/tools/cargo-miden/src/lib.rs b/tools/cargo-miden/src/lib.rs index 73ba7907..7078d252 100644 --- a/tools/cargo-miden/src/lib.rs +++ b/tools/cargo-miden/src/lib.rs @@ -1,10 +1,10 @@ use std::path::PathBuf; -use anyhow::bail; use cargo_component::load_metadata; use cargo_component_core::terminal::Terminal; use clap::{CommandFactory, Parser}; use config::CargoArguments; +use midenc_session::diagnostics::Report; use new_project::NewCommand; use crate::run_cargo_command::run_cargo_command; @@ -25,7 +25,7 @@ const BUILTIN_COMMANDS: &[&str] = &[ "new", ]; -const AFTER_HELP: &str = "Unrecognized subcommands will be passed to cargo verbatim +const AFTER_HELP: &str = "Unrecognized subcommands will be passed to cargo verbatim and the artifacts will be processed afterwards (e.g. `build` command compiles MASM). \nSee `cargo help` for more information on available cargo commands."; @@ -80,7 +80,7 @@ where None } -pub fn run(args: T, terminal: &Terminal) -> anyhow::Result> +pub fn run(args: T, terminal: &Terminal) -> Result, Report> where T: Iterator, { @@ -92,7 +92,7 @@ where Some(cmd) if BUILTIN_COMMANDS.contains(&cmd) => { match CargoMiden::parse_from(args.clone()) { CargoMiden::Miden(cmd) | CargoMiden::Command(cmd) => match cmd { - Command::New(cmd) => vec![cmd.exec()?], + Command::New(cmd) => vec![cmd.exec().map_err(Report::msg)?], }, } } @@ -104,19 +104,21 @@ where // If somehow the CLI parsed correctly despite no subcommand, // print the help instead - CargoMiden::command().print_long_help()?; + CargoMiden::command().print_long_help().map_err(Report::msg)?; Vec::new() } _ => { // Not a built-in command, run the cargo command - let cargo_args = CargoArguments::parse_from(args.clone().into_iter())?; - let metadata = load_metadata(terminal, cargo_args.manifest_path.as_deref(), false)?; + let cargo_args = + CargoArguments::parse_from(args.clone().into_iter()).map_err(Report::msg)?; + let metadata = load_metadata(terminal, cargo_args.manifest_path.as_deref(), false) + .map_err(Report::msg)?; if metadata.packages.is_empty() { - bail!( + return Err(Report::msg(format!( "manifest `{path}` contains no package or the workspace has no members", path = metadata.workspace_root.join("Cargo.toml") - ); + ))); } let spawn_args: Vec<_> = args.into_iter().skip(1).collect(); diff --git a/tools/cargo-miden/src/run_cargo_command.rs b/tools/cargo-miden/src/run_cargo_command.rs index 23ea0c62..c35d4c9f 100644 --- a/tools/cargo-miden/src/run_cargo_command.rs +++ b/tools/cargo-miden/src/run_cargo_command.rs @@ -1,7 +1,7 @@ use std::{path::PathBuf, process::Command}; -use anyhow::bail; use cargo_metadata::Metadata; +use midenc_session::diagnostics::{IntoDiagnostic, Report}; use crate::{ build::build_masm, @@ -21,7 +21,7 @@ pub fn run_cargo_command( subcommand: Option<&str>, cargo_args: &CargoArguments, spawn_args: &[String], -) -> anyhow::Result> { +) -> Result, Report> { let cargo = std::env::var("CARGO") .map(PathBuf::from) .ok() @@ -48,7 +48,7 @@ pub fn run_cargo_command( // Handle the target for build commands if is_build { - install_wasm32_wasi()?; + install_wasm32_wasi().map_err(Report::msg)?; // Add an implicit wasm32-wasi target if there isn't a wasm target present if !cargo_args.targets.iter().any(|t| is_wasm_target(t)) { @@ -68,11 +68,17 @@ pub fn run_cargo_command( match cmd.status() { Ok(status) => { if !status.success() { - bail!("cargo failed with exit code {}", status.code().unwrap_or(1)); + return Err(Report::msg(format!( + "cargo failed with exit code {}", + status.code().unwrap_or(1) + ))); } } Err(e) => { - bail!("failed to spawn `{cargo}`: {e}", cargo = cargo.display()); + return Err(Report::msg(format!( + "failed to spawn `{cargo}`: {e}", + cargo = cargo.display() + ))); } } let mut outputs = Vec::new(); @@ -99,7 +105,7 @@ pub fn run_cargo_command( "debug" }); if !miden_out_dir.exists() { - std::fs::create_dir_all(&miden_out_dir)?; + std::fs::create_dir_all(&miden_out_dir).into_diagnostic()?; } for package in &metadata.packages { @@ -119,7 +125,7 @@ pub fn run_cargo_command( outputs.push(output); } else { log::debug!("no output found for package `{name}`", name = package.name); - bail!("Cargo build failed, no Wasm artifact found"); + return Err(Report::msg("Cargo build failed, no Wasm artifact found")); } } } diff --git a/tools/cargo-miden/src/target.rs b/tools/cargo-miden/src/target.rs index 3088396a..51d257d1 100644 --- a/tools/cargo-miden/src/target.rs +++ b/tools/cargo-miden/src/target.rs @@ -6,20 +6,20 @@ use std::{ use anyhow::{bail, Result}; -pub const WASM32_WASI_TARGET: &str = "wasm32-wasi"; +pub const WASM32_WASI_TARGET: &str = "wasm32-wasip1"; pub fn install_wasm32_wasi() -> Result<()> { log::info!("Installing {WASM32_WASI_TARGET} target"); let sysroot = get_sysroot()?; - if sysroot.join("lib/rustlib/wasm32-wasi").exists() { + if sysroot.join(format!("lib/rustlib/{}", WASM32_WASI_TARGET)).exists() { return Ok(()); } if env::var_os("RUSTUP_TOOLCHAIN").is_none() { bail!( - "failed to find the `wasm32-wasi` target and `rustup` is not available. If you're \ - using rustup make sure that it's correctly installed; if not, make sure to install \ - the `wasm32-wasi` target before using this command" + "failed to find the `{WASM32_WASI_TARGET}` target and `rustup` is not available. If \ + you're using rustup make sure that it's correctly installed; if not, make sure to \ + install the `{WASM32_WASI_TARGET}` target before using this command", ); } @@ -32,7 +32,7 @@ pub fn install_wasm32_wasi() -> Result<()> { .output()?; if !output.status.success() { - bail!("failed to install the `wasm32-wasi` target"); + bail!("failed to install the `{WASM32_WASI_TARGET}` target"); } Ok(())