diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..24fb4b81 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,166 @@ +name: CI + +on: + push: + branches: [master] + tags: + - "v**" + pull_request: + schedule: + - cron: '0 0 * * 3' # At 12:00 AM, only on Wednesday + workflow_dispatch: + +jobs: + build-test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - { os: windows-latest, rust-version: stable, shell: 'msys2 {0}' } + - { os: macos-11, rust-version: stable, shell: bash } + - { os: ubuntu-20.04, rust-version: stable, shell: bash, extra: true } + - { os: ubuntu-20.04, rust-version: 1.65, shell: bash } + - { os: ubuntu-20.04, rust-version: beta, shell: bash } + - { os: ubuntu-20.04, rust-version: nightly, shell: bash } + defaults: + run: + shell: ${{ matrix.shell }} + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + if: "!contains(matrix.os,'windows')" + id: toolchain + with: + toolchain: ${{ matrix.rust-version }} + components: clippy, rustfmt + - uses: msys2/setup-msys2@v2 + if: contains(matrix.os,'windows') + with: + update: true + install: >- + base-devel + mingw-w64-x86_64-rust + - uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ matrix.os }}_rustc-${{ steps.toolchain.outputs.cachekey }}_cargo-${{ hashFiles('**/Cargo.lock') }} + + # Build and test. + - name: Build library + run: cargo rustc --verbose --lib -- -D warnings + - name: Test + if: "!matrix.extra" + run: cargo test --all --verbose + + # Extra steps only run once to avoid duplication, when matrix.extra is true + - name: Test and report + if: matrix.extra + run: | + cargo install cargo2junit --force + RUSTC_BOOTSTRAP=1 cargo test --all -- -Z unstable-options --format json --report-time | cargo2junit > cargo_test_results.xml + - name: Publish cargo test results artifact + if: matrix.extra + uses: actions/upload-artifact@v3 + with: + name: cargo-test-results + path: cargo_test_results.xml + - name: Publish cargo test summary + if: matrix.extra + uses: EnricoMi/publish-unit-test-result-action/composite@master + with: + check_name: Cargo test summary + files: cargo_test_results.xml + fail_on: nothing + comment_mode: off + - name: Check formatting + if: matrix.extra + run: cargo fmt --check || echo "::warning ::cargo fmt found some formatting changes that may improve readability" + - name: Check clippy + if: matrix.extra + run: cargo clippy --no-deps || echo "::warning ::cargo clippy found some code style changes that may be more idiomatic" + + # On stable rust builds, build a binary and publish as a github actions + # artifact. These binaries could be useful for testing the pipeline but + # are only retained by github for 90 days. + - name: Build release binary + if: contains(matrix.rust-version,'stable') + run: | + cargo rustc --verbose --bin scryer-prolog --release -- -D warnings + echo "$PWD/target/release" >> $GITHUB_PATH + - name: Publish release binary artifact + if: contains(matrix.rust-version,'stable') + uses: actions/upload-artifact@v3 + with: + path: target/release/scryer-prolog* + name: scryer-prolog_${{ matrix.os }} + + logtalk-test: + runs-on: ubuntu-20.04 + needs: [build-test] + steps: + # Download prebuilt ubuntu binary from build-test job, setup logtalk + - uses: actions/download-artifact@v3 + with: + name: scryer-prolog_ubuntu-20.04 + - run: | + chmod +x scryer-prolog + echo "$PWD" >> "$GITHUB_PATH" + - name: Install Logtalk + uses: logtalk-actions/setup-logtalk@master + with: + logtalk-version: git + logtalk-tool-dependencies: false + + # Run logtalk tests. + - name: Run Logtalk's prolog compliance test suite + working-directory: ${{ env.LOGTALKUSER }}/tests/prolog/ + run: | + pwd + scryerlgt -g '{ack(tester)},halt.' + logtalk_tester -p scryer -g "set_logtalk_flag(clean,off)" -w -t 360 \ + -f xunit \ + -s "$LOGTALKUSER/tests/prolog" \ + || echo "::warning ::logtalk compliance suite failed" + # -u "https://github.com/LogtalkDotOrg/logtalk3/tree/$LOGTALK_GIT_HASH/tests/prolog/" \ + - name: Publish Logtalk test logs + uses: actions/upload-artifact@v3 + with: + name: logtalk-test-logs + path: '${{ env.LOGTALKUSER }}/tests/prolog/logtalk_tester_logs' + - name: Publish Logtalk test results artifact + uses: actions/upload-artifact@v3 + with: + name: logtalk-test-results + path: '${{ env.LOGTALKUSER }}/tests/prolog/**/*.xml' + - name: Publish Logtalk test summary + uses: EnricoMi/publish-unit-test-result-action/composite@master + with: + check_name: Logtalk test summary + files: '${{ env.LOGTALKUSER }}/tests/prolog/**/*.xml' + fail_on: nothing + comment_mode: off + + # Publish binaries when building for a tag + release: + runs-on: ubuntu-20.04 + needs: [build-test] + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/download-artifact@v3 + - name: Zip binaries for release + run: | + zip scryer-prolog_macos-11.zip ./scryer-prolog_macos-11/scryer-prolog + zip scryer-prolog_ubuntu-20.04.zip ./scryer-prolog_ubuntu-20.04/scryer-prolog + zip scryer-prolog_windows-latest.zip ./scryer-prolog_windows-latest/scryer-prolog.exe + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: | + scryer-prolog_macos-11.zip + scryer-prolog_ubuntu-20.04.zip + scryer-prolog_windows-latest.zip diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index b31829e7..dffe1cd7 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -2,10 +2,10 @@ name: Docker Publish on: push: - tags: [ 'v*.*.*' ] - -env: - IMAGE_NAME: mjt128/scryer-prolog + branches: + - 'master' + tags: + - 'v*.*.*' jobs: build: @@ -18,33 +18,36 @@ jobs: # Workaround: https://github.com/docker/build-push-action/issues/461 - name: Setup Docker buildx - uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf + # https://github.com/docker/setup-buildx-action + uses: docker/setup-buildx-action@v2.2.1 # Login against Docker registry - # https://github.com/docker/login-action - name: Log into registry - uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + # https://github.com/docker/login-action + uses: docker/login-action@v2.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} # Extract Docker image tag from git tag. E.g. if git tag is "v0.19.1" then use - # Docker image tag "0.19.1". Tag "latest" is automatically synced with newest - # version. - # https://github.com/docker/metadata-action + # Docker image tag "0.19.1". The "latest" tag reflects the most recent build on + # master. - name: Extract Docker metadata id: meta - uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + # https://github.com/docker/metadata-action + uses: docker/metadata-action@v4.1.1 with: - images: docker.io/${{ env.IMAGE_NAME }} + images: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/scryer-prolog tags: | type=semver,pattern={{version}} + type=raw,value=latest,enable={{is_default_branch}} + # type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }} # Build and push Docker image with Buildx - # https://github.com/docker/build-push-action - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + # https://github.com/docker/build-push-action + uses: docker/build-push-action@v3.2.0 with: context: . push: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index edcd1993..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Test -on: [push, pull_request] - -jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-20.04, macos-10.15] - rust-version: [stable, beta] - steps: - - name: Checkout sources - uses: actions/checkout@v2 - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust-version }} - override: true - - name: Build lib - uses: actions-rs/cargo@v1 - with: - command: rustc - args: --verbose --lib -- -D warnings - - name: Build bin - uses: actions-rs/cargo@v1 - with: - command: rustc - args: --verbose --bin scryer-prolog -- -D warnings - - name: Test - uses: actions-rs/cargo@v1 - with: - command: test - args: --verbose --all - - name: Num tests - uses: actions-rs/cargo@v1 - continue-on-error: true - with: - command: test - args: --verbose --all --no-default-features --features num - msrv: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-20.04, macos-10.15] - steps: - - name: Checkout sources - uses: actions/checkout@v2 - - name: Install cargo-msrv - uses: baptiste0928/cargo-install@v1.1.0 - with: - crate: cargo-msrv - - name: Verify MSRV - run: cargo msrv --verify - windows: - runs-on: windows-latest - defaults: - run: - shell: msys2 {0} - steps: - - name: Setup MSYS2 - uses: msys2/setup-msys2@v2 - with: - update: true - install: >- - base-devel - mingw-w64-x86_64-rust - - name: Checkout sources - uses: actions/checkout@v3 - - name: Test on Windows - run: cargo test --verbose --all diff --git a/Cargo.lock b/Cargo.lock index 5ed25656..c0c62cfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +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.0.2" @@ -11,6 +26,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -40,15 +61,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -56,10 +68,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] -name = "az" -version = "1.2.1" +name = "backtrace" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] [[package]] name = "base64" @@ -67,6 +88,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + [[package]] name = "bit-set" version = "0.5.3" @@ -88,6 +115,24 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake2" version = "0.8.1" @@ -102,11 +147,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.5", + "digest 0.10.7", ] [[package]] @@ -123,11 +168,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -152,9 +197,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "byte-tools" @@ -170,15 +215,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.76" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -188,13 +233,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "time", "wasm-bindgen", @@ -203,34 +248,15 @@ dependencies = [ [[package]] name = "clipboard-win" -version = "4.4.2" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ab1b92798304eedc095b53942963240037c0516452cb11aeba709d420b2219" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" dependencies = [ "error-code", "str-buf", "winapi", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -243,9 +269,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpu-time" @@ -259,9 +285,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] @@ -272,7 +298,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ebde6a9dd5e331cd6c6f48253254d117642c31653baa475e394657c59c1f7d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crossterm_winapi", "libc", "mio 0.7.14", @@ -297,8 +323,8 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2db40892a506901e4e8281f00e42687df82d1d3448cb0289ae9183a60cb42ec1" dependencies = [ - "blake2 0.10.4", - "rand_core 0.6.4", + "blake2 0.10.6", + "rand_core", "sha2", ] @@ -308,7 +334,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "typenum", ] @@ -324,56 +350,103 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.2.3" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173" +checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" dependencies = [ - "nix 0.25.0", - "winapi", + "nix", + "windows-sys 0.48.0", ] [[package]] -name = "cxx" -version = "1.0.81" +name = "dashmap" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888" +checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3" -dependencies = [ - "cc", - "codespan-reporting", + "cfg-if", + "hashbrown 0.14.0", + "lock_api", "once_cell", - "proc-macro2 1.0.47", - "quote 1.0.21", - "scratch", - "syn 1.0.103", + "parking_lot_core 0.9.8", ] [[package]] -name = "cxxbridge-flags" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f" +name = "dashu" +version = "0.3.1" +source = "git+https://github.com/coasys/dashu.git#ae7ee53fad213e09da5fe4b30e9e9e8bce96aedd" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-macros", + "dashu-ratio", +] [[package]] -name = "cxxbridge-macro" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704" +name = "dashu-base" +version = "0.3.1" +source = "git+https://github.com/coasys/dashu.git#ae7ee53fad213e09da5fe4b30e9e9e8bce96aedd" + +[[package]] +name = "dashu-float" +version = "0.3.2" +source = "git+https://github.com/coasys/dashu.git#ae7ee53fad213e09da5fe4b30e9e9e8bce96aedd" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "dashu-base", + "dashu-int", + "num-order", + "num-traits", + "static_assertions", +] + +[[package]] +name = "dashu-int" +version = "0.3.1" +source = "git+https://github.com/coasys/dashu.git#ae7ee53fad213e09da5fe4b30e9e9e8bce96aedd" +dependencies = [ + "cfg-if", + "dashu-base", + "num-modular 0.6.0", + "num-order", + "num-traits", + "static_assertions", +] + +[[package]] +name = "dashu-macros" +version = "0.3.1" +source = "git+https://github.com/coasys/dashu.git#ae7ee53fad213e09da5fe4b30e9e9e8bce96aedd" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-ratio", + "proc-macro2", + "quote", +] + +[[package]] +name = "dashu-ratio" +version = "0.3.2" +source = "git+https://github.com/coasys/dashu.git#ae7ee53fad213e09da5fe4b30e9e9e8bce96aedd" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "num-order", + "num-traits", +] + +[[package]] +name = "derive_deref" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcdbcee2d9941369faba772587a565f4f534e42cb8d17e5295871de730163b2b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -393,13 +466,13 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -437,18 +510,27 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "ed25519" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "signature", ] [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] [[package]] name = "endian-type" @@ -458,13 +540,13 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -489,22 +571,22 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] [[package]] name = "fd-lock" -version = "3.0.8" +version = "3.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb21c69b9fea5e15dbc1049e4b77145dd0ba1c84019c488102de0dc4ea4b0a27" +checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" dependencies = [ "cfg-if", - "rustix", - "windows-sys 0.42.0", + "rustix 0.38.1", + "windows-sys 0.48.0", ] [[package]] @@ -529,10 +611,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "fuchsia-cprng" -version = "0.1.1" +name = "form_urlencoded" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futf" @@ -546,9 +637,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -561,9 +652,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -571,15 +662,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -588,38 +679,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 2.0.22", ] [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -653,9 +744,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -663,15 +754,21 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + [[package]] name = "git-version" version = "0.3.5" @@ -689,26 +786,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", -] - -[[package]] -name = "gmp-mpfr-sys" -version = "1.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3f42dadb6c75f122e9aa87e757ef11d4282f664c9f2e6476a9c2c8970f9d19" -dependencies = [ - "libc", - "winapi", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "h2" -version = "0.3.15" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -729,6 +816,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.3.3" @@ -740,11 +833,17 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "libc", + "windows-sys 0.48.0", ] [[package]] @@ -760,23 +859,23 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.23.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce65ac8028cf5a287a7dbf6c4e0a6cf2dcf022ed5b167a81bae66ebf599a8b7" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" dependencies = [ "log", "mac", "markup5ever", - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -794,6 +893,29 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-body" +version = "1.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ef12f041acdd397010e5fb6433270c147d3b8b2d0a840cd7fff8e531dca5c8" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body 1.0.0-rc.2", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.8.0" @@ -808,9 +930,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.23" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -818,7 +940,7 @@ dependencies = [ "futures-util", "h2", "http", - "http-body", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -830,6 +952,28 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75264b2003a3913f118d35c586e535293b3e22e41f074930762929d071e092" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 1.0.0-rc.2", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", + "tracing", + "want", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -837,7 +981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.27", "native-tls", "tokio", "tokio-native-tls", @@ -845,36 +989,45 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", ] [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg 1.1.0", - "hashbrown", + "autocfg", + "hashbrown 0.12.3", ] [[package]] @@ -888,14 +1041,21 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.1" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ + "hermit-abi", "libc", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + [[package]] name = "itertools" version = "0.10.5" @@ -907,24 +1067,27 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] [[package]] name = "lazy_static" @@ -949,7 +1112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec", - "bitflags", + "bitflags 1.3.2", "cfg-if", "ryu", "static_assertions", @@ -957,9 +1120,36 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.137" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libffi" +version = "3.2.0" +source = "git+https://github.com/coasys/libffi-rs.git?branch=windows-space#f6e9e50efde0aa4e940dd6f709a59bb426875362" +dependencies = [ + "libc", + "libffi-sys", +] + +[[package]] +name = "libffi-sys" +version = "2.3.0" +source = "git+https://github.com/coasys/libffi-rs.git?branch=windows-space#f6e9e50efde0aa4e940dd6f709a59bb426875362" +dependencies = [ + "cc", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] [[package]] name = "libsodium-sys" @@ -974,38 +1164,32 @@ dependencies = [ ] [[package]] -name = "link-cplusplus" -version = "1.0.7" +name = "linux-raw-sys" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" -dependencies = [ - "cc", -] +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.1.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb68f22743a3fb35785f1e7f844ca5a3de2dde5bd0c0ef5b372065814699b121" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ - "autocfg 1.1.0", + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "mac" @@ -1021,21 +1205,30 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "markup5ever" -version = "0.8.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1af46a727284117e09780d05038b1ce6fc9c76cc6df183c3dae5a8955a25e21" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" dependencies = [ "log", - "phf 0.7.24", + "phf 0.10.1", "phf_codegen", - "serde", - "serde_derive", - "serde_json", "string_cache", "string_cache_codegen", "tendril", ] +[[package]] +name = "markup5ever_rcdom" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9521dd6750f8e80ee6c53d65e2e4656d7de37064f3a7a5d2d11d05df93839c2" +dependencies = [ + "html5ever", + "markup5ever", + "tendril", + "xml5ever", +] + [[package]] name = "match_cfg" version = "0.1.0" @@ -1049,12 +1242,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] -name = "memoffset" -version = "0.6.5" +name = "mime" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ - "autocfg 1.1.0", + "adler", ] [[package]] @@ -1072,14 +1271,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -1105,9 +1303,9 @@ name = "modular-bitfield-impl" version = "0.11.2" source = "git+https://github.com/mthom/modular-bitfield#213535c684af277563678179d8496f11b84a283f" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1145,27 +1343,14 @@ dependencies = [ [[package]] name = "nix" -version = "0.23.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", - "cc", - "cfg-if", - "libc", - "memoffset", -] - -[[package]] -name = "nix" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" -dependencies = [ - "autocfg 1.1.0", - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", + "static_assertions", ] [[package]] @@ -1183,7 +1368,32 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg 1.1.0", + "autocfg", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.6.0" +source = "git+https://github.com/coasys/num-modular.git#87d6dc30600207445e07c2cc84e0a47ff58f0aca" + +[[package]] +name = "num-order" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e81e321057a0370997b13e6638bba6bd7f6f426e1f8e9a2562490a28eb23e1bc" +dependencies = [ + "num-modular 0.5.1", "num-traits", ] @@ -1193,24 +1403,33 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ "hermit-abi", "libc", ] [[package]] -name = "once_cell" -version = "1.16.0" +name = "object" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -1220,11 +1439,11 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "openssl" -version = "0.10.42" +version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1235,13 +1454,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 2.0.22", ] [[package]] @@ -1252,11 +1471,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.77" +version = "0.9.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ - "autocfg 1.1.0", "cc", "libc", "pkg-config", @@ -1280,7 +1498,7 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core 0.8.5", + "parking_lot_core 0.8.6", ] [[package]] @@ -1290,44 +1508,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.4", + "parking_lot_core 0.9.8", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ "cfg-if", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "winapi", ] [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", - "windows-sys 0.42.0", + "windows-targets", ] [[package]] -name = "phf" -version = "0.7.24" +name = "percent-encoding" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" -dependencies = [ - "phf_shared 0.7.24", -] +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "phf" @@ -1341,23 +1556,22 @@ dependencies = [ ] [[package]] -name = "phf_codegen" -version = "0.7.24" +name = "phf" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_generator 0.7.24", - "phf_shared 0.7.24", + "phf_shared 0.10.0", ] [[package]] -name = "phf_generator" -version = "0.7.24" +name = "phf_codegen" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" dependencies = [ - "phf_shared 0.7.24", - "rand 0.6.5", + "phf_generator 0.10.0", + "phf_shared 0.10.0", ] [[package]] @@ -1367,7 +1581,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d43f3220d96e0080cc9ea234978ccd80d904eafb17be31bb0f76daaea6493082" dependencies = [ "phf_shared 0.9.0", - "rand 0.8.5", + "rand", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand", ] [[package]] @@ -1379,18 +1603,9 @@ dependencies = [ "phf_generator 0.9.1", "phf_shared 0.9.0", "proc-macro-hack", - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", -] - -[[package]] -name = "phf_shared" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" -dependencies = [ - "siphasher 0.2.3", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1399,7 +1614,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a68318426de33640f02be62b4ae8eb1261be2efbc337b60c54d845bf4484e0d9" dependencies = [ - "siphasher 0.3.10", + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", ] [[package]] @@ -1416,9 +1640,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "ppv-lite86" @@ -1434,9 +1658,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "predicates" -version = "2.1.2" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab68289ded120dcbf9d571afcf70163233229052aec9b08ab09532f698d0e1e6" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "itertools", @@ -1445,15 +1669,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e7125585d872860e9955ca571650b27a4979c5823084168c5ed5bbfb016b56" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" [[package]] name = "predicates-tree" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad3f7fa8d61e139cbc7c3edfebf3b6678883a53f5ffac65d1259329a93ee43a5" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" dependencies = [ "predicates-core", "termtree", @@ -1461,45 +1685,33 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.19" +version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "0.4.30" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "proc-macro2" -version = "1.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "0.6.13" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ - "proc-macro2 0.4.30", + "proc-macro2", ] [[package]] -name = "quote" -version = "1.0.21" +name = "radium" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" -dependencies = [ - "proc-macro2 1.0.47", -] +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "radix_trie" @@ -1511,25 +1723,6 @@ dependencies = [ "nibble_vec", ] -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi", -] - [[package]] name = "rand" version = "0.8.5" @@ -1537,18 +1730,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -1558,24 +1741,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.6.4" @@ -1585,84 +1753,22 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redox_syscall" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", ] [[package]] @@ -1672,7 +1778,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] @@ -1718,12 +1824,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "reqwest" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "winapi", + "base64 0.21.2", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 0.4.5", + "hyper 0.14.27", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", ] [[package]] @@ -1762,54 +1896,61 @@ dependencies = [ ] [[package]] -name = "rug" -version = "1.17.0" +name = "rustc-demangle" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203180f444c95eac53586ed04793ecf6454c5d28f9eca8eead815fc19e136c47" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.37.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25693a73057a1b4cb56179dd3c7ea21a7c6c5ee7d85781f5749b46f34b79c" dependencies = [ - "az", - "gmp-mpfr-sys", + "bitflags 1.3.2", + "errno", + "io-lifetimes", "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", ] [[package]] name = "rustix" -version = "0.36.1" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812a2ec2043c4d6bc6482f5be2ab8244613cac2493d128d36c0759e52a626ab3" +checksum = "fbc6396159432b5c8490d4e301d8c705f61860b8b6c863bf79942ce5401968f3" dependencies = [ - "bitflags", + "bitflags 2.3.3", "errno", - "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys 0.42.0", + "linux-raw-sys 0.4.3", + "windows-sys 0.48.0", ] [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "rustyline" -version = "9.1.2" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db7826789c0e25614b03e5a54a0717a86f9ff6e6e5247f92b369472869320039" +checksum = "994eca4bca05c87e86e15d90fc7a91d1be64b4482b38cb2d27474568fe7c9db9" dependencies = [ - "bitflags", + "bitflags 2.3.3", "cfg-if", "clipboard-win", - "dirs-next", "fd-lock", + "home", "libc", "log", "memchr", - "nix 0.23.1", + "nix", "radix_trie", "scopeguard", - "smallvec", "unicode-segmentation", "unicode-width", "utf8parse", @@ -1818,9 +1959,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "same-file" @@ -1833,12 +1974,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] @@ -1847,50 +1987,52 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" - [[package]] name = "scryer-prolog" version = "0.9.1" dependencies = [ "assert_cmd", - "base64", + "base64 0.12.3", + "bit-set", + "bitvec", "blake2 0.8.1", + "bytes", "chrono", "cpu-time", "crossterm", "crrl", "ctrlc", + "dashu", + "derive_deref", "dirs-next", "divrem", "futures", "fxhash", "git-version", "hostname", - "hyper", - "hyper-tls", + "http-body-util", + "hyper 1.0.0-rc.3", "indexmap", "lazy_static", "lexical", "libc", + "libffi", + "libloading", "maplit", "modular-bitfield", "native-tls", "ordered-float", "phf 0.9.0", "predicates-core", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2", + "quote", + "rand", "ref_thread_local", "regex", + "reqwest", "ring", "ripemd160", "roxmltree", - "rug", "rustyline", "ryu", "select", @@ -1901,7 +2043,7 @@ dependencies = [ "static_assertions", "strum", "strum_macros", - "syn 1.0.103", + "syn 1.0.109", "to-syn-value", "to-syn-value_derive", "tokio", @@ -1910,11 +2052,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -1923,9 +2065,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -1933,36 +2075,26 @@ dependencies = [ [[package]] name = "select" -version = "0.4.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac645958c62108d11f90f8d34e4dc2799c838fc995ed4c2075867a2a8d5be76b" +checksum = "6f9da09dc3f4dfdb6374cbffff7a2cffcec316874d4429899eefdc97b3b94dcd" dependencies = [ "bit-set", "html5ever", + "markup5ever_rcdom", ] [[package]] name = "serde" -version = "1.0.147" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" - -[[package]] -name = "serde_derive" -version = "1.0.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" -dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", -] +checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" dependencies = [ "itoa", "ryu", @@ -1970,36 +2102,51 @@ dependencies = [ ] [[package]] -name = "serial_test" -version = "0.5.1" +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0bccbcf40c8938196944a3da0e133e031a33f4d6b72db3bda3cc556e361905d" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serial_test" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" +dependencies = [ + "dashmap", + "futures", "lazy_static", - "parking_lot 0.11.2", + "log", + "parking_lot 0.12.1", "serial_test_derive", ] [[package]] name = "serial_test_derive" -version = "0.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5" +checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 2.0.22", ] [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.5", + "digest 0.10.7", ] [[package]] @@ -2017,9 +2164,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" dependencies = [ "libc", "signal-hook-registry", @@ -2038,9 +2185,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -2051,12 +2198,6 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -[[package]] -name = "siphasher" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" - [[package]] name = "siphasher" version = "0.3.10" @@ -2065,11 +2206,11 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -2080,9 +2221,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -2120,38 +2261,30 @@ checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" [[package]] name = "string_cache" -version = "0.7.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c058a82f9fd69b1becf8c274f412281038877c553182f1d02eb027045a2d67" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ - "lazy_static", "new_debug_unreachable", - "phf_shared 0.7.24", + "once_cell", + "parking_lot 0.12.1", + "phf_shared 0.10.0", "precomputed-hash", "serde", - "string_cache_codegen", - "string_cache_shared", ] [[package]] name = "string_cache_codegen" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ - "phf_generator 0.7.24", - "phf_shared 0.7.24", - "proc-macro2 1.0.47", - "quote 1.0.21", - "string_cache_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", ] -[[package]] -name = "string_cache_shared" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" - [[package]] name = "strum" version = "0.23.0" @@ -2165,10 +2298,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" dependencies = [ "heck", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2", + "quote", "rustversion", - "syn 1.0.103", + "syn 1.0.109", ] [[package]] @@ -2179,44 +2312,50 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "0.15.44" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid", -] - -[[package]] -name = "syn" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" -dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2", + "quote", "unicode-ident", ] [[package]] -name = "tempfile" -version = "3.3.0" +name = "syn" +version = "2.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +dependencies = [ + "autocfg", "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix 0.37.21", + "windows-sys 0.48.0", ] [[package]] @@ -2230,59 +2369,65 @@ dependencies = [ "utf-8", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "termtree" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 2.0.22", ] [[package]] name = "time" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "to-syn-value" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45dcb7b4108a4793bdd74aa3714296c6eaf43663edf73fa8625d0d7621e68447" dependencies = [ - "syn 1.0.103", + "syn 1.0.109", "to-syn-value_derive", ] @@ -2292,47 +2437,47 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd4fdec6de01b568c1d3721c9d46a352623c536cd55a8a5acfefb63d1fccccbc" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "tokio" -version = "1.21.2" +version = "1.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "374442f06ee49c3a28a8fc9f01a2596fed7559c6b99b31279c3261778e77d84f" dependencies = [ - "autocfg 1.1.0", + "autocfg", + "backtrace", "bytes", "libc", - "memchr", - "mio 0.8.5", + "mio 0.8.8", "num_cpus", "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 2.0.22", ] [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -2340,9 +2485,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -2371,36 +2516,51 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" @@ -2408,18 +2568,23 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "utf-8" version = "0.7.6" @@ -2428,9 +2593,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "vcpkg" @@ -2455,22 +2620,20 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi", "winapi-util", ] [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -2488,9 +2651,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2498,53 +2661,65 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 2.0.22", "wasm-bindgen-shared", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.83" +name = "wasm-bindgen-futures" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ - "quote 1.0.21", + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.103", + "proc-macro2", + "quote", + "syn 2.0.22", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -2582,16 +2757,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows-targets", ] [[package]] @@ -2600,86 +2771,151 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "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", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "xml5ever" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4034e1d05af98b51ad7214527730626f019682d797ba38b51689212118d8e650" +dependencies = [ + "log", + "mac", + "markup5ever", +] [[package]] name = "xmlparser" diff --git a/Cargo.toml b/Cargo.toml index c64b7510..40b66623 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,10 +10,9 @@ license = "BSD-3-Clause" keywords = ["prolog", "prolog-interpreter", "prolog-system"] categories = ["command-line-utilities"] build = "build/main.rs" -rust-version = "1.61" +rust-version = "1.63" [features] -default = ["rug"] [build-dependencies] indexmap = "1.0.2" @@ -27,6 +26,8 @@ to-syn-value_derive = "0.1.0" walkdir = "2" [dependencies] +bit-set = "0.5.3" +bitvec = "1" cpu-time = "1.0.0" crossterm = "0.20.0" dirs-next = "2.0.0" @@ -41,35 +42,41 @@ libc = "0.2.62" modular-bitfield = "0.11.2" ctrlc = "3.2.2" ordered-float = "2.6.0" -phf = { version = "0.9", features = ["macros"] } +phf = { version = "0.9", features = ["macros"] } ref_thread_local = "0.0.0" -rug = { version = "1.15.0", optional = true } -rustyline = "9.0.0" +rustyline = "12.0.0" ring = "0.16.13" ripemd160 = "0.8.0" sha3 = "0.8.2" blake2 = "0.8.1" -crrl ="0.2.0" +crrl = "0.2.0" native-tls = "0.2.4" chrono = "0.4.11" -select = "0.4.3" +select = "0.6.0" roxmltree = "0.11.0" base64 = "0.12.3" smallvec = "1.8.0" sodiumoxide = "0.2.6" static_assertions = "1.1.0" ryu = "1.0.9" -hyper = { version = "0.14", features = ["full"] } -hyper-tls = "0.5.0" -tokio = { version = "1", features = ["full"] } +hyper = { version = "1.0.0-rc.3", features = ["full"] } +tokio = { version = "1.28.2", features = ["full"] } futures = "0.3" regex = "1.9.1" +libloading = "0.7" +derive_deref = "1.1.1" +http-body-util = "0.1.0-rc.2" +bytes = "1" +reqwest = { version = "0.11.18", features = ["blocking"] } +dashu = { git = "https://github.com/coasys/dashu.git" } +libffi = { git = "https://github.com/coasys/libffi-rs.git", branch = "windows-space" } +rand = "0.8.5" [dev-dependencies] assert_cmd = "1.0.3" predicates-core = "1.0.2" -serial_test = "0.5.1" maplit = "1.0.2" +serial_test = "2.0.0" [patch.crates-io] modular-bitfield = { git = "https://github.com/mthom/modular-bitfield" } diff --git a/Dockerfile b/Dockerfile index 501a2dce..0c1195ac 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # See https://github.com/LukeMathWalker/cargo-chef -ARG RUST_VERSION=1.60-buster +ARG RUST_VERSION=1-buster FROM rust:${RUST_VERSION} as planner WORKDIR /scryer-prolog RUN cargo install cargo-chef diff --git a/INDEX.dj b/INDEX.dj new file mode 100644 index 00000000..c7cf6a11 --- /dev/null +++ b/INDEX.dj @@ -0,0 +1,75 @@ +# Scryer Prolog + +``` +?- append("Hello, ", X, "Hello, Scryer Prolog!"). + X = "Scryer Prolog!". +``` + +``` =html +
The first annual Scryer Prolog meetup is going to happen in Düsseldorf (Germany) on the 9th and 10th of November 2023. Join us to discover the present and future of Scryer Prolog! Participation is free, registration not required. More details here.
+ {
- let iter = ChunkedIterator::from_rule(rule);
- let conjunct_info = self.collect_var_data(iter);
-
- let &Rule {
- head: (_, ref args, ref p1),
- ref clauses,
- } = rule;
-
- let mut code = Code::new();
+ pub(crate) fn compile_rule(&mut self, rule: &Rule, var_data: VarData) -> Result {
+ let Rule { head: (_, args), clauses } = rule;
+ self.marker.var_data = var_data;
+ let mut code = VecDeque::new();
self.marker.reset_at_head(args);
- self.compile_seq_prelude(&conjunct_info, &mut code);
- let iter = FactIterator::from_rule_head_clause(args);
- let mut fact = self.compile_target::(iter, GenContext::Head, false);
+ let iter = FactIterator::from_rule_head_clause(&args);
+ let fact = self.compile_target::(iter, GenContext::Head);
if self.marker.max_reg_allocated() > MAX_ARITY {
return Err(CompilationError::ExceededMaxArity);
}
- let mut unsafe_var_marker = UnsafeVarMarker::new();
+ self.marker.reset_free_list();
+ code.extend(fact.into_iter());
- if !fact.is_empty() {
- unsafe_var_marker = self.mark_unsafe_fact_vars(&mut fact);
- code.extend(fact.into_iter());
- }
+ self.compile_seq(clauses, &mut code)?;
- let iter = ChunkedIterator::from_rule_body(p1, clauses);
- self.compile_seq(iter, &conjunct_info, &mut code, false)?;
-
- conjunct_info.mark_unsafe_vars(unsafe_var_marker, &mut code);
- self.compile_cleanup(&mut code, &conjunct_info, clauses.last().unwrap_or(p1));
-
- Ok(code)
+ Ok(Vec::from(code))
}
- fn mark_unsafe_fact_vars(&self, fact: &mut Code) -> UnsafeVarMarker {
- let mut safe_vars = IndexSet::new();
-
- for fact_instr in fact.iter_mut() {
- match fact_instr {
- &mut Instruction::UnifyValue(r) => {
- if !safe_vars.contains(&r) {
- *fact_instr = Instruction::UnifyLocalValue(r);
- safe_vars.insert(r);
- }
- }
- &mut Instruction::UnifyVariable(r) => {
- safe_vars.insert(r);
- }
- _ => {}
- }
- }
-
- UnsafeVarMarker::from_safe_vars(safe_vars)
- }
-
- pub(crate) fn compile_fact(&mut self, term: &Term) -> Result {
- self.update_var_count(post_order_iter(term));
-
- let mut vs = VariableFixtures::new();
-
- vs.mark_vars_in_chunk(post_order_iter(term), term.arity(), GenContext::Head);
-
- vs.populate_restricting_sets();
- self.marker.drain_var_data(vs, 1);
-
+ pub(crate) fn compile_fact(&mut self, fact: &Fact, var_data: VarData) -> Result {
let mut code = Vec::new();
+ self.marker.var_data = var_data;
- if let &Term::Clause(_, _, ref args) = term {
+ if let Term::Clause(_, _, args) = &fact.head {
self.marker.reset_at_head(args);
- let iter = FactInstruction::iter(term);
- let mut compiled_fact = self.compile_target::(
+ let iter = FactInstruction::iter(&fact.head);
+ let compiled_fact = self.compile_target::(
iter,
GenContext::Head,
- false,
);
if self.marker.max_reg_allocated() > MAX_ARITY {
return Err(CompilationError::ExceededMaxArity);
}
- self.mark_unsafe_fact_vars(&mut compiled_fact);
-
- if !compiled_fact.is_empty() {
- code.extend(compiled_fact.into_iter());
- }
+ code.extend(compiled_fact.into_iter());
}
code.push(instr!("proceed"));
Ok(code)
}
- fn compile_query_line(
- &mut self,
- term: &QueryTerm,
- term_loc: GenContext,
- code: &mut Code,
- num_perm_vars_left: usize,
- is_exposed: bool,
- ) {
+ fn compile_query_line(&mut self, term: &QueryTerm, term_loc: GenContext, code: &mut CodeDeque) {
self.marker.reset_arg(term.arity());
- let iter = query_term_post_order_iter(term);
- let query = self.compile_target::(iter, term_loc, is_exposed);
+ let iter = QueryIterator::new(term);
+ let query = self.compile_target::(iter, term_loc);
code.extend(query.into_iter());
- self.add_conditional_call(code, term, num_perm_vars_left);
- }
- #[inline]
- fn increment_jmp_by_locs_by(&mut self, incr: usize) {
- let offset = self.global_jmp_by_locs_offset;
-
- for loc in &mut self.jmp_by_locs[offset..] {
- *loc += incr;
- }
+ match term {
+ &QueryTerm::Clause(_, ref ct, _, call_policy) => {
+ self.add_call(code, ct.to_instr(), call_policy);
+ }
+ _ => unreachable!()
+ };
}
fn split_predicate(clauses: &[PredicateClause]) -> Vec {
@@ -1141,30 +1098,35 @@ impl<'b> CodeGenerator<'b> {
fn compile_pred_subseq(
&mut self,
- clauses: &[PredicateClause],
+ clauses: &mut [PredicateClause],
optimal_index: usize,
) -> Result {
let mut code = VecDeque::new();
let mut code_offsets = CodeOffsets::new(I::new(), optimal_index + 1);
let mut skip_stub_try_me_else = false;
- let jmp_by_locs_len = self.jmp_by_locs.len();
+ let clauses_len = clauses.len();
- for (i, clause) in clauses.iter().enumerate() {
+ for (i, clause) in clauses.iter_mut().enumerate() {
self.marker.reset();
let mut clause_index_info = ClauseIndexInfo::new(code.len());
- self.global_jmp_by_locs_offset = self.jmp_by_locs.len();
let clause_code = match clause {
- &PredicateClause::Fact(ref fact, ..) => self.compile_fact(fact)?,
- &PredicateClause::Rule(ref rule, ..) => self.compile_rule(rule)?,
+ PredicateClause::Fact(fact, var_data) => {
+ let var_data = std::mem::replace(var_data, VarData::default());
+ self.compile_fact(&fact, var_data)?
+ }
+ PredicateClause::Rule(rule, var_data) => {
+ let var_data = std::mem::replace(var_data, VarData::default());
+ self.compile_rule(&rule, var_data)?
+ }
};
- if clauses.len() > 1 {
+ if clauses_len > 1 {
let choice = match i {
0 => self.settings.internal_try_me_else(clause_code.len() + 1),
- _ if i == clauses.len() - 1 => self.settings.internal_trust_me(),
+ _ if i + 1 == clauses_len => self.settings.internal_trust_me(),
_ => self.settings.internal_retry_me_else(clause_code.len() + 1),
};
@@ -1190,45 +1152,23 @@ impl<'b> CodeGenerator<'b> {
if let Some(arg) = arg {
let index = code.len();
- if clauses.len() > 1 || self.settings.is_dynamic() {
+ if clauses_len > 1 || self.settings.is_extensible {
code_offsets.index_term(arg, index, &mut clause_index_info, self.atom_tbl);
}
}
- if !(code_offsets.no_indices() && clauses.len() == 1 && self.settings.is_extensible) {
- // the peculiar condition of this block, when false,
- // anticipates code.pop_front() being called about a
- // dozen lines below.
-
- if !skip_stub_try_me_else {
- // if the condition is false, code_offsets.no_indices() is false,
- // so don't repeat the work of the condition on skip_stub_try_me_else
- // below.
- self.increment_jmp_by_locs_by(code.len());
- }
- }
-
self.skeleton.clauses.push_back(clause_index_info);
code.extend(clause_code.into_iter());
}
- let index_code = if clauses.len() > 1 || self.settings.is_dynamic() {
+ let index_code = if clauses_len > 1 || self.settings.is_extensible {
code_offsets.compute_indices(skip_stub_try_me_else)
} else {
vec![]
};
- self.global_jmp_by_locs_offset = jmp_by_locs_len;
-
if !index_code.is_empty() {
code.push_front(Instruction::IndexingCode(index_code));
-
- if skip_stub_try_me_else {
- // skip the TryMeElse(0) also.
- self.increment_jmp_by_locs_by(2);
- } else {
- self.increment_jmp_by_locs_by(1);
- }
} else if clauses.len() == 1 && self.settings.is_extensible {
// the condition is the value of skip_stub_try_me_else, which is
// true if the predicate is not dynamic. This operation must apply
@@ -1243,7 +1183,7 @@ impl<'b> CodeGenerator<'b> {
pub(crate) fn compile_predicate(
&mut self,
- clauses: &Vec,
+ mut clauses: Vec,
) -> Result {
let mut code = Code::new();
@@ -1254,12 +1194,12 @@ impl<'b> CodeGenerator<'b> {
let skel_lower_bound = self.skeleton.clauses.len();
let code_segment = if self.settings.is_dynamic() {
self.compile_pred_subseq::(
- &clauses[left..right],
+ &mut clauses[left..right],
instantiated_arg_index,
)?
} else {
self.compile_pred_subseq::(
- &clauses[left..right],
+ &mut clauses[left..right],
instantiated_arg_index,
)?
};
@@ -1291,9 +1231,6 @@ impl<'b> CodeGenerator<'b> {
}
}
- self.increment_jmp_by_locs_by(code.len());
- self.global_jmp_by_locs_offset = self.jmp_by_locs.len();
-
code.extend(code_segment.into_iter());
}
diff --git a/src/debray_allocator.rs b/src/debray_allocator.rs
index 1c81fcdd..0337ed4d 100644
--- a/src/debray_allocator.rs
+++ b/src/debray_allocator.rs
@@ -1,42 +1,252 @@
-use indexmap::IndexMap;
-
use crate::allocator::*;
-use crate::fixtures::*;
+use crate::codegen::SubsumedBranchHits;
use crate::forms::Level;
use crate::instructions::*;
-use crate::machine::machine_indices::*;
+use crate::machine::disjuncts::VarData;
use crate::parser::ast::*;
-use crate::targets::CompilationTarget;
-
-use crate::temp_v;
+use crate::targets::*;
+use crate::variable_records::*;
+use bit_set::*;
+use bitvec::prelude::*;
use fxhash::FxBuildHasher;
+use indexmap::IndexMap;
use std::cell::Cell;
-use std::collections::BTreeSet;
-use std::rc::Rc;
+use std::collections::VecDeque;
+use std::ops::{Deref, DerefMut};
+
+pub type BranchHits = IndexMap; // key: var_num, value: branch arm occurrences.
+
+#[derive(Debug, Default)]
+pub struct BranchOccurrences {
+ pub hits: BranchHits,
+ pub shallow_safety: BitSet, // unset means safe, set means unsafe (after the branch merge)
+ pub deep_safety: BitSet,
+ pub num_branches: usize,
+ pub current_branch: usize,
+ pub subsumed_hits: SubsumedBranchHits,
+}
+
+impl BranchOccurrences {
+ fn new(num_branches: usize) -> Self {
+ Self {
+ hits: BranchHits::with_hasher(FxBuildHasher::default()),
+ shallow_safety: BitSet::default(),
+ deep_safety: BitSet::default(),
+ num_branches,
+ current_branch: 0,
+ subsumed_hits: SubsumedBranchHits::with_hasher(FxBuildHasher::default()),
+ }
+ }
+}
+
+#[derive(Debug)]
+pub(crate) struct BranchStack {
+ stack: Vec,
+}
+
+impl Deref for BranchStack {
+ type Target = Vec;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.stack
+ }
+}
+
+impl DerefMut for BranchStack {
+ #[inline]
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.stack
+ }
+}
+
+impl BranchStack {
+ fn branch_subsumes(&self, branch: &BranchDesignator, sub_branch: &BranchDesignator) -> bool {
+ if branch.branch_stack_num < sub_branch.branch_stack_num {
+ if branch.branch_stack_num == 0 {
+ true
+ } else {
+ let idx = branch.branch_stack_num - 1;
+ self[idx].current_branch == branch.branch_num
+ }
+ } else {
+ branch == sub_branch
+ }
+ }
+
+ fn safety_unneeded_in_branch(&self, safety: &VarSafetyStatus, branch: &BranchDesignator) -> bool {
+ match safety {
+ VarSafetyStatus::Needed => false,
+ VarSafetyStatus::LocallyUnneeded(planter_branch) =>
+ self.branch_subsumes(planter_branch, branch),
+ VarSafetyStatus::GloballyUnneeded => true,
+ }
+ }
+
+ pub(crate) fn add_branch_occurrence(&mut self, var_num: usize) {
+ if let Some(occurrences) = self.last_mut() {
+ debug_assert!(occurrences.current_branch < occurrences.num_branches);
+
+ let num_branches = occurrences.num_branches;
+
+ let entry = occurrences.hits.entry(var_num)
+ .or_insert_with(|| BitVec::repeat(false, num_branches));
+
+ entry.set(occurrences.current_branch, true);
+ occurrences.subsumed_hits.insert(var_num);
+ }
+ }
+
+ pub(crate) fn add_branch_stack(&mut self, num_branches: usize) {
+ self.push(BranchOccurrences::new(num_branches));
+ }
+
+ pub(crate) fn current_branch_designator(&self) -> BranchDesignator {
+ let branch_stack_num = self.len();
+ let branch_num = self.last()
+ .map(|occurrences| occurrences.current_branch)
+ .unwrap_or(0);
+
+ BranchDesignator { branch_stack_num, branch_num }
+ }
+
+ #[inline]
+ pub(crate) fn incr_current_branch(&mut self) {
+ let branch_occurrences = self.last_mut().unwrap();
+ branch_occurrences.current_branch += 1;
+ }
+
+ #[inline]
+ pub(crate) fn drain_branches(&mut self, depth: usize) -> std::vec::Drain {
+ let start_idx = self.len() - depth;
+ self.drain(start_idx ..)
+ }
+}
#[derive(Debug)]
pub(crate) struct DebrayAllocator {
- bindings: IndexMap, VarData, FxBuildHasher>,
+ pub(crate) var_data: VarData, // var_data replaces bindings.
+ pub(crate) branch_stack: BranchStack,
+ pub(crate) in_tail_position: bool,
arg_c: usize,
temp_lb: usize,
+ perm_lb: usize,
arity: usize, // 0 if not at head.
- contents: IndexMap, FxBuildHasher>,
- in_use: BTreeSet,
+ shallow_temp_mappings: IndexMap,
+ in_use: BitSet, // deep and non-var allocations
+ temp_free_list: Vec,
+ perm_free_list: VecDeque<(usize, usize)>, // chunk_num, var_num
}
impl DebrayAllocator {
- fn is_curr_arg_distinct_from(&self, var: &String) -> bool {
- match self.contents.get(&self.arg_c) {
- Some(t_var) if **t_var != *var => true,
+ pub(crate) fn add_branch(&mut self) {
+ let branch_designator = self.branch_stack.current_branch_designator();
+ let subsumed_hits = {
+ let branch_occurrences = self.branch_stack.last_mut().unwrap();
+
+ std::mem::replace(
+ &mut branch_occurrences.subsumed_hits,
+ SubsumedBranchHits::with_hasher(FxBuildHasher::default()),
+ )
+ };
+
+ for var_num in subsumed_hits {
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, ref mut allocation) => {
+ match allocation {
+ PermVarAllocation::Done { shallow_safety, deep_safety, .. } => {
+ if !self.branch_stack.safety_unneeded_in_branch(shallow_safety, &branch_designator) {
+ let branch_occurrences = self.branch_stack.last_mut().unwrap();
+ branch_occurrences.shallow_safety.insert(var_num);
+ }
+
+ if !self.branch_stack.safety_unneeded_in_branch(deep_safety, &branch_designator) {
+ let branch_occurrences = self.branch_stack.last_mut().unwrap();
+ branch_occurrences.deep_safety.insert(var_num);
+ }
+ }
+ _ => {
+ unreachable!();
+ }
+ }
+
+ *allocation = PermVarAllocation::Pending;
+ }
+ _ => unreachable!(),
+ }
+ }
+ }
+
+ pub(crate) fn pop_branch(&mut self, depth: usize, subsumed_hits: SubsumedBranchHits) {
+ let removed_branches = self.branch_stack.drain_branches(depth);
+
+ let (deep_safety, shallow_safety) = removed_branches
+ .into_iter()
+ .fold((BitSet::default(), BitSet::default()),
+ |(mut deep_safety, mut shallow_safety), branch_occurrences| {
+ deep_safety.union_with(&branch_occurrences.deep_safety);
+ shallow_safety.union_with(&branch_occurrences.shallow_safety);
+
+ (deep_safety, shallow_safety)
+ });
+
+ let branch_designator = self.branch_stack.current_branch_designator();
+
+ let (deep_safety, shallow_safety) = match self.branch_stack.last_mut() {
+ Some(latest_branch) => {
+ latest_branch.deep_safety.union_with(&deep_safety);
+ latest_branch.shallow_safety.union_with(&shallow_safety);
+
+ (&latest_branch.deep_safety, &latest_branch.shallow_safety)
+ }
+ None => (&deep_safety, &shallow_safety)
+ };
+
+ for var_num in subsumed_hits.iter().cloned() {
+ let running_count = self.var_data.records[var_num].running_count;
+ let num_occurrences = self.var_data.records[var_num].num_occurrences;
+
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, allocation) => {
+ let shallow_safety = VarSafetyStatus::needed_if(
+ shallow_safety.contains(var_num),
+ branch_designator,
+ );
+
+ let deep_safety = VarSafetyStatus::needed_if(
+ deep_safety.contains(var_num),
+ branch_designator,
+ );
+
+ if running_count < num_occurrences {
+ *allocation = PermVarAllocation::Done { shallow_safety, deep_safety };
+ }
+ }
+ _ => unreachable!()
+ }
+ }
+
+ if self.branch_stack.len() > 0 {
+ for var_num in subsumed_hits {
+ self.branch_stack.add_branch_occurrence(var_num);
+ }
+ }
+ }
+
+ fn is_curr_arg_distinct_from(&self, var_num: usize) -> bool {
+ match self.shallow_temp_mappings.get(&self.arg_c).cloned() {
+ Some(t_var) => t_var != var_num,
_ => false,
}
}
- fn occurs_shallowly_in_head(&self, var: &String, r: usize) -> bool {
- match self.bindings.get(var).unwrap() {
- &VarData::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)),
+ fn occurs_shallowly_in_head(&self, var_num: usize, r: usize) -> bool {
+ match &self.var_data.records[var_num].allocation {
+ VarAlloc::Temp { temp_var_data, term_loc: GenContext::Head, .. } => {
+ temp_var_data.use_set.contains(&(GenContext::Head, r))
+ }
_ => false,
}
}
@@ -44,13 +254,13 @@ impl DebrayAllocator {
#[inline]
fn is_in_use(&self, r: usize) -> bool {
let in_use_range = r <= self.arity && r >= self.arg_c;
- in_use_range || self.in_use.contains(&r)
+ in_use_range || self.in_use.contains(r)
}
- fn alloc_with_cr(&self, var: &String) -> usize {
- match self.bindings.get(var) {
- Some(&VarData::Temp(_, _, ref tvd)) => {
- for &(_, reg) in tvd.use_set.iter() {
+ fn alloc_with_cr(&self, var_num: usize) -> usize {
+ match &self.var_data.records[var_num].allocation {
+ VarAlloc::Temp { temp_var_data, .. } => {
+ for &(_, reg) in temp_var_data.use_set.iter() {
if !self.is_in_use(reg) {
return reg;
}
@@ -60,7 +270,7 @@ impl DebrayAllocator {
for reg in self.temp_lb.. {
if !self.is_in_use(reg) {
- if !tvd.no_use_set.contains(®) {
+ if !temp_var_data.no_use_set.contains(reg) {
result = reg;
break;
}
@@ -73,10 +283,10 @@ impl DebrayAllocator {
}
}
- fn alloc_with_ca(&self, var: &String) -> usize {
- match self.bindings.get(var) {
- Some(&VarData::Temp(_, _, ref tvd)) => {
- for &(_, reg) in tvd.use_set.iter() {
+ fn alloc_with_ca(&self, var_num: usize) -> usize {
+ match &self.var_data.records[var_num].allocation {
+ VarAlloc::Temp { temp_var_data, .. } => {
+ for &(_, reg) in temp_var_data.use_set.iter() {
if !self.is_in_use(reg) {
return reg;
}
@@ -86,8 +296,8 @@ impl DebrayAllocator {
for reg in self.temp_lb.. {
if !self.is_in_use(reg) {
- if !tvd.no_use_set.contains(®) {
- if !tvd.conflict_set.contains(®) {
+ if !temp_var_data.no_use_set.contains(reg) {
+ if !temp_var_data.conflict_set.contains(reg) {
result = reg;
break;
}
@@ -101,22 +311,25 @@ impl DebrayAllocator {
}
}
- fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc, usize)> {
+ fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(usize, usize)> {
// we want to allocate a register to the k^{th} parameter, par_k.
// par_k may not be a temporary variable.
let k = self.arg_c;
- match self.contents.get(&k) {
+ match self.shallow_temp_mappings.get(&k).cloned() {
Some(t_var) => {
// suppose this branch fires. then t_var is a
// temp. var. belonging to the current chunk.
// consider its use set. T == par_k iff
// (GenContext::Last(_), k) is in t_var.use_set.
- let tvd = self.bindings.get(t_var).unwrap();
- if let &VarData::Temp(_, _, ref tvd) = tvd {
- if !tvd.use_set.contains(&(GenContext::Last(chunk_num), k)) {
- return Some((t_var.clone(), self.alloc_with_ca(t_var)));
+ match &self.var_data.records[t_var].allocation {
+ VarAlloc::Temp { temp_var_data, .. } => {
+ if !temp_var_data.use_set.contains(&(GenContext::Last(chunk_num), k)) {
+ return Some((t_var, self.alloc_with_ca(t_var)));
+ }
+ }
+ _ => {
}
}
@@ -129,21 +342,21 @@ impl DebrayAllocator {
fn evacuate_arg<'a, Target: CompilationTarget<'a>>(
&mut self,
chunk_num: usize,
- code: &mut Code,
+ code: &mut CodeDeque,
) {
match self.alloc_in_last_goal_hint(chunk_num) {
- Some((var, r)) => {
+ Some((var_num, r)) => {
let k = self.arg_c;
if r != k {
let r = RegType::Temp(r);
- code.push(Target::move_to_register(r, k));
+ code.push_back(Target::move_to_register(r, k));
- self.contents.swap_remove(&k);
- self.contents.insert(r.reg_num(), var.clone());
+ self.shallow_temp_mappings.swap_remove(&k);
+ self.shallow_temp_mappings.insert(r.reg_num(), var_num);
- self.record_register(var, r);
+ self.var_data.records[var_num].allocation.set_register(r.reg_num());
self.in_use.insert(r.reg_num());
}
}
@@ -153,27 +366,27 @@ impl DebrayAllocator {
fn alloc_reg_to_var<'a, Target: CompilationTarget<'a>>(
&mut self,
- var: &String,
+ var_num: usize,
lvl: Level,
term_loc: GenContext,
- target: &mut Vec,
+ target: &mut CodeDeque,
) -> usize {
match term_loc {
GenContext::Head => {
if let Level::Shallow = lvl {
self.evacuate_arg::(0, target);
- self.alloc_with_cr(var)
+ self.alloc_with_cr(var_num)
} else {
- self.alloc_with_ca(var)
+ self.alloc_with_ca(var_num)
}
}
- GenContext::Mid(_) => self.alloc_with_ca(var),
+ GenContext::Mid(_) => self.alloc_with_ca(var_num),
GenContext::Last(chunk_num) => {
if let Level::Shallow = lvl {
self.evacuate_arg::(chunk_num, target);
- self.alloc_with_cr(var)
+ self.alloc_with_cr(var_num)
} else {
- self.alloc_with_ca(var)
+ self.alloc_with_ca(var_num)
}
}
}
@@ -182,38 +395,238 @@ impl DebrayAllocator {
fn alloc_reg_to_non_var(&mut self) -> usize {
let mut final_index = 0;
+ while let Some(r) = self.temp_free_list.pop() {
+ if !self.is_in_use(r) {
+ self.in_use.insert(r);
+ return r;
+ }
+ }
+
for index in self.temp_lb.. {
- if !self.in_use.contains(&index) {
+ if !self.in_use.contains(index) {
final_index = index;
+ self.in_use.insert(final_index);
break;
}
}
- self.in_use.insert(final_index);
self.temp_lb = final_index + 1;
final_index
}
- fn in_place(&self, var: &String, term_loc: GenContext, r: RegType, k: usize) -> bool {
+ fn in_place(&self, var_num: usize, term_loc: GenContext, r: RegType, k: usize) -> bool {
match term_loc {
GenContext::Head if !r.is_perm() => r.reg_num() == k,
- _ => match self.bindings().get(var).unwrap() {
- &VarData::Temp(_, o, _) if r.reg_num() == k => o == k,
- _ => false,
+ _ => {
+ match &self.var_data.records[var_num].allocation {
+ &VarAlloc::Temp { temp_reg, .. } if r.reg_num() == k =>
+ temp_reg == k,
+ _ => false,
+ }
},
}
}
+
+ fn alloc_perm_var(&mut self, var_num: usize, chunk_num: usize) -> usize {
+ let p = if let Some(p) = self.pop_free_perm(chunk_num) {
+ p
+ } else {
+ let p = self.perm_lb;
+ self.perm_lb += 1;
+
+ p
+ };
+
+ self.var_data.records[var_num].allocation = VarAlloc::Perm(p, PermVarAllocation::done());
+ p
+ }
+
+ pub(crate) fn add_reg_to_free_list(&mut self, r: RegType) {
+ if let RegType::Temp(r) = r {
+ self.in_use.remove(r);
+ self.temp_free_list.push(r);
+ }
+ }
+
+ pub fn reset_free_list(&mut self) {
+ self.temp_free_list.clear();
+ }
+
+ #[inline(always)]
+ pub fn get_binding(&self, var_num: usize) -> RegType {
+ self.var_data.records[var_num].allocation.as_reg_type()
+ }
+
+ pub fn num_perm_vars(&self) -> usize {
+ self.perm_lb - 1
+ }
+
+ pub fn increment_running_count(&mut self, var_num: usize) {
+ self.var_data.records[var_num].running_count += 1;
+ }
+
+ fn add_perm_to_free_list(&mut self, chunk_num: usize, var_num: usize) {
+ match &self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(..) => {
+ self.perm_free_list.push_back((chunk_num, var_num));
+ }
+ _ => {}
+ }
+ }
+
+ fn pop_free_perm(&mut self, chunk_num: usize) -> Option {
+ while let Some((perm_chunk_num, var_num)) = self.perm_free_list.front().cloned() {
+ if chunk_num > perm_chunk_num {
+ self.perm_free_list.pop_front();
+
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(p, PermVarAllocation::Pending) if *p > 0 => {
+ return Some(std::mem::replace(p, 0));
+ }
+ _ => {
+ }
+ }
+ } else {
+ return None;
+ }
+ }
+
+ None
+ }
+
+ pub(crate) fn free_var(&mut self, chunk_num: usize, var_num: usize) {
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, allocation) => {
+ *allocation = PermVarAllocation::Pending;
+ self.add_perm_to_free_list(chunk_num, var_num);
+ }
+ _ => {
+ }
+ }
+ }
+
+ pub(crate) fn mark_safe_var_unconditionally(&mut self, var_num: usize) {
+ let branch_designator = self.branch_stack.current_branch_designator();
+
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, PermVarAllocation::Done { deep_safety, shallow_safety, .. }) => {
+ *deep_safety = VarSafetyStatus::unneeded(branch_designator);
+ *shallow_safety = VarSafetyStatus::unneeded(branch_designator);
+ }
+ VarAlloc::Temp { safety, .. } => {
+ *safety = VarSafetyStatus::unneeded(branch_designator);
+ }
+ _ => unreachable!(),
+ }
+ }
+
+ fn mark_safe_var(&mut self, var_num: usize, lvl: Level, term_loc: GenContext) {
+ let branch_designator = self.branch_stack.current_branch_designator();
+
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, PermVarAllocation::Done { deep_safety, shallow_safety, .. }) => {
+ // GetVariable in head chunk is considered safe.
+ if lvl == Level::Deep {
+ *deep_safety = VarSafetyStatus::unneeded(branch_designator);
+ *shallow_safety = VarSafetyStatus::unneeded(branch_designator);
+ } else if term_loc == GenContext::Head {
+ *shallow_safety = VarSafetyStatus::GloballyUnneeded;
+ } else {
+ if let Some(temp_var_num) = self.shallow_temp_mappings.get(&self.arg_c).cloned() {
+ match &mut self.var_data.records[temp_var_num].allocation {
+ VarAlloc::Temp { ref mut to_perm_var_num, .. } => {
+ *to_perm_var_num = Some(var_num);
+ }
+ _ => unreachable!()
+ }
+ }
+ }
+ }
+ VarAlloc::Temp { ref mut safety, .. } => {
+ *safety = VarSafetyStatus::GloballyUnneeded;
+ }
+ _ => {
+ unreachable!()
+ }
+ }
+ }
+
+ fn argument_to_value<'a, Target: CompilationTarget<'a>>(
+ &mut self,
+ var_num: usize,
+ r: RegType,
+ arg_c: usize,
+ ) -> Instruction {
+ let branch_designator = self.branch_stack.current_branch_designator();
+
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, PermVarAllocation::Done { ref mut shallow_safety, .. }) => {
+ if !self.in_tail_position || self.branch_stack.safety_unneeded_in_branch(shallow_safety, &branch_designator) {
+ Target::argument_to_value(r, arg_c)
+ } else {
+ *shallow_safety = VarSafetyStatus::unneeded(branch_designator);
+ Target::unsafe_argument_to_value(r, arg_c)
+ }
+ }
+ VarAlloc::Temp { ref mut safety, .. } => {
+ if self.branch_stack.safety_unneeded_in_branch(safety, &branch_designator) {
+ Target::argument_to_value(r, arg_c)
+ } else {
+ *safety = VarSafetyStatus::GloballyUnneeded;
+ Target::unsafe_argument_to_value(r, arg_c)
+ }
+ }
+ _ => {
+ unreachable!()
+ }
+ }
+ }
+
+ fn subterm_to_value<'a, Target: CompilationTarget<'a>>(
+ &mut self,
+ var_num: usize,
+ r: RegType,
+ ) -> Instruction {
+ let branch_designator = self.branch_stack.current_branch_designator();
+
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, PermVarAllocation::Done { ref mut deep_safety, .. }) => {
+ if self.branch_stack.safety_unneeded_in_branch(deep_safety, &branch_designator) {
+ Target::subterm_to_value(r)
+ } else {
+ *deep_safety = VarSafetyStatus::unneeded(branch_designator);
+ Target::unsafe_subterm_to_value(r)
+ }
+ }
+ VarAlloc::Temp { ref mut safety, .. } => {
+ if self.branch_stack.safety_unneeded_in_branch(safety, &branch_designator) {
+ Target::subterm_to_value(r)
+ } else {
+ *safety = VarSafetyStatus::unneeded(branch_designator);
+ Target::unsafe_subterm_to_value(r)
+ }
+ }
+ _ => {
+ unreachable!()
+ }
+ }
+ }
}
impl Allocator for DebrayAllocator {
fn new() -> DebrayAllocator {
- DebrayAllocator {
+ Self {
+ var_data: VarData::default(),
+ in_tail_position: false,
arity: 0,
arg_c: 1,
temp_lb: 1,
- bindings: IndexMap::with_hasher(FxBuildHasher::default()),
- contents: IndexMap::with_hasher(FxBuildHasher::default()),
- in_use: BTreeSet::new(),
+ perm_lb: 1,
+ shallow_temp_mappings: IndexMap::with_hasher(FxBuildHasher::default()),
+ in_use: BitSet::default(),
+ temp_free_list: vec![],
+ perm_free_list: VecDeque::new(),
+ branch_stack: BranchStack { stack: vec![] }
}
}
@@ -221,12 +634,12 @@ impl Allocator for DebrayAllocator {
&mut self,
lvl: Level,
term_loc: GenContext,
- code: &mut Code,
+ code: &mut CodeDeque,
) {
let r = RegType::Temp(self.alloc_reg_to_non_var());
match lvl {
- Level::Deep => code.push(Target::subterm_to_variable(r)),
+ Level::Deep => code.push_back(Target::subterm_to_variable(r)),
Level::Root | Level::Shallow => {
let k = self.arg_c;
@@ -236,7 +649,7 @@ impl Allocator for DebrayAllocator {
self.arg_c += 1;
- code.push(Target::argument_to_variable(r, k));
+ code.push_back(Target::argument_to_variable(r, k));
}
};
}
@@ -246,7 +659,7 @@ impl Allocator for DebrayAllocator {
lvl: Level,
term_loc: GenContext,
cell: &'a Cell,
- code: &mut Code,
+ code: &mut CodeDeque,
) {
let r = cell.get();
@@ -273,39 +686,49 @@ impl Allocator for DebrayAllocator {
fn mark_var<'a, Target: CompilationTarget<'a>>(
&mut self,
- var: Rc,
+ var_num: usize,
lvl: Level,
cell: &'a Cell,
term_loc: GenContext,
- code: &mut Code,
+ code: &mut CodeDeque,
) {
- let (r, is_new_var) = match self.get(var.clone()) {
+ let (r, is_new_var) = match self.get_binding(var_num) {
RegType::Temp(0) => {
- // here, r is temporary *and* unassigned.
- let o = self.alloc_reg_to_var::(&var, lvl, term_loc, code);
+ let o = self.alloc_reg_to_var::(var_num, lvl, term_loc, code);
cell.set(VarReg::Norm(RegType::Temp(o)));
(RegType::Temp(o), true)
}
RegType::Perm(0) => {
- let pr = cell.get().norm();
- self.record_register(var.clone(), pr);
+ let p = self.alloc_perm_var(var_num, term_loc.chunk_num());
+ (RegType::Perm(p), true)
+ }
+ r @ RegType::Perm(_) => {
+ let is_new_var = match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, allocation) => if allocation.pending() {
+ *allocation = PermVarAllocation::done();
+ true
+ } else {
+ false
+ },
+ _ => unreachable!(),
+ };
- (pr, true)
+ (r, is_new_var)
}
r => (r, false),
};
- self.mark_reserved_var::(var, lvl, cell, term_loc, code, r, is_new_var);
+ self.mark_reserved_var::(var_num, lvl, cell, term_loc, code, r, is_new_var);
}
fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
&mut self,
- var: Rc,
+ var_num: usize,
lvl: Level,
cell: &'a Cell,
term_loc: GenContext,
- code: &mut Code,
+ code: &mut CodeDeque,
r: RegType,
is_new_var: bool,
) {
@@ -313,84 +736,99 @@ impl Allocator for DebrayAllocator {
Level::Root | Level::Shallow => {
let k = self.arg_c;
- if self.is_curr_arg_distinct_from(&var) {
+ if self.is_curr_arg_distinct_from(var_num) {
self.evacuate_arg::(term_loc.chunk_num(), code);
}
- self.arg_c += 1;
-
cell.set(VarReg::ArgAndNorm(r, k));
- if !self.in_place(&var, term_loc, r, k) {
+ if !self.in_place(var_num, term_loc, r, k) {
if is_new_var {
- code.push(Target::argument_to_variable(r, k));
+ self.mark_safe_var(var_num, lvl, term_loc);
+ code.push_back(Target::argument_to_variable(r, k));
} else {
- code.push(Target::argument_to_value(r, k));
+ code.push_back(self.argument_to_value::(var_num, r, k));
}
}
+
+ self.arg_c += 1;
}
Level::Deep if is_new_var => {
if let GenContext::Head = term_loc {
- if self.occurs_shallowly_in_head(&var, r.reg_num()) {
- code.push(Target::subterm_to_value(r));
+ if self.occurs_shallowly_in_head(var_num, r.reg_num()) {
+ code.push_back(self.subterm_to_value::(var_num, r));
} else {
- code.push(Target::subterm_to_variable(r));
+ self.mark_safe_var(var_num, lvl, term_loc);
+ code.push_back(Target::subterm_to_variable(r));
}
} else {
- code.push(Target::subterm_to_variable(r));
+ self.mark_safe_var(var_num, lvl, term_loc);
+ code.push_back(Target::subterm_to_variable(r));
}
}
- Level::Deep => code.push(Target::subterm_to_value(r)),
- };
+ Level::Deep => code.push_back(self.subterm_to_value::(var_num, r)),
+ }
+
+ let o = r.reg_num();
if !r.is_perm() {
- let o = r.reg_num();
+ self.shallow_temp_mappings.insert(o, var_num);
+ } else if r.is_perm() && is_new_var {
+ self.branch_stack.add_branch_occurrence(var_num);
+ }
- self.contents.insert(o, var.clone());
- self.record_register(var.clone(), r);
- self.in_use.insert(o);
+ let record = &mut self.var_data.records[var_num];
+
+ record.allocation.set_register(o);
+
+ if record.running_count < record.num_occurrences {
+ record.running_count += 1;
+ } else {
+ self.free_var(term_loc.chunk_num(), var_num);
+ }
+
+ self.in_use.insert(o);
+ }
+
+ fn mark_cut_var(&mut self, var_num: usize, chunk_num: usize) -> RegType {
+ match self.get_binding(var_num) {
+ RegType::Perm(0) | RegType::Temp(0) => {
+ RegType::Perm(self.alloc_perm_var(var_num, chunk_num))
+ }
+ r => r,
}
}
fn reset(&mut self) {
- self.bindings.clear();
- self.contents.clear();
+ self.perm_lb = 1;
+ self.shallow_temp_mappings.clear();
self.in_use.clear();
+ self.temp_free_list.clear();
}
fn reset_contents(&mut self) {
- self.contents.clear();
self.in_use.clear();
+ self.shallow_temp_mappings.clear();
+ self.temp_free_list.clear();
}
fn advance_arg(&mut self) {
self.arg_c += 1;
}
- fn bindings(&self) -> &AllocVarDict {
- &self.bindings
- }
-
- fn bindings_mut(&mut self) -> &mut AllocVarDict {
- &mut self.bindings
- }
-
- fn take_bindings(self) -> AllocVarDict {
- self.bindings
- }
-
fn reset_at_head(&mut self, args: &Vec) {
self.reset_arg(args.len());
self.arity = args.len();
for (idx, arg) in args.iter().enumerate() {
if let &Term::Var(_, ref var) = arg {
- let r = self.get(var.clone());
+ let var_num = var.to_var_num().unwrap();
+ let r = self.get_binding(var_num);
if !r.is_perm() && r.reg_num() == 0 {
self.in_use.insert(idx + 1);
- self.contents.insert(idx + 1, var.clone());
- self.record_register(var.clone(), temp_v!(idx + 1));
+ self.shallow_temp_mappings.insert(idx + 1, var_num);
+ self.var_data.records[var_num].allocation.set_register(idx + 1);
}
}
}
diff --git a/src/ffi.rs b/src/ffi.rs
new file mode 100644
index 00000000..a48ed62e
--- /dev/null
+++ b/src/ffi.rs
@@ -0,0 +1,444 @@
+/* How does FFI work?
+
+Each WAM machine has a ForeignFunctionTable instance that contains a table of functions and structs.
+
+Structs are defined via foreign_struct/2. Basic types are defined by libffi, but struct types need to
+be manually defined to get an ffi_type. Additionally, to recover structs from return arguments, we store
+fields and atom_fields, as a way to lookup the content of the struct (fields) and the nested structs (atom_fields).
+
+Functions are defined via use_foreign_module/2. It opens a library and leaks the memory of the library,
+to prevent Rust freeing the memory. There's no way to recover that memory at the moment. We get a pointer for
+each function and we build a CIF for each one, with the input arguments and the return argument.
+
+Exec happens via '$foreign_call', we find the function, we try to cast the values that we have to the definition
+of the function, we reserve memory for them and we build an array of pointers. To get the return argument, we
+reserve enough memory for the return and we build the Scryer values from them.
+
+Structs are a bit tricky as they need to be aligned. For that, we reserve enough memory (libffi calculates that)
+and for each field: we add to the pointer until we're aligned to the next data type we're going to write, we write it,
+and finally we add the pointer the size of what we've written.
+*/
+
+use crate::atom_table::Atom;
+
+use std::alloc::{alloc, Layout};
+use std::any::Any;
+use std::collections::HashMap;
+use std::error::Error;
+use std::ffi::{CString, c_void};
+use std::convert::TryFrom;
+
+use libffi::low::{ffi_cif, types, CodePtr, ffi_abi_FFI_DEFAULT_ABI, prep_cif, ffi_type, type_tag};
+use libloading::{Symbol, Library};
+
+pub struct FunctionDefinition {
+ pub name: String,
+ pub return_value: Atom,
+ pub args: Vec,
+}
+
+#[derive(Debug)]
+pub struct FunctionImpl {
+ cif: ffi_cif,
+ args: Vec<*mut ffi_type>,
+ code_ptr: CodePtr,
+ return_struct_name: Option,
+}
+
+#[derive(Debug, Default)]
+pub struct ForeignFunctionTable {
+ table: HashMap,
+ structs: HashMap,
+}
+
+#[derive(Debug, Clone)]
+struct StructImpl {
+ ffi_type: ffi_type,
+ fields: Vec<*mut ffi_type>,
+ atom_fields: Vec,
+}
+
+struct PointerArgs {
+ pointers: Vec<*mut c_void>,
+ _memory: Vec>,
+}
+
+impl ForeignFunctionTable {
+ pub fn merge(&mut self, other: ForeignFunctionTable) {
+ self.table.extend(other.table);
+ }
+
+ pub fn define_struct(&mut self, name: &str, atom_fields: Vec) {
+ let mut fields: Vec<_> = atom_fields.iter().map(|x| self.map_type_ffi(&x)).collect();
+ fields.push(std::ptr::null_mut::());
+ let mut struct_type: ffi_type = Default::default();
+ struct_type.type_ = type_tag::STRUCT;
+ struct_type.elements = fields.as_mut_ptr();
+ self.structs.insert(name.to_string(), StructImpl { ffi_type: struct_type, fields, atom_fields});
+ }
+
+ fn map_type_ffi(&mut self, source: &Atom) -> *mut ffi_type {
+ unsafe {
+ match source {
+ atom!("sint64") => &mut types::sint64,
+ atom!("sint32") => &mut types::sint32,
+ atom!("sint16") => &mut types::sint16,
+ atom!("sint8") => &mut types::sint8,
+ atom!("uint64") => &mut types::uint64,
+ atom!("uint32") => &mut types::uint32,
+ atom!("uint16") => &mut types::uint16,
+ atom!("uint8") => &mut types::uint8,
+ atom!("bool") => &mut types::sint8,
+ atom!("void") => &mut types::void,
+ atom!("cstr") => &mut types::pointer,
+ atom!("ptr") => &mut types::pointer,
+ atom!("f32") => &mut types::float,
+ atom!("f64") => &mut types::double,
+ struct_name => {
+ match self.structs.get_mut(struct_name.as_str()) {
+ Some(ref mut struct_type) => {
+ &mut struct_type.ffi_type
+ },
+ None => unreachable!()
+ }
+ }
+ }
+ }
+ }
+
+ pub(crate) fn load_library(&mut self, library_name: &str, functions: &Vec) -> Result<(), Box> {
+ let mut ff_table: ForeignFunctionTable = Default::default();
+ unsafe {
+ let library = Library::new(library_name)?;
+ for function in functions {
+ let symbol_name: CString = CString::new(function.name.clone())?;
+ let code_ptr: Symbol<*mut c_void> = library.get(&symbol_name.into_bytes_with_nul())?;
+ let mut args: Vec<_> = function.args.iter().map(|x| self.map_type_ffi(&x)).collect();
+ let mut cif: ffi_cif = Default::default();
+ prep_cif(
+ &mut cif,
+ ffi_abi_FFI_DEFAULT_ABI,
+ args.len(),
+ self.map_type_ffi(&function.return_value),
+ args.as_mut_ptr()
+ ).unwrap();
+
+ let return_struct_name = if (*self.map_type_ffi(&function.return_value)).type_ as u32 == libffi::raw::FFI_TYPE_STRUCT {
+ Some(function.return_value.as_str().to_string())
+ } else {
+ None
+ };
+
+ ff_table.table.insert(function.name.clone(), FunctionImpl {
+ cif,
+ args,
+ code_ptr: CodePtr(code_ptr.into_raw().into_raw() as *mut _),
+ return_struct_name,
+ });
+ }
+ std::mem::forget(library);
+ }
+ self.merge(ff_table);
+ Ok(())
+ }
+
+ fn build_pointer_args(args: &mut Vec, type_args: &Vec<*mut ffi_type>, structs_table: &mut HashMap) -> Result {
+ let mut pointers = Vec::with_capacity(args.len());
+ let mut _memory = Vec::new();
+ for i in 0..args.len() {
+ let field_type = type_args[i];
+ unsafe {
+ macro_rules! push_int {
+ ($type:ty) => {
+ {
+ let n: $type = <$type>::try_from(args[i].as_int()?).map_err(|_| FFIError::ValueDontFit)?;
+ let mut box_value = Box::new(n) as Box;
+ pointers.push(&mut *box_value as *mut _ as *mut c_void);
+ _memory.push(box_value);
+ }
+ }
+ }
+
+ match (*field_type).type_ as u32 {
+ libffi::raw::FFI_TYPE_UINT8 => push_int!(u8),
+ libffi::raw::FFI_TYPE_SINT8 => push_int!(i8),
+ libffi::raw::FFI_TYPE_UINT16 => push_int!(u16),
+ libffi::raw::FFI_TYPE_SINT16 => push_int!(i16),
+ libffi::raw::FFI_TYPE_UINT32 => push_int!(u32),
+ libffi::raw::FFI_TYPE_SINT32 => push_int!(i32),
+ libffi::raw::FFI_TYPE_UINT64 => push_int!(u64),
+ libffi::raw::FFI_TYPE_SINT64 => push_int!(i64),
+ libffi::raw::FFI_TYPE_FLOAT => {
+ let n: f32 = args[i].as_float()? as f32;
+ let mut box_value = Box::new(n) as Box;
+ pointers.push(&mut *box_value as *mut _ as *mut c_void);
+ _memory.push(box_value);
+ },
+ libffi::raw::FFI_TYPE_DOUBLE => {
+ let n: f64 = args[i].as_float()?;
+ let mut box_value = Box::new(n) as Box;
+ pointers.push(&mut *box_value as *mut _ as *mut c_void);
+ _memory.push(box_value);
+ },
+ libffi::raw::FFI_TYPE_POINTER => {
+ let ptr: *mut c_void = args[i].as_ptr()?;
+ pointers.push(ptr);
+ },
+ libffi::raw::FFI_TYPE_STRUCT => {
+ let (mut ptr, _size, _align) = Self::build_struct(&mut args[i], structs_table)?;
+ pointers.push(&mut *ptr as *mut _ as *mut c_void);
+ _memory.push(ptr);
+ },
+ _ => return Err(FFIError::InvalidFFIType)
+ }
+ }
+ }
+ Ok(PointerArgs {
+ pointers,
+ _memory
+ })
+ }
+
+ fn build_struct(arg: &mut Value, structs_table: &mut HashMap) -> Result<(Box, usize, usize), FFIError> {
+ unsafe {
+ match arg {
+ Value::Struct(ref name, ref mut struct_args) => {
+ if let Some(ref mut struct_type) = structs_table.clone().get_mut(name) {
+ let layout = Layout::from_size_align(struct_type.ffi_type.size, struct_type.ffi_type.alignment.into()).unwrap();
+ let align = struct_type.ffi_type.alignment as usize;
+ let size = struct_type.ffi_type.size;
+ let ptr = alloc(layout) as *mut c_void;
+ let mut field_ptr = ptr;
+
+ for i in 0..(struct_type.fields.len()-1) {
+ macro_rules! try_write_int {
+ ($type:ty) => {
+ {
+ field_ptr = field_ptr.add(field_ptr.align_offset(std::mem::align_of::<$type>()));
+ let n: $type = <$type>::try_from(struct_args[i].as_int()?).map_err(|_| FFIError::ValueDontFit)?;
+ std::ptr::write(field_ptr as *mut $type, n);
+ field_ptr = field_ptr.add(std::mem::size_of::<$type>());
+ }
+ }
+ }
+
+ macro_rules! write {
+ ($type:ty, $value:expr) => {
+ {
+ let data: $type = $value;
+ std::ptr::write(field_ptr as *mut $type, data);
+ field_ptr = field_ptr.add(align);
+ }
+ }
+ }
+
+ let field = struct_type.fields[i];
+ match (*field).type_ as u32 {
+ libffi::raw::FFI_TYPE_UINT8 => try_write_int!(u8),
+ libffi::raw::FFI_TYPE_SINT8 => try_write_int!(i8),
+ libffi::raw::FFI_TYPE_UINT16 => try_write_int!(u16),
+ libffi::raw::FFI_TYPE_SINT16 => try_write_int!(i16),
+ libffi::raw::FFI_TYPE_UINT32 => try_write_int!(u32),
+ libffi::raw::FFI_TYPE_SINT32 => try_write_int!(i32),
+ libffi::raw::FFI_TYPE_UINT64 => try_write_int!(u64),
+ libffi::raw::FFI_TYPE_SINT64 => try_write_int!(i64),
+ libffi::raw::FFI_TYPE_POINTER => write!(*mut c_void, struct_args[i].as_ptr()?),
+ libffi::raw::FFI_TYPE_FLOAT => write!(f32, struct_args[i].as_float()? as f32),
+ libffi::raw::FFI_TYPE_DOUBLE => write!(f64, struct_args[i].as_float()?),
+ libffi::raw::FFI_TYPE_STRUCT => {
+ let (struct_ptr, struct_size, struct_align) = Self::build_struct(&mut struct_args[i], structs_table)?;
+ field_ptr = field_ptr.add(field_ptr.align_offset(struct_align));
+
+ std::ptr::copy(& *struct_ptr as *const _ as *const c_void, field_ptr as *mut c_void, struct_size);
+ field_ptr = field_ptr.add(struct_size);
+ },
+ _ => {
+ unreachable!()
+ }
+ }
+ }
+ return Ok((Box::from_raw(ptr), size, align));
+ } else {
+ return Err(FFIError::InvalidStructName);
+ }
+ }
+ _ => return Err(FFIError::ValueCast)
+ }
+ }
+ }
+
+ pub fn exec(&mut self, name: &str, mut args: Vec) -> Result {
+ let function_impl = self.table.get_mut(name).ok_or(FFIError::FunctionNotFound)?;
+ let mut pointer_args = Self::build_pointer_args(&mut args, &function_impl.args, &mut self.structs)?;
+
+ return unsafe {
+ macro_rules! call_and_return {
+ ($type:ty) => {
+ {
+ let mut n: Box = Box::new(0);
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *n as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
+ );
+ Ok(Value::Int(i64::from(*n)))
+ }
+ }
+ }
+
+ match (*function_impl.cif.rtype).type_ as u32 {
+ libffi::raw::FFI_TYPE_VOID => call_and_return!(i32),
+ libffi::raw::FFI_TYPE_UINT8 => call_and_return!(u8),
+ libffi::raw::FFI_TYPE_SINT8 => call_and_return!(i8),
+ libffi::raw::FFI_TYPE_UINT16 => call_and_return!(u16),
+ libffi::raw::FFI_TYPE_SINT16 => call_and_return!(i16),
+ libffi::raw::FFI_TYPE_UINT32 => call_and_return!(u32),
+ libffi::raw::FFI_TYPE_SINT32 => call_and_return!(i32),
+ libffi::raw::FFI_TYPE_UINT64 => {
+ let mut n: Box = Box::new(0);
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *n as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
+ );
+ Ok(Value::Int(i64::try_from(*n).map_err(|_| FFIError::ValueDontFit)?))
+ },
+ libffi::raw::FFI_TYPE_SINT64 => call_and_return!(i64),
+ libffi::raw::FFI_TYPE_POINTER => call_and_return!(*mut c_void),
+ libffi::raw::FFI_TYPE_FLOAT => {
+ let mut n: Box = Box::new(0.0);
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *n as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
+ );
+ Ok(Value::Float((*n).into()))
+ },
+ libffi::raw::FFI_TYPE_DOUBLE => {
+ let mut n: Box = Box::new(0.0);
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *n as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
+ );
+ Ok(Value::Float(*n))
+ },
+ libffi::raw::FFI_TYPE_STRUCT => {
+ let name = &function_impl.return_struct_name.clone().ok_or(FFIError::StructNotFound)?;
+ let struct_type = self.structs.get(name).ok_or(FFIError::StructNotFound)?;
+ let layout = Layout::from_size_align(struct_type.ffi_type.size, struct_type.ffi_type.alignment.into()).unwrap();
+ let ptr = alloc(layout) as *mut c_void;
+
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *ptr as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
+ );
+ let struct_val = self.read_struct(ptr, name, struct_type);
+ drop(Box::from_raw(ptr));
+ struct_val
+ }
+ _ => unreachable!()
+ }
+ };
+ }
+
+ fn read_struct(&self, ptr: *mut c_void, name: &str, struct_type: &StructImpl) -> Result {
+ unsafe {
+ let mut returns = Vec::new();
+ let mut field_ptr = ptr;
+
+ for i in 0..(struct_type.fields.len()-1) {
+ let field = struct_type.fields[i];
+
+ macro_rules! read_and_push_int {
+ ($type:ty) => {
+ {
+ field_ptr = field_ptr.add(field_ptr.align_offset(std::mem::align_of::<$type>()));
+ let n = std::ptr::read(field_ptr as *mut $type);
+ returns.push(Value::Int(i64::from(n)));
+ field_ptr = field_ptr.add(std::mem::size_of::<$type>());
+ }
+ }
+ }
+
+ match (*field).type_ as u32 {
+ libffi::raw::FFI_TYPE_UINT8 => read_and_push_int!(u8),
+ libffi::raw::FFI_TYPE_SINT8 => read_and_push_int!(i8),
+ libffi::raw::FFI_TYPE_UINT16 => read_and_push_int!(u16),
+ libffi::raw::FFI_TYPE_SINT16 => read_and_push_int!(i16),
+ libffi::raw::FFI_TYPE_UINT32 => read_and_push_int!(u32),
+ libffi::raw::FFI_TYPE_SINT32 => read_and_push_int!(i32),
+ libffi::raw::FFI_TYPE_UINT64 => {
+ field_ptr = field_ptr.add(field_ptr.align_offset(std::mem::align_of::()));
+ let n = std::ptr::read(field_ptr as *mut u64);
+ returns.push(Value::Int(i64::try_from(n).map_err(|_| FFIError::ValueDontFit)?));
+ field_ptr = field_ptr.add(std::mem::size_of::());
+ },
+ libffi::raw::FFI_TYPE_SINT64 => read_and_push_int!(i64),
+ libffi::raw::FFI_TYPE_POINTER => read_and_push_int!(i64),
+ libffi::raw::FFI_TYPE_STRUCT => {
+ let substruct = struct_type.atom_fields[i].as_str();
+ let struct_type = self.structs.get(substruct).ok_or(FFIError::StructNotFound)?;
+ field_ptr = field_ptr.add(field_ptr.align_offset(struct_type.ffi_type.alignment as usize));
+ let struct_val = self.read_struct(field_ptr, substruct, struct_type);
+ returns.push(struct_val?);
+ field_ptr = field_ptr.add(struct_type.ffi_type.size);
+ },
+ _ => {
+ unreachable!()
+ }
+ }
+ }
+ Ok(Value::Struct(name.into(), returns))
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub enum Value {
+ Int(i64),
+ Float(f64),
+ CString(CString),
+ Struct(String, Vec),
+}
+
+impl Value {
+ fn as_int(&self) -> Result {
+ match self {
+ Value::Int(n) => Ok(*n),
+ _ => Err(FFIError::ValueCast),
+ }
+ }
+
+ fn as_float(&self) -> Result {
+ match self {
+ Value::Float(n) => Ok(*n),
+ Value::Int(n) => Ok(*n as f64),
+ _ => Err(FFIError::ValueCast),
+ }
+ }
+
+ fn as_ptr(&mut self) -> Result<*mut c_void, FFIError> {
+ match self {
+ Value::CString(ref mut cstr) => Ok(&mut *cstr as *mut _ as *mut c_void),
+ Value::Int(n) => Ok(*n as *mut c_void),
+ _ => Err(FFIError::ValueCast)
+ }
+ }
+}
+
+#[derive(Debug)]
+pub enum FFIError {
+ ValueCast,
+ ValueDontFit,
+ InvalidFFIType,
+ InvalidStructName,
+ FunctionNotFound,
+ StructNotFound,
+}
diff --git a/src/fixtures.rs b/src/fixtures.rs
deleted file mode 100644
index 43c3ace8..00000000
--- a/src/fixtures.rs
+++ /dev/null
@@ -1,320 +0,0 @@
-use crate::parser::ast::*;
-
-use crate::forms::*;
-use crate::instructions::*;
-use crate::iterators::*;
-
-use indexmap::{IndexMap, IndexSet};
-
-use std::cell::Cell;
-use std::collections::BTreeSet;
-use std::mem::swap;
-use std::rc::Rc;
-use std::vec::Vec;
-
-// labeled with chunk numbers.
-#[derive(Debug)]
-pub(crate) enum VarStatus {
- Perm(usize),
- Temp(usize, TempVarData), // Perm(chunk_num) | Temp(chunk_num, _)
-}
-
-pub(crate) type OccurrenceSet = BTreeSet<(GenContext, usize)>;
-
-// Perm: 0 initially, a stack register once processed.
-// Temp: labeled with chunk_num and temp offset (unassigned if 0).
-#[derive(Debug)]
-pub(crate) enum VarData {
- Perm(usize),
- Temp(usize, usize, TempVarData),
-}
-
-impl VarData {
- pub(crate) fn as_reg_type(&self) -> RegType {
- match self {
- &VarData::Temp(_, r, _) => RegType::Temp(r),
- &VarData::Perm(r) => RegType::Perm(r),
- }
- }
-}
-
-#[derive(Debug)]
-pub(crate) struct TempVarData {
- pub(crate) last_term_arity: usize,
- pub(crate) use_set: OccurrenceSet,
- pub(crate) no_use_set: BTreeSet,
- pub(crate) conflict_set: BTreeSet,
-}
-
-impl TempVarData {
- pub(crate) fn new(last_term_arity: usize) -> Self {
- TempVarData {
- last_term_arity: last_term_arity,
- use_set: BTreeSet::new(),
- no_use_set: BTreeSet::new(),
- conflict_set: BTreeSet::new(),
- }
- }
-
- pub(crate) fn uses_reg(&self, reg: usize) -> bool {
- for &(_, nreg) in self.use_set.iter() {
- if reg == nreg {
- return true;
- }
- }
-
- return false;
- }
-
- pub(crate) fn populate_conflict_set(&mut self) {
- if self.last_term_arity > 0 {
- let arity = self.last_term_arity;
- let mut conflict_set: BTreeSet = (1..arity).collect();
-
- for &(_, reg) in self.use_set.iter() {
- conflict_set.remove(®);
- }
-
- self.conflict_set = conflict_set;
- }
- }
-}
-
-type VariableFixture<'a> = (VarStatus, Vec<&'a Cell>);
-
-#[derive(Debug)]
-pub(crate) struct VariableFixtures<'a> {
- perm_vars: IndexMap, VariableFixture<'a>>,
- last_chunk_temp_vars: IndexSet>,
-}
-
-impl<'a> VariableFixtures<'a> {
- pub(crate) fn new() -> Self {
- VariableFixtures {
- perm_vars: IndexMap::new(),
- last_chunk_temp_vars: IndexSet::new(),
- }
- }
-
- pub(crate) fn insert(&mut self, var: Rc, vs: VariableFixture<'a>) {
- self.perm_vars.insert(var, vs);
- }
-
- pub(crate) fn insert_last_chunk_temp_var(&mut self, var: Rc) {
- self.last_chunk_temp_vars.insert(var);
- }
-
- // computes no_use and conflict sets for all temp vars.
- pub(crate) fn populate_restricting_sets(&mut self) {
- // three stages:
- // 1. move the use sets of each variable to a local IndexMap, use_set
- // (iterate mutably, swap mutable refs).
- // 2. drain use_set. For each use set of U, add into the
- // no-use sets of appropriate variables T =/= U.
- // 3. Move the use sets back to their original locations in the fixture.
- // Compute the conflict set of u.
-
- // 1.
- let mut use_sets: IndexMap, OccurrenceSet> = IndexMap::new();
-
- for (var, &mut (ref mut var_status, _)) in self.iter_mut() {
- if let &mut VarStatus::Temp(_, ref mut var_data) = var_status {
- let mut use_set = OccurrenceSet::new();
-
- swap(&mut var_data.use_set, &mut use_set);
- use_sets.insert((*var).clone(), use_set);
- }
- }
-
- for (u, use_set) in use_sets.drain(..) {
- // 2.
- for &(term_loc, reg) in use_set.iter() {
- if let GenContext::Last(cn_u) = term_loc {
- for (ref t, &mut (ref mut var_status, _)) in self.iter_mut() {
- if let &mut VarStatus::Temp(cn_t, ref mut t_data) = var_status {
- if cn_u == cn_t && *u != ***t {
- if !t_data.uses_reg(reg) {
- t_data.no_use_set.insert(reg);
- }
- }
- }
- }
- }
- }
-
- // 3.
- match self.get_mut(u).unwrap() {
- &mut (VarStatus::Temp(_, ref mut u_data), _) => {
- u_data.use_set = use_set;
- u_data.populate_conflict_set();
- }
- _ => {}
- };
- }
- }
-
- fn get_mut(&mut self, u: Rc) -> Option<&mut VariableFixture<'a>> {
- self.perm_vars.get_mut(&u)
- }
-
- fn iter_mut(&mut self) -> indexmap::map::IterMut, VariableFixture<'a>> {
- self.perm_vars.iter_mut()
- }
-
- fn record_temp_info(&mut self, tvd: &mut TempVarData, arg_c: usize, term_loc: GenContext) {
- match term_loc {
- GenContext::Head | GenContext::Last(_) => {
- tvd.use_set.insert((term_loc, arg_c));
- }
- _ => {}
- };
- }
-
- pub(crate) fn vars_above_threshold(&self, index: usize) -> usize {
- let mut var_count = 0;
-
- for &(ref var_status, _) in self.values() {
- if let &VarStatus::Perm(i) = var_status {
- if i > index {
- var_count += 1;
- }
- }
- }
-
- var_count
- }
-
- pub(crate) fn mark_vars_in_chunk(&mut self, iter: I, lt_arity: usize, term_loc: GenContext)
- where
- I: Iterator- >,
- {
- let chunk_num = term_loc.chunk_num();
- let mut arg_c = 1;
-
- for term_ref in iter {
- if let &TermRef::Var(lvl, cell, ref var) = &term_ref {
- let mut status = self.perm_vars.swap_remove(var).unwrap_or((
- VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)),
- Vec::new(),
- ));
-
- status.1.push(cell);
-
- match status.0 {
- VarStatus::Temp(cn, ref mut tvd) if cn == chunk_num => {
- if let Level::Shallow = lvl {
- self.record_temp_info(tvd, arg_c, term_loc);
- }
- }
- _ => status.0 = VarStatus::Perm(chunk_num),
- };
-
- self.perm_vars.insert(var.clone(), status);
- }
-
- if let Level::Shallow = term_ref.level() {
- arg_c += 1;
- }
- }
- }
-
- pub(crate) fn into_iter(self) -> indexmap::map::IntoIter
, VariableFixture<'a>> {
- self.perm_vars.into_iter()
- }
-
- fn values(&self) -> indexmap::map::Values, VariableFixture<'a>> {
- self.perm_vars.values()
- }
-
- pub(crate) fn size(&self) -> usize {
- self.perm_vars.len()
- }
-
- pub(crate) fn set_perm_vals(&self, has_deep_cuts: bool) {
- let mut values_vec: Vec<_> = self
- .values()
- .filter_map(|ref v| match &v.0 {
- &VarStatus::Perm(i) => Some((i, &v.1)),
- _ => None,
- })
- .collect();
-
- values_vec.sort_by_key(|ref v| v.0);
-
- let offset = has_deep_cuts as usize;
-
- for (i, (_, cells)) in values_vec.into_iter().rev().enumerate() {
- for cell in cells {
- cell.set(VarReg::Norm(RegType::Perm(i + 1 + offset)));
- }
- }
- }
-}
-
-#[derive(Debug)]
-pub(crate) struct UnsafeVarMarker {
- pub(crate) unsafe_vars: IndexMap,
- pub(crate) safe_vars: IndexSet,
-}
-
-impl UnsafeVarMarker {
- pub(crate) fn new() -> Self {
- UnsafeVarMarker {
- unsafe_vars: IndexMap::new(),
- safe_vars: IndexSet::new(),
- }
- }
-
- pub(crate) fn from_safe_vars(safe_vars: IndexSet) -> Self {
- UnsafeVarMarker {
- unsafe_vars: IndexMap::new(),
- safe_vars,
- }
- }
-
- pub(crate) fn mark_safe_vars(&mut self, query_instr: &Instruction) -> bool {
- match query_instr {
- &Instruction::PutVariable(r @ RegType::Temp(_), _) |
- &Instruction::SetVariable(r) => {
- self.safe_vars.insert(r);
- true
- }
- _ => false,
- }
- }
-
- pub(crate) fn mark_phase(&mut self, query_instr: &Instruction, phase: usize) {
- match query_instr {
- &Instruction::PutValue(r @ RegType::Perm(_), _) |
- &Instruction::SetValue(r) => {
- let p = self.unsafe_vars.entry(r).or_insert(0);
- *p = phase;
- }
- _ => {}
- }
- }
-
- pub(crate) fn mark_unsafe_vars(&mut self, query_instr: &mut Instruction, phase: usize) {
- match query_instr {
- &mut Instruction::PutValue(RegType::Perm(i), arg) => {
- if let Some(p) = self.unsafe_vars.swap_remove(&RegType::Perm(i)) {
- if p == phase {
- *query_instr = Instruction::PutUnsafeValue(i, arg);
- self.safe_vars.insert(RegType::Perm(i));
- } else {
- self.unsafe_vars.insert(RegType::Perm(i), p);
- }
- }
- }
- &mut Instruction::SetValue(r) => {
- if !self.safe_vars.contains(&r) {
- *query_instr = Instruction::SetLocalValue(r);
-
- self.safe_vars.insert(r);
- self.unsafe_vars.remove(&r);
- }
- }
- _ => {}
- }
- }
-}
diff --git a/src/forms.rs b/src/forms.rs
index 97864370..fd9c1e28 100644
--- a/src/forms.rs
+++ b/src/forms.rs
@@ -1,13 +1,14 @@
use crate::arena::*;
use crate::atom_table::*;
use crate::instructions::*;
+use crate::machine::disjuncts::VarData;
use crate::machine::heap::*;
use crate::machine::loader::PredicateQueue;
use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*;
use crate::parser::ast::*;
use crate::parser::parser::CompositeOpDesc;
-use crate::parser::rug::{Integer, Rational};
+use crate::parser::dashu::{Integer, Rational};
use crate::types::*;
use fxhash::FxBuildHasher;
@@ -19,26 +20,23 @@ use std::cell::Cell;
use std::collections::VecDeque;
use std::convert::TryFrom;
use std::fmt;
-use std::ops::AddAssign;
+use std::ops::{AddAssign, Deref, DerefMut};
use std::path::PathBuf;
-use std::rc::Rc;
use crate::{is_infix, is_postfix};
pub type PredicateKey = (Atom, usize); // name, arity.
-pub type Predicate = Vec;
-
+/*
// vars of predicate, toplevel offset. Vec is always a vector
// of vars (we get their adjoining cells this way).
pub type JumpStub = Vec;
+*/
-#[derive(Debug, Clone)]
+#[derive(Debug)]
pub enum TopLevel {
- Fact(Term), // Term, line_num, col_num
- Predicate(Predicate),
- Query(Vec),
- Rule(Rule), // Rule, line_num, col_num
+ Fact(Fact, VarData), // Term, line_num, col_num
+ Rule(Rule, VarData), // Rule, line_num, col_num
}
#[derive(Debug, Clone, Copy)]
@@ -57,7 +55,13 @@ impl AppendOrPrepend {
}
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy)]
+pub enum VarComparison {
+ Indistinct,
+ Distinct
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Level {
Deep,
Root,
@@ -79,38 +83,144 @@ pub enum CallPolicy {
Counted,
}
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum ChunkType {
+ Head,
+ Mid,
+ Last,
+}
+
+#[derive(Debug)]
+pub enum RootIterationPolicy {
+ Iterated,
+ NotIterated,
+}
+
+impl RootIterationPolicy {
+ #[inline(always)]
+ pub fn iterable(&self) -> bool {
+ if let RootIterationPolicy::Iterated = self {
+ true
+ } else {
+ false
+ }
+ }
+}
+
+impl ChunkType {
+ #[inline(always)]
+ pub fn to_gen_context(self, chunk_num: usize) -> GenContext {
+ match self {
+ ChunkType::Head => GenContext::Head,
+ ChunkType::Mid => GenContext::Mid(chunk_num),
+ ChunkType::Last => GenContext::Last(chunk_num),
+ }
+ }
+
+ #[inline(always)]
+ pub fn is_last(self) -> bool {
+ self == ChunkType::Last
+ }
+}
+
+#[derive(Debug)]
+pub enum ChunkedTerms {
+ Branch(Vec>),
+ Chunk(VecDeque),
+}
+
+#[derive(Debug)]
+pub struct ChunkedTermVec {
+ pub chunk_vec: VecDeque,
+}
+
+impl Deref for ChunkedTermVec {
+ type Target = VecDeque;
+
+ #[inline(always)]
+ fn deref(&self) -> &Self::Target {
+ &self.chunk_vec
+ }
+}
+
+impl DerefMut for ChunkedTermVec {
+ #[inline(always)]
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.chunk_vec
+ }
+}
+
+impl ChunkedTermVec {
+ #[inline]
+ pub fn new() -> Self {
+ Self { chunk_vec: VecDeque::new() }
+ }
+
+ pub fn reserve_branch(&mut self, capacity: usize) {
+ self.chunk_vec.push_back(ChunkedTerms::Branch(Vec::with_capacity(capacity)));
+ }
+
+ pub fn push_branch_arm(&mut self, branch: VecDeque) {
+ match self.chunk_vec.back_mut().unwrap() {
+ ChunkedTerms::Branch(branches) => {
+ branches.push(branch);
+ }
+ ChunkedTerms::Chunk(_) => {
+ self.chunk_vec.push_back(ChunkedTerms::Branch(vec![branch]));
+ }
+ }
+ }
+
+ #[inline]
+ pub fn add_chunk(&mut self) {
+ self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![])));
+ }
+
+ pub fn push_chunk_term(&mut self, term: QueryTerm) {
+ match self.chunk_vec.back_mut() {
+ Some(ChunkedTerms::Branch(_)) => {
+ self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term])));
+ }
+ Some(ChunkedTerms::Chunk(chunk)) => {
+ chunk.push_back(term);
+ }
+ None => {
+ self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term])));
+ }
+ }
+ }
+}
+
+#[derive(Debug)]
pub enum QueryTerm {
// register, clause type, subterms, clause call policy.
Clause(Cell, ClauseType, Vec, CallPolicy),
- BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
- UnblockedCut(Cell),
- GetLevelAndUnify(Cell, Rc),
- Jump(JumpStub),
+ Fail,
+ LocalCut(usize), // var_num
+ GlobalCut(usize), // var_num
+ GetCutPoint { var_num: usize, prev_b: bool },
+ GetLevel(usize), // var_num
}
impl QueryTerm {
- pub(crate) fn set_call_policy(&mut self, cp: CallPolicy) {
- match self {
- &mut QueryTerm::Clause(_, _, _, ref mut clause_cp) => *clause_cp = cp,
- _ => {}
- }
- }
-
pub(crate) fn arity(&self) -> usize {
match self {
&QueryTerm::Clause(_, _, ref subterms, ..) => subterms.len(),
- &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => 0,
- &QueryTerm::Jump(ref vars) => vars.len(),
- &QueryTerm::GetLevelAndUnify(..) => 1,
+ &QueryTerm::GetLevel(_) | &QueryTerm::GetCutPoint { .. } => 1,
+ _ => 0,
}
}
}
-#[derive(Debug, Clone)]
+#[derive(Debug)]
+pub struct Fact {
+ pub(crate) head: Term,
+}
+
+#[derive(Debug)]
pub struct Rule {
- pub(crate) head: (Atom, Vec, QueryTerm),
- pub(crate) clauses: Vec,
+ pub(crate) head: (Atom, Vec),
+ pub(crate) clauses: ChunkedTermVec,
}
#[derive(Clone, Debug, Hash)]
@@ -201,29 +311,29 @@ impl ClauseInfo for Rule {
impl ClauseInfo for PredicateClause {
fn name(&self) -> Option {
match self {
- &PredicateClause::Fact(ref term, ..) => term.name(),
+ &PredicateClause::Fact(ref term, ..) => term.head.name(),
&PredicateClause::Rule(ref rule, ..) => rule.name(),
}
}
fn arity(&self) -> usize {
match self {
- &PredicateClause::Fact(ref term, ..) => term.arity(),
+ &PredicateClause::Fact(ref term, ..) => term.head.arity(),
&PredicateClause::Rule(ref rule, ..) => rule.arity(),
}
}
}
-#[derive(Debug, Clone)]
+#[derive(Debug)]
pub enum PredicateClause {
- Fact(Term),
- Rule(Rule),
+ Fact(Fact, VarData),
+ Rule(Rule, VarData),
}
impl PredicateClause {
pub(crate) fn args(&self) -> Option<&[Term]> {
match self {
- PredicateClause::Fact(term, ..) => match term {
+ PredicateClause::Fact(term, ..) => match &term.head {
Term::Clause(_, _, args) => Some(&args),
_ => None,
},
@@ -661,9 +771,9 @@ impl Number {
pub(crate) fn is_positive(&self) -> bool {
match self {
&Number::Fixnum(n) => n.get_num() > 0,
- &Number::Integer(ref n) => &**n > &0,
+ &Number::Integer(ref n) => &**n > &Integer::from(0),
&Number::Float(f) => f.is_sign_positive(),
- &Number::Rational(ref r) => &**r > &0,
+ &Number::Rational(ref r) => &**r > &Rational::from(0),
}
}
@@ -671,9 +781,9 @@ impl Number {
pub(crate) fn is_negative(&self) -> bool {
match self {
&Number::Fixnum(n) => n.get_num() < 0,
- &Number::Integer(ref n) => &**n < &0,
+ &Number::Integer(ref n) => &**n < &Integer::from(0),
&Number::Float(OrderedFloat(f)) => f.is_sign_negative() && OrderedFloat(f) != -0f64,
- &Number::Rational(ref r) => &**r < &0,
+ &Number::Rational(ref r) => &**r < &Rational::from(0),
}
}
@@ -681,9 +791,9 @@ impl Number {
pub(crate) fn is_zero(&self) -> bool {
match self {
&Number::Fixnum(n) => n.get_num() == 0,
- &Number::Integer(ref n) => &**n == &0,
+ &Number::Integer(ref n) => &**n == &Integer::from(0),
&Number::Float(f) => f == OrderedFloat(0f64) || f == OrderedFloat(-0f64),
- &Number::Rational(ref r) => &**r == &0,
+ &Number::Rational(ref r) => &**r == &Rational::from(0),
}
}
@@ -812,8 +922,9 @@ impl PredicateInfo {
}
#[inline]
- pub(crate) fn must_retract_local_clauses(&self) -> bool {
- self.is_extensible && self.has_clauses && !self.is_discontiguous
+ pub(crate) fn must_retract_local_clauses(&self, is_cross_module_clause: bool) -> bool {
+ self.is_extensible && self.has_clauses && !self.is_discontiguous &&
+ !(self.is_multifile && is_cross_module_clause)
}
}
diff --git a/src/heap_iter.rs b/src/heap_iter.rs
index 9760be9e..c20840b7 100644
--- a/src/heap_iter.rs
+++ b/src/heap_iter.rs
@@ -1,8 +1,9 @@
#[cfg(test)]
pub(crate) use crate::machine::gc::{IteratorUMP, StacklessPreOrderHeapIter};
-use crate::machine::heap::*;
use crate::atom_table::*;
+use crate::machine::heap::*;
+use crate::machine::stack::*;
use crate::types::*;
use modular_bitfield::prelude::*;
@@ -18,28 +19,45 @@ enum IterStackLocTag {
PendingMark,
}
+#[derive(BitfieldSpecifier, Clone, Copy, Debug, PartialEq, Eq)]
+#[bits = 1]
+pub enum HeapOrStackTag {
+ Heap,
+ Stack,
+}
+
#[bitfield]
#[repr(u64)]
#[derive(Clone, Copy, Debug)]
pub struct IterStackLoc {
- value: B62,
+ pub value: B61,
tag: IterStackLocTag,
+ heap_or_stack: HeapOrStackTag,
}
impl IterStackLoc {
#[inline]
- pub fn iterable_heap_loc(h: usize) -> Self {
- IterStackLoc::new().with_tag(IterStackLocTag::Iterable).with_value(h as u64)
+ pub fn iterable_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
+ IterStackLoc::new()
+ .with_tag(IterStackLocTag::Iterable)
+ .with_heap_or_stack(heap_or_stack)
+ .with_value(h as u64)
}
#[inline]
- pub fn mark_heap_loc(h: usize) -> Self {
- IterStackLoc::new().with_tag(IterStackLocTag::Marked).with_value(h as u64)
+ fn mark_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
+ IterStackLoc::new()
+ .with_tag(IterStackLocTag::Marked)
+ .with_heap_or_stack(heap_or_stack)
+ .with_value(h as u64)
}
#[inline]
- pub fn pending_mark_heap_loc(h: usize) -> Self {
- IterStackLoc::new().with_tag(IterStackLocTag::PendingMark).with_value(h as u64)
+ fn pending_mark_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
+ IterStackLoc::new()
+ .with_tag(IterStackLocTag::PendingMark)
+ .with_heap_or_stack(heap_or_stack)
+ .with_value(h as u64)
}
#[inline]
@@ -51,38 +69,35 @@ impl IterStackLoc {
pub fn is_pending_mark(self) -> bool {
self.tag() == IterStackLocTag::PendingMark
}
-}
-#[inline]
-fn forward_if_referent_marked(heap: &mut [HeapCellValue], h: usize) {
- read_heap_cell!(heap[h],
- (HeapCellValueTag::Str
- | HeapCellValueTag::Lis
- | HeapCellValueTag::AttrVar
- | HeapCellValueTag::Var
- | HeapCellValueTag::PStrLoc, vh) => {
- if heap[vh].get_mark_bit() {
- heap[h].set_forwarding_bit(true);
+ #[inline]
+ pub fn as_ref(self) -> Ref {
+ match self.heap_or_stack() {
+ HeapOrStackTag::Heap => {
+ Ref::heap_cell(self.value() as usize)
+ }
+ HeapOrStackTag::Stack => {
+ Ref::stack_cell(self.value() as usize)
}
}
- _ => {}
- )
+ }
}
#[derive(Debug)]
pub struct StackfulPreOrderHeapIter<'a> {
pub heap: &'a mut Vec,
+ pub machine_stack: &'a mut Stack,
stack: Vec,
- h: usize,
+ h: IterStackLoc,
}
impl<'a> Drop for StackfulPreOrderHeapIter<'a> {
fn drop(&mut self) {
while let Some(h) = self.stack.pop() {
- let h = h.value() as usize;
+ let cell = self.read_cell_mut(h);
- self.heap[h].set_forwarding_bit(false);
- self.heap[h].set_mark_bit(false);
+ cell.set_forwarding_bit(false);
+ cell.set_mark_bit(false);
}
self.heap.pop();
@@ -90,48 +105,93 @@ impl<'a> Drop for StackfulPreOrderHeapIter<'a> {
}
pub trait FocusedHeapIter: Iterator- {
- fn focus(&self) -> usize;
+ fn focus(&self) -> IterStackLoc;
}
impl<'a> FocusedHeapIter for StackfulPreOrderHeapIter<'a> {
#[inline]
- fn focus(&self) -> usize {
+ fn focus(&self) -> IterStackLoc {
self.h
}
}
impl<'a> StackfulPreOrderHeapIter<'a> {
#[inline]
- fn new(heap: &'a mut Vec
, cell: HeapCellValue) -> Self {
- let h = heap.len();
+ fn new(heap: &'a mut Vec, stack: &'a mut Stack, cell: HeapCellValue) -> Self {
+ let h = IterStackLoc::iterable_loc(heap.len(), HeapOrStackTag::Heap);
heap.push(cell);
Self {
heap,
h,
- stack: vec![IterStackLoc::iterable_heap_loc(h)],
+ machine_stack: stack,
+ stack: vec![h],
}
}
#[inline]
- pub fn push_stack(&mut self, h: usize) {
- self.stack.push(IterStackLoc::iterable_heap_loc(h));
+ fn forward_if_referent_marked(&mut self, loc: IterStackLoc) {
+ read_heap_cell!(self.read_cell(loc),
+ (HeapCellValueTag::Str |
+ HeapCellValueTag::Lis |
+ HeapCellValueTag::AttrVar |
+ HeapCellValueTag::Var |
+ HeapCellValueTag::PStrLoc, vh) => {
+ if self.heap[vh].get_mark_bit() {
+ self.read_cell_mut(loc).set_forwarding_bit(true);
+ }
+ }
+ (HeapCellValueTag::StackVar, vs) => {
+ if self.machine_stack[vs].get_mark_bit() {
+ self.read_cell_mut(loc).set_forwarding_bit(true);
+ }
+ }
+ _ => {}
+ );
}
#[inline]
- pub fn stack_last(&self) -> Option {
+ pub fn push_stack(&mut self, h: IterStackLoc) {
+ self.stack.push(h);
+ }
+
+ #[inline]
+ pub fn read_cell_mut(&mut self, loc: IterStackLoc) -> &mut HeapCellValue {
+ match loc.heap_or_stack() {
+ HeapOrStackTag::Heap => {
+ &mut self.heap[loc.value() as usize]
+ }
+ HeapOrStackTag::Stack => {
+ &mut self.machine_stack[loc.value() as usize]
+ }
+ }
+ }
+
+ #[inline]
+ pub fn read_cell(&self, loc: IterStackLoc) -> HeapCellValue {
+ match loc.heap_or_stack() {
+ HeapOrStackTag::Heap => {
+ self.heap[loc.value() as usize]
+ }
+ HeapOrStackTag::Stack => {
+ self.machine_stack[loc.value() as usize]
+ }
+ }
+ }
+
+ #[inline]
+ pub fn stack_last(&self) -> Option {
for h in self.stack.iter().rev() {
let is_readable_marked = h.is_marked();
- let h = h.value() as usize;
- let cell = self.heap[h];
+ let cell = self.read_cell(*h);
if cell.get_forwarding_bit() {
- return Some(h);
+ return Some(*h);
} else if cell.get_mark_bit() && !is_readable_marked {
continue;
}
- return Some(h);
+ return Some(*h);
}
None
@@ -141,10 +201,9 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
pub fn pop_stack(&mut self) -> Option {
while let Some(h) = self.stack.pop() {
let is_readable_marked = h.is_marked();
- let h = h.value() as usize;
- self.h = h;
- let cell = &mut self.heap[h];
+ self.h = h;
+ let cell = self.read_cell_mut(h);
if cell.get_forwarding_bit() {
cell.set_forwarding_bit(false);
@@ -159,30 +218,34 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
None
}
- fn push_if_unmarked(&mut self, h: usize) {
- if !self.heap[h].get_mark_bit() {
- self.heap[h].set_mark_bit(true);
- self.stack.push(IterStackLoc::iterable_heap_loc(h));
+ #[inline]
+ pub fn stack_len(&self) -> usize {
+ self.stack.len()
+ }
+
+ fn push_if_unmarked(&mut self, loc: IterStackLoc) {
+ let cell = self.read_cell_mut(loc);
+
+ if !cell.get_mark_bit() {
+ cell.set_mark_bit(true);
+ self.stack.push(IterStackLoc::iterable_loc(loc.value() as usize, loc.heap_or_stack()));
}
}
fn follow(&mut self) -> Option {
while let Some(h) = self.stack.pop() {
if h.is_pending_mark() {
- let h = h.value() as usize;
-
self.push_if_unmarked(h);
- self.stack.push(IterStackLoc::mark_heap_loc(h));
+ self.stack.push(IterStackLoc::mark_loc(h.value() as usize, h.heap_or_stack()));
- forward_if_referent_marked(&mut self.heap, h);
+ self.forward_if_referent_marked(h);
continue;
}
- let is_readable_marked = h.is_marked();
- let h = h.value() as usize;
-
self.h = h;
- let cell = &mut self.heap[h];
+
+ let is_readable_marked = h.is_marked();
+ let cell = self.read_cell_mut(h);
if cell.get_forwarding_bit() {
let copy = *cell;
@@ -195,50 +258,68 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
read_heap_cell!(*cell,
(HeapCellValueTag::Str | HeapCellValueTag::PStrLoc, vh) => {
- self.push_if_unmarked(vh);
- self.stack.push(IterStackLoc::mark_heap_loc(vh));
+ let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
+
+ self.push_if_unmarked(loc);
+ self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap));
}
(HeapCellValueTag::Lis, vh) => {
- self.push_if_unmarked(vh);
+ let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
- self.stack.push(IterStackLoc::pending_mark_heap_loc(vh + 1));
- self.stack.push(IterStackLoc::mark_heap_loc(vh));
+ self.push_if_unmarked(loc);
- forward_if_referent_marked(&mut self.heap, vh);
+ self.stack.push(IterStackLoc::pending_mark_loc(vh + 1, HeapOrStackTag::Heap));
+ self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap));
- return Some(self.heap[h]);
+ self.forward_if_referent_marked(loc);
+
+ return Some(self.read_cell(h));
}
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, vh) => {
- self.push_if_unmarked(vh);
- self.stack.push(IterStackLoc::mark_heap_loc(vh));
- forward_if_referent_marked(&mut self.heap, vh);
+ let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
+
+ self.push_if_unmarked(loc);
+ self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap));
+ self.forward_if_referent_marked(loc);
+ }
+ (HeapCellValueTag::StackVar, vs) => {
+ let loc = IterStackLoc::iterable_loc(vs, HeapOrStackTag::Stack);
+
+ self.push_if_unmarked(loc);
+ self.stack.push(IterStackLoc::mark_loc(vs, HeapOrStackTag::Stack));
+ self.forward_if_referent_marked(loc);
}
(HeapCellValueTag::PStrOffset, offset) => {
- self.push_if_unmarked(offset);
- self.stack.push(IterStackLoc::iterable_heap_loc(h+1));
+ self.push_if_unmarked(IterStackLoc::iterable_loc(offset, HeapOrStackTag::Heap));
+ self.stack.push(IterStackLoc::iterable_loc((h.value()+1) as usize, HeapOrStackTag::Heap));
- return Some(self.heap[h]);
+ return Some(self.read_cell(h));
}
(HeapCellValueTag::PStr) => {
- self.push_if_unmarked(h);
+ let tail_loc = IterStackLoc::iterable_loc((h.value()+1) as usize, HeapOrStackTag::Heap);
- self.stack.push(IterStackLoc::iterable_heap_loc(h+1));
- forward_if_referent_marked(&mut self.heap, h+1);
+ self.push_if_unmarked(IterStackLoc::iterable_loc(h.value() as usize, HeapOrStackTag::Heap));
+ self.stack.push(tail_loc);
+ self.forward_if_referent_marked(tail_loc);
- return Some(self.heap[h]);
+ return Some(self.read_cell(h));
}
(HeapCellValueTag::Atom, (_name, arity)) => {
- for h in (h + 2 .. h + arity + 1).rev() {
- self.stack.push(IterStackLoc::pending_mark_heap_loc(h));
+ let l = h.value() as usize;
+
+ for l in (l + 2 .. l + arity + 1).rev() {
+ self.stack.push(IterStackLoc::pending_mark_loc(l, HeapOrStackTag::Heap));
}
if arity > 0 {
- self.push_if_unmarked(h+1);
- self.stack.push(IterStackLoc::mark_heap_loc(h+1));
- forward_if_referent_marked(&mut self.heap, h+1);
+ let first_arg_loc = IterStackLoc::iterable_loc(l+1, HeapOrStackTag::Heap);
+
+ self.push_if_unmarked(first_arg_loc);
+ self.stack.push(IterStackLoc::mark_loc(l+1, HeapOrStackTag::Heap));
+ self.forward_if_referent_marked(first_arg_loc);
}
- return Some(self.heap[h]);
+ return Some(self.read_cell(h));
}
_ => {
return Some(*cell);
@@ -269,19 +350,20 @@ pub(crate) fn stackless_preorder_iter(
}
#[inline(always)]
-pub(crate) fn stackful_preorder_iter(
- heap: &mut Vec,
+pub(crate) fn stackful_preorder_iter<'a>(
+ heap: &'a mut Vec,
+ stack: &'a mut Stack,
cell: HeapCellValue,
-) -> StackfulPreOrderHeapIter {
- StackfulPreOrderHeapIter::new(heap, cell)
+) -> StackfulPreOrderHeapIter<'a> {
+ StackfulPreOrderHeapIter::new(heap, stack, cell)
}
#[derive(Debug)]
pub(crate) struct PostOrderIterator {
- focus: usize,
+ focus: IterStackLoc,
base_iter: Iter,
base_iter_valid: bool,
- parent_stack: Vec<(usize, HeapCellValue, usize)>, // number of children, parent node, focus.
+ parent_stack: Vec<(usize, HeapCellValue, IterStackLoc)>, // number of children, parent node, focus.
}
impl Deref for PostOrderIterator {
@@ -295,7 +377,7 @@ impl Deref for PostOrderIterator {
impl PostOrderIterator {
pub(crate) fn new(base_iter: Iter) -> Self {
PostOrderIterator {
- focus: 0,
+ focus: IterStackLoc::iterable_loc(0, HeapOrStackTag::Heap),
base_iter,
base_iter_valid: true,
parent_stack: vec![],
@@ -352,7 +434,7 @@ impl Iterator for PostOrderIterator {
impl FocusedHeapIter for PostOrderIterator {
#[inline(always)]
- fn focus(&self) -> usize {
+ fn focus(&self) -> IterStackLoc {
self.focus
}
}
@@ -368,7 +450,8 @@ impl PostOrderIterator {
if let Some((_child_count, item, focus)) = self.parent_stack.last() {
read_heap_cell!(item,
(HeapCellValueTag::Atom, (_name, arity)) => {
- return focus + arity >= idx_loc && *focus < idx_loc;
+ let focus = focus.value() as usize;
+ return focus + arity >= idx_loc && focus < idx_loc;
}
_ => {}
);
@@ -401,9 +484,10 @@ impl<'a> LeftistPostOrderHeapIter<'a> {
#[inline]
pub(crate) fn stackful_post_order_iter<'a>(
heap: &'a mut Heap,
+ stack: &'a mut Stack,
cell: HeapCellValue,
) -> LeftistPostOrderHeapIter<'a> {
- PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, cell))
+ PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, stack, cell))
}
#[cfg(test)]
@@ -1382,7 +1466,11 @@ mod tests {
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, str_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ str_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1413,7 +1501,11 @@ mod tests {
));
for _ in 0..20 {
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, str_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ str_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1441,7 +1533,12 @@ mod tests {
{
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
+
let mut var = heap_loc_as_cell!(0);
// self-referencing variables are copied with their forwarding
@@ -1463,7 +1560,11 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(1));
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1483,7 +1584,11 @@ mod tests {
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1515,7 +1620,11 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(0));
{
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
// the cycle will be iterated twice before being detected.
assert_eq!(
@@ -1543,7 +1652,11 @@ mod tests {
}
{
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
// cut the iteration short to check that all cells are
// unmarked and unforwarded by the Drop instance of
@@ -1577,7 +1690,11 @@ mod tests {
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
assert_eq!(
@@ -1597,7 +1714,11 @@ mod tests {
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{
- let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackful_preorder_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
@@ -1616,7 +1737,12 @@ mod tests {
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{
- let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter = stackful_preorder_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ pstr_loc_as_cell!(0),
+ );
+
let pstr_offset_cell = pstr_offset_as_cell!(0);
// pstr_offset_cell.set_forwarding_bit(true);
@@ -1641,7 +1767,12 @@ mod tests {
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{
- let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter = stackful_preorder_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ pstr_loc_as_cell!(0),
+ );
+
let pstr_offset_cell = pstr_offset_as_cell!(0);
// pstr_offset_cell.set_forwarding_bit(true);
@@ -1654,7 +1785,7 @@ mod tests {
let h = iter.focus();
- assert_eq!(h, 5);
+ assert_eq!(h.value(), 5);
assert_eq!(unmark_cell_bits!(iter.heap[4]), pstr_offset_as_cell!(0));
assert_eq!(unmark_cell_bits!(iter.heap[5]), fixnum_as_cell!(Fixnum::build_with(1i64)));
@@ -1674,7 +1805,11 @@ mod tests {
wam.machine_st.heap.extend(functor);
{
- let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = StackfulPreOrderHeapIter::new(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1733,7 +1868,11 @@ mod tests {
wam.machine_st.heap[4] = list_loc_as_cell!(1);
{
- let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackful_preorder_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1800,6 +1939,7 @@ mod tests {
{
let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
@@ -1831,6 +1971,7 @@ mod tests {
{
let mut iter = stackful_preorder_iter(
&mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
@@ -1865,6 +2006,7 @@ mod tests {
{
let mut iter = stackful_preorder_iter(
&mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
@@ -1899,7 +2041,11 @@ mod tests {
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ str_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1930,7 +2076,11 @@ mod tests {
));
for _ in 0..20 { // 0000 {
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ str_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1960,7 +2110,12 @@ mod tests {
{
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
+
let mut var = heap_loc_as_cell!(0);
// self-referencing variables are copied with their forwarding
@@ -1982,7 +2137,11 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(1));
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2002,7 +2161,11 @@ mod tests {
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2034,7 +2197,11 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(0));
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
// the cycle will be iterated twice before being detected.
assert_eq!(
@@ -2064,6 +2231,7 @@ mod tests {
{
let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
@@ -2099,7 +2267,11 @@ mod tests {
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ pstr_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2118,7 +2290,11 @@ mod tests {
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ pstr_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2137,7 +2313,11 @@ mod tests {
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ pstr_loc_as_cell!(0),
+ );
assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(0i64)));
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
@@ -2152,7 +2332,11 @@ mod tests {
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ pstr_loc_as_cell!(0),
+ );
assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(1i64)));
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
@@ -2176,7 +2360,11 @@ mod tests {
wam.machine_st.heap.extend(functor);
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2236,7 +2424,11 @@ mod tests {
wam.machine_st.heap[4] = list_loc_as_cell!(1);
{
- let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackful_post_order_iter(
+ &mut wam.machine_st.heap,
+ &mut wam.machine_st.stack,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2343,7 +2535,10 @@ mod tests {
));
for _ in 0..20 {
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
+ let mut iter = stackless_post_order_iter(
+ &mut wam.machine_st.heap,
+ str_loc_as_cell!(0),
+ );
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
@@ -2373,7 +2568,10 @@ mod tests {
{
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackless_post_order_iter(
+ &mut wam.machine_st.heap,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2389,7 +2587,10 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(1));
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter = stackless_post_order_iter(
+ &mut wam.machine_st.heap,
+ heap_loc_as_cell!(0),
+ );
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
diff --git a/src/heap_print.rs b/src/heap_print.rs
index 54f52cd6..8be39076 100644
--- a/src/heap_print.rs
+++ b/src/heap_print.rs
@@ -1,7 +1,7 @@
use crate::arena::*;
use crate::atom_table::*;
use crate::parser::ast::*;
-use crate::parser::rug::{Integer, Rational};
+use crate::parser::dashu::{Integer, Rational};
use crate::{
alpha_numeric_char, capital_letter_char, cut_char, decimal_digit_char, graphic_token_char,
is_fx, is_infix, is_postfix, is_prefix, is_xf, is_xfx, is_xfy, is_yfx, semicolon_char,
@@ -14,9 +14,12 @@ use crate::machine::heap::*;
use crate::machine::machine_indices::*;
use crate::machine::machine_state::pstr_loc_and_offset;
use crate::machine::partial_string::*;
+use crate::machine::stack::*;
use crate::machine::streams::*;
use crate::types::*;
+use dashu::base::DivRem;
+use dashu::base::DivRemEuclid;
use ordered_float::OrderedFloat;
use indexmap::IndexMap;
@@ -25,7 +28,6 @@ use std::cell::Cell;
use std::convert::TryFrom;
use std::iter::once;
use std::net::{IpAddr, TcpListener};
-use std::ops::{Range, RangeFrom};
use std::rc::Rc;
/* contains the location, name, precision and Specifier of the parent op. */
@@ -43,6 +45,15 @@ impl DirectedOp {
}
}
+ #[inline]
+ fn is_prefix(&self )-> bool {
+ match self {
+ &DirectedOp::Left(_name, cell) | &DirectedOp::Right(_name, cell) => {
+ is_prefix!(cell.get_spec() as u32)
+ }
+ }
+ }
+
#[inline]
fn is_negative_sign(&self) -> bool {
match self {
@@ -54,11 +65,7 @@ impl DirectedOp {
#[inline]
fn is_left(&self) -> bool {
- if let &DirectedOp::Left(..) = self {
- true
- } else {
- false
- }
+ matches!(self, DirectedOp::Left(..))
}
}
@@ -115,7 +122,9 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
let mut parent_spec = DirectedOp::Left(atom!("-"), OpDesc::build_with(200, FY as u8));
loop {
- read_heap_cell!(self.heap[h],
+ let cell = self.read_cell(h);
+
+ read_heap_cell!(cell,
(HeapCellValueTag::Str, s) => {
read_heap_cell!(self.heap[s],
(HeapCellValueTag::Atom, (name, _arity)) => {
@@ -124,7 +133,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
if needs_bracketing(spec, &parent_spec) {
return false;
} else {
- h = s + 1;
+ h = IterStackLoc::iterable_loc(s + 1, HeapOrStackTag::Heap);
parent_spec = DirectedOp::Right(name, spec);
continue;
}
@@ -139,7 +148,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
)
}
_ => {
- return property_check(self.heap[h]);
+ return property_check(cell);
}
)
}
@@ -149,12 +158,12 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
where
P: Fn(HeapCellValue) -> bool,
{
- let addr = match self.stack_last() {
- Some(h) => self.heap[h],
+ let cell = match self.stack_last() {
+ Some(h) => self.read_cell(h),
None => return false,
};
- property_check(addr)
+ property_check(cell)
}
}
@@ -169,11 +178,16 @@ fn char_to_string(is_quoted: bool, c: char) -> String {
'\u{08}' if is_quoted => "\\b".to_string(), // UTF-8 backspace
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
'\\' if is_quoted => "\\\\".to_string(),
- '\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
+ ' ' | '\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
c.to_string()
}
- '\u{0}'..='\u{1f}' => format!("\\x{:x}\\", c as u32), // print all other control characters in hex.
- _ => c.to_string(),
+ _ =>
+ if c.is_whitespace() || c.is_control() {
+ // print all other control and whitespace characters in hex.
+ format!("\\x{:x}\\", c as u32)
+ } else {
+ c.to_string()
+ }
}
}
@@ -188,7 +202,7 @@ impl NumberFocus {
fn is_negative(&self) -> bool {
match self {
NumberFocus::Unfocused(n) => n.is_negative(),
- NumberFocus::Denominator(r) | NumberFocus::Numerator(r) => **r < 0,
+ NumberFocus::Denominator(r) | NumberFocus::Numerator(r) => **r < Rational::from(0),
}
}
}
@@ -212,6 +226,8 @@ enum TokenOrRedirect {
Space,
LeftCurly,
RightCurly,
+ ChildOpenList,
+ ChildCloseList,
OpenList(Rc>),
CloseList(Rc>),
HeadTailSeparator,
@@ -311,8 +327,7 @@ pub trait HCValueOutputter {
fn ends_with(&self, s: &str) -> bool;
fn len(&self) -> usize;
fn truncate(&mut self, len: usize);
- fn range(&self, range: Range) -> &str;
- fn range_from(&self, range: RangeFrom) -> &str;
+ fn as_str(&self) -> &str;
}
#[derive(Debug)]
@@ -367,12 +382,8 @@ impl HCValueOutputter for PrinterOutputter {
self.contents.truncate(len);
}
- fn range(&self, index: Range) -> &str {
- &self.contents.as_str()[index]
- }
-
- fn range_from(&self, index: RangeFrom) -> &str {
- &self.contents.as_str().get(index).unwrap_or("")
+ fn as_str(&self) -> &str {
+ &self.contents
}
}
@@ -392,8 +403,8 @@ fn negated_op_needs_bracketing(
&& iter.leftmost_leaf_has_property(op_dir, |addr| match Number::try_from(addr) {
Ok(Number::Fixnum(n)) => n.get_num() > 0,
Ok(Number::Float(f)) => f > OrderedFloat(0f64),
- Ok(Number::Integer(n)) => &*n > &0,
- Ok(Number::Rational(n)) => &*n > &0,
+ Ok(Number::Integer(n)) => &*n > &Integer::from(0),
+ Ok(Number::Rational(n)) => &*n > &Rational::from(0),
_ => false,
})
} else {
@@ -468,17 +479,20 @@ pub fn fmt_float(mut fl: f64) -> String {
pub struct HCPrinter<'a, Outputter> {
outputter: Outputter,
iter: StackfulPreOrderHeapIter<'a>,
+ atom_tbl: &'a mut AtomTable,
op_dir: &'a OpDir,
state_stack: Vec,
toplevel_spec: Option,
last_item_idx: usize,
- pub var_names: IndexMap>,
+ parent_of_first_op: Option<(DirectedOp, usize)>,
+ pub var_names: IndexMap,
pub numbervars_offset: Integer,
pub numbervars: bool,
pub quoted: bool,
pub ignore_ops: bool,
pub print_strings_as_strs: bool,
pub max_depth: usize,
+ pub double_quotes: bool,
}
macro_rules! push_space_if_amb {
@@ -499,11 +513,13 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
];
- let i = n.mod_u(26) as usize;
- let j = n.div_rem_floor(Integer::from(26));
+ let n_clone: Integer = n.clone();
+
+ let i = n.div_rem_euclid(Integer::from(26)).1.to_f32().value() as usize;
+ let j = n_clone.div_rem(Integer::from(26));
let j = <(Integer, Integer)>::from(j).0;
- if j == 0 {
+ if j == Integer::from(0) {
CHAR_CODES[i].to_string()
} else {
format!("{}{}", CHAR_CODES[i], j)
@@ -519,7 +535,7 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option
}
}
Ok(Number::Integer(n)) => {
- if &*n >= &0 {
+ if &*n >= &Integer::from(0) {
Some(numbervar(Integer::from(offset + &*n)))
} else {
None
@@ -532,17 +548,21 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
pub fn new(
heap: &'a mut Heap,
+ atom_tbl: &'a mut AtomTable,
+ stack: &'a mut Stack,
op_dir: &'a OpDir,
output: Outputter,
cell: HeapCellValue,
) -> Self {
HCPrinter {
outputter: output,
- iter: stackful_preorder_iter(heap, cell),
+ iter: stackful_preorder_iter(heap, stack, cell),
+ atom_tbl,
op_dir,
state_stack: vec![],
toplevel_spec: None,
last_item_idx: 0,
+ parent_of_first_op: None,
numbervars: false,
numbervars_offset: Integer::from(0),
quoted: false,
@@ -550,59 +570,64 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
var_names: IndexMap::new(),
print_strings_as_strs: false,
max_depth: 0,
+ double_quotes: false,
}
}
#[inline]
fn ambiguity_check(&self, atom: &str) -> bool {
- let tail = self.outputter.range_from(self.last_item_idx..);
- requires_space(tail, atom)
+ let tail = &self.outputter.as_str()[self.last_item_idx..];
+
+ if !self.quoted || non_quoted_token(atom.chars()) {
+ requires_space(tail, atom)
+ } else {
+ requires_space(tail, "'")
+ }
+ }
+
+ fn set_parent_of_first_op(&mut self, parent_op: Option) {
+ if let Some(op) = parent_op {
+ if op.is_left() && op.is_prefix() {
+ self.parent_of_first_op = Some((op, self.last_item_idx));
+ }
+ }
}
fn enqueue_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc) {
if is_postfix!(spec.get_spec()) {
- if self.check_max_depth(&mut max_depth) {
+ if self.max_depth_exhausted(max_depth) {
+ self.iter.pop_stack();
+ self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
+ } else if self.check_max_depth(&mut max_depth) {
self.iter.pop_stack();
self.state_stack.push(TokenOrRedirect::Op(name, spec));
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
+ } else {
+ let right_directed_op = DirectedOp::Right(name, spec);
- return;
+ self.state_stack.push(TokenOrRedirect::Op(name, spec));
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(
+ max_depth,
+ right_directed_op,
+ ));
}
-
- let right_directed_op = DirectedOp::Right(name, spec);
-
- self.state_stack.push(TokenOrRedirect::Op(name, spec));
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(
- max_depth,
- right_directed_op,
- ));
} else if is_prefix!(spec.get_spec()) {
- match name {
- atom!("-") | atom!("\\") => {
- self.format_prefix_op_with_space(max_depth, name, spec);
- return;
- }
- _ => {}
- };
-
- if self.check_max_depth(&mut max_depth) {
+ if self.max_depth_exhausted(max_depth) {
+ self.iter.pop_stack();
+ self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
+ return;
+ } else if self.check_max_depth(&mut max_depth) {
self.iter.pop_stack();
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
self.state_stack.push(TokenOrRedirect::Op(name, spec));
+ } else {
+ let op = DirectedOp::Left(name, spec);
- return;
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
+ self.state_stack.push(TokenOrRedirect::Op(name, spec));
}
-
- let left_directed_op = DirectedOp::Left(name, spec);
-
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(
- max_depth,
- left_directed_op,
- ));
-
- self.state_stack.push(TokenOrRedirect::Op(name, spec));
} else {
match name.as_str() {
"|" => {
@@ -612,31 +637,26 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
_ => {}
};
- let ellipsis_atom = atom!("...");
-
- if self.check_max_depth(&mut max_depth) {
+ if self.max_depth_exhausted(max_depth) {
self.iter.pop_stack();
self.iter.pop_stack();
- self.state_stack.push(TokenOrRedirect::Atom(ellipsis_atom));
+ self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
+ } else if self.check_max_depth(&mut max_depth) {
+ self.iter.pop_stack();
+ self.iter.pop_stack();
+
+ self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
self.state_stack.push(TokenOrRedirect::Op(name, spec));
- self.state_stack.push(TokenOrRedirect::Atom(ellipsis_atom));
+ self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
+ } else {
+ let left_directed_op = DirectedOp::Left(name, spec);
+ let right_directed_op = DirectedOp::Right(name, spec);
- return;
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op));
+ self.state_stack.push(TokenOrRedirect::Op(name, spec));
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
}
-
- let left_directed_op = DirectedOp::Left(name, spec);
- let right_directed_op = DirectedOp::Right(name, spec);
-
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(
- max_depth,
- left_directed_op,
- ));
- self.state_stack.push(TokenOrRedirect::Op(name, spec));
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(
- max_depth,
- right_directed_op,
- ));
}
}
@@ -675,27 +695,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
true
}
- fn format_prefix_op_with_space(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc) {
- if self.check_max_depth(&mut max_depth) {
- self.iter.pop_stack();
-
- self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
- self.state_stack.push(TokenOrRedirect::Space);
- self.state_stack.push(TokenOrRedirect::Atom(name));
-
- return;
- }
-
- let op = DirectedOp::Left(name, spec);
-
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
- self.state_stack.push(TokenOrRedirect::Space);
- self.state_stack.push(TokenOrRedirect::Atom(name));
- }
-
fn format_bar_separator_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc) {
if self.check_max_depth(&mut max_depth) {
self.iter.pop_stack();
+ self.iter.pop_stack();
let ellipsis_atom = atom!("...");
@@ -746,14 +749,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
fn format_numbered_vars(&mut self) -> bool {
let h = self.iter.stack_last().unwrap();
- let addr = self.iter.heap[h];
- let addr = heap_bound_store(
+ let cell = self.iter.read_cell(h);
+ let cell = heap_bound_store(
&self.iter.heap,
- heap_bound_deref(&self.iter.heap, addr),
+ heap_bound_deref(&self.iter.heap, cell),
);
// 7.10.4
- if let Some(var) = numbervar(&self.numbervars_offset, addr) {
+ if let Some(var) = numbervar(&self.numbervars_offset, cell) {
self.iter.pop_stack();
self.state_stack.push(TokenOrRedirect::NumberedVar(var));
return true;
@@ -797,13 +800,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
};
}
- fn offset_as_string(&mut self, h: usize) -> Option {
- let addr = self.iter.heap[h];
+ fn offset_as_string(&mut self, h: IterStackLoc) -> Option {
+ let cell = self.iter.read_cell(h);
- if let Some(var) = self.var_names.get(&addr) {
- read_heap_cell!(addr,
+ if let Some(var) = self.var_names.get(&cell) {
+ read_heap_cell!(cell,
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
- return Some(format!("{}", var.as_str()));
+ return Some(var.borrow().to_string());
}
_ => {
self.iter.push_stack(h);
@@ -812,7 +815,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
);
}
- read_heap_cell!(addr,
+ read_heap_cell!(cell,
(HeapCellValueTag::Lis | HeapCellValueTag::Str, h) => {
Some(format!("{}", h))
}
@@ -829,41 +832,42 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
}
fn check_for_seen(&mut self) -> Option | |