diff --git a/.github/scripts/release-wasm-post.sh b/.github/scripts/release-wasm-post.sh index 885b0c2..d8851d4 100755 --- a/.github/scripts/release-wasm-post.sh +++ b/.github/scripts/release-wasm-post.sh @@ -1,3 +1,4 @@ + #!/usr/bin/env bash set -ex @@ -5,10 +6,12 @@ set -ex # This script takes the generated .wasm and preparse it for the release. wasm_file="$1" dirname="$(dirname "$wasm_file")" +mkdir -p "$dirname" cd "$dirname" wasm_file="$(basename "$wasm_file")" cat >index.html < @@ -29,11 +32,11 @@ cat >index.html < SDFViewer.run_app("sdf-viewer")); // Run the actual App - // Start a toggleable web console for mobile devices only (to help with debugging) + // Start a toggleable web console for mobile devices only (to help with debugging) if (/Mobi|Android/i.test(navigator.userAgent)) { var src = '//cdn.jsdelivr.net/npm/eruda'; - document.write(''); - document.write('eruda.init();'); + document.write(''); + document.write('eruda.init();'); } diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f0ff27f..c3f504d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -71,7 +71,7 @@ jobs: target: wasm32-unknown-unknown ext: tar.gz # After post-processing pre: rustup target add wasm32-unknown-unknown && curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - build: wasm-pack build --target web --out-dir ./target/pkg -- --no-default-features --features "app meshers web" + build: wasm-pack build --target web --out-dir ./target/pkg -- --no-default-features --features default-wasm post: ".github/scripts/release-wasm-post.sh ./target/pkg/${GITHUB_REPOSITORY#*/}.wasm" # TODO: Android # - os: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index ba53a32..ada9cc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -464,16 +464,10 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide 0.6.2", - "object 0.30.3", + "object", "rustc-demangle", ] -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - [[package]] name = "base64" version = "0.12.3" @@ -692,7 +686,7 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.17", + "semver", "serde", "serde_json", ] @@ -919,7 +913,7 @@ dependencies = [ "rand 0.8.5", "sha2", "subtle", - "time 0.3.21", + "time", "version_check", ] @@ -986,6 +980,72 @@ dependencies = [ "libc", ] +[[package]] +name = "cranelift-bforest" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "529ffacce2249ac60edba2941672dfedf3d96558b415d0d8083cd007456e0f55" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427d105f617efc8cb55f8d036a7fded2e227892d8780b4985e5551f8d27c4a92" +dependencies = [ + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-entity", + "cranelift-isle", + "gimli 0.26.2", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551674bed85b838d45358e3eab4f0ffaa6790c70dc08184204b9a54b41cdb7d1" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b3a63ae57498c3eb495360944a33571754241e15e47e3bcae6082f40fec5866" + +[[package]] +name = "cranelift-entity" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11aa8aa624c72cc1c94ea3d0739fa61248260b5b14d3646f51593a88d67f3e6e" + +[[package]] +name = "cranelift-frontend" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "544ee8f4d1c9559c9aa6d46e7aaeac4a13856d620561094f35527356c7d21bd0" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.86.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed16b14363d929b8c37e3c557d0a7396791b383ecc302141643c054343170aad" + [[package]] name = "crc32fast" version = "1.3.2" @@ -1171,12 +1231,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "dispatch" version = "0.2.0" @@ -1207,32 +1261,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" -[[package]] -name = "dynasm" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add9a102807b524ec050363f09e06f1504214b0e1c7797f64261c891022dce8b" -dependencies = [ - "bitflags", - "byteorder", - "lazy_static", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "dynasmrt" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fba5a42bd76a17cad4bfa00de168ee1cbfa06a5e8ce992ae880218c05641a9" -dependencies = [ - "byteorder", - "dynasm", - "memmap2", -] - [[package]] name = "ecolor" version = "0.22.0" @@ -1688,6 +1716,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "gdk-pixbuf-sys" version = "0.16.3" @@ -1718,15 +1755,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "generational-arena" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877e94aff08e743b651baaea359664321055749b398adff8740a7399af7796e7" -dependencies = [ - "cfg-if", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1996,15 +2024,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash 0.7.6", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -2037,7 +2056,7 @@ dependencies = [ "http", "httpdate", "mime", - "sha1 0.10.5", + "sha1", ] [[package]] @@ -2236,7 +2255,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -2502,9 +2520,9 @@ checksum = "f9275e0933cf8bb20f008924c0cb07a0692fe54d8064996520bf998de9eb79aa" [[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", "scopeguard", @@ -2516,27 +2534,6 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" -[[package]] -name = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap 1.9.3", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "lru" version = "0.11.0" @@ -2926,18 +2923,6 @@ dependencies = [ "objc", ] -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap 1.9.3", - "memchr", -] - [[package]] name = "object" version = "0.30.3" @@ -3029,15 +3014,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "smallvec", - "windows-sys 0.45.0", + "windows-targets 0.48.0", ] [[package]] @@ -3149,8 +3134,6 @@ source = "git+https://github.com/EmbarkStudios/poll-promise/?rev=49daf6c1b91be2d dependencies = [ "static_assertions", "tokio", - "wasm-bindgen", - "wasm-bindgen-futures", ] [[package]] @@ -3221,12 +3204,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.59" @@ -3439,6 +3416,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regalloc2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779" +dependencies = [ + "fxhash", + "log", + "slice-group-by", + "smallvec", +] + [[package]] name = "regex" version = "1.8.3" @@ -3526,6 +3515,7 @@ dependencies = [ "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap 1.9.3", "ptr_meta", "rend", "rkyv_derive", @@ -3562,15 +3552,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustix" version = "0.37.19" @@ -3597,12 +3578,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "rustversion" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" - [[package]] name = "ryu" version = "1.0.13" @@ -3770,7 +3745,6 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasmer", - "wasmer-wasi", "web-sys", ] @@ -3780,15 +3754,6 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.17" @@ -3798,12 +3763,6 @@ dependencies = [ "serde", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.163" @@ -3814,24 +3773,26 @@ dependencies = [ ] [[package]] -name = "serde-xml-rs" -version = "0.6.0" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ - "log", + "js-sys", "serde", - "thiserror", - "xml-rs", + "wasm-bindgen", ] [[package]] -name = "serde_bytes" -version = "0.11.9" +name = "serde-xml-rs" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" dependencies = [ + "log", "serde", + "thiserror", + "xml-rs", ] [[package]] @@ -3888,15 +3849,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - [[package]] name = "sha1" version = "0.10.5" @@ -3908,12 +3860,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - [[package]] name = "sha2" version = "0.10.6" @@ -3934,7 +3880,7 @@ dependencies = [ "const_format", "git2", "is_debug", - "time 0.3.21", + "time", "tzdb", ] @@ -3992,6 +3938,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "slotmap" version = "1.0.6" @@ -4077,70 +4029,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn 1.0.109", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1 0.6.1", - "syn 1.0.109", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "str-buf" version = "1.0.6" @@ -4319,21 +4213,6 @@ dependencies = [ "weezl", ] -[[package]] -name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros 0.1.1", - "version_check", - "winapi", -] - [[package]] name = "time" version = "0.3.21" @@ -4345,7 +4224,7 @@ dependencies = [ "num_threads", "serde", "time-core", - "time-macros 0.2.9", + "time-macros", ] [[package]] @@ -4354,16 +4233,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - [[package]] name = "time-macros" version = "0.2.9" @@ -4373,19 +4242,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn 1.0.109", -] - [[package]] name = "tiny-skia" version = "0.8.4" @@ -4521,7 +4377,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4819,6 +4674,29 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-futures" version = "0.4.37" @@ -4860,84 +4738,90 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +[[package]] +name = "wasm-encoder" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41763f20eafed1399fff1afb466496d3a959f58241436cfdc17e3f5ca954de16" +dependencies = [ + "leb128", +] + [[package]] name = "wasmer" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "840af6d21701220cb805dc7201af301cb99e9b4f646f48a41befbc1d949f0f90" dependencies = [ + "bytes", "cfg-if", "indexmap 1.9.3", "js-sys", - "loupe", "more-asserts", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasm-bindgen-futures", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", - "wasmer-compiler-singlepass", + "wasmer-compiler-cranelift", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "wasmparser", + "wat", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86fab98beaaace77380cb04e681773739473860d1b8499ea6b14f920923e0c5" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", + "rustc-demangle", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] -name = "wasmer-compiler-singlepass" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" +name = "wasmer-compiler-cranelift" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "015eef629fc84889540dc1686bd7fa524b93da9fd2d275b16c49dbe96268e58f" dependencies = [ - "byteorder", - "dynasm", - "dynasmrt", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", "gimli 0.26.2", - "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", + "target-lexicon", + "tracing", "wasmer-compiler", "wasmer-types", ] [[package]] name = "wasmer-derive" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff577b7c1cfcd3d7c5b3a09fe1a499b73f7c17084845ff71225c8250a6a63a9" dependencies = [ "proc-macro-error", "proc-macro2", @@ -4945,127 +4829,26 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", -] - -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9600f9da966abae3be0b0a4560e7d1f2c88415a2d01ce362ac06063cb1c473" dependencies = [ - "backtrace", "enum-iterator", + "enumset", "indexmap 1.9.3", - "loupe", "more-asserts", "rkyv", - "serde", - "thiserror", -] - -[[package]] -name = "wasmer-vfs" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" -dependencies = [ - "slab", + "target-lexicon", "thiserror", - "tracing", ] [[package]] name = "wasmer-vm" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc68a7f0a003e6cb63845b7510065097d289553201d64afb9a5e1744da3c6a0" dependencies = [ "backtrace", "cc", @@ -5075,53 +4858,42 @@ dependencies = [ "indexmap 1.9.3", "lazy_static", "libc", - "loupe", "mach", "memoffset 0.6.5", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] -name = "wasmer-wasi" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" -dependencies = [ - "cfg-if", - "generational-arena", - "getrandom 0.2.9", - "libc", - "thiserror", - "tracing", - "wasm-bindgen", - "wasmer", - "wasmer-vfs", - "wasmer-wasi-types", - "winapi", -] +name = "wasmparser" +version = "0.83.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] -name = "wasmer-wasi-types" -version = "2.3.0" -source = "git+https://github.com/Yeicor/wasmer?branch=2.3.0-async#adf3caae6c460c98f002750ccb27366032a3e12e" +name = "wast" +version = "62.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ae06f09dbe377b889fbd620ff8fa21e1d49d1d9d364983c0cdbf9870cb9f1f" dependencies = [ - "byteorder", - "time 0.2.27", - "wasmer-types", + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", ] [[package]] -name = "wasmparser" -version = "0.83.0" +name = "wat" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" +checksum = "842e15861d203fb4a96d314b0751cdeaf0f6f8b35e8d81d2953af2af5e44e637" +dependencies = [ + "wast", +] [[package]] name = "wayland-client" @@ -5260,17 +5032,6 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" -[[package]] -name = "which" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" -dependencies = [ - "either", - "libc", - "once_cell", -] - [[package]] name = "winapi" version = "0.3.9" @@ -5657,7 +5418,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_repr", - "sha1 0.10.5", + "sha1", "static_assertions", "tracing", "uds_windows", diff --git a/Cargo.toml b/Cargo.toml index b2da994..449989e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,11 +14,11 @@ crate-type = ["cdylib", "rlib"] # Required for web (and Android...). Also publis [features] # By default build the app and the server (if not on wasm). default = ["app", "server", "meshers", "native"] +default-wasm = ["app", "meshers", "web"] # === ARCH-BASED FEATURES (only to select dependencies' features) === -web = ["wasmer/js-default", "wasmer-wasi/js", "poll-promise/web"] -native = ["wasmer/sys", "wasmer/default-singlepass", # TODO: Faster wasm runtime that is slower to compile? - "wasmer/default-universal", "wasmer-wasi/sys", "native_no_wasmer"] +web = ["wasmer/js-default"] #, "wasmer-wasi/js", "poll-promise/web" +native = ["wasmer/sys-default", "native_no_wasmer"] # "wasmer-wasi/sys" native_no_wasmer = ["poll-promise/tokio"] # Android (Termux) server-only builds can't compile wasmer (and don't need it). # === FUNCTIONALITY-BASED FEATURES === @@ -53,7 +53,7 @@ sdfffi = ["sdf"] sdfdemoffi = ["sdfdemo", "sdfffi"] # The wasm interpreters are neede for the app and the meshers, so a new feature is needed for convenience. -wasminterpreters = ["wasmer", "wasmer-wasi"] +wasminterpreters = ["wasmer"] # ========== DEPENDENCIES ========== [dependencies] @@ -76,9 +76,7 @@ httpdate = { version = "1.0", optional = true } # Formatting of dates lru = { version = "0.11", optional = true } # For caching resources # === WEBASSEMBLY COMPILERS/INTERPRETERS === -wasmer = { git = "https://github.com/Yeicor/wasmer", branch = "2.3.0-async", default-features = false, optional = true } # Very fast WebAssembly runtime for x86_64, wasm32 and ARM64 -# Wasmer includes a patch to perform asynchronous compilation and instantiation of WASM modules (to work around chrome's enforced main thread compilation size limit). -wasmer-wasi = { git = "https://github.com/Yeicor/wasmer", branch = "2.3.0-async", default-features = false, optional = true, features = ["mem-fs", "logging"] } # WASI runtime for wasmer +wasmer = { version = "3.1.1", default-features = false, optional = true } # Very fast WebAssembly runtime for x86_64, wasm32 and ARM64 # === CONFIGURATION & CLI === clap = { version = "3", features = ["derive"], optional = true } # CLI parser. Heavy dependency on this version because of klask. @@ -93,7 +91,7 @@ isosurface = { git = "https://github.com/swiftcoder/isosurface", optional = true auto_impl = { version = "1.1", optional = true } # Automatic trait implementations for Box<_>, &_, etc. instant = { version = "0.1", default-features = false, features = ["wasm-bindgen"], optional = true } # Cross platform current time cgmath = { version = "0.18", optional = true } # Math library (shared with three-d) -anyhow = { version = "1.0", optional = true, default-features = false, features=["std"] } # Error handling +anyhow = { version = "1.0", optional = true, default-features = false, features = ["std"] } # Error handling poll-promise = { git = "https://github.com/EmbarkStudios/poll-promise/", rev = "49daf6c1b91be2dbfe59d41ae5547909268c6d46", optional = true } # Polls a future until it resolves once_cell = { version = "1.18", optional = true } # Static globals with lazy initialization diff --git a/README.md b/README.md index aa9d911..df352fa 100644 --- a/README.md +++ b/README.md @@ -58,10 +58,10 @@ out [shadertoy](https://www.shadertoy.com/results?query=tag%3Ddistancefields). 👉 [Click to run the latest web demo](https://yeicor.github.io/sdf-viewer/?envdark) 👈 -This (outdated) example loads and renders an SDF with custom materials at the maximum framerate of **60 FPS on an -integrated graphics card** (i7-9750H). The initial load of the SDF is also interactive at 30 FPS (configurable): it -quickly loads a low-resolution version of the object and iteratively increases the level of detail until the SDF is -fully loaded. Parameters are configured from the UI, also rendering the changes in real time. +This example loads and renders an SDF with custom materials at the maximum framerate of **60 FPS on an integrated +graphics card** (i7-9750H). The initial load of the SDF is also interactive at 30 FPS (configurable): it quickly loads a +low-resolution version of the object and iteratively increases the level of detail until the SDF is fully loaded. +Parameters are configured from the UI, also rendering the changes in real time. ![demo.gif](.github/docs/demo.gif) @@ -83,6 +83,7 @@ These are the steps to follow to start using SDF Viewer. 4. Display the WebAssembly file that defines the SDF with the app. 1. If running the native app, use the CLI to set the path to the file or URL (`sdf-viewer app url `). 2. If running on a web browser, start a server to provide the file and add `?cliurl=` to the URL. + 1. Chrome forbids synchronous compilation for wasm files larger than 4KB, so use a different browser for now... 3. In both cases, you can also use the Settings window inside the app to set the URL. Any change to the sources of the SDF would require you to repeat steps 3 and 4 to display the updated version. diff --git a/src/app/scene/mod.rs b/src/app/scene/mod.rs index 6acea23..403c2d8 100644 --- a/src/app/scene/mod.rs +++ b/src/app/scene/mod.rs @@ -120,11 +120,11 @@ impl SDFViewerAppScene { let skybox = Skybox::new_from_equirectangular( &ctx, &skybox_texture); let ambient_light = AmbientLight::new_with_environment( - &ctx, 0.1, Color::WHITE, skybox.texture()); + &ctx, 0.1, Srgba::WHITE, skybox.texture()); objects.push(Box::new(skybox)); lights.push(Box::new(ambient_light)); } else { - lights.push(Box::new(AmbientLight::new(&ctx, 0.1, Color::WHITE))); + lights.push(Box::new(AmbientLight::new(&ctx, 0.1, Srgba::WHITE))); } // TODO: Custom user-defined objects (gltf) with transforms @@ -142,7 +142,7 @@ impl SDFViewerAppScene { // Create more lights lights.push(Box::new(DirectionalLight::new( - &ctx, 0.9, Color::WHITE, &vec3(-1.0, -1.0, -1.0)))); + &ctx, 0.9, Srgba::WHITE, &vec3(-1.0, -1.0, -1.0)))); Self { ctx, diff --git a/src/app/scene/sdf/material.frag b/src/app/scene/sdf/material.frag index 19be0dc..afebb93 100644 --- a/src/app/scene/sdf/material.frag +++ b/src/app/scene/sdf/material.frag @@ -65,7 +65,7 @@ vec3 sdfSampleTex0Color(vec4 raw) { } // Extract material properties from raw SDF sample. -vec3 sdfSampleTex1MetallicRoughnessOcclussion(vec4 raw) { +vec3 sdfSampleTex1MetallicRoughnessOcclusion(vec4 raw) { return raw.rgb; } @@ -155,14 +155,13 @@ void main() { // Read material properties from the texture color vec3 sampleColor = sdfSampleTex0Color(sampleTex0Raw); - sampleColor = pow(sampleColor, vec3(2.2)); // gamma correction sampleColor *= surfaceColorTint.rgb;// Usually white, does nothing to the surface's color - vec3 sampleProps = sdfSampleTex1MetallicRoughnessOcclussion(sampleTex1Raw); + vec3 sampleProps = sdfSampleTex1MetallicRoughnessOcclusion(sampleTex1Raw); // Compute the color using the lighting model. outColor.rgb = calculate_lighting(cameraPosition, sampleColor, hitPos, normal, sampleProps.x, sampleProps.y, sampleProps.z); - outColor.rgb = reinhard_tone_mapping(outColor.rgb); - outColor.rgb = srgb_from_rgb(outColor.rgb); + // Gamma correction (web-only): outColor.rgb = pow(outColor.rgb, vec3(1.0/2.2)); + // Gamma correction (non-web): outColor.rgb = pow(outColor.rgb, vec3(1.0/1.5)); outColor.a = surfaceColorTint.a; // FIXME: Circle artifacts when computing normals while looking straight at an object diff --git a/src/app/scene/sdf/material.rs b/src/app/scene/sdf/material.rs index d7d3ce6..f1ba730 100644 --- a/src/app/scene/sdf/material.rs +++ b/src/app/scene/sdf/material.rs @@ -1,5 +1,5 @@ use cgmath::{vec3, Vector3}; -use three_d::{Blend, Camera, Color, Cull, FragmentAttributes, FragmentShader, Light, LightingModel, lights_shader_source, Material, MaterialType, RenderStates, Texture3D}; +use three_d::{Blend, Camera, Cull, FragmentAttributes, Light, LightingModel, lights_shader_source, Material, MaterialType, RenderStates, Srgba, Texture3D}; use three_d::core::Program; /// The material properties used for the shader that renders the SDF. It can be applied to any mesh @@ -15,7 +15,7 @@ pub struct SDFViewerMaterial { /// A value of n means that n samples should be skipped in each dimension in between each read. pub lod_dist_between_samples: f32, /// Base surface color (tint). Assumed to be in linear color space. - pub color: Color, + pub color: Srgba, /// The lighting model used to render the voxel data. pub lighting_model: LightingModel, } @@ -27,25 +27,40 @@ impl SDFViewerMaterial { tex1, voxels_bounds, lod_dist_between_samples: 1f32, - color: Color::WHITE, + color: Srgba::WHITE, lighting_model: LightingModel::Phong, } } } impl Material for SDFViewerMaterial { - fn fragment_shader(&self, lights: &[&dyn Light]) -> FragmentShader { + + fn fragment_shader_source(&self, lights: &[&dyn Light]) -> String { let mut output = lights_shader_source(lights, self.lighting_model); output.push_str(include_str!("material.frag")); - FragmentShader { - source: output, - attributes: FragmentAttributes { - position: true, - normal: false, - tangents: false, - uv: false, - color: false, - }, + // HACK: Different gamma-corrections for different platforms. + #[cfg(target_arch = "wasm32")] + { + output = output.replace("// Gamma correction (web-only): ", ""); + } + #[cfg(not(target_arch = "wasm32"))] + { + output = output.replace("// Gamma correction (non-web): ", ""); + } + output + } + + fn id(&self) -> u16 { + 0 + } + + fn fragment_attributes(&self) -> FragmentAttributes { + FragmentAttributes { + position: true, + normal: false, + tangents: false, + uv: false, + color: false, } } @@ -61,7 +76,7 @@ impl Material for SDFViewerMaterial { program.use_uniform("cameraPosition", camera.position()); program.use_uniform("BVP", bvp_matrix(camera)); - program.use_uniform("surfaceColorTint", self.color); + program.use_uniform("surfaceColorTint", self.color.to_linear_srgb()); program.use_texture_3d("sdfTex0", &self.tex0); program.use_texture_3d("sdfTex1", &self.tex1); diff --git a/src/lib.rs b/src/lib.rs index 2b5985d..fbe816e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ pub async fn run_app(canvas_id: String) -> Result<(), wasm_bindgen::prelude::JsV let web_options = eframe::WebOptions { ..eframe::WebOptions::default() }; - eframe::start_web(&canvas_id, web_options, app_creator).await?; + eframe::WebRunner::new().start(&canvas_id, web_options, app_creator).await?; } Ok(()) } diff --git a/src/sdf/wasm/mod.rs b/src/sdf/wasm/mod.rs index a1c43bf..d5fb273 100644 --- a/src/sdf/wasm/mod.rs +++ b/src/sdf/wasm/mod.rs @@ -40,3 +40,4 @@ pub(crate) mod load; mod native; mod util; +mod wasi; \ No newline at end of file diff --git a/src/sdf/wasm/native.rs b/src/sdf/wasm/native.rs index bb72a04..9d06777 100644 --- a/src/sdf/wasm/native.rs +++ b/src/sdf/wasm/native.rs @@ -5,117 +5,110 @@ use std::fmt::Debug; use std::mem::size_of; use std::ops::RangeInclusive; +use std::sync::{Arc, Mutex}; use cgmath::{Vector3, Zero}; -use wasmer::*; -use wasmer_wasi::*; +use wasmer::{Function, Instance, Memory, Module, Store, Value}; +use wasmer::AsStoreMut; +use wasmer::AsStoreRef; use crate::sdf::{SDFParam, SDFParamKind, SDFParamValue, SDFSample, SDFSurface}; use crate::sdf::defaults::{children_default_impl, name_default_impl, parameters_default_impl, set_parameter_default_impl}; use crate::sdf::wasm::util::reinterpret_i32_as_u32; use crate::sdf::wasm::util::reinterpret_u32_as_i32; +//use wasmer_wasi::*; + #[cfg(all(not(feature = "web"), target_arch = "wasm32"))] compile_error!("On wasm32 targets, you need to enable the web feature (and disable any native* features)."); -macro_rules! load_sdf_wasm_code { - ($name: ident, $kind: ty) => { - /// Loads the given bytes as a WebAssembly module that is then queried to satisfy the SDF trait. - pub async fn $name(wasm_bytes: &[u8]) -> $kind { - // TODO: Test other compilers provided by the wasmer crate - - let store = Store::default(); - let module = { // HACK: chrome requires asynchronous compilation - #[cfg(target_arch = "wasm32")] - { - // HACK: Basic validation because the wasm32 wasmer crate doesn't do it for us. - Module::validate(&store, wasm_bytes)?; - Module::new(&store, wasm_bytes).await? - } - #[cfg(not(target_arch = "wasm32"))] - { - Module::new(&store, wasm_bytes)? - } - }; +/// Loads the given bytes as a WebAssembly module that is then queried to satisfy the SDF trait. +pub async fn load_sdf_wasm(wasm_bytes: &[u8]) -> anyhow::Result> { + unsafe { std::mem::transmute(load_sdf_wasm_send_sync(wasm_bytes).await?) } +} - // The module shouldn't import anything, except maybe WASI. - let wasi_state = WasiState::new("program_name") - // .env(b"HOME", "/home/home".to_string()) - // .arg("--help") - // .preopen(|p| p.directory("src").read(true).write(true).create(true))? - // .preopen(|p| p.directory(".").alias("dot").read(true))? - .build()?; - let mut wasi_env = WasiEnv::new(wasi_state); - let import_object = wasi_env.import_object_for_all_wasi_versions(&module)?; +/// Loads the given bytes as a WebAssembly module that is then queried to satisfy the SDF trait. +pub async fn load_sdf_wasm_send_sync(wasm_bytes: &[u8]) -> anyhow::Result> { + // TODO: Test other compilers provided by the wasmer crate - let instance = { // HACK: chrome requires asynchronous instantiation - #[cfg(target_arch = "wasm32")] - { - Instance::new(&module, &import_object).await? - } - #[cfg(not(target_arch = "wasm32"))] - { - Instance::new(&module, &import_object)? - } - }; + let mut store = Store::default(); + #[cfg(target_arch = "wasm32")] + { + // HACK: Basic validation because the wasm32 wasmer crate doesn't do it for us. + Module::validate(&store, wasm_bytes)?; + } + let module = Module::new(&store, wasm_bytes)?; - // Call init() to initialize the module (optional). - if let Ok(init) = instance.exports.get_function("init") { - if let Err(err) = init.call(&[]) { - tracing::error!("Calling init() failed: {:?}", err); - } - } + // // The module shouldn't import anything. TODO: except maybe WASI. + // let wasi_state = WasiState::new("program_name") + // // .env(b"HOME", "/home/home".to_string()) + // // .arg("--help") + // // .preopen(|p| p.directory("src").read(true).write(true).create(true))? + // // .preopen(|p| p.directory(".").alias("dot").read(true))? + // .build()?; + // let mut wasi_env = WasiEnv::new(wasi_state); + // let import_object = wasi_env.import_object_for_all_wasi_versions(&module)?; + let import_object = super::wasi::wasi_imports(&mut store); - // Cache the exports of the module. - let memory = instance.exports.get_memory("memory")?.clone(); - let f_bounding_box = instance.exports.get_function("bounding_box")?.clone(); - let f_bounding_box_free = instance.exports.get_function("bounding_box_free").ok().cloned(); - let f_sample = instance.exports.get_function("sample")?.clone(); - let f_sample_free = instance.exports.get_function("sample_free").ok().cloned(); - let f_children = instance.exports.get_function("children").ok().cloned(); - let f_children_free = instance.exports.get_function("children_free").ok().cloned(); - let f_name = instance.exports.get_function("name").ok().cloned(); - let f_name_free = instance.exports.get_function("name_free").ok().cloned(); - let f_parameters = instance.exports.get_function("parameters").ok().cloned(); - let f_parameters_free = instance.exports.get_function("parameters_free").ok().cloned(); - let f_set_parameter = instance.exports.get_function("set_parameter").ok().cloned(); - let f_set_parameter_free = instance.exports.get_function("set_parameter_free").ok().cloned(); - let f_changed = instance.exports.get_function("changed").ok().cloned(); - let f_changed_free = instance.exports.get_function("changed_free").ok().cloned(); - let f_normal = instance.exports.get_function("normal").ok().cloned(); - let f_normal_free = instance.exports.get_function("normal_free").ok().cloned(); + let instance = Instance::new(&mut store, &module, &import_object)?; - Ok(Box::new(WasmerSDF { - sdf_id: 0, // This must always be the ID of the root SDF (as specified by the docs) - memory, - f_bounding_box, - f_bounding_box_free, - f_sample, - f_sample_free, - f_children, - f_children_free, - f_name, - f_name_free, - f_parameters, - f_parameters_free, - f_set_parameter, - f_set_parameter_free, - f_changed, - f_changed_free, - f_normal, - f_normal_free, - })) + // Call init() to initialize the module (optional). + if let Ok(init) = instance.exports.get_function("init") { + if let Err(err) = init.call(&mut store, &[]) { + tracing::error!("Calling init() failed: {:?}", err); } - }; + } + + // Cache the exports of the module. + let memory = instance.exports.get_memory("memory")?.clone(); + let f_bounding_box = instance.exports.get_function("bounding_box")?.clone(); + let f_bounding_box_free = instance.exports.get_function("bounding_box_free").ok().cloned(); + let f_sample = instance.exports.get_function("sample")?.clone(); + let f_sample_free = instance.exports.get_function("sample_free").ok().cloned(); + let f_children = instance.exports.get_function("children").ok().cloned(); + let f_children_free = instance.exports.get_function("children_free").ok().cloned(); + let f_name = instance.exports.get_function("name").ok().cloned(); + let f_name_free = instance.exports.get_function("name_free").ok().cloned(); + let f_parameters = instance.exports.get_function("parameters").ok().cloned(); + let f_parameters_free = instance.exports.get_function("parameters_free").ok().cloned(); + let f_set_parameter = instance.exports.get_function("set_parameter").ok().cloned(); + let f_set_parameter_free = instance.exports.get_function("set_parameter_free").ok().cloned(); + let f_changed = instance.exports.get_function("changed").ok().cloned(); + let f_changed_free = instance.exports.get_function("changed_free").ok().cloned(); + let f_normal = instance.exports.get_function("normal").ok().cloned(); + let f_normal_free = instance.exports.get_function("normal_free").ok().cloned(); + + Ok(Box::new(WasmerSDF { + sdf_id: 0, // This must always be the ID of the root SDF (as specified by the docs) + store: Arc::new(Mutex::new(store)), + memory, + f_bounding_box, + f_bounding_box_free, + f_sample, + f_sample_free, + f_children, + f_children_free, + f_name, + f_name_free, + f_parameters, + f_parameters_free, + f_set_parameter, + f_set_parameter_free, + f_changed, + f_changed_free, + f_normal, + f_normal_free, + })) } // HACK: Is there a better alternative to implement both return types than macros for code duplication? -load_sdf_wasm_code!(load_sdf_wasm_send_sync, anyhow::Result>); -load_sdf_wasm_code!(load_sdf_wasm, anyhow::Result>); +// load_sdf_wasm_code!(load_sdf_wasm_send_sync, anyhow::Result>); +// load_sdf_wasm_code!(load_sdf_wasm, anyhow::Result>); #[derive(Debug, Clone)] // Note: cloning is "cheap" (implementation details of wasmer) pub struct WasmerSDF { sdf_id: u32, + store: Arc>, memory: Memory, f_bounding_box: Function, f_bounding_box_free: Option, @@ -136,58 +129,46 @@ pub struct WasmerSDF { } impl WasmerSDF { - fn read_memory(&self, mem_pointer: u32, length: usize) -> Vec { + fn read_memory(&self, mem_pointer: u32, length: usize, store: &impl AsStoreRef) -> Vec { let mut res = vec![0u8; length]; - #[cfg(target_arch = "wasm32")] - { - self.memory.uint8view() - .subarray(mem_pointer, mem_pointer + length as u32) - .copy_to(&mut res); - } - #[cfg(not(target_arch = "wasm32"))] - { - // Future version of wasmer: - // self.memory.read(mem_pointer as u64, &mut res).unwrap_or_else(|err| { - // tracing::error!("Out of bounds memory access at index {}, length {}: {:?}", mem_pointer, length, err); - // }); - let mem_view = self.memory.view::(); - for (i, v) in res.iter_mut().enumerate() { - *v = mem_view.get(mem_pointer as usize + i).map(|b| b.get()).unwrap_or_else(|| { - debug_assert!(false, "Out of bounds memory access at index {mem_pointer}, length {length}"); - tracing::error!("Out of bounds memory access at index {}, length {}", mem_pointer, length); - 0 - }) - } + let mem_view = self.memory.view(store); + for (i, v) in res.iter_mut().enumerate() { + *v = mem_view.read_u8(mem_pointer as u64 + i as u64).unwrap_or_else(|err| { + debug_assert!(false, "Out of bounds memory access at index {mem_pointer}, length {length}"); + tracing::error!("Out of bounds memory access at index {}, length {}: {:?}", mem_pointer, length, err); + 0 + }) } res } - fn write_memory(&self, mem_pointer: u32, to_write: &[u8]) { + fn write_memory(&self, mem_pointer: u32, to_write: &[u8], store: &impl AsStoreRef) { // HACK: How to reserve free memory for this instead of randomly overwriting it? // TODO: Maybe try malloc/free, which is published by tinygo binaries. #[allow(unused_unsafe)] // This is not unsafe on wasm32 unsafe { // SAFETY: No data races. - self.memory.uint8view() - .subarray(mem_pointer, mem_pointer + to_write.len() as u32) - .copy_from(to_write); + self.memory.view(store).write(mem_pointer as u64, to_write).unwrap_or_else(|err| { + tracing::error!("Out of bounds memory access at index {}, length {}: {:?}", mem_pointer, to_write.len(), err); + }); } } - fn read_pointer_length_memory(&self, mem_bytes: Vec) -> Vec { + fn read_pointer_length_memory(&self, mem_bytes: Vec, store: &impl AsStoreRef) -> Vec { let pointer = u32::from_le_bytes(mem_bytes[0..size_of::()].try_into().unwrap()); let length_bytes = u32::from_le_bytes(mem_bytes[size_of::()..2 * size_of::()].try_into().unwrap()); // if length_bytes == 8 { // // DEBUG: "Should" be very stable over time if wasm is properly freeing the memory // println!("Pointer to 8 bytes at {}", pointer); // } - self.read_memory(pointer, length_bytes as usize) + self.read_memory(pointer, length_bytes as usize, store) } } impl SDFSurface for WasmerSDF { fn bounding_box(&self) -> [Vector3; 2] { - let result = self.f_bounding_box.call(&[ - Val::I32(reinterpret_u32_as_i32(self.sdf_id)), + let mut _store = self.store.lock().unwrap(); + let result = self.f_bounding_box.call(&mut _store.as_store_mut(), &[ + Value::I32(reinterpret_u32_as_i32(self.sdf_id)), ]).unwrap_or_else(|err| { tracing::error!("Failed to get bounding box of wasm SDF with ID {}: {}", self.sdf_id, err); Box::new([]) @@ -197,8 +178,8 @@ impl SDFSurface for WasmerSDF { Some(mem_pointer) => mem_pointer, None => return res, // Errors already logged }; - let mem_bytes = self.read_memory(mem_pointer, size_of::<[Vector3; 2]>()); - self.f_bounding_box_free.as_ref().map(|f| f.call(&result)); // Free the memory, now that we copied it + let mem_bytes = self.read_memory(mem_pointer, size_of::<[Vector3; 2]>(), &_store.as_store_ref()); + self.f_bounding_box_free.as_ref().map(|f| f.call(&mut _store.as_store_mut(), &result)); // Free the memory, now that we copied it res[0].x = f32::from_le_bytes(mem_bytes[0..size_of::()].try_into().unwrap()); res[0].y = f32::from_le_bytes(mem_bytes[size_of::()..2 * size_of::()].try_into().unwrap()); res[0].z = f32::from_le_bytes(mem_bytes[2 * size_of::()..3 * size_of::()].try_into().unwrap()); @@ -209,12 +190,13 @@ impl SDFSurface for WasmerSDF { } fn sample(&self, p: Vector3, distance_only: bool) -> SDFSample { - let result = self.f_sample.call(&[ - Val::I32(reinterpret_u32_as_i32(self.sdf_id)), - Val::F32(p.x), - Val::F32(p.y), - Val::F32(p.z), - Val::I32(i32::from(distance_only)), + let mut _store = self.store.lock().unwrap(); + let result = self.f_sample.call(&mut _store.as_store_mut(), &[ + Value::I32(reinterpret_u32_as_i32(self.sdf_id)), + Value::F32(p.x), + Value::F32(p.y), + Value::F32(p.z), + Value::I32(i32::from(distance_only)), ]).unwrap_or_else(|err| { tracing::error!("Failed to get sample of wasm SDF with ID {}: {}", self.sdf_id, err); Box::new([]) @@ -223,8 +205,8 @@ impl SDFSurface for WasmerSDF { Some(mem_pointer) => mem_pointer, None => return SDFSample::new(1.0, Vector3::zero()), // Errors already logged }; - let mem_bytes = self.read_memory(mem_pointer, size_of::()); - self.f_sample_free.as_ref().map(|f| f.call(&result)); // Free the memory, now that we copied it + let mem_bytes = self.read_memory(mem_pointer, size_of::(), &_store.as_store_ref()); + self.f_sample_free.as_ref().map(|f| f.clone().call(&mut _store.as_store_mut(), &result)); // Free the memory, now that we copied it SDFSample { distance: f32::from_le_bytes(mem_bytes[0..size_of::()].try_into().unwrap()), color: Vector3::new( @@ -239,12 +221,13 @@ impl SDFSurface for WasmerSDF { } fn children(&self) -> Vec> { + let mut _store = self.store.lock().unwrap(); let f_children = match &self.f_children { Some(f_children) => f_children, None => return children_default_impl(self), }; - let result = f_children.call(&[ - Val::I32(reinterpret_u32_as_i32(self.sdf_id)), + let result = f_children.clone().call(&mut _store.as_store_mut(), &[ + Value::I32(reinterpret_u32_as_i32(self.sdf_id)), ]).unwrap_or_else(|err| { tracing::error!("Failed to get children of wasm SDF with ID {}: {}", self.sdf_id, err); Box::new([]) @@ -253,9 +236,9 @@ impl SDFSurface for WasmerSDF { Some(mem_pointer) => mem_pointer, None => return children_default_impl(self), // Errors already logged }; - let pointer_length = self.read_memory(mem_pointer, 2 * size_of::()); - let mem_bytes = self.read_pointer_length_memory(pointer_length); - self.f_children_free.as_ref().map(|f| f.call(&result)); // Free the memory, now that we copied it + let pointer_length = self.read_memory(mem_pointer, 2 * size_of::(), &_store.as_store_ref()); + let mem_bytes = self.read_pointer_length_memory(pointer_length, &_store.as_store_ref()); + self.f_children_free.as_ref().map(|f| f.call(&mut _store.as_store_mut(), &result)); // Free the memory, now that we copied it mem_bytes.chunks_exact(size_of::()) .map(|ch| u32::from_le_bytes(ch.try_into().unwrap())) .filter_map(|child_sdf_id| { @@ -275,12 +258,13 @@ impl SDFSurface for WasmerSDF { } fn name(&self) -> String { + let mut _store = self.store.lock().unwrap(); let f_name = match &self.f_name { Some(f_name) => f_name, None => return name_default_impl(self), }; - let result = f_name.call(&[ - Val::I32(reinterpret_u32_as_i32(self.sdf_id)), + let result = f_name.call(&mut _store.as_store_mut(), &[ + Value::I32(reinterpret_u32_as_i32(self.sdf_id)), ]).unwrap_or_else(|err| { tracing::error!("Failed to get name of wasm SDF with ID {}: {}", self.sdf_id, err); Box::new([]) @@ -289,19 +273,20 @@ impl SDFSurface for WasmerSDF { Some(mem_pointer) => mem_pointer, None => return name_default_impl(self), // Errors already logged }; - let pointer_length = self.read_memory(mem_pointer, 2 * size_of::()); - let mem_bytes = self.read_pointer_length_memory(pointer_length); - self.f_name_free.as_ref().map(|f| f.call(&result)); // Free the memory, now that we copied it + let pointer_length = self.read_memory(mem_pointer, 2 * size_of::(), &_store.as_store_ref()); + let mem_bytes = self.read_pointer_length_memory(pointer_length, &_store.as_store_ref()); + self.f_name_free.as_ref().map(|f| f.call(&mut _store.as_store_mut(), &result)); // Free the memory, now that we copied it String::from_utf8_lossy(mem_bytes.as_slice()).to_string() } fn parameters(&self) -> Vec { + let mut _store = self.store.lock().unwrap(); let f_parameters = match &self.f_parameters { Some(f_parameters) => f_parameters, None => return parameters_default_impl(self), }; - let result = f_parameters.call(&[ - Val::I32(reinterpret_u32_as_i32(self.sdf_id)), + let result = f_parameters.call(&mut _store.as_store_mut(), &[ + Value::I32(reinterpret_u32_as_i32(self.sdf_id)), ]).unwrap_or_else(|err| { tracing::error!("Failed to get parameters of wasm SDF with ID {}: {}", self.sdf_id, err); Box::new([]) @@ -310,8 +295,8 @@ impl SDFSurface for WasmerSDF { Some(mem_pointer) => mem_pointer, None => return parameters_default_impl(self), // Errors already logged }; - let pointer_length = self.read_memory(mem_pointer, 2 * size_of::()); - let mem_bytes = self.read_pointer_length_memory(pointer_length); + let pointer_length = self.read_memory(mem_pointer, 2 * size_of::(), &_store.as_store_ref()); + let mem_bytes = self.read_pointer_length_memory(pointer_length, &_store.as_store_ref()); let res = mem_bytes.chunks_exact( size_of::() /* param ID */ + 2 * size_of::() /* name pointer */ + @@ -325,7 +310,7 @@ impl SDFSurface for WasmerSDF { cur_offset += size_of::(); /* name pointer */ let name_pointer_length = sdf_param_mem[cur_offset..cur_offset + 2 * size_of::()].try_into().unwrap(); - let name_mem_bytes = self.read_pointer_length_memory(name_pointer_length); + let name_mem_bytes = self.read_pointer_length_memory(name_pointer_length, &_store.as_store_ref()); // println!("sdf_param_mem: {:?} (name: {:?})", sdf_param_mem, String::from_utf8_lossy(&name_mem_bytes)); cur_offset += 2 * size_of::(); /* SDFParamKindC */ @@ -350,10 +335,10 @@ impl SDFSurface for WasmerSDF { }, 3 => { let choices_pointer_length = sdf_param_mem[cur_offset..cur_offset + 2 * size_of::()].try_into().unwrap(); - let choices_mem_bytes = self.read_pointer_length_memory(choices_pointer_length); + let choices_mem_bytes = self.read_pointer_length_memory(choices_pointer_length, &_store.as_store_ref()); let choices = choices_mem_bytes.chunks_exact(2 * size_of::()) .map(|choice_mem_bytes| { - let choice_mem_bytes = self.read_pointer_length_memory(choice_mem_bytes.to_vec()); + let choice_mem_bytes = self.read_pointer_length_memory(choice_mem_bytes.to_vec(), &_store.as_store_ref()); String::from_utf8_lossy(choice_mem_bytes.as_slice()).to_string() }) .collect(); @@ -377,7 +362,7 @@ impl SDFSurface for WasmerSDF { 2 => SDFParamValue::Float(f32::from_le_bytes(sdf_param_mem[cur_offset..cur_offset + size_of::()].try_into().unwrap())), 3 => { let value_pointer_length = sdf_param_mem[cur_offset..cur_offset + 2 * size_of::()].try_into().unwrap(); - let value_mem_bytes = self.read_pointer_length_memory(value_pointer_length); + let value_mem_bytes = self.read_pointer_length_memory(value_pointer_length, &_store.as_store_ref()); SDFParamValue::String(String::from_utf8_lossy(value_mem_bytes.as_slice()).to_string()) } _ => { @@ -389,7 +374,7 @@ impl SDFSurface for WasmerSDF { cur_offset += 2 * size_of::(); // Maximum size of SDFParamValueC /* description */ let desc_pointer_length = sdf_param_mem[cur_offset..cur_offset + 2 * size_of::()].try_into().unwrap(); - let desc_mem_bytes = self.read_pointer_length_memory(desc_pointer_length); + let desc_mem_bytes = self.read_pointer_length_memory(desc_pointer_length, &_store.as_store_ref()); Some(SDFParam { id: param_id, @@ -400,35 +385,37 @@ impl SDFSurface for WasmerSDF { }) }) .collect(); - self.f_parameters_free.as_ref().map(|f| f.call(&result)); // Free the memory, now that we copied it + self.f_parameters_free.as_ref().map(|f| f.call(&mut _store.as_store_mut(), &result)); // Free the memory, now that we copied it res } fn set_parameter(&self, param_id: u32, param_value: &SDFParamValue) -> Result<(), String> { + let mut _store = self.store.lock().unwrap(); let f_set_parameter = match &self.f_set_parameter { Some(f_set_parameter) => f_set_parameter, None => return set_parameter_default_impl(self, param_id, param_value), }; - let result = f_set_parameter.call(&[ - Val::I32(reinterpret_u32_as_i32(self.sdf_id)), - Val::I32(reinterpret_u32_as_i32(param_id)), - Val::I32(match param_value { + let tmp_store_mut = &mut _store.as_store_mut(); + let result = f_set_parameter.call(tmp_store_mut, &[ + Value::I32(reinterpret_u32_as_i32(self.sdf_id)), + Value::I32(reinterpret_u32_as_i32(param_id)), + Value::I32(match param_value { SDFParamValue::Boolean(_value) => 0, SDFParamValue::Int(_value) => 1, SDFParamValue::Float(_value) => 2, SDFParamValue::String(_value) => 3, }), - Val::I32(match param_value { + Value::I32(match param_value { SDFParamValue::Boolean(value) => i32::from(*value), SDFParamValue::Int(value) => *value, SDFParamValue::Float(value) => unsafe { *(value as *const f32 as *const i32) }, // f32 bits to i32 SDFParamValue::String(value) => { let write_string_address = 0x12345; - self.write_memory(write_string_address, value.as_bytes()); + self.write_memory(write_string_address, value.as_bytes(), &tmp_store_mut); reinterpret_u32_as_i32(write_string_address) } }), - Val::I32(match param_value { + Value::I32(match param_value { SDFParamValue::String(value) => reinterpret_u32_as_i32(value.len() as u32), _ => 0, // Unused }), @@ -440,7 +427,7 @@ impl SDFSurface for WasmerSDF { Some(mem_pointer) => mem_pointer, None => return set_parameter_default_impl(self, param_id, param_value), // Errors already logged }; - let mem_bytes = self.read_memory(mem_pointer, 3 * size_of::()); + let mem_bytes = self.read_memory(mem_pointer, 3 * size_of::(), &_store.as_store_ref()); let mut cur_offset = 0; let enum_result_kind = u32::from_le_bytes(mem_bytes[cur_offset..cur_offset + size_of::()].try_into().unwrap()); cur_offset += size_of::(); @@ -451,7 +438,7 @@ impl SDFSurface for WasmerSDF { cur_offset += size_of::(); let error_string_length = u32::from_le_bytes(mem_bytes[cur_offset..cur_offset + size_of::()].try_into().unwrap()); // cur_offset += size_of::(); - let error_string_bytes = self.read_memory(error_string_ptr, error_string_length as usize); + let error_string_bytes = self.read_memory(error_string_ptr, error_string_length as usize, &_store.as_store_ref()); Err(String::from_utf8_lossy(&error_string_bytes[..]).to_string()) } _ => { @@ -460,17 +447,18 @@ impl SDFSurface for WasmerSDF { Err(String::from("Unknown SDF set parameter result kind enum type")) } }; - self.f_set_parameter_free.as_ref().map(|f| f.call(&result)); // Free the memory, now that we copied it + self.f_set_parameter_free.as_ref().map(|f| f.call(&mut _store.as_store_mut(), &result)); // Free the memory, now that we copied it res } fn changed(&self) -> Option<[Vector3; 2]> { + let mut _store = self.store.lock().unwrap(); let f_changed = match &self.f_changed { Some(f_changed) => f_changed, None => return None, }; - let result = f_changed.call(&[ - Val::I32(reinterpret_u32_as_i32(self.sdf_id)), + let result = f_changed.clone().call(&mut _store.as_store_mut(), &[ + Value::I32(reinterpret_u32_as_i32(self.sdf_id)), ]).unwrap_or_else(|err| { tracing::error!("Failed to get changed of wasm SDF with ID {}: {}", self.sdf_id, err); Box::new([]) @@ -479,7 +467,7 @@ impl SDFSurface for WasmerSDF { Some(mem_pointer) => mem_pointer, None => return None, // Errors already logged }; - let mem_bytes = self.read_memory(mem_pointer, (1 + 6) * size_of::()); + let mem_bytes = self.read_memory(mem_pointer, (1 + 6) * size_of::(), &_store.as_store_ref()); let mut cur_offset = 0; let enum_result_kind = u32::from_le_bytes(mem_bytes[cur_offset..cur_offset + size_of::()].try_into().unwrap()); cur_offset += size_of::(); @@ -506,30 +494,32 @@ impl SDFSurface for WasmerSDF { None } }; - self.f_changed_free.as_ref().map(|f| f.call(&result)); // Free the memory, now that we copied it + self.f_changed_free.as_ref().map(|f| f.call(&mut _store.as_store_mut(), &result)); // Free the memory, now that we copied it res } fn normal(&self, p: Vector3, eps: Option) -> Vector3 { + let mut _store = self.store.lock().unwrap(); let f_normal = match &self.f_normal { Some(f_normal) => f_normal, None => return Vector3::new(0.0, 0.0, 0.0), }; - let result = f_normal.call(&[ - Val::I32(reinterpret_u32_as_i32(self.sdf_id)), - Val::F32(p.x), - Val::F32(p.y), - Val::F32(p.z), - Val::I32({ + let tmp_store_mut = &mut _store.as_store_mut(); + let result = f_normal.call(tmp_store_mut, &[ + Value::I32(reinterpret_u32_as_i32(self.sdf_id)), + Value::F32(p.x), + Value::F32(p.y), + Value::F32(p.z), + Value::I32({ let write_string_address = 0x12300; self.write_memory(write_string_address, match eps { None => &[0, 0, 0, 0], Some(_) => &[1, 0, 0, 0], // Little-endian 1 for error - }); + }, &tmp_store_mut); self.write_memory(write_string_address + size_of::() as u32, &match eps { None => [0; size_of::()], Some(eps) => eps.to_le_bytes(), - }); + }, &tmp_store_mut); reinterpret_u32_as_i32(write_string_address) }), ]).unwrap_or_else(|err| { @@ -540,16 +530,16 @@ impl SDFSurface for WasmerSDF { Some(mem_pointer) => mem_pointer, None => return Vector3::new(0.0, 0.0, 0.0), // Errors already logged }; - let mem_bytes = self.read_memory(mem_pointer, 3 * size_of::()); + let mem_bytes = self.read_memory(mem_pointer, 3 * size_of::(), &_store.as_store_ref()); let x = f32::from_le_bytes(mem_bytes[0..size_of::()].try_into().unwrap()); let y = f32::from_le_bytes(mem_bytes[size_of::()..2 * size_of::()].try_into().unwrap()); let z = f32::from_le_bytes(mem_bytes[2 * size_of::()..3 * size_of::()].try_into().unwrap()); - self.f_normal_free.as_ref().map(|f| f.call(&result)); // Free the memory, now that we copied it + self.f_normal_free.as_ref().map(|f| f.call(&mut _store.as_store_mut(), &result)); // Free the memory, now that we copied it Vector3::new(x, y, z) } } -fn return_value_to_mem_pointer(result: &[Val]) -> Option { +fn return_value_to_mem_pointer(result: &[Value]) -> Option { if result.len() != 1 { tracing::error!("Expected 1 output, got {}", result.len()); return None; diff --git a/src/sdf/wasm/wasi.rs b/src/sdf/wasm/wasi.rs new file mode 100644 index 0000000..56297e6 --- /dev/null +++ b/src/sdf/wasm/wasi.rs @@ -0,0 +1,110 @@ +use wasmer::{AsStoreMut, Function, imports}; + +macro_rules! wasi_func_stub { + ($name:ident, $($arg:ident: $arg_type:ty),* > $ret_type:ty) => { + fn $name($($arg: $arg_type),*) -> $ret_type { + tracing::warn!("WASI function {} (args: {:?}) not implemented, returning 0", stringify!($name), vec![$($arg as i64),*] as Vec); + 0 + } + } +} + +wasi_func_stub!(args_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(args_sizes_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(environ_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(environ_sizes_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(clock_res_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(clock_time_get, _arg0: i32, _arg1: i32, _arg2: i32 > i32); +wasi_func_stub!(fd_advise, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32 > i32); +wasi_func_stub!(fd_allocate, _arg0: i32, _arg1: i32, _arg2: i32 > i32); +wasi_func_stub!(fd_close, _arg0: i32 > i32); +wasi_func_stub!(fd_datasync, _arg0: i32 > i32); +wasi_func_stub!(fd_fdstat_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(fd_fdstat_set_flags, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(fd_fdstat_set_rights, _arg0: i32, _arg1: i64, _arg2: i64 > i32); +wasi_func_stub!(fd_filestat_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(fd_filestat_set_size, _arg0: i32, _arg1: i64 > i32); +wasi_func_stub!(fd_filestat_set_times, _arg0: i32, _arg1: i64, _arg2: i64, _arg3: i32 > i32); +wasi_func_stub!(fd_pread, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i64, _arg4: i32 > i32); +wasi_func_stub!(fd_prestat_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(fd_prestat_dir_name, _arg0: i32, _arg1: i32, _arg2: i32 > i32); +wasi_func_stub!(fd_pwrite, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i64, _arg4: i32 > i32); +wasi_func_stub!(fd_read, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32 > i32); +wasi_func_stub!(fd_readdir, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i64, _arg4: i32 > i32); +wasi_func_stub!(fd_renumber, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(fd_seek, _arg0: i32, _arg1: i64, _arg2: i32, _arg3: i32 > i32); +wasi_func_stub!(fd_sync, _arg0: i32 > i32); +wasi_func_stub!(fd_tell, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(fd_write, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32 > i32); +wasi_func_stub!(path_create_directory, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(path_filestat_get, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32 > i32); +wasi_func_stub!(path_filestat_set_times, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32, _arg5: i32, _arg6: i32 > i32); +wasi_func_stub!(path_link, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32, _arg5: i32, _arg6: i32 > i32); +wasi_func_stub!(path_open, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32, _arg5: i64, _arg6: i64, _arg7: i32, _arg8: i32 > i32); +wasi_func_stub!(path_readlink, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32, _arg5: i32 > i32); +wasi_func_stub!(path_remove_directory, _arg0: i32, _arg1: i32, _arg2: i32 > i32); +wasi_func_stub!(path_rename, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32, _arg5: i32 > i32); +wasi_func_stub!(path_symlink, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32 > i32); +wasi_func_stub!(path_unlink_file, _arg0: i32, _arg1: i32, _arg2: i32 > i32); +wasi_func_stub!(poll_oneoff, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32 > i32); +wasi_func_stub!(proc_exit, _arg0: i32 > i32); +wasi_func_stub!(proc_raise, _arg0: i32 > i32); +wasi_func_stub!(sched_yield, > i32); +wasi_func_stub!(random_get, _arg0: i32, _arg1: i32 > i32); +wasi_func_stub!(sock_accept, _arg0: i32, _arg1: i32, _arg2: i32 > i32); +wasi_func_stub!(sock_recv, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32, _arg5: i32 > i32); +wasi_func_stub!(sock_send, _arg0: i32, _arg1: i32, _arg2: i32, _arg3: i32, _arg4: i32 > i32); +wasi_func_stub!(sock_shutdown, _arg0: i32, _arg1: i32 > i32); + +pub(crate) fn wasi_imports(store: &mut impl AsStoreMut) -> wasmer::Imports { + imports! { + "wasi_snapshot_preview1" => { + "args_get" => Function::new_typed(store, args_get), + "args_sizes_get" => Function::new_typed(store, args_sizes_get), + "clock_res_get" => Function::new_typed(store, clock_res_get), + "clock_time_get" => Function::new_typed(store, clock_time_get), + "environ_get" => Function::new_typed(store, environ_get), + "environ_sizes_get" => Function::new_typed(store, environ_sizes_get), + "fd_advise" => Function::new_typed(store, fd_advise), + "fd_allocate" => Function::new_typed(store, fd_allocate), + "fd_close" => Function::new_typed(store, fd_close), + "fd_datasync" => Function::new_typed(store, fd_datasync), + "fd_fdstat_get" => Function::new_typed(store, fd_fdstat_get), + "fd_fdstat_set_flags" => Function::new_typed(store, fd_fdstat_set_flags), + "fd_fdstat_set_rights" => Function::new_typed(store, fd_fdstat_set_rights), + "fd_filestat_get" => Function::new_typed(store, fd_filestat_get), + "fd_filestat_set_size" => Function::new_typed(store, fd_filestat_set_size), + "fd_filestat_set_times" => Function::new_typed(store, fd_filestat_set_times), + "fd_pread" => Function::new_typed(store, fd_pread), + "fd_prestat_get" => Function::new_typed(store, fd_prestat_get), + "fd_prestat_dir_name" => Function::new_typed(store, fd_prestat_dir_name), + "fd_pwrite" => Function::new_typed(store, fd_pwrite), + "fd_read" => Function::new_typed(store, fd_read), + "fd_readdir" => Function::new_typed(store, fd_readdir), + "fd_renumber" => Function::new_typed(store, fd_renumber), + "fd_seek" => Function::new_typed(store, fd_seek), + "fd_sync" => Function::new_typed(store, fd_sync), + "fd_tell" => Function::new_typed(store, fd_tell), + "fd_write" => Function::new_typed(store, fd_write), + "path_create_directory" => Function::new_typed(store, path_create_directory), + "path_filestat_get" => Function::new_typed(store, path_filestat_get), + "path_filestat_set_times" => Function::new_typed(store, path_filestat_set_times), + "path_link" => Function::new_typed(store, path_link), + "path_open" => Function::new_typed(store, path_open), + "path_readlink" => Function::new_typed(store, path_readlink), + "path_remove_directory" => Function::new_typed(store, path_remove_directory), + "path_rename" => Function::new_typed(store, path_rename), + "path_symlink" => Function::new_typed(store, path_symlink), + "path_unlink_file" => Function::new_typed(store, path_unlink_file), + "poll_oneoff" => Function::new_typed(store, poll_oneoff), + "proc_exit" => Function::new_typed(store, proc_exit), + "proc_raise" => Function::new_typed(store, proc_raise), + "sched_yield" => Function::new_typed(store, sched_yield), + "random_get" => Function::new_typed(store, random_get), + "sock_accept" => Function::new_typed(store, sock_accept), + "sock_recv" => Function::new_typed(store, sock_recv), + "sock_send" => Function::new_typed(store, sock_send), + "sock_shutdown" => Function::new_typed(store, sock_shutdown), + } + } +}