From 1ee6e823889de347c510569250ab4e0edfc59f85 Mon Sep 17 00:00:00 2001 From: "hkrn (a.k.a shimacpyon)" <129939+hkrn@users.noreply.github.com> Date: Thu, 20 Oct 2022 23:19:28 +0900 Subject: [PATCH] [rust] bump wasmer to 3.0.0 (beta) (#231) --- .github/dependabot.yml | 2 +- rust/Cargo.lock | 579 +++++++----------- rust/Cargo.toml | 7 +- rust/deny.toml | 8 +- rust/plugin_wasm/Cargo.toml | 6 +- rust/plugin_wasm/src/lib.rs | 299 +++++---- rust/plugin_wasm/src/model/c_api.rs | 10 +- rust/plugin_wasm/src/model/core.rs | 77 +-- rust/plugin_wasm/src/model/plugin.rs | 306 ++++++--- rust/plugin_wasm/src/model/test/full.rs | 194 +++--- rust/plugin_wasm/src/model/test/minimum.rs | 187 +++--- rust/plugin_wasm/src/model/test/mod.rs | 52 +- rust/plugin_wasm/src/motion/c_api.rs | 19 +- rust/plugin_wasm/src/motion/core.rs | 61 +- rust/plugin_wasm/src/motion/plugin.rs | 335 +++++++--- rust/plugin_wasm/src/motion/test/full.rs | 189 +++--- rust/plugin_wasm/src/motion/test/minimum.rs | 182 +++--- rust/plugin_wasm/src/motion/test/mod.rs | 52 +- rust/plugin_wasm_test_model_full/src/lib.rs | 43 +- .../plugin_wasm_test_model_minimum/src/lib.rs | 41 +- rust/plugin_wasm_test_motion_full/src/lib.rs | 43 +- .../src/lib.rs | 41 +- rust/scripts/build.bat | 11 + rust/scripts/build.sh | 11 + rust/scripts/test.bat | 11 - rust/scripts/test.sh | 11 - 26 files changed, 1470 insertions(+), 1307 deletions(-) create mode 100644 rust/scripts/build.bat create mode 100755 rust/scripts/build.sh delete mode 100644 rust/scripts/test.bat delete mode 100755 rust/scripts/test.sh diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8cad4e88..fce64a19 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,4 +3,4 @@ updates: - package-ecosystem: "cargo" directory: "/rust" schedule: - interval: "weekly" + interval: "monthly" diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 3f8dbad8..7c729228 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -28,20 +28,11 @@ dependencies = [ "version_check", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9a8f622bcf6ff3df478e9deba3e03e4e04b300f8e6a139e192c05fa3490afc7" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" [[package]] name = "autocfg" @@ -60,7 +51,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "miniz_oxide", - "object 0.29.0", + "object", "rustc-demangle", ] @@ -78,9 +69,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytecheck" @@ -154,56 +145,57 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.86.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "529ffacce2249ac60edba2941672dfedf3d96558b415d0d8083cd007456e0f55" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.86.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "427d105f617efc8cb55f8d036a7fded2e227892d8780b4985e5551f8d27c4a92" dependencies = [ "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-entity", + "cranelift-isle", "gimli", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.86.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "551674bed85b838d45358e3eab4f0ffaa6790c70dc08184204b9a54b41cdb7d1" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.86.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "2b3a63ae57498c3eb495360944a33571754241e15e47e3bcae6082f40fec5866" [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.86.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "11aa8aa624c72cc1c94ea3d0739fa61248260b5b14d3646f51593a88d67f3e6e" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.86.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "544ee8f4d1c9559c9aa6d46e7aaeac4a13856d620561094f35527356c7d21bd0" dependencies = [ "cranelift-codegen", "log", @@ -212,13 +204,10 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.86.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "ed16b14363d929b8c37e3c557d0a7396791b383ecc302141643c054343170aad" [[package]] name = "crossbeam-channel" @@ -243,33 +232,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" +checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" dependencies = [ "autocfg", "cfg-if 1.0.0", "crossbeam-utils", "memoffset", - "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" dependencies = [ "cfg-if 1.0.0", - "once_cell", ] [[package]] name = "ctor" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", "syn", @@ -277,9 +264,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.13.4" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02" dependencies = [ "darling_core", "darling_macro", @@ -287,9 +274,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.4" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f" dependencies = [ "fnv", "ident_case", @@ -300,15 +287,26 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.13.4" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5" dependencies = [ "darling_core", "quote", "syn", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "diff" version = "0.1.13" @@ -323,9 +321,9 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "either" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "enum-iterator" @@ -349,18 +347,18 @@ dependencies = [ [[package]] name = "enumset" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4799cdb24d48f1f8a7a98d06b7fde65a85a2d1e42b25a889f5406aa1fbefe074" +checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea83a3fbdc1d999ccfbcbee717eab36f8edf2d71693a23ce0d7cca19e085304c" +checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" dependencies = [ "darling", "proc-macro2", @@ -395,6 +393,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generational-arena" version = "0.2.8" @@ -426,15 +433,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -472,8 +470,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", - "hashbrown 0.12.3", - "serde", + "hashbrown", ] [[package]] @@ -487,24 +484,24 @@ dependencies = [ [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -523,19 +520,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.132" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" - -[[package]] -name = "libloading" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" -dependencies = [ - "cfg-if 1.0.0", - "winapi", -] +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" [[package]] name = "log" @@ -546,27 +533,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "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", -] - [[package]] name = "mach" version = "0.3.2" @@ -608,9 +574,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] @@ -637,25 +603,23 @@ dependencies = [ ] [[package]] -name = "num_cpus" -version = "1.13.1" +name = "nu-ansi-term" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ - "hermit-abi", - "libc", + "overload", + "winapi", ] [[package]] -name = "object" -version = "0.28.4" +name = "num_cpus" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", + "hermit-abi", + "libc", ] [[package]] @@ -669,9 +633,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "output_vt100" @@ -682,6 +646,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "petgraph" version = "0.6.2" @@ -806,9 +776,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -918,9 +888,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -959,13 +929,14 @@ dependencies = [ ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1021,7 +992,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" dependencies = [ "bytecheck", - "hashbrown 0.12.3", + "hashbrown", + "indexmap", "ptr_meta", "rend", "rkyv_derive", @@ -1045,12 +1017,6 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc_version" version = "0.2.3" @@ -1060,12 +1026,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustversion" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" - [[package]] name = "ryu" version = "1.0.11" @@ -1110,27 +1070,15 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.144" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_bytes" -version = "0.11.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" -dependencies = [ - "serde", -] +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" [[package]] name = "serde_derive" -version = "1.0.144" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -1139,9 +1087,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "itoa", "ryu", @@ -1172,11 +1120,26 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" + [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "stable_deref_trait" @@ -1244,9 +1207,9 @@ checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", @@ -1275,18 +1238,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.32" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.32" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -1342,12 +1305,11 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if 1.0.0", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1355,9 +1317,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", @@ -1366,9 +1328,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -1387,11 +1349,11 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ - "ansi_term", + "nu-ansi-term", "sharded-slab", "smallvec", "thread_local", @@ -1401,15 +1363,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" - -[[package]] -name = "unicode-width" -version = "0.1.9" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "valuable" @@ -1442,9 +1398,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -1452,9 +1408,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", @@ -1467,9 +1423,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1477,9 +1433,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -1490,88 +1446,66 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" - -[[package]] -name = "wasm-encoder" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8905fd25fdadeb0e7e8bf43a9f46f9f972d6291ad0c7a32573b88dd13a6cfa6b" -dependencies = [ - "leb128", -] +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasmer" -version = "2.3.0" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "01fc47a9d4ebb42b3a9a3d802e809bbdb5afaf3028373a82b989e51f4e400903" dependencies = [ + "bytes", "cfg-if 1.0.0", "indexmap", "js-sys", - "loupe", "more-asserts", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", - "wat", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "54d7b5068f9ed673f0fc8513b4702067a0f5712d3ea226eb71fc4a9c6c4fe9c7" dependencies = [ + "backtrace", + "cfg-if 1.0.0", + "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-cranelift" -version = "2.3.0" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "f0fac321e5d3dc4f157f28bf6001f06d2e821422ce60449da97d39af171b4169" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1583,9 +1517,9 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "02b38c7a442cffa5efb799631013bb30aeb1d553c50effa51905ea8b36ecc6c8" dependencies = [ "proc-macro-error", "proc-macro2", @@ -1594,134 +1528,46 @@ dependencies = [ ] [[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -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 = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if 1.0.0", - "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 = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if 1.0.0", - "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" +name = "wasmer-types" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" +checksum = "7d47fb87929c956693d68393d4778670ed1ce9733804b74bbd5fa6fa6d725250" dependencies = [ "enum-iterator", "enumset", - "loupe", + "indexmap", + "more-asserts", "rkyv", + "target-lexicon", "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", -] - -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", ] [[package]] -name = "wasmer-types" -version = "2.3.0" +name = "wasmer-vbus" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "106dd8032075e49d9935ff2ea69360c85f5b942fe0bc5f777a0278f2b039145e" dependencies = [ - "backtrace", - "enum-iterator", - "indexmap", - "loupe", - "more-asserts", - "rkyv", - "serde", "thiserror", + "wasmer-vfs", ] [[package]] name = "wasmer-vfs" -version = "2.3.0" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9302eae3edc53cb540c2d681e7f16d8274918c1ce207591f04fed351649e97c0" +checksum = "8dee30860fda7b4e37601624ccb3273fba67d7ac850d6a7338ce922ca2aa5737" dependencies = [ - "libc", + "slab", "thiserror", "tracing", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "6a72cac9f0ce7a9f3d0fe01604202270cdfe8d3dae9d84742b85c5d935cad74d" dependencies = [ "backtrace", "cc", @@ -1731,27 +1577,36 @@ dependencies = [ "indexmap", "lazy_static", "libc", - "loupe", "mach", "memoffset", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] +[[package]] +name = "wasmer-vnet" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b808bda0282639f7d590b75e1eb87339d34adbb5504fe6784e993549f275f2c" +dependencies = [ + "bytes", + "thiserror", + "wasmer-vfs", +] + [[package]] name = "wasmer-wasi" -version = "2.3.0" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadbe31e3c1b6f3e398ad172b169152ae1a743ae6efd5f9ffb34019983319d99" +checksum = "94f757f3c46db35742d56bea0a7f695c33abeb468bfa71a68a09d2c04239fb3b" dependencies = [ + "bytes", "cfg-if 1.0.0", + "derivative", "generational-arena", "getrandom", "libc", @@ -1759,19 +1614,22 @@ dependencies = [ "tracing", "wasm-bindgen", "wasmer", + "wasmer-vbus", "wasmer-vfs", + "wasmer-vnet", "wasmer-wasi-types", "winapi", ] [[package]] name = "wasmer-wasi-types" -version = "2.3.0" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22dc83aadbdf97388de3211cb6f105374f245a3cf2a5c65a16776e7a087a8468" +checksum = "a5ada7a7fc8ac363e750518f3a81257cbc9d7188895a05fbe5e557b9d7a6366c" dependencies = [ "byteorder", "time", + "wasmer-derive", "wasmer-types", ] @@ -1781,36 +1639,15 @@ version = "0.83.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" -[[package]] -name = "wast" -version = "45.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186c474c4f9bb92756b566d592a16591b4526b1a4841171caa3f31d7fe330d96" -dependencies = [ - "leb128", - "memchr", - "unicode-width", - "wasm-encoder", -] - -[[package]] -name = "wat" -version = "1.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d4bc4724b4f02a482c8cab053dac5ef26410f264c06ce914958f9a42813556" -dependencies = [ - "wast", -] - [[package]] name = "which" -version = "4.2.5" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "lazy_static", "libc", + "once_cell", ] [[package]] diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5920018d..f167c4b6 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -9,7 +9,10 @@ members = [ ] default-members = ["plugin_wasm", "protobuf"] -[profile.release] +[profile.release-lto] +inherits = "release" lto = true +strip = true codegen-units = 1 -strip = "debuginfo" +opt-level = "s" +panic = "abort" diff --git a/rust/deny.toml b/rust/deny.toml index da8a20af..6c2acb28 100644 --- a/rust/deny.toml +++ b/rust/deny.toml @@ -5,6 +5,9 @@ vulnerability = "deny" unmaintained = "warn" yanked = "warn" notice = "warn" +ignore = [ + "RUSTSEC-2020-0056", # unmaintained stdweb issue +] [licenses] unlicensed = "deny" @@ -15,7 +18,6 @@ allow = [ "BSD-3-Clause", "BSD-2-Clause", "CC0-1.0", - "ISC", "MIT", "MPL-2.0", "Unicode-DFS-2016", @@ -30,8 +32,8 @@ confidence-threshold = 0.8 ignore = false [bans] -multiple-versions = "warn" -wildcards = "allow" +multiple-versions = "allow" +wildcards = "warn" highlight = "all" [sources] diff --git a/rust/plugin_wasm/Cargo.toml b/rust/plugin_wasm/Cargo.toml index c067b845..bae597ef 100644 --- a/rust/plugin_wasm/Cargo.toml +++ b/rust/plugin_wasm/Cargo.toml @@ -9,8 +9,8 @@ license = "MPL-2.0" anyhow = "1" tracing = { version = "0.1", default-features = false, features = ["std"] } tracing-subscriber = "0.3" -wasmer = "2" -wasmer-wasi = "2" +wasmer = { version = "3.0.0-beta", default-features = false, features = ["sys", "cranelift"] } +wasmer-wasi = { version = "3.0.0-beta", default-features = false, features = ["sys", "mem-fs"] } walkdir = "2" [dev-dependencies] @@ -19,7 +19,7 @@ serde_derive = "1" serde_json = "1" maplit = "1" rand = "0.8" -pretty_assertions = "1.3" +pretty_assertions = "1" [lib] path = "src/lib.rs" diff --git a/rust/plugin_wasm/src/lib.rs b/rust/plugin_wasm/src/lib.rs index f14a6739..f77ab3b9 100644 --- a/rust/plugin_wasm/src/lib.rs +++ b/rust/plugin_wasm/src/lib.rs @@ -8,7 +8,7 @@ use core::slice; use std::mem::size_of; use anyhow::Result; -use wasmer::{Array, Instance, Memory, NativeFunc, WasmPtr}; +use wasmer::{Instance, Memory, Store, TypedFunction, WasmPtr}; pub(crate) const PLUGIN_MODEL_IO_ABI_VERSION: u32 = 2 << 16; pub(crate) const PLUGIN_MOTION_IO_ABI_VERSION: u32 = 2 << 16; @@ -38,8 +38,8 @@ impl nanoem_application_plugin_status_t { } } -pub(crate) type ByteArray = WasmPtr; -pub(crate) type OpaquePtr = WasmPtr<()>; +pub(crate) type ByteArray = WasmPtr; +pub(crate) type OpaquePtr = WasmPtr; pub(crate) type SizePtr = WasmPtr; pub(crate) type StatusPtr = WasmPtr; @@ -53,24 +53,29 @@ fn notify_export_function_error(name: &str) { fn inner_get_data_internal( instance: &Instance, opaque: &OpaquePtr, - get_data_size: NativeFunc<(OpaquePtr, SizePtr), ()>, - get_data_body: NativeFunc<(OpaquePtr, ByteArray, u32, StatusPtr), ()>, + get_data_size: TypedFunction<(OpaquePtr, SizePtr), ()>, + get_data_body: TypedFunction<(OpaquePtr, ByteArray, u32, StatusPtr), ()>, output_data: &mut Vec, + store: &mut Store, ) -> Result<()> { - let data_size_ptr = allocate_size_ptr(instance)?; - get_data_size.call(*opaque, data_size_ptr)?; - let data_size = data_size_ptr.deref(inner_memory(instance)).unwrap().get(); - let bytes = allocate_byte_array(instance, data_size)?; - let status_ptr = allocate_status_ptr(instance)?; - get_data_body.call(*opaque, bytes, data_size, status_ptr)?; - let cell = bytes.deref(inner_memory(instance), 0, data_size).unwrap(); + let data_size_ptr = allocate_size_ptr(instance, store)?; + get_data_size.call(store, *opaque, data_size_ptr)?; + let data_size = data_size_ptr + .deref(&inner_memory(instance).view(store)) + .read()?; + let bytes = allocate_byte_array(instance, data_size, store)?; + let status_ptr = allocate_status_ptr(instance, store)?; + get_data_body.call(store, *opaque, bytes, data_size, status_ptr)?; + let cell = bytes.deref(&inner_memory(instance).view(store)).as_ptr32(); output_data.resize(data_size as usize, 0); - for byte in cell { - output_data.push(byte.get()); + let view = inner_memory(instance).view(store); + let slice = cell.slice(&view, data_size)?; + for byte in slice.iter() { + output_data.push(byte.read()?); } - release_byte_array(instance, bytes)?; - release_size_ptr(instance, data_size_ptr)?; - release_status_ptr(instance, status_ptr)?; + release_byte_array(instance, bytes, store)?; + release_size_ptr(instance, data_size_ptr, store)?; + release_status_ptr(instance, status_ptr, store)?; Ok(()) } @@ -80,14 +85,16 @@ fn inner_set_data_internal( data: &[u8], component_size: usize, name: &str, + store: &mut Store, ) -> Result<()> { if let Ok(set_input_model_data) = instance .exports - .get_native_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>(name) + .get_typed_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>(store, name) { - let data_ptr = allocate_byte_array_with_data(instance, data)?; - let status_ptr = allocate_status_ptr(instance)?; + let data_ptr = allocate_byte_array_with_data(instance, data, store)?; + let status_ptr = allocate_status_ptr(instance, store)?; set_input_model_data.call( + store, *opaque, data_ptr, if component_size > 1 { @@ -97,8 +104,8 @@ fn inner_set_data_internal( }, status_ptr, )?; - release_byte_array(instance, data_ptr)?; - release_status_ptr(instance, status_ptr)?; + release_byte_array(instance, data_ptr, store)?; + release_status_ptr(instance, status_ptr, store)?; } else { notify_export_function_error(name); } @@ -113,83 +120,100 @@ pub(crate) fn inner_memory(instance: &Instance) -> &Memory { instance.exports.get_memory("memory").unwrap() } -pub(crate) fn allocate_byte_array(instance: &Instance, data_size: u32) -> Result { +pub(crate) fn allocate_byte_array( + instance: &Instance, + data_size: u32, + store: &mut Store, +) -> Result { let malloc_func = instance .exports - .get_native_function::(MALLOC_FN)?; - let data_ptr = malloc_func.call(data_size)?; + .get_typed_function::(store, MALLOC_FN)?; + let data_ptr = malloc_func.call(store, data_size)?; tracing::debug!(size = data_size, "Allocated byte array"); Ok(data_ptr) } -pub(crate) fn allocate_byte_array_with_data(instance: &Instance, data: &[u8]) -> Result { +pub(crate) fn allocate_byte_array_with_data( + instance: &Instance, + data: &[u8], + store: &mut Store, +) -> Result { let data_size = data.len() as u32; - let data_ptr = allocate_byte_array(instance, data_size)?; - let cell = data_ptr - .deref(inner_memory(instance), 0, data_size) - .unwrap(); + let data_ptr = allocate_byte_array(instance, data_size, store)?; + let view = inner_memory(instance).view(store); + let cell = data_ptr.deref(&view); + let ptr = cell.as_ptr32(); for (offset, byte) in data.iter().enumerate() { - cell[offset].set(*byte); + ptr.add_offset(offset as u32)?.write(&view, *byte)?; } tracing::debug!(size = data_size, "Allocated byte array with data"); Ok(data_ptr) } -pub(crate) fn allocate_status_ptr(instance: &Instance) -> Result { - let memory = inner_memory(instance); +pub(crate) fn allocate_status_ptr(instance: &Instance, store: &mut Store) -> Result { let malloc_func = instance .exports - .get_native_function::(MALLOC_FN)?; - let data_ptr = malloc_func.call(size_of::() as u32)?; - data_ptr.deref(memory).unwrap().set(0); + .get_typed_function::(store, MALLOC_FN)?; + let data_ptr = malloc_func.call(store, size_of::() as u32)?; + let view = inner_memory(instance).view(store); + data_ptr.deref(&view).write(0)?; Ok(data_ptr) } -pub(crate) fn allocate_size_ptr(instance: &Instance) -> Result { +pub(crate) fn allocate_size_ptr(instance: &Instance, store: &mut Store) -> Result { let memory = inner_memory(instance); let malloc_func = instance .exports - .get_native_function::(MALLOC_FN)?; - let size_ptr = malloc_func.call(size_of::() as u32)?; - size_ptr.deref(memory).unwrap().set(0); + .get_typed_function::(store, MALLOC_FN)?; + let size_ptr = malloc_func.call(store, size_of::() as u32)?; + let view = memory.view(store); + size_ptr.deref(&view).write(0)?; Ok(size_ptr) } -pub(crate) fn release_byte_array(instance: &Instance, ptr: ByteArray) -> Result<()> { +pub(crate) fn release_byte_array( + instance: &Instance, + ptr: ByteArray, + store: &mut Store, +) -> Result<()> { let free_func = instance .exports - .get_native_function::(FREE_FN) + .get_typed_function::(store, FREE_FN) .unwrap(); - free_func.call(ptr)?; + free_func.call(store, ptr)?; tracing::debug!("Released byte array"); Ok(()) } -pub(crate) fn release_size_ptr(instance: &Instance, ptr: SizePtr) -> Result<()> { +pub(crate) fn release_size_ptr(instance: &Instance, ptr: SizePtr, store: &mut Store) -> Result<()> { let free_func = instance .exports - .get_native_function::(FREE_FN) + .get_typed_function::(store, FREE_FN) .unwrap(); - free_func.call(ptr)?; + free_func.call(store, ptr)?; Ok(()) } -pub(crate) fn release_status_ptr(instance: &Instance, ptr: StatusPtr) -> Result<()> { +pub(crate) fn release_status_ptr( + instance: &Instance, + ptr: StatusPtr, + store: &mut Store, +) -> Result<()> { let free_func = instance .exports - .get_native_function::(FREE_FN) + .get_typed_function::(store, FREE_FN) .unwrap(); - let status = ptr.deref(inner_memory(instance)).unwrap().get(); - free_func.call(ptr)?; - if status != 0 { - return Err(anyhow::anyhow!("code={}", status)); - } + free_func.call(store, ptr)?; Ok(()) } -pub(crate) fn inner_initialize_function(instance: &Instance, name: &str) -> Result<()> { - if let Ok(initialize) = instance.exports.get_native_function::<(), ()>(name) { - initialize.call()?; +pub(crate) fn inner_initialize_function( + instance: &Instance, + name: &str, + store: &mut Store, +) -> Result<()> { + if let Ok(initialize) = instance.exports.get_typed_function::<(), ()>(store, name) { + initialize.call(store)?; tracing::debug!(name = name, "Called initialization"); } else { notify_export_function_error(name); @@ -197,19 +221,31 @@ pub(crate) fn inner_initialize_function(instance: &Instance, name: &str) -> Resu Ok(()) } -pub(crate) fn inner_create_opaque(instance: &Instance, name: &str) -> Result { +pub(crate) fn inner_create_opaque( + instance: &Instance, + name: &str, + store: &mut Store, +) -> Result { let create = instance .exports - .get_native_function::<(), OpaquePtr>(name)?; - let opaque = create.call()?; + .get_typed_function::<(), OpaquePtr>(store, name)?; + let opaque = create.call(store)?; tracing::debug!(name = name, opaque = ?opaque, "Called creating opaque"); Ok(opaque) } -pub(crate) fn inner_destroy_opaque(instance: &Instance, opaque: &Option, name: &str) { +pub(crate) fn inner_destroy_opaque( + instance: &Instance, + opaque: &Option, + name: &str, + store: &mut Store, +) { if let Some(opaque) = opaque { - if let Ok(destroy) = instance.exports.get_native_function::(name) { - match destroy.call(*opaque) { + if let Ok(destroy) = instance + .exports + .get_typed_function::(store, name) + { + match destroy.call(store, *opaque) { Ok(_) => tracing::debug!(name = name, opaque = ?opaque, "Called destroying opaque"), Err(err) => { tracing::warn!(name = name, opaque = ?opaque, error = %err, "Catched runtime error") @@ -219,9 +255,9 @@ pub(crate) fn inner_destroy_opaque(instance: &Instance, opaque: &Option(name) { - terminate.call().unwrap(); +pub(crate) fn inner_terminate_function(instance: &Instance, name: &str, store: &mut Store) { + if let Ok(terminate) = instance.exports.get_typed_function::<(), ()>(store, name) { + terminate.call(store).unwrap(); tracing::debug!(name = name, "Called termination"); } else { notify_export_function_error(name); @@ -232,16 +268,17 @@ pub(crate) fn inner_get_string( instance: &Instance, opaque: &Option, name: &str, + store: &mut Store, ) -> Result { if let Some(opaque) = opaque { if let Ok(get_string) = instance .exports - .get_native_function::(name) + .get_typed_function::(store, name) { let memory = inner_memory(instance); let value = get_string - .call(*opaque)? - .get_utf8_string_with_nul(memory) + .call(store, *opaque)? + .read_utf8_string_with_nul(&memory.view(store)) .unwrap_or_default(); tracing::debug!( name = name, @@ -264,10 +301,11 @@ pub(crate) fn inner_get_data( opaque: &Option, body_func_name: &str, size_func_name: &str, + store: &mut Store, ) -> Result> { if let Some(opaque) = opaque { - let get_data_size = instance.exports.get_native_function(size_func_name); - let get_data_body = instance.exports.get_native_function(body_func_name); + let get_data_size = instance.exports.get_typed_function(store, size_func_name); + let get_data_body = instance.exports.get_typed_function(store, body_func_name); let mut output_data = Vec::new(); if get_data_size.is_ok() && get_data_body.is_ok() { let get_data_size = get_data_size?; @@ -278,6 +316,7 @@ pub(crate) fn inner_get_data( get_data_size, get_data_body, &mut output_data, + store, )?; tracing::debug!( name = body_func_name, @@ -297,12 +336,13 @@ pub(crate) fn inner_set_data( opaque: &Option, data: &[T], name: &str, + store: &mut Store, ) -> Result<()> { if let Some(opaque) = opaque { let component_size = size_of::(); let len = data.len() * component_size; let data = unsafe { slice::from_raw_parts(data.as_ptr() as *const u8, len) }; - inner_set_data_internal(instance, opaque, data, component_size, name)?; + inner_set_data_internal(instance, opaque, data, component_size, name, store)?; tracing::debug!(name = name, opaque = ?opaque, size = len, "Called setting data"); } Ok(()) @@ -313,12 +353,13 @@ pub(crate) fn inner_set_language( opaque: &Option, value: i32, name: &str, + store: &mut Store, ) -> Result<()> { if let Some(opaque) = opaque { let set_language = instance .exports - .get_native_function::<(OpaquePtr, i32), ()>(name)?; - set_language.call(*opaque, value)?; + .get_typed_function::<(OpaquePtr, i32), ()>(store, name)?; + set_language.call(store, *opaque, value)?; tracing::debug!(name = name, opaque = ?opaque, value = value, "Called setting language"); } Ok(()) @@ -328,12 +369,13 @@ pub(crate) fn inner_count_all_functions( instance: &Instance, opaque: &Option, name: &str, + store: &mut Store, ) -> Result { if let Some(opaque) = opaque { let count_all_functions = instance .exports - .get_native_function::(name)?; - let count = count_all_functions.call(*opaque)?; + .get_typed_function::(store, name)?; + let count = count_all_functions.call(store, *opaque)?; tracing::debug!(name = name, opaque = ?opaque, count = count, "Called counting all functions"); Ok(count) } else { @@ -346,15 +388,16 @@ pub(crate) fn inner_get_function_name( opaque: &Option, index: i32, name: &str, + store: &mut Store, ) -> Result { if let Some(opaque) = opaque { let get_function_name = instance .exports - .get_native_function::<(OpaquePtr, i32), ByteArray>(name)?; + .get_typed_function::<(OpaquePtr, i32), ByteArray>(store, name)?; let memory = inner_memory(instance); let function_name = get_function_name - .call(*opaque, index)? - .get_utf8_string_with_nul(memory) + .call(store, *opaque, index)? + .read_utf8_string_with_nul(&memory.view(store)) .unwrap_or_default(); tracing::debug!( name = name, @@ -374,53 +417,70 @@ pub(crate) fn inner_set_function( opaque: &Option, index: i32, name: &str, -) -> Result<()> { - if let Some(opaque) = opaque { - let status_ptr = allocate_status_ptr(instance)?; + store: &mut Store, +) -> Result { + let result = if let Some(opaque) = opaque { + let status_ptr = allocate_status_ptr(instance, store)?; let set_function = instance .exports - .get_native_function::<(OpaquePtr, i32, StatusPtr), ()>(name)?; - set_function.call(*opaque, index, status_ptr)?; + .get_typed_function::<(OpaquePtr, i32, StatusPtr), ()>(store, name)?; + set_function.call(store, *opaque, index, status_ptr)?; + let result = status_ptr.read(&inner_memory(instance).view(store))?; tracing::debug!(name = name, opaque = ?opaque, index = index, "Called setting function"); - release_status_ptr(instance, status_ptr)?; - } - Ok(()) + release_status_ptr(instance, status_ptr, store)?; + result + } else { + nanoem_application_plugin_status_t::ERROR_NULL_OBJECT as i32 + }; + Ok(result) } pub(crate) fn inner_execute( instance: &Instance, opaque: &Option, name: &str, -) -> Result<()> { - if let Some(opaque) = opaque { - let status_ptr = allocate_status_ptr(instance)?; + store: &mut Store, +) -> Result { + let result = if let Some(opaque) = opaque { + let status_ptr = allocate_status_ptr(instance, store)?; let execute = instance .exports - .get_native_function::<(OpaquePtr, StatusPtr), ()>(name)?; - execute.call(*opaque, status_ptr)?; + .get_typed_function::<(OpaquePtr, StatusPtr), ()>(store, name)?; + execute.call(store, *opaque, status_ptr)?; + let result = status_ptr.read(&inner_memory(instance).view(store))?; tracing::debug!(name = name, opaque = ?opaque, "Called executing function"); - release_status_ptr(instance, status_ptr)?; - } - Ok(()) + release_status_ptr(instance, status_ptr, store)?; + result + } else { + nanoem_application_plugin_status_t::ERROR_NULL_OBJECT as i32 + }; + Ok(result) } pub(crate) fn inner_load_ui_window( instance: &Instance, opaque: &Option, name: &str, -) -> Result<()> { - if let Some(opaque) = opaque { + store: &mut Store, +) -> Result { + let result = if let Some(opaque) = opaque { if let Ok(load_ui_window_layout) = instance .exports - .get_native_function::<(OpaquePtr, StatusPtr), ()>(name) + .get_typed_function::<(OpaquePtr, StatusPtr), ()>(store, name) { - let status_ptr = allocate_status_ptr(instance)?; - load_ui_window_layout.call(*opaque, status_ptr)?; - release_status_ptr(instance, status_ptr)?; + let status_ptr = allocate_status_ptr(instance, store)?; + load_ui_window_layout.call(store, *opaque, status_ptr)?; + let result = status_ptr.read(&inner_memory(instance).view(store))?; tracing::debug!(name = name, opaque = ?opaque, "Called loading UI window"); + release_status_ptr(instance, status_ptr, store)?; + result + } else { + nanoem_application_plugin_status_t::SUCCESS as i32 } - } - Ok(()) + } else { + nanoem_application_plugin_status_t::ERROR_NULL_OBJECT as i32 + }; + Ok(result) } pub(crate) fn inner_set_ui_component_layout( @@ -430,22 +490,24 @@ pub(crate) fn inner_set_ui_component_layout( data: &[u8], name: &str, reload: &mut bool, -) -> Result<()> { - if let Some(opaque) = opaque { - if let Ok(set_ui_component_layout) = instance.exports.get_native_function::<( + store: &mut Store, +) -> Result { + let result = if let Some(opaque) = opaque { + if let Ok(set_ui_component_layout) = instance.exports.get_typed_function::<( OpaquePtr, ByteArray, ByteArray, u32, SizePtr, StatusPtr, - ), ()>(name) + ), ()>(store, name) { - let id_ptr = allocate_byte_array_with_data(instance, id.as_bytes())?; - let data_ptr = allocate_byte_array_with_data(instance, data)?; - let reload_layout_ptr = allocate_size_ptr(instance)?; - let status_ptr = allocate_status_ptr(instance)?; + let id_ptr = allocate_byte_array_with_data(instance, id.as_bytes(), store)?; + let data_ptr = allocate_byte_array_with_data(instance, data, store)?; + let reload_layout_ptr = allocate_size_ptr(instance, store)?; + let status_ptr = allocate_status_ptr(instance, store)?; set_ui_component_layout.call( + store, *opaque, id_ptr, data_ptr, @@ -454,16 +516,21 @@ pub(crate) fn inner_set_ui_component_layout( status_ptr, )?; *reload = false; + let result = status_ptr.read(&inner_memory(instance).view(store))?; tracing::debug!(name = name, opaque = ?opaque, "Called setting UI component layout"); - release_byte_array(instance, id_ptr)?; - release_byte_array(instance, data_ptr)?; - release_size_ptr(instance, reload_layout_ptr)?; - release_status_ptr(instance, status_ptr)?; + release_byte_array(instance, id_ptr, store)?; + release_byte_array(instance, data_ptr, store)?; + release_size_ptr(instance, reload_layout_ptr, store)?; + release_status_ptr(instance, status_ptr, store)?; + result } else { notify_export_function_error(name); + nanoem_application_plugin_status_t::SUCCESS as i32 } - } - Ok(()) + } else { + nanoem_application_plugin_status_t::ERROR_NULL_OBJECT as i32 + }; + Ok(result) } mod model; diff --git a/rust/plugin_wasm/src/model/c_api.rs b/rust/plugin_wasm/src/model/c_api.rs index 0ef33b9f..e6d84055 100644 --- a/rust/plugin_wasm/src/model/c_api.rs +++ b/rust/plugin_wasm/src/model/c_api.rs @@ -65,7 +65,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOSetLanguage( plugin: *mut nanoem_application_plugin_model_io_t, value: i32, ) { - if let Some(instance) = nanoem_application_plugin_model_io_t::get(plugin) { + if let Some(instance) = nanoem_application_plugin_model_io_t::get_mut(plugin) { instance.set_language(value).unwrap_or_default(); } } @@ -559,7 +559,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOGetOutputModelDataSize( plugin: *mut nanoem_application_plugin_model_io_t, length: *mut u32, ) { - if let Some(instance) = nanoem_application_plugin_model_io_t::get(plugin) { + if let Some(instance) = nanoem_application_plugin_model_io_t::get_mut(plugin) { if !length.is_null() { *length = instance.output_slice().len() as u32 } @@ -576,7 +576,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOGetOutputModelData( length: u32, status_ptr: *mut nanoem_application_plugin_status_t, ) { - let status = match nanoem_application_plugin_model_io_t::get(plugin) { + let status = match nanoem_application_plugin_model_io_t::get_mut(plugin) { Some(instance) => { if !data.is_null() && length > 0 { let slice = instance.output_slice(); @@ -621,7 +621,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOGetUIWindowLayoutDataSize plugin: *mut nanoem_application_plugin_model_io_t, length: *mut u32, ) { - if let Some(instance) = nanoem_application_plugin_model_io_t::get(plugin) { + if let Some(instance) = nanoem_application_plugin_model_io_t::get_mut(plugin) { if !length.is_null() { *length = instance.window_layout_data_slice().len() as u32 } @@ -638,7 +638,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOGetUIWindowLayoutData( length: u32, status_ptr: *mut nanoem_application_plugin_status_t, ) { - let status = match nanoem_application_plugin_model_io_t::get(plugin) { + let status = match nanoem_application_plugin_model_io_t::get_mut(plugin) { Some(instance) => { if !data.is_null() && length > 0 { let slice = instance.window_layout_data_slice(); diff --git a/rust/plugin_wasm/src/model/core.rs b/rust/plugin_wasm/src/model/core.rs index baaeb4a3..0f9a3725 100644 --- a/rust/plugin_wasm/src/model/core.rs +++ b/rust/plugin_wasm/src/model/core.rs @@ -5,8 +5,6 @@ */ use anyhow::Result; -use wasmer::Store; -use wasmer_wasi::WasiState; use crate::nanoem_application_plugin_status_t; @@ -19,7 +17,6 @@ use std::ptr::null; #[allow(non_camel_case_types)] pub struct nanoem_application_plugin_model_io_t { controller: ModelIOPluginController, - reason: Option, } impl Drop for nanoem_application_plugin_model_io_t { @@ -33,14 +30,9 @@ impl Drop for nanoem_application_plugin_model_io_t { impl nanoem_application_plugin_model_io_t { pub fn new(path: &CStr) -> Result { let path = Path::new(path.to_str()?); - let store = Store::default(); - let mut env = WasiState::new("nanoem").finalize()?; - let controller = ModelIOPluginController::from_path(path, &store, &mut env)?; + let mut controller = ModelIOPluginController::from_path(path)?; controller.initialize()?; - Ok(Self { - controller, - reason: None, - }) + Ok(Self { controller }) } pub(crate) unsafe fn get(plugin: *const Self) -> Option<&'static Self> { if !plugin.is_null() { @@ -78,92 +70,83 @@ impl nanoem_application_plugin_model_io_t { null() } } - pub fn set_language(&self, value: i32) -> Result<()> { + pub fn set_language(&mut self, value: i32) -> Result<()> { self.controller.set_language(value) } - pub fn set_function(&mut self, value: i32) -> Result<()> { + pub fn set_function(&mut self, value: i32) -> Result { self.controller.set_function(value) } - pub fn set_all_selected_vertex_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_vertex_indices(&mut self, data: &[i32]) -> Result<()> { self.controller.set_all_selected_vertex_indices(data) } - pub fn set_all_selected_material_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_material_indices(&mut self, data: &[i32]) -> Result<()> { self.controller.set_all_selected_material_indices(data) } - pub fn set_all_selected_bone_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_bone_indices(&mut self, data: &[i32]) -> Result<()> { self.controller.set_all_selected_bone_indices(data) } - pub fn set_all_selected_morph_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_morph_indices(&mut self, data: &[i32]) -> Result<()> { self.controller.set_all_selected_morph_indices(data) } - pub fn set_all_selected_label_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_label_indices(&mut self, data: &[i32]) -> Result<()> { self.controller.set_all_selected_label_indices(data) } - pub fn set_all_selected_rigid_body_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_rigid_body_indices(&mut self, data: &[i32]) -> Result<()> { self.controller.set_all_selected_rigid_body_indices(data) } - pub fn set_all_selected_joint_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_joint_indices(&mut self, data: &[i32]) -> Result<()> { self.controller.set_all_selected_joint_indices(data) } - pub fn set_all_selected_soft_body_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_soft_body_indices(&mut self, data: &[i32]) -> Result<()> { self.controller.set_all_selected_soft_body_indices(data) } - pub fn set_audio_description(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_description(&mut self, data: &[u8]) -> Result<()> { self.controller.set_audio_description(data) } - pub fn set_camera_description(&self, data: &[u8]) -> Result<()> { + pub fn set_camera_description(&mut self, data: &[u8]) -> Result<()> { self.controller.set_camera_description(data) } - pub fn set_light_description(&self, data: &[u8]) -> Result<()> { + pub fn set_light_description(&mut self, data: &[u8]) -> Result<()> { self.controller.set_light_description(data) } - pub fn set_audio_data(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_data(&mut self, data: &[u8]) -> Result<()> { self.controller.set_audio_data(data) } - pub fn set_input_data(&self, data: &[u8]) -> Result<()> { + pub fn set_input_data(&mut self, data: &[u8]) -> Result<()> { self.controller.set_input_model_data(data) } - pub fn execute(&self) -> Result<()> { + pub fn execute(&mut self) -> Result<()> { self.controller.execute() } - pub fn output_slice(&self) -> Vec { + pub fn output_slice(&mut self) -> Vec { self.controller.get_output_data().unwrap_or_default() } - pub fn load_window_layout(&self) -> Result<()> { + pub fn load_window_layout(&mut self) -> Result<()> { self.controller.load_ui_window_layout() } - pub fn set_component_layout(&self, id: &CStr, data: &[u8], reload: &mut bool) -> Result<()> { + pub fn set_component_layout( + &mut self, + id: &CStr, + data: &[u8], + reload: &mut bool, + ) -> Result<()> { self.controller .set_ui_component_layout(id.to_str()?, data, reload) } - pub fn window_layout_data_slice(&self) -> Vec { + pub fn window_layout_data_slice(&mut self) -> Vec { self.controller.get_ui_window_layout().unwrap_or_default() } pub fn failure_reason(&self) -> Option { - if self.reason.is_some() { - self.reason.clone() - } else { - let reason = self.controller.failure_reason().unwrap(); - if !reason.is_empty() { - Some(reason) - } else { - None - } - } + self.controller.failure_reason() } pub fn recovery_suggestion(&self) -> Option { - let suggestion = self.controller.recovery_suggestion().unwrap(); - if !suggestion.is_empty() { - Some(suggestion) - } else { - None - } + self.controller.recovery_suggestion() } pub fn assign_failure_reason( &mut self, value: anyhow::Error, ) -> nanoem_application_plugin_status_t { - self.reason = Some(value.to_string()); + self.controller.assign_failure_reason(value); nanoem_application_plugin_status_t::ERROR_REFER_REASON } } diff --git a/rust/plugin_wasm/src/model/plugin.rs b/rust/plugin_wasm/src/model/plugin.rs index 94200f4b..5f56c80c 100644 --- a/rust/plugin_wasm/src/model/plugin.rs +++ b/rust/plugin_wasm/src/model/plugin.rs @@ -9,7 +9,7 @@ use std::{ffi::CString, path::Path}; use anyhow::Result; use walkdir::WalkDir; use wasmer::{Instance, Module, Store}; -use wasmer_wasi::WasiEnv; +use wasmer_wasi::{WasiEnv, WasiFunctionEnv, WasiState}; use crate::{ inner_count_all_functions, inner_create_opaque, inner_destroy_opaque, inner_execute, @@ -19,253 +19,311 @@ use crate::{ StatusPtr, FREE_FN, MALLOC_FN, }; -fn validate_plugin(instance: &Instance) -> Result<()> { +fn validate_plugin(instance: &Instance, store: &mut Store) -> Result<()> { let e = &instance.exports; e.get_memory("memory")?; - e.get_native_function::(MALLOC_FN)?; - e.get_native_function::(FREE_FN)?; - e.get_native_function::<(), OpaquePtr>("nanoemApplicationPluginModelIOCreate")?; - e.get_native_function::("nanoemApplicationPluginModelIOGetName")?; - e.get_native_function::("nanoemApplicationPluginModelIOGetVersion")?; - e.get_native_function::<(OpaquePtr, i32), ()>("nanoemApplicationPluginModelIOSetLanguage")?; - e.get_native_function::("nanoemApplicationPluginModelIOCountAllFunctions")?; - e.get_native_function::<(OpaquePtr, i32), ByteArray>( + e.get_typed_function::(store, MALLOC_FN)?; + e.get_typed_function::(store, FREE_FN)?; + e.get_typed_function::<(), OpaquePtr>(store, "nanoemApplicationPluginModelIOCreate")?; + e.get_typed_function::(store, "nanoemApplicationPluginModelIOGetName")?; + e.get_typed_function::( + store, + "nanoemApplicationPluginModelIOGetVersion", + )?; + e.get_typed_function::<(OpaquePtr, i32), ()>( + store, + "nanoemApplicationPluginModelIOSetLanguage", + )?; + e.get_typed_function::( + store, + "nanoemApplicationPluginModelIOCountAllFunctions", + )?; + e.get_typed_function::<(OpaquePtr, i32), ByteArray>( + store, "nanoemApplicationPluginModelIOGetFunctionName", )?; - e.get_native_function::<(OpaquePtr, i32, StatusPtr), ()>( + e.get_typed_function::<(OpaquePtr, i32, StatusPtr), ()>( + store, "nanoemApplicationPluginModelIOSetFunction", )?; - e.get_native_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>( + e.get_typed_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>( + store, "nanoemApplicationPluginModelIOSetInputModelData", )?; - e.get_native_function::<(OpaquePtr, StatusPtr), ()>("nanoemApplicationPluginModelIOExecute")?; - e.get_native_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>( + e.get_typed_function::<(OpaquePtr, StatusPtr), ()>( + store, + "nanoemApplicationPluginModelIOExecute", + )?; + e.get_typed_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>( + store, "nanoemApplicationPluginModelIOGetOutputModelData", )?; - e.get_native_function::<(OpaquePtr, SizePtr), ()>( + e.get_typed_function::<(OpaquePtr, SizePtr), ()>( + store, "nanoemApplicationPluginModelIOGetOutputModelDataSize", )?; - e.get_native_function::( + e.get_typed_function::( + store, "nanoemApplicationPluginModelIOGetFailureReason", )?; - e.get_native_function::("nanoemApplicationPluginModelIODestroy")?; + e.get_typed_function::(store, "nanoemApplicationPluginModelIODestroy")?; Ok(()) } pub struct ModelIOPlugin { instance: Instance, + store: Store, + env: WasiFunctionEnv, opaque: Option, } impl ModelIOPlugin { - pub fn new(bytes: &[u8], store: &Store, env: &mut WasiEnv) -> Result { - let module = Module::new(store, bytes)?; - let imports = env.import_object(&module)?; - let instance = Instance::new(&module, &imports)?; - validate_plugin(&instance)?; + pub fn new(bytes: &[u8], env: WasiFunctionEnv, mut store: Store) -> Result { + let module = Module::new(&store, bytes)?; + let imports = env.import_object(&mut store, &module)?; + let instance = Instance::new(&mut store, &module, &imports)?; + let memory = instance.exports.get_memory("memory")?; + env.data_mut(&mut store).set_memory(memory.clone()); + validate_plugin(&instance, &mut store)?; Ok(Self { instance, + env, + store, opaque: None, }) } - pub fn initialize(&self) -> Result<()> { - inner_initialize_function(&self.instance, "nanoemApplicationPluginModelIOInitialize") + pub fn initialize(&mut self) -> Result<()> { + inner_initialize_function( + &self.instance, + "nanoemApplicationPluginModelIOInitialize", + &mut self.store, + ) } pub fn create(&mut self) -> Result<()> { self.opaque = Some(inner_create_opaque( &self.instance, "nanoemApplicationPluginModelIOCreate", + &mut self.store, )?); Ok(()) } - pub fn set_language(&self, value: i32) -> Result<()> { + pub fn set_language(&mut self, value: i32) -> Result<()> { inner_set_language( &self.instance, &self.opaque, value, "nanoemApplicationPluginModelIOSetLanguage", + &mut self.store, ) } - pub fn name(&self) -> Result { + pub fn name(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOGetName", + &mut self.store, ) } #[allow(unused)] - pub fn description(&self) -> Result { + pub fn description(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOGetDescription", + &mut self.store, ) } - pub fn version(&self) -> Result { + pub fn version(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOGetVersion", + &mut self.store, ) } - pub fn count_all_functions(&self) -> Result { + pub fn count_all_functions(&mut self) -> Result { inner_count_all_functions( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOCountAllFunctions", + &mut self.store, ) } - pub fn function_name(&self, index: i32) -> Result { + pub fn function_name(&mut self, index: i32) -> Result { inner_get_function_name( &self.instance, &self.opaque, index, "nanoemApplicationPluginModelIOGetFunctionName", + &mut self.store, ) } - pub fn set_function(&self, index: i32) -> Result<()> { + pub fn set_function(&mut self, index: i32) -> Result { inner_set_function( &self.instance, &self.opaque, index, "nanoemApplicationPluginModelIOSetFunction", + &mut self.store, ) } - pub fn set_all_selected_vertex_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_vertex_indices(&mut self, data: &[i32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAllSelectedVertexObjectIndices", + &mut self.store, ) } - pub fn set_all_selected_material_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_material_indices(&mut self, data: &[i32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAllSelectedMaterialObjectIndices", + &mut self.store, ) } - pub fn set_all_selected_bone_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_bone_indices(&mut self, data: &[i32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAllSelectedBoneObjectIndices", + &mut self.store, ) } - pub fn set_all_selected_morph_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_morph_indices(&mut self, data: &[i32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAllSelectedMorphObjectIndices", + &mut self.store, ) } - pub fn set_all_selected_label_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_label_indices(&mut self, data: &[i32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAllSelectedLabelObjectIndices", + &mut self.store, ) } - pub fn set_all_selected_rigid_body_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_rigid_body_indices(&mut self, data: &[i32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAllSelectedRigidBodyObjectIndices", + &mut self.store, ) } - pub fn set_all_selected_joint_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_joint_indices(&mut self, data: &[i32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAllSelectedJointObjectIndices", + &mut self.store, ) } - pub fn set_all_selected_soft_body_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_soft_body_indices(&mut self, data: &[i32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAllSelectedSoftBodyObjectIndices", + &mut self.store, ) } - pub fn set_audio_description(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_description(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetAudioDescription", + &mut self.store, ) } - pub fn set_camera_description(&self, data: &[u8]) -> Result<()> { + pub fn set_camera_description(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetCameraDescription", + &mut self.store, ) } - pub fn set_light_description(&self, data: &[u8]) -> Result<()> { + pub fn set_light_description(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetLightDescription", + &mut self.store, ) } - pub fn set_audio_data(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_data(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetInputAudioData", + &mut self.store, ) } - pub fn set_input_model_data(&self, data: &[u8]) -> Result<()> { + pub fn set_input_model_data(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginModelIOSetInputModelData", + &mut self.store, ) } - pub fn execute(&self) -> Result<()> { + pub fn execute(&mut self) -> Result { inner_execute( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOExecute", + &mut self.store, ) } - pub fn get_output_data(&self) -> Result> { + pub fn get_output_data(&mut self) -> Result> { inner_get_data( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOGetOutputModelData", "nanoemApplicationPluginModelIOGetOutputModelDataSize", + &mut self.store, ) } - pub fn load_ui_window_layout(&self) -> Result<()> { + pub fn load_ui_window_layout(&mut self) -> Result { inner_load_ui_window( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOLoadUIWindowLayout", + &mut self.store, ) } - pub fn get_ui_window_layout(&self) -> Result> { + pub fn get_ui_window_layout(&mut self) -> Result> { inner_get_data( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOGetUIWindowLayoutData", "nanoemApplicationPluginModelIOGetUIWindowLayoutDataSize", + &mut self.store, ) } - pub fn set_ui_component_layout(&self, id: &str, data: &[u8], reload: &mut bool) -> Result<()> { + pub fn set_ui_component_layout( + &mut self, + id: &str, + data: &[u8], + reload: &mut bool, + ) -> Result { inner_set_ui_component_layout( &self.instance, &self.opaque, @@ -273,31 +331,43 @@ impl ModelIOPlugin { data, "nanoemApplicationPluginModelIOSetUIComponentLayoutData", reload, + &mut self.store, ) } - pub fn failure_reason(&self) -> Result { + pub fn failure_reason(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOGetFailureReason", + &mut self.store, ) } - pub fn recovery_suggestion(&self) -> Result { + pub fn recovery_suggestion(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginModelIOGetRecoverySuggestion", + &mut self.store, ) } - pub fn destroy(&self) { + pub fn destroy(&mut self) { inner_destroy_opaque( &self.instance, &self.opaque, "nanoemApplicationPluginModelIODestroy", + &mut self.store, ) } - pub fn terminate(&self) { - inner_terminate_function(&self.instance, "nanoemApplicationPluginModelIOTerminate") + pub fn terminate(&mut self) { + inner_terminate_function( + &self.instance, + "nanoemApplicationPluginModelIOTerminate", + &mut self.store, + ) + } + #[allow(dead_code)] + pub(super) fn wasi_env(&mut self) -> &mut WasiEnv { + self.env.env.as_mut(&mut self.store) } } @@ -305,6 +375,8 @@ pub struct ModelIOPluginController { plugins: Vec, function_indices: Vec<(usize, i32, CString)>, plugin_index: Option, + failure_reason: Option, + recovery_suggestion: Option, } impl ModelIOPluginController { @@ -314,16 +386,20 @@ impl ModelIOPluginController { plugins, function_indices, plugin_index: None, + failure_reason: None, + recovery_suggestion: None, } } - pub fn from_path(path: &Path, store: &Store, env: &mut WasiEnv) -> Result { + pub fn from_path(path: &Path) -> Result { let mut plugins = vec![]; for entry in WalkDir::new(path.parent().unwrap()) { let entry = entry?; let filename = entry.file_name().to_str(); if filename.map(|s| s.ends_with(".wasm")).unwrap_or(false) { let bytes = std::fs::read(entry.path())?; - match ModelIOPlugin::new(&bytes, store, env) { + let mut store = Store::default(); + let env = WasiState::new("nanoem").finalize(&mut store)?; + match ModelIOPlugin::new(&bytes, env, store) { Ok(plugin) => { plugins.push(plugin); tracing::debug!(filename = filename.unwrap(), "Loaded model WASM plugin"); @@ -340,33 +416,30 @@ impl ModelIOPluginController { } Ok(Self::new(plugins)) } - pub fn initialize(&self) -> Result<()> { + pub fn initialize(&mut self) -> Result<()> { self.plugins - .iter() + .iter_mut() .try_for_each(|plugin| plugin.initialize()) } pub fn create(&mut self) -> Result<()> { self.plugins .iter_mut() .try_for_each(|plugin| plugin.create())?; - for (offset, plugin) in self.plugins.iter().enumerate() { + for (offset, plugin) in self.plugins.iter_mut().enumerate() { + let name = plugin.name()?; + let version = plugin.version()?; for index in 0..plugin.count_all_functions()? { let name = CString::new( - &format!( - "{}: {} ({})", - plugin.name()?, - plugin.function_name(index)?, - plugin.version()? - )[..], + &format!("{}: {} ({})", name, plugin.function_name(index)?, version)[..], )?; self.function_indices.push((offset, index, name)); } } Ok(()) } - pub fn set_language(&self, value: i32) -> Result<()> { + pub fn set_language(&mut self, value: i32) -> Result<()> { self.plugins - .iter() + .iter_mut() .try_for_each(|plugin| plugin.set_language(value)) } pub fn count_all_functions(&self) -> i32 { @@ -379,7 +452,7 @@ impl ModelIOPluginController { Err(anyhow::anyhow!("out of bound function index: {}", index)) } } - pub fn set_function(&mut self, index: i32) -> Result<()> { + pub fn set_function(&mut self, index: i32) -> Result { if let Some((plugin_index, function_index, _)) = self.function_indices.get(index as usize) { let result = self.plugins[*plugin_index].set_function(*function_index); self.plugin_index = Some(*plugin_index); @@ -388,83 +461,118 @@ impl ModelIOPluginController { Err(anyhow::anyhow!("out of bound function index: {}", index)) } } - pub fn set_all_selected_vertex_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_vertex_indices(&mut self, data: &[i32]) -> Result<()> { self.current_plugin()?.set_all_selected_vertex_indices(data) } - pub fn set_all_selected_material_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_material_indices(&mut self, data: &[i32]) -> Result<()> { self.current_plugin()? .set_all_selected_material_indices(data) } - pub fn set_all_selected_bone_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_bone_indices(&mut self, data: &[i32]) -> Result<()> { self.current_plugin()?.set_all_selected_bone_indices(data) } - pub fn set_all_selected_morph_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_morph_indices(&mut self, data: &[i32]) -> Result<()> { self.current_plugin()?.set_all_selected_morph_indices(data) } - pub fn set_all_selected_label_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_label_indices(&mut self, data: &[i32]) -> Result<()> { self.current_plugin()?.set_all_selected_label_indices(data) } - pub fn set_all_selected_rigid_body_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_rigid_body_indices(&mut self, data: &[i32]) -> Result<()> { self.current_plugin()? .set_all_selected_rigid_body_indices(data) } - pub fn set_all_selected_joint_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_joint_indices(&mut self, data: &[i32]) -> Result<()> { self.current_plugin()?.set_all_selected_joint_indices(data) } - pub fn set_all_selected_soft_body_indices(&self, data: &[i32]) -> Result<()> { + pub fn set_all_selected_soft_body_indices(&mut self, data: &[i32]) -> Result<()> { self.current_plugin()? .set_all_selected_soft_body_indices(data) } - pub fn set_audio_description(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_description(&mut self, data: &[u8]) -> Result<()> { self.current_plugin()?.set_audio_description(data) } - pub fn set_camera_description(&self, data: &[u8]) -> Result<()> { + pub fn set_camera_description(&mut self, data: &[u8]) -> Result<()> { self.current_plugin()?.set_camera_description(data) } - pub fn set_light_description(&self, data: &[u8]) -> Result<()> { + pub fn set_light_description(&mut self, data: &[u8]) -> Result<()> { self.current_plugin()?.set_light_description(data) } - pub fn set_audio_data(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_data(&mut self, data: &[u8]) -> Result<()> { self.current_plugin()?.set_audio_data(data) } - pub fn set_input_model_data(&self, bytes: &[u8]) -> Result<()> { + pub fn set_input_model_data(&mut self, bytes: &[u8]) -> Result<()> { self.current_plugin()?.set_input_model_data(bytes) } - pub fn execute(&self) -> Result<()> { - self.current_plugin()?.execute() + pub fn execute(&mut self) -> Result<()> { + match self.current_plugin()?.execute() { + Ok(0) => Ok(()), + Ok(_) => self.set_failure(), + Err(err) => Err(err), + } } - pub fn get_output_data(&self) -> Result> { + pub fn get_output_data(&mut self) -> Result> { self.current_plugin()?.get_output_data() } - pub fn load_ui_window_layout(&self) -> Result<()> { - self.current_plugin()?.load_ui_window_layout() + pub fn load_ui_window_layout(&mut self) -> Result<()> { + match self.current_plugin()?.load_ui_window_layout() { + Ok(0) => Ok(()), + Ok(_) => self.set_failure(), + Err(err) => Err(err), + } } - pub fn get_ui_window_layout(&self) -> Result> { + pub fn get_ui_window_layout(&mut self) -> Result> { self.current_plugin()?.get_ui_window_layout() } - pub fn set_ui_component_layout(&self, id: &str, data: &[u8], reload: &mut bool) -> Result<()> { - self.current_plugin()? + pub fn set_ui_component_layout( + &mut self, + id: &str, + data: &[u8], + reload: &mut bool, + ) -> Result<()> { + match self + .current_plugin()? .set_ui_component_layout(id, data, reload) + { + Ok(0) => Ok(()), + Ok(_) => self.set_failure(), + Err(err) => Err(err), + } } - pub fn failure_reason(&self) -> Result { - self.current_plugin()?.failure_reason() + pub fn failure_reason(&self) -> Option { + self.failure_reason.clone() } - pub fn recovery_suggestion(&self) -> Result { - self.current_plugin()?.recovery_suggestion() + pub fn recovery_suggestion(&self) -> Option { + self.recovery_suggestion.clone() } - pub fn destroy(&self) { - self.plugins.iter().for_each(|plugin| plugin.destroy()) + pub fn assign_failure_reason(&mut self, value: anyhow::Error) { + self.failure_reason = Some(value.to_string()); } - pub fn terminate(&self) { - self.plugins.iter().for_each(|plugin| plugin.terminate()) + pub fn destroy(&mut self) { + self.plugins.iter_mut().for_each(|plugin| plugin.destroy()) + } + pub fn terminate(&mut self) { + self.plugins + .iter_mut() + .for_each(|plugin| plugin.terminate()) } #[allow(unused)] pub(super) fn all_plugins_mut(&mut self) -> &mut [ModelIOPlugin] { &mut self.plugins } - fn current_plugin(&self) -> Result<&ModelIOPlugin> { + fn set_failure(&mut self) -> Result<()> { + let value = self.current_plugin()?.failure_reason()?; + if !value.is_empty() { + self.failure_reason = Some(value); + } + let value = self.current_plugin()?.recovery_suggestion()?; + if !value.is_empty() { + self.recovery_suggestion = Some(value); + } + Ok(()) + } + fn current_plugin(&mut self) -> Result<&mut ModelIOPlugin> { if let Some(plugin_index) = self.plugin_index { - Ok(&self.plugins[plugin_index]) + Ok(&mut self.plugins[plugin_index]) } else { Err(anyhow::anyhow!("plugin is not set")) } diff --git a/rust/plugin_wasm/src/model/test/full.rs b/rust/plugin_wasm/src/model/test/full.rs index 45bb7ccd..afdbadf8 100644 --- a/rust/plugin_wasm/src/model/test/full.rs +++ b/rust/plugin_wasm/src/model/test/full.rs @@ -8,37 +8,30 @@ use anyhow::{Context, Result}; use maplit::hashmap; use pretty_assertions::assert_eq; use serde_json::json; -use wasmer_wasi::WasiEnv; use crate::model::{ plugin::ModelIOPluginController, - test::{ - create_random_data, create_wasi_env, flush_plugin_output, read_plugin_output, PluginOutput, - }, + test::{create_random_data, flush_plugin_output, read_plugin_output, PluginOutput}, }; -use super::inner_create_controller; +use super::{build_type_and_flags, inner_create_controller}; -fn create_controller(env: &mut WasiEnv) -> Result { +fn create_controller() -> Result { let package = "plugin_wasm_test_model_full"; - let (ty, flag) = if cfg!(debug_assertions) { - ("debug", "") - } else { - ("release", " --release") - }; - inner_create_controller(&format!("target/wasm32-wasi/{}/{}.wasm", ty, package), env) - .with_context(|| { + let (ty, flag) = build_type_and_flags(); + inner_create_controller(&format!("target/wasm32-wasi/{}/{}.wasm", ty, package)).with_context( + || { format!( "try build with \"cargo build --package {} --target wasm32-wasi{}\"", package, flag ) - }) + }, + ) } #[test] fn create() -> Result<()> { - let mut env = create_wasi_env()?; - let result = create_controller(&mut env); + let result = create_controller(); assert!(result.is_ok()); let mut controller = result?; assert!(controller.initialize().is_ok()); @@ -54,11 +47,15 @@ fn create() -> Result<()> { ..Default::default() }, PluginOutput { - function: "nanoemApplicationPluginModelIOCountAllFunctions".to_owned(), + function: "nanoemApplicationPluginModelIOGetName".to_owned(), ..Default::default() }, PluginOutput { - function: "nanoemApplicationPluginModelIOGetName".to_owned(), + function: "nanoemApplicationPluginModelIOGetVersion".to_owned(), + ..Default::default() + }, + PluginOutput { + function: "nanoemApplicationPluginModelIOCountAllFunctions".to_owned(), ..Default::default() }, PluginOutput { @@ -68,17 +65,23 @@ fn create() -> Result<()> { }) }, PluginOutput { - function: "nanoemApplicationPluginModelIOGetVersion".to_owned(), - ..Default::default() + function: "nanoemApplicationPluginModelIOGetFunctionName".to_owned(), + arguments: Some(hashmap! { + "index".to_owned() => json!(1), + }) }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); - assert_eq!(1, controller.count_all_functions()); + assert_eq!(2, controller.count_all_functions()); assert_eq!( "plugin_wasm_test_model_full: function0 (1.2.3)", controller.function_name(0)?.to_str()? ); + assert_eq!( + "plugin_wasm_test_model_full: function0 (1.2.3)", + controller.function_name(1)?.to_str()? + ); controller.destroy(); controller.terminate(); assert_eq!( @@ -92,19 +95,18 @@ fn create() -> Result<()> { ..Default::default() }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); Ok(()) } #[test] fn set_language() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_language(0).is_ok()); assert_eq!( vec![PluginOutput { @@ -113,7 +115,7 @@ fn set_language() -> Result<()> { "value".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -122,13 +124,12 @@ fn set_language() -> Result<()> { #[test] fn execute() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_input_model_data(&data).is_ok()); assert!(controller.execute().is_ok()); let output = controller.get_output_data(); @@ -165,7 +166,7 @@ fn execute() -> Result<()> { }) }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -174,13 +175,12 @@ fn execute() -> Result<()> { #[test] fn set_all_selected_vertex_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_vertex_indices(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -191,7 +191,7 @@ fn set_all_selected_vertex_indices() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -200,13 +200,12 @@ fn set_all_selected_vertex_indices() -> Result<()> { #[test] fn set_all_selected_material_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_material_indices(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -218,7 +217,7 @@ fn set_all_selected_material_indices() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -227,13 +226,12 @@ fn set_all_selected_material_indices() -> Result<()> { #[test] fn set_all_selected_bone_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_bone_indices(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -244,7 +242,7 @@ fn set_all_selected_bone_indices() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -253,13 +251,12 @@ fn set_all_selected_bone_indices() -> Result<()> { #[test] fn set_all_selected_morph_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_morph_indices(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -270,7 +267,7 @@ fn set_all_selected_morph_indices() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -279,13 +276,12 @@ fn set_all_selected_morph_indices() -> Result<()> { #[test] fn set_all_selected_label_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_label_indices(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -296,7 +292,7 @@ fn set_all_selected_label_indices() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -305,13 +301,12 @@ fn set_all_selected_label_indices() -> Result<()> { #[test] fn set_all_selected_rigid_body_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_rigid_body_indices(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -323,7 +318,7 @@ fn set_all_selected_rigid_body_indices() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -332,13 +327,12 @@ fn set_all_selected_rigid_body_indices() -> Result<()> { #[test] fn set_all_selected_joint_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_joint_indices(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -349,7 +343,7 @@ fn set_all_selected_joint_indices() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -358,13 +352,12 @@ fn set_all_selected_joint_indices() -> Result<()> { #[test] fn set_all_selected_soft_body_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_soft_body_indices(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -376,7 +369,7 @@ fn set_all_selected_soft_body_indices() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -385,13 +378,12 @@ fn set_all_selected_soft_body_indices() -> Result<()> { #[test] fn set_audio_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_audio_description(&data).is_ok()); assert_eq!( vec![PluginOutput { @@ -402,7 +394,7 @@ fn set_audio_description() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -411,13 +403,12 @@ fn set_audio_description() -> Result<()> { #[test] fn set_audio_data() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_audio_data(&data).is_ok()); assert_eq!( vec![PluginOutput { @@ -428,7 +419,7 @@ fn set_audio_data() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -437,13 +428,12 @@ fn set_audio_data() -> Result<()> { #[test] fn set_camera_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_camera_description(&data).is_ok()); assert_eq!( vec![PluginOutput { @@ -454,7 +444,7 @@ fn set_camera_description() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -463,13 +453,12 @@ fn set_camera_description() -> Result<()> { #[test] fn set_light_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_light_description(&data).is_ok()); assert_eq!( vec![PluginOutput { @@ -480,7 +469,7 @@ fn set_light_description() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -489,13 +478,12 @@ fn set_light_description() -> Result<()> { #[test] fn ui_window() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.load_ui_window_layout().is_ok()); let output = controller.get_ui_window_layout(); assert!(output.is_ok()); @@ -536,7 +524,7 @@ fn ui_window() -> Result<()> { }) }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -545,22 +533,16 @@ fn ui_window() -> Result<()> { #[test] fn get_failure_reason() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; - controller.set_function(0)?; - flush_plugin_output(&mut env)?; + controller.set_function(1)?; + controller.execute().unwrap_or_default(); + flush_plugin_output(&mut controller)?; let result = controller.failure_reason(); - assert!(result.is_ok()); - assert_eq!("Failure Reason", result?); - assert_eq!( - vec![PluginOutput { - function: "nanoemApplicationPluginModelIOGetFailureReason".to_owned(), - ..Default::default() - },], - read_plugin_output(&mut env)? - ); + assert!(result.is_some()); + assert_eq!("Failure Reason", result.unwrap()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -568,22 +550,16 @@ fn get_failure_reason() -> Result<()> { #[test] fn get_recovery_suggestion() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; - controller.set_function(0)?; - flush_plugin_output(&mut env)?; + controller.set_function(1)?; + controller.execute().unwrap_or_default(); + flush_plugin_output(&mut controller)?; let result = controller.recovery_suggestion(); - assert!(result.is_ok()); - assert_eq!("Recovery Suggestion", result?); - assert_eq!( - vec![PluginOutput { - function: "nanoemApplicationPluginModelIOGetRecoverySuggestion".to_owned(), - ..Default::default() - },], - read_plugin_output(&mut env)? - ); + assert!(result.is_some()); + assert_eq!("Recovery Suggestion", result.unwrap()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) diff --git a/rust/plugin_wasm/src/model/test/minimum.rs b/rust/plugin_wasm/src/model/test/minimum.rs index 569e15d5..644db5d2 100644 --- a/rust/plugin_wasm/src/model/test/minimum.rs +++ b/rust/plugin_wasm/src/model/test/minimum.rs @@ -8,37 +8,30 @@ use anyhow::{Context, Result}; use maplit::hashmap; use pretty_assertions::assert_eq; use serde_json::json; -use wasmer_wasi::WasiEnv; use crate::model::{ plugin::ModelIOPluginController, - test::{ - create_random_data, create_wasi_env, flush_plugin_output, read_plugin_output, PluginOutput, - }, + test::{create_random_data, flush_plugin_output, read_plugin_output, PluginOutput}, }; -use super::inner_create_controller; +use super::{build_type_and_flags, inner_create_controller}; -fn create_controller(env: &mut WasiEnv) -> Result { +fn create_controller() -> Result { let package = "plugin_wasm_test_model_minimum"; - let (ty, flag) = if cfg!(debug_assertions) { - ("debug", "") - } else { - ("release", " --release") - }; - inner_create_controller(&format!("target/wasm32-wasi/{}/{}.wasm", ty, package), env) - .with_context(|| { + let (ty, flag) = build_type_and_flags(); + inner_create_controller(&format!("target/wasm32-wasi/{}/{}.wasm", ty, package)).with_context( + || { format!( "try build with \"cargo build --package {} --target wasm32-wasi{}\"", package, flag ) - }) + }, + ) } #[test] fn create() -> Result<()> { - let mut env = create_wasi_env()?; - let result = create_controller(&mut env); + let result = create_controller(); assert!(result.is_ok()); let mut controller = result?; assert!(controller.initialize().is_ok()); @@ -50,11 +43,15 @@ fn create() -> Result<()> { ..Default::default() }, PluginOutput { - function: "nanoemApplicationPluginModelIOCountAllFunctions".to_owned(), + function: "nanoemApplicationPluginModelIOGetName".to_owned(), ..Default::default() }, PluginOutput { - function: "nanoemApplicationPluginModelIOGetName".to_owned(), + function: "nanoemApplicationPluginModelIOGetVersion".to_owned(), + ..Default::default() + }, + PluginOutput { + function: "nanoemApplicationPluginModelIOCountAllFunctions".to_owned(), ..Default::default() }, PluginOutput { @@ -64,17 +61,23 @@ fn create() -> Result<()> { }) }, PluginOutput { - function: "nanoemApplicationPluginModelIOGetVersion".to_owned(), - ..Default::default() + function: "nanoemApplicationPluginModelIOGetFunctionName".to_owned(), + arguments: Some(hashmap! { + "index".to_owned() => json!(1), + }) }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); - assert_eq!(1, controller.count_all_functions()); + assert_eq!(2, controller.count_all_functions()); assert_eq!( "plugin_wasm_test_model_minimum: function0 (1.2.3)", controller.function_name(0)?.to_str()? ); + assert_eq!( + "plugin_wasm_test_model_minimum: function0 (1.2.3)", + controller.function_name(1)?.to_str()? + ); controller.destroy(); controller.terminate(); assert_eq!( @@ -82,19 +85,18 @@ fn create() -> Result<()> { function: "nanoemApplicationPluginModelIODestroy".to_owned(), ..Default::default() },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); Ok(()) } #[test] fn set_language() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_language(0).is_ok()); assert_eq!( vec![PluginOutput { @@ -103,7 +105,7 @@ fn set_language() -> Result<()> { "value".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -112,13 +114,12 @@ fn set_language() -> Result<()> { #[test] fn execute() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_input_model_data(&data).is_ok()); assert!(controller.execute().is_ok()); let output = controller.get_output_data(); @@ -155,7 +156,7 @@ fn execute() -> Result<()> { }) }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -164,15 +165,14 @@ fn execute() -> Result<()> { #[test] fn set_all_selected_vertex_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_vertex_indices(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -180,15 +180,14 @@ fn set_all_selected_vertex_indices() -> Result<()> { #[test] fn set_all_selected_material_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_material_indices(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -196,15 +195,14 @@ fn set_all_selected_material_indices() -> Result<()> { #[test] fn set_all_selected_bone_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_bone_indices(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -212,15 +210,14 @@ fn set_all_selected_bone_indices() -> Result<()> { #[test] fn set_all_selected_morph_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_morph_indices(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -228,15 +225,14 @@ fn set_all_selected_morph_indices() -> Result<()> { #[test] fn set_all_selected_label_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_label_indices(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -244,15 +240,14 @@ fn set_all_selected_label_indices() -> Result<()> { #[test] fn set_all_selected_rigid_body_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_rigid_body_indices(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -260,15 +255,14 @@ fn set_all_selected_rigid_body_indices() -> Result<()> { #[test] fn set_all_selected_joint_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_joint_indices(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -276,15 +270,14 @@ fn set_all_selected_joint_indices() -> Result<()> { #[test] fn set_all_selected_soft_body_indices() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, i32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_soft_body_indices(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -292,15 +285,14 @@ fn set_all_selected_soft_body_indices() -> Result<()> { #[test] fn set_audio_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_audio_description(&data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -308,15 +300,14 @@ fn set_audio_description() -> Result<()> { #[test] fn set_audio_data() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_audio_data(&data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -324,15 +315,14 @@ fn set_audio_data() -> Result<()> { #[test] fn set_camera_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_camera_description(&data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -340,15 +330,14 @@ fn set_camera_description() -> Result<()> { #[test] fn set_light_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_light_description(&data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -356,13 +345,12 @@ fn set_light_description() -> Result<()> { #[test] fn ui_window() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.load_ui_window_layout().is_ok()); let output = controller.get_ui_window_layout(); assert!(output.is_ok()); @@ -371,7 +359,7 @@ fn ui_window() -> Result<()> { assert!(controller .set_ui_component_layout("ui_window", &data, &mut reload) .is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -379,22 +367,16 @@ fn ui_window() -> Result<()> { #[test] fn get_failure_reason() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; - controller.set_function(0)?; - flush_plugin_output(&mut env)?; + controller.set_function(1)?; + controller.execute().unwrap_or_default(); + flush_plugin_output(&mut controller)?; let result = controller.failure_reason(); - assert!(result.is_ok()); - assert_eq!("Failure Reason", result?); - assert_eq!( - vec![PluginOutput { - function: "nanoemApplicationPluginModelIOGetFailureReason".to_owned(), - ..Default::default() - },], - read_plugin_output(&mut env)? - ); + assert!(result.is_some()); + assert_eq!("Failure Reason", result.unwrap()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -402,16 +384,15 @@ fn get_failure_reason() -> Result<()> { #[test] fn get_recovery_suggestion() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; - controller.set_function(0)?; - flush_plugin_output(&mut env)?; + controller.set_function(1)?; + controller.execute().unwrap_or_default(); + flush_plugin_output(&mut controller)?; let result = controller.recovery_suggestion(); - assert!(result.is_ok()); - assert_eq!("", result?); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(result.is_none()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) diff --git a/rust/plugin_wasm/src/model/test/mod.rs b/rust/plugin_wasm/src/model/test/mod.rs index 481a9899..ea6ae2e3 100644 --- a/rust/plugin_wasm/src/model/test/mod.rs +++ b/rust/plugin_wasm/src/model/test/mod.rs @@ -7,6 +7,7 @@ use std::{ collections::{HashMap, HashSet}, env::current_dir, + sync::Arc, }; use anyhow::Result; @@ -15,7 +16,7 @@ use rand::{thread_rng, Rng}; use serde_derive::{Deserialize, Serialize}; use serde_json::Value; use wasmer::Store; -use wasmer_wasi::{Pipe, WasiEnv, WasiState}; +use wasmer_wasi::{types::__WASI_STDOUT_FILENO, Pipe, WasiFunctionEnv, WasiState}; use super::plugin::{ModelIOPlugin, ModelIOPluginController}; @@ -25,9 +26,17 @@ struct PluginOutput { arguments: Option>, } -fn create_wasi_env() -> Result { +fn build_type_and_flags() -> (&'static str, &'static str) { + if cfg!(debug_assertions) { + ("debug", "") + } else { + ("release-lto", " --profile release-lto") + } +} + +fn create_wasi_env(store: &mut Store) -> Result { let stdout = Box::new(Pipe::new()); - Ok(WasiState::new("nanoem").stdout(stdout).finalize()?) + Ok(WasiState::new("nanoem").stdout(stdout).finalize(store)?) } fn create_random_data(size: usize) -> Vec { @@ -40,17 +49,21 @@ fn create_random_data(size: usize) -> Vec { data } -fn flush_plugin_output(env: &mut WasiEnv) -> Result<()> { - let mut state = env.state(); - let stdout = state.fs.stdout_mut()?.as_mut().unwrap(); +fn flush_plugin_output(controller: &mut ModelIOPluginController) -> Result<()> { + let plugin = controller.all_plugins_mut().first_mut().unwrap(); + let env = plugin.wasi_env(); + let mut stdout = env.state().stdout()?; + let stdout = stdout.as_mut().unwrap(); let mut v = vec![]; stdout.read_to_end(&mut v)?; Ok(()) } -fn read_plugin_output(env: &mut WasiEnv) -> Result> { - let mut state = env.state(); - let stdout = state.fs.stdout_mut()?.as_mut().unwrap(); +fn read_plugin_output(controller: &mut ModelIOPluginController) -> Result> { + let plugin = controller.all_plugins_mut().first_mut().unwrap(); + let env = plugin.wasi_env(); + let mut stdout = env.state().stdout()?; + let stdout = stdout.as_mut().unwrap(); let mut s = String::new(); stdout.read_to_string(&mut s)?; let mut data: Vec<_> = s.split('\n').collect(); @@ -61,30 +74,29 @@ fn read_plugin_output(env: &mut WasiEnv) -> Result> { .collect()) } -fn inner_create_controller(path: &str, env: &mut WasiEnv) -> Result { +fn inner_create_controller(path: &str) -> Result { let path = current_dir()?.parent().unwrap().join(path); - let store = Store::default(); + let mut store = Store::default(); + let env = create_wasi_env(&mut store)?; let bytes = std::fs::read(path)?; - let plugin = ModelIOPlugin::new(&bytes, &store, env)?; + let plugin = ModelIOPlugin::new(&bytes, env, store)?; Ok(ModelIOPluginController::new(vec![plugin])) } #[test] fn from_path() -> Result<()> { - let ty = if cfg!(debug_assertions) { - "debug" - } else { - "release" - }; + let (ty, _) = build_type_and_flags(); let path = current_dir()? .parent() .unwrap() .join(format!("target/wasm32-wasi/{}/deps", ty)); - let store = Store::default(); - let mut env = create_wasi_env()?; - let mut controller = ModelIOPluginController::from_path(&path, &store, &mut env)?; + let mut controller = ModelIOPluginController::from_path(&path)?; let mut names = vec![]; for plugin in controller.all_plugins_mut() { + let stdout = Box::new(Pipe::new()); + let state = Arc::clone(&plugin.wasi_env().state); + let inodes = state.inodes.read().unwrap(); + state.fs.swap_file(&inodes, __WASI_STDOUT_FILENO, stdout)?; plugin.create()?; names.push(plugin.name()?); } diff --git a/rust/plugin_wasm/src/motion/c_api.rs b/rust/plugin_wasm/src/motion/c_api.rs index e63a21eb..4c56987d 100644 --- a/rust/plugin_wasm/src/motion/c_api.rs +++ b/rust/plugin_wasm/src/motion/c_api.rs @@ -65,7 +65,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOSetLanguage( plugin: *mut nanoem_application_plugin_motion_io_t, value: i32, ) { - if let Some(instance) = nanoem_application_plugin_motion_io_t::get(plugin) { + if let Some(instance) = nanoem_application_plugin_motion_io_t::get_mut(plugin) { instance.set_language(value).unwrap_or_default(); } } @@ -173,7 +173,9 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOSetAllNamedSelectedBoneK } else { &[] }; - match instance.set_all_named_selected_bone_keyframes(CStr::from_ptr(name as *const c_char), slice) { + match instance + .set_all_named_selected_bone_keyframes(CStr::from_ptr(name as *const c_char), slice) + { Ok(_) => nanoem_application_plugin_status_t::SUCCESS, Err(value) => instance.assign_failure_reason(value), } @@ -201,7 +203,10 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOSetAllNamedSelectedMorph } else { &[] }; - match instance.set_all_named_selected_morph_keyframes(CStr::from_ptr(name as *const c_char), slice) { + match instance.set_all_named_selected_morph_keyframes( + CStr::from_ptr(name as *const c_char), + slice, + ) { Ok(_) => nanoem_application_plugin_status_t::SUCCESS, Err(value) => instance.assign_failure_reason(value), } @@ -534,7 +539,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOGetOutputMotionDataSize( plugin: *mut nanoem_application_plugin_motion_io_t, length: *mut u32, ) { - if let Some(instance) = nanoem_application_plugin_motion_io_t::get(plugin) { + if let Some(instance) = nanoem_application_plugin_motion_io_t::get_mut(plugin) { if !length.is_null() { *length = instance.output_slice().len() as u32 } @@ -551,7 +556,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOGetOutputMotionData( length: u32, status_ptr: *mut nanoem_application_plugin_status_t, ) { - let status = match nanoem_application_plugin_motion_io_t::get(plugin) { + let status = match nanoem_application_plugin_motion_io_t::get_mut(plugin) { Some(instance) => { if !data.is_null() && length > 0 { let slice = instance.output_slice(); @@ -596,7 +601,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOGetUIWindowLayoutDataSiz plugin: *mut nanoem_application_plugin_motion_io_t, length: *mut u32, ) { - if let Some(instance) = nanoem_application_plugin_motion_io_t::get(plugin) { + if let Some(instance) = nanoem_application_plugin_motion_io_t::get_mut(plugin) { if !length.is_null() { *length = instance.window_layout_data_slice().len() as u32 } @@ -613,7 +618,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOGetUIWindowLayoutData( length: u32, status_ptr: *mut nanoem_application_plugin_status_t, ) { - let status = match nanoem_application_plugin_motion_io_t::get(plugin) { + let status = match nanoem_application_plugin_motion_io_t::get_mut(plugin) { Some(instance) => { if !data.is_null() && length > 0 { let slice = instance.window_layout_data_slice(); diff --git a/rust/plugin_wasm/src/motion/core.rs b/rust/plugin_wasm/src/motion/core.rs index fcab0ab1..fd384d4f 100644 --- a/rust/plugin_wasm/src/motion/core.rs +++ b/rust/plugin_wasm/src/motion/core.rs @@ -5,8 +5,6 @@ */ use anyhow::Result; -use wasmer::Store; -use wasmer_wasi::WasiState; use crate::nanoem_application_plugin_status_t; @@ -19,7 +17,6 @@ use std::ptr::null; #[allow(non_camel_case_types)] pub struct nanoem_application_plugin_motion_io_t { controller: MotionIOPluginController, - reason: Option, } impl Drop for nanoem_application_plugin_motion_io_t { @@ -33,14 +30,9 @@ impl Drop for nanoem_application_plugin_motion_io_t { impl nanoem_application_plugin_motion_io_t { pub fn new(path: &CStr) -> Result { let path = Path::new(path.to_str()?); - let store = Store::default(); - let mut env = WasiState::new("nanoem").finalize()?; - let controller = MotionIOPluginController::from_path(path, &store, &mut env)?; + let mut controller = MotionIOPluginController::from_path(path)?; controller.initialize()?; - Ok(Self { - controller, - reason: None, - }) + Ok(Self { controller }) } pub(crate) unsafe fn get(plugin: *const Self) -> Option<&'static Self> { if !plugin.is_null() { @@ -78,7 +70,7 @@ impl nanoem_application_plugin_motion_io_t { null() } } - pub fn set_language(&self, value: i32) -> Result<()> { + pub fn set_language(&mut self, value: i32) -> Result<()> { self.controller.set_language(value) } pub fn set_function(&mut self, value: i32) -> Result<()> { @@ -116,65 +108,56 @@ impl nanoem_application_plugin_motion_io_t { self.controller .set_all_selected_self_shadow_keyframes(value) } - pub fn set_audio_description(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_description(&mut self, data: &[u8]) -> Result<()> { self.controller.set_audio_description(data) } - pub fn set_camera_description(&self, data: &[u8]) -> Result<()> { + pub fn set_camera_description(&mut self, data: &[u8]) -> Result<()> { self.controller.set_camera_description(data) } - pub fn set_light_description(&self, data: &[u8]) -> Result<()> { + pub fn set_light_description(&mut self, data: &[u8]) -> Result<()> { self.controller.set_light_description(data) } - pub fn set_audio_data(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_data(&mut self, data: &[u8]) -> Result<()> { self.controller.set_audio_data(data) } - pub fn set_input_model_data(&self, data: &[u8]) -> Result<()> { + pub fn set_input_model_data(&mut self, data: &[u8]) -> Result<()> { self.controller.set_input_model_data(data) } - pub fn set_input_motion_data(&self, data: &[u8]) -> Result<()> { + pub fn set_input_motion_data(&mut self, data: &[u8]) -> Result<()> { self.controller.set_input_motion_data(data) } - pub fn execute(&self) -> Result<()> { + pub fn execute(&mut self) -> Result<()> { self.controller.execute() } - pub fn output_slice(&self) -> Vec { + pub fn output_slice(&mut self) -> Vec { self.controller.get_output_data().unwrap_or_default() } - pub fn load_window_layout(&self) -> Result<()> { + pub fn load_window_layout(&mut self) -> Result<()> { self.controller.load_ui_window_layout() } - pub fn set_component_layout(&self, id: &CStr, data: &[u8], reload: &mut bool) -> Result<()> { + pub fn set_component_layout( + &mut self, + id: &CStr, + data: &[u8], + reload: &mut bool, + ) -> Result<()> { self.controller .set_ui_component_layout(id.to_str()?, data, reload) } - pub fn window_layout_data_slice(&self) -> Vec { + pub fn window_layout_data_slice(&mut self) -> Vec { self.controller.get_ui_window_layout().unwrap_or_default() } pub fn failure_reason(&self) -> Option { - if self.reason.is_some() { - self.reason.clone() - } else { - let reason = self.controller.failure_reason().unwrap(); - if !reason.is_empty() { - Some(reason) - } else { - None - } - } + self.controller.failure_reason() } pub fn recovery_suggestion(&self) -> Option { - let suggestion = self.controller.recovery_suggestion().unwrap(); - if !suggestion.is_empty() { - Some(suggestion) - } else { - None - } + self.controller.recovery_suggestion() } pub fn assign_failure_reason( &mut self, value: anyhow::Error, ) -> nanoem_application_plugin_status_t { - self.reason = Some(value.to_string()); + self.controller.assign_failure_reason(value); nanoem_application_plugin_status_t::ERROR_REFER_REASON } } diff --git a/rust/plugin_wasm/src/motion/plugin.rs b/rust/plugin_wasm/src/motion/plugin.rs index 53d0a7e4..0837d600 100644 --- a/rust/plugin_wasm/src/motion/plugin.rs +++ b/rust/plugin_wasm/src/motion/plugin.rs @@ -10,7 +10,7 @@ use anyhow::Result; use tracing::warn; use walkdir::WalkDir; use wasmer::{Instance, Module, Store}; -use wasmer_wasi::WasiEnv; +use wasmer_wasi::{WasiEnv, WasiFunctionEnv, WasiState}; use crate::{ allocate_byte_array_with_data, allocate_status_ptr, inner_count_all_functions, @@ -23,6 +23,8 @@ use crate::{ pub struct MotionIOPlugin { instance: Instance, + store: Store, + env: WasiFunctionEnv, opaque: Option, } @@ -32,12 +34,15 @@ fn inner_set_named_data( name: &str, data: &[u32], func: &str, + store: &mut Store, ) -> Result<()> { if let Some(opaque) = opaque { if let Ok(set_input_model_data) = instance .exports - .get_native_function::<(OpaquePtr, ByteArray, ByteArray, u32, StatusPtr), ()>(func) + .get_typed_function::<(OpaquePtr, ByteArray, ByteArray, u32, StatusPtr), ()>( + store, func, + ) { let component_size = size_of::(); let data_size = data.len(); @@ -45,263 +50,334 @@ fn inner_set_named_data( let data = unsafe { slice::from_raw_parts(data.as_ptr() as *const u8, len) }; let mut name = name.as_bytes().to_vec(); name.push(0); - let name_ptr = allocate_byte_array_with_data(instance, name.as_slice())?; - let data_ptr = allocate_byte_array_with_data(instance, data)?; - let status_ptr = allocate_status_ptr(instance)?; - set_input_model_data.call(*opaque, name_ptr, data_ptr, data_size as u32, status_ptr)?; - release_byte_array(instance, name_ptr)?; - release_byte_array(instance, data_ptr)?; - release_status_ptr(instance, status_ptr)?; + let name_ptr = allocate_byte_array_with_data(instance, name.as_slice(), store)?; + let data_ptr = allocate_byte_array_with_data(instance, data, store)?; + let status_ptr = allocate_status_ptr(instance, store)?; + set_input_model_data.call( + store, + *opaque, + name_ptr, + data_ptr, + data_size as u32, + status_ptr, + )?; + release_byte_array(instance, name_ptr, store)?; + release_byte_array(instance, data_ptr, store)?; + release_status_ptr(instance, status_ptr, store)?; } } Ok(()) } -fn validate_plugin(instance: &Instance) -> Result<()> { +fn validate_plugin(instance: &Instance, store: &Store) -> Result<()> { let e = &instance.exports; e.get_memory("memory")?; - e.get_native_function::(MALLOC_FN)?; - e.get_native_function::(FREE_FN)?; - e.get_native_function::<(), OpaquePtr>("nanoemApplicationPluginMotionIOCreate")?; - e.get_native_function::("nanoemApplicationPluginMotionIOGetName")?; - e.get_native_function::("nanoemApplicationPluginMotionIOGetVersion")?; - e.get_native_function::<(OpaquePtr, i32), ()>("nanoemApplicationPluginMotionIOSetLanguage")?; - e.get_native_function::("nanoemApplicationPluginMotionIOCountAllFunctions")?; - e.get_native_function::<(OpaquePtr, i32), ByteArray>( + e.get_typed_function::(store, MALLOC_FN)?; + e.get_typed_function::(store, FREE_FN)?; + e.get_typed_function::<(), OpaquePtr>(store, "nanoemApplicationPluginMotionIOCreate")?; + e.get_typed_function::(store, "nanoemApplicationPluginMotionIOGetName")?; + e.get_typed_function::( + store, + "nanoemApplicationPluginMotionIOGetVersion", + )?; + e.get_typed_function::<(OpaquePtr, i32), ()>( + store, + "nanoemApplicationPluginMotionIOSetLanguage", + )?; + e.get_typed_function::( + store, + "nanoemApplicationPluginMotionIOCountAllFunctions", + )?; + e.get_typed_function::<(OpaquePtr, i32), ByteArray>( + store, "nanoemApplicationPluginMotionIOGetFunctionName", )?; - e.get_native_function::<(OpaquePtr, i32, StatusPtr), ()>( + e.get_typed_function::<(OpaquePtr, i32, StatusPtr), ()>( + store, "nanoemApplicationPluginMotionIOSetFunction", )?; - e.get_native_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>( + e.get_typed_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>( + store, "nanoemApplicationPluginMotionIOSetInputMotionData", )?; - e.get_native_function::<(OpaquePtr, StatusPtr), ()>("nanoemApplicationPluginMotionIOExecute")?; - e.get_native_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>( + e.get_typed_function::<(OpaquePtr, StatusPtr), ()>( + store, + "nanoemApplicationPluginMotionIOExecute", + )?; + e.get_typed_function::<(OpaquePtr, ByteArray, u32, StatusPtr), ()>( + store, "nanoemApplicationPluginMotionIOGetOutputMotionData", )?; - e.get_native_function::<(OpaquePtr, SizePtr), ()>( + e.get_typed_function::<(OpaquePtr, SizePtr), ()>( + store, "nanoemApplicationPluginMotionIOGetOutputMotionDataSize", )?; - e.get_native_function::( + e.get_typed_function::( + store, "nanoemApplicationPluginMotionIOGetFailureReason", )?; - e.get_native_function::("nanoemApplicationPluginMotionIODestroy")?; + e.get_typed_function::(store, "nanoemApplicationPluginMotionIODestroy")?; Ok(()) } impl MotionIOPlugin { - pub fn new(bytes: &[u8], store: &Store, env: &mut WasiEnv) -> Result { - let module = Module::new(store, bytes)?; - let imports = env.import_object(&module)?; - let instance = Instance::new(&module, &imports)?; - validate_plugin(&instance)?; + pub fn new(bytes: &[u8], env: WasiFunctionEnv, mut store: Store) -> Result { + let module = Module::new(&store, bytes)?; + let imports = env.import_object(&mut store, &module)?; + let instance = Instance::new(&mut store, &module, &imports)?; + let memory = instance.exports.get_memory("memory")?; + env.data_mut(&mut store).set_memory(memory.clone()); + validate_plugin(&instance, &store)?; Ok(Self { instance, + store, + env, opaque: None, }) } - pub fn initialize(&self) -> Result<()> { - inner_initialize_function(&self.instance, "nanoemApplicationPluginMotionIOInitialize") + pub fn initialize(&mut self) -> Result<()> { + inner_initialize_function( + &self.instance, + "nanoemApplicationPluginMotionIOInitialize", + &mut self.store, + ) } pub fn create(&mut self) -> Result<()> { self.opaque = Some(inner_create_opaque( &self.instance, "nanoemApplicationPluginMotionIOCreate", + &mut self.store, )?); Ok(()) } - pub fn set_language(&self, value: i32) -> Result<()> { + pub fn set_language(&mut self, value: i32) -> Result<()> { inner_set_language( &self.instance, &self.opaque, value, "nanoemApplicationPluginMotionIOSetLanguage", + &mut self.store, ) } - pub fn name(&self) -> Result { + pub fn name(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOGetName", + &mut self.store, ) } #[allow(unused)] - pub fn description(&self) -> Result { + pub fn description(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOGetDescription", + &mut self.store, ) } #[allow(unused)] - pub fn version(&self) -> Result { + pub fn version(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOGetVersion", + &mut self.store, ) } - pub fn count_all_functions(&self) -> Result { + pub fn count_all_functions(&mut self) -> Result { inner_count_all_functions( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOCountAllFunctions", + &mut self.store, ) } - pub fn function_name(&self, index: i32) -> Result { + pub fn function_name(&mut self, index: i32) -> Result { inner_get_function_name( &self.instance, &self.opaque, index, "nanoemApplicationPluginMotionIOGetFunctionName", + &mut self.store, ) } - pub fn set_function(&self, index: i32) -> Result<()> { + pub fn set_function(&mut self, index: i32) -> Result { inner_set_function( &self.instance, &self.opaque, index, "nanoemApplicationPluginMotionIOSetFunction", + &mut self.store, ) } - pub fn set_all_selected_accessory_keyframes(&self, value: &[u32]) -> Result<()> { + pub fn set_all_selected_accessory_keyframes(&mut self, value: &[u32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, value, "nanoemApplicationPluginMotionIOSetAllSelectedAccessoryKeyframes", + &mut self.store, ) } - pub fn set_all_named_selected_bone_keyframes(&self, name: &str, value: &[u32]) -> Result<()> { + pub fn set_all_named_selected_bone_keyframes( + &mut self, + name: &str, + value: &[u32], + ) -> Result<()> { inner_set_named_data( &self.instance, &self.opaque, name, value, "nanoemApplicationPluginMotionIOSetAllNamedSelectedBoneKeyframes", + &mut self.store, ) } - pub fn set_all_selected_camera_keyframes(&self, value: &[u32]) -> Result<()> { + pub fn set_all_selected_camera_keyframes(&mut self, value: &[u32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, value, "nanoemApplicationPluginMotionIOSetAllSelectedCameraKeyframes", + &mut self.store, ) } - pub fn set_all_selected_light_keyframes(&self, value: &[u32]) -> Result<()> { + pub fn set_all_selected_light_keyframes(&mut self, value: &[u32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, value, "nanoemApplicationPluginMotionIOSetAllSelectedLightKeyframes", + &mut self.store, ) } - pub fn set_all_selected_model_keyframes(&self, value: &[u32]) -> Result<()> { + pub fn set_all_selected_model_keyframes(&mut self, value: &[u32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, value, "nanoemApplicationPluginMotionIOSetAllSelectedModelKeyframes", + &mut self.store, ) } - pub fn set_all_named_selected_morph_keyframes(&self, name: &str, value: &[u32]) -> Result<()> { + pub fn set_all_named_selected_morph_keyframes( + &mut self, + name: &str, + value: &[u32], + ) -> Result<()> { inner_set_named_data( &self.instance, &self.opaque, name, value, "nanoemApplicationPluginMotionIOSetAllNamedSelectedMorphKeyframes", + &mut self.store, ) } - pub fn set_all_selected_self_shadow_keyframes(&self, value: &[u32]) -> Result<()> { + pub fn set_all_selected_self_shadow_keyframes(&mut self, value: &[u32]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, value, "nanoemApplicationPluginMotionIOSetAllSelectedSelfShadowKeyframes", + &mut self.store, ) } - pub fn set_audio_description(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_description(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginMotionIOSetAudioDescription", + &mut self.store, ) } - pub fn set_camera_description(&self, data: &[u8]) -> Result<()> { + pub fn set_camera_description(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginMotionIOSetCameraDescription", + &mut self.store, ) } - pub fn set_light_description(&self, data: &[u8]) -> Result<()> { + pub fn set_light_description(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginMotionIOSetLightDescription", + &mut self.store, ) } - pub fn set_audio_data(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_data(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginMotionIOSetInputAudioData", + &mut self.store, ) } - pub fn set_input_model_data(&self, data: &[u8]) -> Result<()> { + pub fn set_input_model_data(&mut self, data: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, data, "nanoemApplicationPluginMotionIOSetInputActiveModelData", + &mut self.store, ) } - pub fn set_input_motion_data(&self, bytes: &[u8]) -> Result<()> { + pub fn set_input_motion_data(&mut self, bytes: &[u8]) -> Result<()> { inner_set_data( &self.instance, &self.opaque, bytes, "nanoemApplicationPluginMotionIOSetInputMotionData", + &mut self.store, ) } - pub fn execute(&self) -> Result<()> { + pub fn execute(&mut self) -> Result { inner_execute( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOExecute", + &mut self.store, ) } - pub fn get_output_data(&self) -> Result> { + pub fn get_output_data(&mut self) -> Result> { inner_get_data( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOGetOutputMotionData", "nanoemApplicationPluginMotionIOGetOutputMotionDataSize", + &mut self.store, ) } - pub fn load_ui_window_layout(&self) -> Result<()> { + pub fn load_ui_window_layout(&mut self) -> Result { inner_load_ui_window( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOLoadUIWindowLayout", + &mut self.store, ) } - pub fn get_ui_window_layout(&self) -> Result> { + pub fn get_ui_window_layout(&mut self) -> Result> { inner_get_data( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOGetUIWindowLayoutData", "nanoemApplicationPluginMotionIOGetUIWindowLayoutDataSize", + &mut self.store, ) } - pub fn set_ui_component_layout(&self, id: &str, data: &[u8], reload: &mut bool) -> Result<()> { + pub fn set_ui_component_layout( + &mut self, + id: &str, + data: &[u8], + reload: &mut bool, + ) -> Result { inner_set_ui_component_layout( &self.instance, &self.opaque, @@ -309,31 +385,43 @@ impl MotionIOPlugin { data, "nanoemApplicationPluginMotionIOSetUIComponentLayoutData", reload, + &mut self.store, ) } - pub fn failure_reason(&self) -> Result { + pub fn failure_reason(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOGetFailureReason", + &mut self.store, ) } - pub fn recovery_suggestion(&self) -> Result { + pub fn recovery_suggestion(&mut self) -> Result { inner_get_string( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIOGetRecoverySuggestion", + &mut self.store, ) } - pub fn destroy(&self) { + pub fn destroy(&mut self) { inner_destroy_opaque( &self.instance, &self.opaque, "nanoemApplicationPluginMotionIODestroy", + &mut self.store, ) } - pub fn terminate(&self) { - inner_terminate_function(&self.instance, "nanoemApplicationPluginMotionIOTerminate") + pub fn terminate(&mut self) { + inner_terminate_function( + &self.instance, + "nanoemApplicationPluginMotionIOTerminate", + &mut self.store, + ) + } + #[allow(dead_code)] + pub(super) fn wasi_env(&mut self) -> &mut WasiEnv { + self.env.env.as_mut(&mut self.store) } } @@ -341,6 +429,8 @@ pub struct MotionIOPluginController { plugins: Vec, function_indices: Vec<(usize, i32, CString)>, plugin_index: Option, + failure_reason: Option, + recovery_suggestion: Option, } impl MotionIOPluginController { @@ -350,16 +440,20 @@ impl MotionIOPluginController { plugins, function_indices, plugin_index: None, + failure_reason: None, + recovery_suggestion: None, } } - pub fn from_path(path: &Path, store: &Store, env: &mut WasiEnv) -> Result { + pub fn from_path(path: &Path) -> Result { let mut plugins = vec![]; for entry in WalkDir::new(path.parent().unwrap()) { let entry = entry?; let filename = entry.file_name().to_str(); if filename.map(|s| s.ends_with(".wasm")).unwrap_or(false) { let bytes = std::fs::read(entry.path())?; - match MotionIOPlugin::new(&bytes, store, env) { + let mut store = Store::default(); + let env = WasiState::new("nanoem").finalize(&mut store)?; + match MotionIOPlugin::new(&bytes, env, store) { Ok(plugin) => { plugins.push(plugin); tracing::debug!(filename = filename.unwrap(), "Loaded motion WASM plugin"); @@ -376,33 +470,30 @@ impl MotionIOPluginController { } Ok(Self::new(plugins)) } - pub fn initialize(&self) -> Result<()> { + pub fn initialize(&mut self) -> Result<()> { self.plugins - .iter() + .iter_mut() .try_for_each(|plugin| plugin.initialize()) } pub fn create(&mut self) -> Result<()> { self.plugins .iter_mut() .try_for_each(|plugin| plugin.create())?; - for (offset, plugin) in self.plugins.iter().enumerate() { + for (offset, plugin) in self.plugins.iter_mut().enumerate() { + let name = plugin.name()?; + let version = plugin.version()?; for index in 0..plugin.count_all_functions()? { let name = CString::new( - &format!( - "{}: {} ({})", - plugin.name()?, - plugin.function_name(index)?, - plugin.version()? - )[..], + &format!("{}: {} ({})", name, plugin.function_name(index)?, version)[..], )?; self.function_indices.push((offset, index, name)); } } Ok(()) } - pub fn set_language(&self, value: i32) -> Result<()> { + pub fn set_language(&mut self, value: i32) -> Result<()> { self.plugins - .iter() + .iter_mut() .try_for_each(|plugin| plugin.set_language(value)) } pub fn count_all_functions(&self) -> i32 { @@ -417,9 +508,14 @@ impl MotionIOPluginController { } pub fn set_function(&mut self, index: i32) -> Result<()> { if let Some((plugin_index, function_index, _)) = self.function_indices.get(index as usize) { - let result = self.plugins[*plugin_index].set_function(*function_index); - self.plugin_index = Some(*plugin_index); - result + match self.plugins[*plugin_index].set_function(*function_index) { + Ok(0) => { + self.plugin_index = Some(*plugin_index); + Ok(()) + } + Ok(_) => self.set_failure(), + Err(err) => Err(err), + } } else { Err(anyhow::anyhow!("out of bound function index: {}", index)) } @@ -460,59 +556,94 @@ impl MotionIOPluginController { self.current_plugin()? .set_all_selected_self_shadow_keyframes(value) } - pub fn set_audio_description(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_description(&mut self, data: &[u8]) -> Result<()> { self.current_plugin()?.set_audio_description(data) } - pub fn set_camera_description(&self, data: &[u8]) -> Result<()> { + pub fn set_camera_description(&mut self, data: &[u8]) -> Result<()> { self.current_plugin()?.set_camera_description(data) } - pub fn set_light_description(&self, data: &[u8]) -> Result<()> { + pub fn set_light_description(&mut self, data: &[u8]) -> Result<()> { self.current_plugin()?.set_light_description(data) } - pub fn set_audio_data(&self, data: &[u8]) -> Result<()> { + pub fn set_audio_data(&mut self, data: &[u8]) -> Result<()> { self.current_plugin()?.set_audio_data(data) } - pub fn set_input_model_data(&self, bytes: &[u8]) -> Result<()> { + pub fn set_input_model_data(&mut self, bytes: &[u8]) -> Result<()> { self.current_plugin()?.set_input_model_data(bytes) } - pub fn set_input_motion_data(&self, bytes: &[u8]) -> Result<()> { + pub fn set_input_motion_data(&mut self, bytes: &[u8]) -> Result<()> { self.current_plugin()?.set_input_motion_data(bytes) } - pub fn execute(&self) -> Result<()> { - self.current_plugin()?.execute() + pub fn execute(&mut self) -> Result<()> { + match self.current_plugin()?.execute() { + Ok(0) => Ok(()), + Ok(_) => self.set_failure(), + Err(err) => Err(err), + } } - pub fn get_output_data(&self) -> Result> { + pub fn get_output_data(&mut self) -> Result> { self.current_plugin()?.get_output_data() } - pub fn load_ui_window_layout(&self) -> Result<()> { - self.current_plugin()?.load_ui_window_layout() + pub fn load_ui_window_layout(&mut self) -> Result<()> { + match self.current_plugin()?.load_ui_window_layout() { + Ok(0) => Ok(()), + Ok(_) => self.set_failure(), + Err(err) => Err(err), + } } - pub fn get_ui_window_layout(&self) -> Result> { + pub fn get_ui_window_layout(&mut self) -> Result> { self.current_plugin()?.get_ui_window_layout() } - pub fn set_ui_component_layout(&self, id: &str, data: &[u8], reload: &mut bool) -> Result<()> { - self.current_plugin()? + pub fn set_ui_component_layout( + &mut self, + id: &str, + data: &[u8], + reload: &mut bool, + ) -> Result<()> { + match self + .current_plugin()? .set_ui_component_layout(id, data, reload) + { + Ok(0) => Ok(()), + Ok(_) => self.set_failure(), + Err(err) => Err(err), + } } - pub fn failure_reason(&self) -> Result { - self.current_plugin()?.failure_reason() + pub fn failure_reason(&self) -> Option { + self.failure_reason.clone() } - pub fn recovery_suggestion(&self) -> Result { - self.current_plugin()?.recovery_suggestion() + pub fn recovery_suggestion(&self) -> Option { + self.recovery_suggestion.clone() } - pub fn destroy(&self) { - self.plugins.iter().for_each(|plugin| plugin.destroy()) + pub fn assign_failure_reason(&mut self, value: anyhow::Error) { + self.failure_reason = Some(value.to_string()); } - pub fn terminate(&self) { - self.plugins.iter().for_each(|plugin| plugin.terminate()) + pub fn destroy(&mut self) { + self.plugins.iter_mut().for_each(|plugin| plugin.destroy()) + } + pub fn terminate(&mut self) { + self.plugins + .iter_mut() + .for_each(|plugin| plugin.terminate()) } #[allow(unused)] pub(super) fn all_plugins_mut(&mut self) -> &mut [MotionIOPlugin] { &mut self.plugins } - fn current_plugin(&self) -> Result<&MotionIOPlugin> { + fn set_failure(&mut self) -> Result<()> { + let value = self.current_plugin()?.failure_reason()?; + if !value.is_empty() { + self.failure_reason = Some(value); + } + let value = self.current_plugin()?.recovery_suggestion()?; + if !value.is_empty() { + self.recovery_suggestion = Some(value); + } + Ok(()) + } + fn current_plugin(&mut self) -> Result<&mut MotionIOPlugin> { if let Some(plugin_index) = self.plugin_index { - Ok(&self.plugins[plugin_index]) + Ok(&mut self.plugins[plugin_index]) } else { Err(anyhow::anyhow!("plugin is not set")) } diff --git a/rust/plugin_wasm/src/motion/test/full.rs b/rust/plugin_wasm/src/motion/test/full.rs index 7172d1d6..f88c6534 100644 --- a/rust/plugin_wasm/src/motion/test/full.rs +++ b/rust/plugin_wasm/src/motion/test/full.rs @@ -8,36 +8,33 @@ use anyhow::{Context, Result}; use maplit::hashmap; use pretty_assertions::assert_eq; use serde_json::json; -use wasmer_wasi::WasiEnv; use crate::motion::{ plugin::MotionIOPluginController, test::{ - create_random_data, create_wasi_env, flush_plugin_output, inner_create_controller, - read_plugin_output, PluginOutput, + create_random_data, flush_plugin_output, inner_create_controller, read_plugin_output, + PluginOutput, }, }; -fn create_controller(env: &mut WasiEnv) -> Result { +use super::build_type_and_flags; + +fn create_controller() -> Result { let package = "plugin_wasm_test_motion_full"; - let (ty, flag) = if cfg!(debug_assertions) { - ("debug", "") - } else { - ("release", " --release") - }; - inner_create_controller(&format!("target/wasm32-wasi/{}/{}.wasm", ty, package), env) - .with_context(|| { + let (ty, flag) = build_type_and_flags(); + inner_create_controller(&format!("target/wasm32-wasi/{}/{}.wasm", ty, package)).with_context( + || { format!( "try build with \"cargo build --package {} --target wasm32-wasi{}\"", package, flag ) - }) + }, + ) } #[test] fn create() -> Result<()> { - let mut env = create_wasi_env()?; - let result = create_controller(&mut env); + let result = create_controller(); assert!(result.is_ok()); let mut controller = result?; assert!(controller.initialize().is_ok()); @@ -53,11 +50,15 @@ fn create() -> Result<()> { ..Default::default() }, PluginOutput { - function: "nanoemApplicationPluginMotionIOCountAllFunctions".to_owned(), + function: "nanoemApplicationPluginMotionIOGetName".to_owned(), ..Default::default() }, PluginOutput { - function: "nanoemApplicationPluginMotionIOGetName".to_owned(), + function: "nanoemApplicationPluginMotionIOGetVersion".to_owned(), + ..Default::default() + }, + PluginOutput { + function: "nanoemApplicationPluginMotionIOCountAllFunctions".to_owned(), ..Default::default() }, PluginOutput { @@ -67,17 +68,23 @@ fn create() -> Result<()> { }) }, PluginOutput { - function: "nanoemApplicationPluginMotionIOGetVersion".to_owned(), - ..Default::default() - } + function: "nanoemApplicationPluginMotionIOGetFunctionName".to_owned(), + arguments: Some(hashmap! { + "index".to_owned() => json!(1), + }) + }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); - assert_eq!(1, controller.count_all_functions()); + assert_eq!(2, controller.count_all_functions()); assert_eq!( "plugin_wasm_test_motion_full: function0 (1.2.3)", controller.function_name(0)?.to_str()? ); + assert_eq!( + "plugin_wasm_test_motion_full: function0 (1.2.3)", + controller.function_name(1)?.to_str()? + ); controller.destroy(); controller.terminate(); assert_eq!( @@ -91,19 +98,18 @@ fn create() -> Result<()> { ..Default::default() }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); Ok(()) } #[test] fn set_language() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_language(0).is_ok()); assert_eq!( vec![PluginOutput { @@ -112,7 +118,7 @@ fn set_language() -> Result<()> { "value".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -121,13 +127,12 @@ fn set_language() -> Result<()> { #[test] fn execute() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_input_model_data(&data).is_ok()); assert!(controller.set_input_motion_data(&data).is_ok()); assert!(controller.execute().is_ok()); @@ -173,7 +178,7 @@ fn execute() -> Result<()> { }) }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -182,13 +187,12 @@ fn execute() -> Result<()> { #[test] fn set_all_selected_accessory_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller .set_all_selected_accessory_keyframes(data) .is_ok()); @@ -201,7 +205,7 @@ fn set_all_selected_accessory_keyframes() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -210,13 +214,12 @@ fn set_all_selected_accessory_keyframes() -> Result<()> { #[test] fn set_all_selected_camera_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_camera_keyframes(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -227,7 +230,7 @@ fn set_all_selected_camera_keyframes() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -236,13 +239,12 @@ fn set_all_selected_camera_keyframes() -> Result<()> { #[test] fn set_all_selected_light_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_light_keyframes(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -253,7 +255,7 @@ fn set_all_selected_light_keyframes() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -262,13 +264,12 @@ fn set_all_selected_light_keyframes() -> Result<()> { #[test] fn set_all_selected_model_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_model_keyframes(data).is_ok()); assert_eq!( vec![PluginOutput { @@ -279,7 +280,7 @@ fn set_all_selected_model_keyframes() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -288,13 +289,12 @@ fn set_all_selected_model_keyframes() -> Result<()> { #[test] fn set_all_selected_self_shadow_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller .set_all_selected_self_shadow_keyframes(data) .is_ok()); @@ -307,7 +307,7 @@ fn set_all_selected_self_shadow_keyframes() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -316,13 +316,12 @@ fn set_all_selected_self_shadow_keyframes() -> Result<()> { #[test] fn set_all_named_selected_bone_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller .set_all_named_selected_bone_keyframes("bone", data) .is_ok()); @@ -336,7 +335,7 @@ fn set_all_named_selected_bone_keyframes() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -345,13 +344,12 @@ fn set_all_named_selected_bone_keyframes() -> Result<()> { #[test] fn set_all_named_selected_morph_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller .set_all_named_selected_morph_keyframes("morph", data) .is_ok()); @@ -365,7 +363,7 @@ fn set_all_named_selected_morph_keyframes() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -374,13 +372,12 @@ fn set_all_named_selected_morph_keyframes() -> Result<()> { #[test] fn set_audio_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_audio_description(&data).is_ok()); assert_eq!( vec![PluginOutput { @@ -391,7 +388,7 @@ fn set_audio_description() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -400,13 +397,12 @@ fn set_audio_description() -> Result<()> { #[test] fn set_audio_data() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_audio_data(&data).is_ok()); assert_eq!( vec![PluginOutput { @@ -417,7 +413,7 @@ fn set_audio_data() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -426,13 +422,12 @@ fn set_audio_data() -> Result<()> { #[test] fn set_camera_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_camera_description(&data).is_ok()); assert_eq!( vec![PluginOutput { @@ -443,7 +438,7 @@ fn set_camera_description() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -452,13 +447,12 @@ fn set_camera_description() -> Result<()> { #[test] fn set_light_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_light_description(&data).is_ok()); assert_eq!( vec![PluginOutput { @@ -469,7 +463,7 @@ fn set_light_description() -> Result<()> { "status".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -478,13 +472,12 @@ fn set_light_description() -> Result<()> { #[test] fn ui_window() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.load_ui_window_layout().is_ok()); let output = controller.get_ui_window_layout(); assert!(output.is_ok()); @@ -525,7 +518,7 @@ fn ui_window() -> Result<()> { }) }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -534,22 +527,16 @@ fn ui_window() -> Result<()> { #[test] fn get_failure_reason() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; - controller.set_function(0)?; - flush_plugin_output(&mut env)?; + controller.set_function(1)?; + controller.execute().unwrap_or_default(); + flush_plugin_output(&mut controller)?; let result = controller.failure_reason(); - assert!(result.is_ok()); - assert_eq!("Failure Reason", result?); - assert_eq!( - vec![PluginOutput { - function: "nanoemApplicationPluginMotionIOGetFailureReason".to_owned(), - ..Default::default() - },], - read_plugin_output(&mut env)? - ); + assert!(result.is_some()); + assert_eq!("Failure Reason", result.unwrap()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -557,22 +544,16 @@ fn get_failure_reason() -> Result<()> { #[test] fn get_recovery_suggestion() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; - controller.set_function(0)?; - flush_plugin_output(&mut env)?; + controller.set_function(1)?; + controller.execute().unwrap_or_default(); + flush_plugin_output(&mut controller)?; let result = controller.recovery_suggestion(); - assert!(result.is_ok()); - assert_eq!("Recovery Suggestion", result?); - assert_eq!( - vec![PluginOutput { - function: "nanoemApplicationPluginMotionIOGetRecoverySuggestion".to_owned(), - ..Default::default() - },], - read_plugin_output(&mut env)? - ); + assert!(result.is_some()); + assert_eq!("Recovery Suggestion", result.unwrap()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) diff --git a/rust/plugin_wasm/src/motion/test/minimum.rs b/rust/plugin_wasm/src/motion/test/minimum.rs index 69b08a80..6286f018 100644 --- a/rust/plugin_wasm/src/motion/test/minimum.rs +++ b/rust/plugin_wasm/src/motion/test/minimum.rs @@ -8,37 +8,30 @@ use anyhow::{Context, Result}; use maplit::hashmap; use pretty_assertions::assert_eq; use serde_json::json; -use wasmer_wasi::WasiEnv; use crate::motion::{ plugin::MotionIOPluginController, - test::{ - create_random_data, create_wasi_env, flush_plugin_output, read_plugin_output, PluginOutput, - }, + test::{create_random_data, flush_plugin_output, read_plugin_output, PluginOutput}, }; -use super::inner_create_controller; +use super::{build_type_and_flags, inner_create_controller}; -fn create_controller(env: &mut WasiEnv) -> Result { +fn create_controller() -> Result { let package = "plugin_wasm_test_motion_minimum"; - let (ty, flag) = if cfg!(debug_assertions) { - ("debug", "") - } else { - ("release", " --release") - }; - inner_create_controller(&format!("target/wasm32-wasi/{}/{}.wasm", ty, package), env) - .with_context(|| { + let (ty, flag) = build_type_and_flags(); + inner_create_controller(&format!("target/wasm32-wasi/{}/{}.wasm", ty, package)).with_context( + || { format!( "try build with \"cargo build --package {} --target wasm32-wasi{}\"", package, flag ) - }) + }, + ) } #[test] fn create() -> Result<()> { - let mut env = create_wasi_env()?; - let result = create_controller(&mut env); + let result = create_controller(); assert!(result.is_ok()); let mut controller = result?; assert!(controller.initialize().is_ok()); @@ -50,11 +43,15 @@ fn create() -> Result<()> { ..Default::default() }, PluginOutput { - function: "nanoemApplicationPluginMotionIOCountAllFunctions".to_owned(), + function: "nanoemApplicationPluginMotionIOGetName".to_owned(), ..Default::default() }, PluginOutput { - function: "nanoemApplicationPluginMotionIOGetName".to_owned(), + function: "nanoemApplicationPluginMotionIOGetVersion".to_owned(), + ..Default::default() + }, + PluginOutput { + function: "nanoemApplicationPluginMotionIOCountAllFunctions".to_owned(), ..Default::default() }, PluginOutput { @@ -64,17 +61,23 @@ fn create() -> Result<()> { }) }, PluginOutput { - function: "nanoemApplicationPluginMotionIOGetVersion".to_owned(), - ..Default::default() - } + function: "nanoemApplicationPluginMotionIOGetFunctionName".to_owned(), + arguments: Some(hashmap! { + "index".to_owned() => json!(1), + }) + }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); - assert_eq!(1, controller.count_all_functions()); + assert_eq!(2, controller.count_all_functions()); assert_eq!( "plugin_wasm_test_motion_minimum: function0 (1.2.3)", controller.function_name(0)?.to_str()? ); + assert_eq!( + "plugin_wasm_test_motion_minimum: function0 (1.2.3)", + controller.function_name(1)?.to_str()? + ); controller.destroy(); controller.terminate(); assert_eq!( @@ -82,19 +85,18 @@ fn create() -> Result<()> { function: "nanoemApplicationPluginMotionIODestroy".to_owned(), ..Default::default() },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); Ok(()) } #[test] fn set_language() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_language(0).is_ok()); assert_eq!( vec![PluginOutput { @@ -103,7 +105,7 @@ fn set_language() -> Result<()> { "value".to_owned() => json!(0), }) },], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -112,13 +114,12 @@ fn set_language() -> Result<()> { #[test] fn execute() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_input_model_data(&data).is_ok()); assert!(controller.set_input_motion_data(&data).is_ok()); assert!(controller.execute().is_ok()); @@ -156,7 +157,7 @@ fn execute() -> Result<()> { }) }, ], - read_plugin_output(&mut env)? + read_plugin_output(&mut controller)? ); controller.destroy(); controller.terminate(); @@ -165,17 +166,16 @@ fn execute() -> Result<()> { #[test] fn set_all_selected_accessory_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller .set_all_selected_accessory_keyframes(data) .is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -183,15 +183,14 @@ fn set_all_selected_accessory_keyframes() -> Result<()> { #[test] fn set_all_selected_camera_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_camera_keyframes(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -199,15 +198,14 @@ fn set_all_selected_camera_keyframes() -> Result<()> { #[test] fn set_all_selected_light_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_light_keyframes(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -215,15 +213,14 @@ fn set_all_selected_light_keyframes() -> Result<()> { #[test] fn set_all_selected_model_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_all_selected_model_keyframes(data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -231,17 +228,16 @@ fn set_all_selected_model_keyframes() -> Result<()> { #[test] fn set_all_selected_self_shadow_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller .set_all_selected_self_shadow_keyframes(data) .is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -249,17 +245,16 @@ fn set_all_selected_self_shadow_keyframes() -> Result<()> { #[test] fn set_all_named_selected_bone_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller .set_all_named_selected_bone_keyframes("bone", data) .is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -267,17 +262,16 @@ fn set_all_named_selected_bone_keyframes() -> Result<()> { #[test] fn set_all_named_selected_morph_keyframes() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = &[1, 4, 9, 16, 25, u32::MAX]; controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller .set_all_named_selected_morph_keyframes("morph", data) .is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -285,15 +279,14 @@ fn set_all_named_selected_morph_keyframes() -> Result<()> { #[test] fn set_audio_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_audio_description(&data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -301,15 +294,14 @@ fn set_audio_description() -> Result<()> { #[test] fn set_audio_data() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_audio_data(&data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -317,15 +309,14 @@ fn set_audio_data() -> Result<()> { #[test] fn set_camera_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_camera_description(&data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -333,15 +324,14 @@ fn set_camera_description() -> Result<()> { #[test] fn set_light_description() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.set_light_description(&data).is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -349,13 +339,12 @@ fn set_light_description() -> Result<()> { #[test] fn ui_window() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; let data = create_random_data(4096); controller.initialize()?; controller.create()?; controller.set_function(0)?; - flush_plugin_output(&mut env)?; + flush_plugin_output(&mut controller)?; assert!(controller.load_ui_window_layout().is_ok()); let output = controller.get_ui_window_layout(); assert!(output.is_ok()); @@ -364,7 +353,7 @@ fn ui_window() -> Result<()> { assert!(controller .set_ui_component_layout("ui_window", &data, &mut reload) .is_ok()); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -372,22 +361,16 @@ fn ui_window() -> Result<()> { #[test] fn get_failure_reason() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; - controller.set_function(0)?; - flush_plugin_output(&mut env)?; + controller.set_function(1)?; + controller.execute().unwrap_or_default(); + flush_plugin_output(&mut controller)?; let result = controller.failure_reason(); - assert!(result.is_ok()); - assert_eq!("Failure Reason", result?); - assert_eq!( - vec![PluginOutput { - function: "nanoemApplicationPluginMotionIOGetFailureReason".to_owned(), - ..Default::default() - },], - read_plugin_output(&mut env)? - ); + assert!(result.is_some()); + assert_eq!("Failure Reason", result.unwrap()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) @@ -395,16 +378,15 @@ fn get_failure_reason() -> Result<()> { #[test] fn get_recovery_suggestion() -> Result<()> { - let mut env = create_wasi_env()?; - let mut controller = create_controller(&mut env)?; + let mut controller = create_controller()?; controller.initialize()?; controller.create()?; - controller.set_function(0)?; - flush_plugin_output(&mut env)?; + controller.set_function(1)?; + controller.execute().unwrap_or_default(); + flush_plugin_output(&mut controller)?; let result = controller.recovery_suggestion(); - assert!(result.is_ok()); - assert_eq!("", result?); - assert!(read_plugin_output(&mut env)?.is_empty()); + assert!(result.is_none()); + assert!(read_plugin_output(&mut controller)?.is_empty()); controller.destroy(); controller.terminate(); Ok(()) diff --git a/rust/plugin_wasm/src/motion/test/mod.rs b/rust/plugin_wasm/src/motion/test/mod.rs index 268cbf0f..1b22939c 100644 --- a/rust/plugin_wasm/src/motion/test/mod.rs +++ b/rust/plugin_wasm/src/motion/test/mod.rs @@ -7,6 +7,7 @@ use std::{ collections::{HashMap, HashSet}, env::current_dir, + sync::Arc, }; use anyhow::Result; @@ -15,7 +16,7 @@ use rand::{thread_rng, Rng}; use serde_derive::{Deserialize, Serialize}; use serde_json::Value; use wasmer::Store; -use wasmer_wasi::{Pipe, WasiEnv, WasiState}; +use wasmer_wasi::{types::__WASI_STDOUT_FILENO, Pipe, WasiFunctionEnv, WasiState}; use super::plugin::{MotionIOPlugin, MotionIOPluginController}; @@ -25,9 +26,17 @@ struct PluginOutput { arguments: Option>, } -fn create_wasi_env() -> Result { +fn build_type_and_flags() -> (&'static str, &'static str) { + if cfg!(debug_assertions) { + ("debug", "") + } else { + ("release-lto", " --profile release-lto") + } +} + +fn create_wasi_env(store: &mut Store) -> Result { let stdout = Box::new(Pipe::new()); - Ok(WasiState::new("nanoem").stdout(stdout).finalize()?) + Ok(WasiState::new("nanoem").stdout(stdout).finalize(store)?) } fn create_random_data(size: usize) -> Vec { @@ -40,17 +49,21 @@ fn create_random_data(size: usize) -> Vec { data } -fn flush_plugin_output(env: &mut WasiEnv) -> Result<()> { - let mut state = env.state(); - let stdout = state.fs.stdout_mut()?.as_mut().unwrap(); +fn flush_plugin_output(controller: &mut MotionIOPluginController) -> Result<()> { + let plugin = controller.all_plugins_mut().first_mut().unwrap(); + let env = plugin.wasi_env(); + let mut stdout = env.state().stdout()?; + let stdout = stdout.as_mut().unwrap(); let mut v = vec![]; stdout.read_to_end(&mut v)?; Ok(()) } -fn read_plugin_output(env: &mut WasiEnv) -> Result> { - let mut state = env.state(); - let stdout = state.fs.stdout_mut()?.as_mut().unwrap(); +fn read_plugin_output(controller: &mut MotionIOPluginController) -> Result> { + let plugin = controller.all_plugins_mut().first_mut().unwrap(); + let env = plugin.wasi_env(); + let mut stdout = env.state().stdout()?; + let stdout = stdout.as_mut().unwrap(); let mut s = String::new(); stdout.read_to_string(&mut s)?; let mut data: Vec<_> = s.split('\n').collect(); @@ -61,30 +74,29 @@ fn read_plugin_output(env: &mut WasiEnv) -> Result> { .collect()) } -fn inner_create_controller(path: &str, env: &mut WasiEnv) -> Result { +fn inner_create_controller(path: &str) -> Result { let path = current_dir()?.parent().unwrap().join(path); - let store = Store::default(); + let mut store = Store::default(); + let env = create_wasi_env(&mut store)?; let bytes = std::fs::read(path)?; - let plugin = MotionIOPlugin::new(&bytes, &store, env)?; + let plugin = MotionIOPlugin::new(&bytes, env, store)?; Ok(MotionIOPluginController::new(vec![plugin])) } #[test] fn from_path() -> Result<()> { - let ty = if cfg!(debug_assertions) { - "debug" - } else { - "release" - }; + let (ty, _) = build_type_and_flags(); let path = current_dir()? .parent() .unwrap() .join(format!("target/wasm32-wasi/{}/deps", ty)); - let store = Store::default(); - let mut env = create_wasi_env()?; - let mut controller = MotionIOPluginController::from_path(&path, &store, &mut env)?; + let mut controller = MotionIOPluginController::from_path(&path)?; let mut names = vec![]; for plugin in controller.all_plugins_mut() { + let stdout = Box::new(Pipe::new()); + let state = Arc::clone(&plugin.wasi_env().state); + let inodes = state.inodes.read().unwrap(); + state.fs.swap_file(&inodes, __WASI_STDOUT_FILENO, stdout)?; plugin.create()?; names.push(plugin.name()?); } diff --git a/rust/plugin_wasm_test_model_full/src/lib.rs b/rust/plugin_wasm_test_model_full/src/lib.rs index 51f0ba50..498ae33d 100644 --- a/rust/plugin_wasm_test_model_full/src/lib.rs +++ b/rust/plugin_wasm_test_model_full/src/lib.rs @@ -6,14 +6,27 @@ use serde_derive::{Deserialize, Serialize}; use serde_json::{json, Value}; -use std::os::raw::{c_void, c_char}; -use std::{collections::HashMap, ffi::CStr, ptr::null_mut}; +use std::os::raw::{c_char, c_void}; +use std::{collections::HashMap, ffi::CStr}; #[allow(non_camel_case_types)] pub type nanoem_application_plugin_status_t = i32; #[allow(non_camel_case_types)] -pub struct nanoem_application_plugin_model_io_t {} +#[derive(Default)] +pub struct nanoem_application_plugin_model_io_t { + function_index: i32, +} + +impl nanoem_application_plugin_model_io_t { + pub(self) unsafe fn get_mut(plugin: *mut Self) -> Option<&'static mut Self> { + if !plugin.is_null() { + Some(&mut (*plugin)) + } else { + None + } + } +} macro_rules! function { () => {{ @@ -83,7 +96,8 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOCreate( }) .unwrap() ); - null_mut() + let plugin = Box::new(nanoem_application_plugin_model_io_t::default()); + std::mem::transmute(plugin) } /// # Safety @@ -175,7 +189,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOCountAllFunctions( }) .unwrap() ); - 1 + 2 } /// # Safety @@ -204,13 +218,16 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOGetFunctionName( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginModelIOSetFunction( - _plugin: *mut nanoem_application_plugin_model_io_t, + plugin: *mut nanoem_application_plugin_model_io_t, index: i32, status_ptr: *mut nanoem_application_plugin_status_t, ) { let mut arguments = HashMap::new(); arguments.insert("index".to_owned(), json!(index)); arguments.insert("status".to_owned(), json!(*status_ptr)); + if let Some(plugin) = nanoem_application_plugin_model_io_t::get_mut(plugin) { + plugin.function_index = index; + } println!( "{}", serde_json::to_string(&Output { @@ -576,10 +593,15 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOSetInputModelData( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginModelIOExecute( - _plugin: *mut nanoem_application_plugin_model_io_t, + plugin: *mut nanoem_application_plugin_model_io_t, status_ptr: *mut nanoem_application_plugin_status_t, ) { let mut arguments = HashMap::new(); + if let Some(plugin) = nanoem_application_plugin_model_io_t::get_mut(plugin) { + if plugin.function_index == 1 { + *status_ptr = -1; + } + } arguments.insert("status".to_owned(), json!(*status_ptr)); println!( "{}", @@ -771,7 +793,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOGetRecoverySuggestion( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginModelIODestroy( - _plugin: *mut nanoem_application_plugin_model_io_t, + plugin: *mut nanoem_application_plugin_model_io_t, ) { println!( "{}", @@ -780,7 +802,10 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIODestroy( ..Default::default() }) .unwrap() - ) + ); + if !plugin.is_null() { + let _: Box = std::mem::transmute(plugin); + } } /// # Safety diff --git a/rust/plugin_wasm_test_model_minimum/src/lib.rs b/rust/plugin_wasm_test_model_minimum/src/lib.rs index 18220dd2..b821079c 100644 --- a/rust/plugin_wasm_test_model_minimum/src/lib.rs +++ b/rust/plugin_wasm_test_model_minimum/src/lib.rs @@ -6,14 +6,27 @@ use serde_derive::{Deserialize, Serialize}; use serde_json::{json, Value}; +use std::collections::HashMap; use std::os::raw::c_void; -use std::{collections::HashMap, ptr::null_mut}; #[allow(non_camel_case_types)] pub type nanoem_application_plugin_status_t = i32; #[allow(non_camel_case_types)] -pub struct nanoem_application_plugin_model_io_t {} +#[derive(Default)] +pub struct nanoem_application_plugin_model_io_t { + function_index: i32, +} + +impl nanoem_application_plugin_model_io_t { + pub(self) unsafe fn get_mut(plugin: *mut Self) -> Option<&'static mut Self> { + if !plugin.is_null() { + Some(&mut (*plugin)) + } else { + None + } + } +} macro_rules! function { () => {{ @@ -52,7 +65,8 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOCreate( }) .unwrap() ); - null_mut() + let plugin = Box::new(nanoem_application_plugin_model_io_t::default()); + std::mem::transmute(plugin) } /// # Safety @@ -126,7 +140,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOCountAllFunctions( }) .unwrap() ); - 1 + 2 } /// # Safety @@ -155,13 +169,16 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOGetFunctionName( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginModelIOSetFunction( - _plugin: *mut nanoem_application_plugin_model_io_t, + plugin: *mut nanoem_application_plugin_model_io_t, index: i32, status_ptr: *mut nanoem_application_plugin_status_t, ) { let mut arguments = HashMap::new(); arguments.insert("index".to_owned(), json!(index)); arguments.insert("status".to_owned(), json!(*status_ptr)); + if let Some(plugin) = nanoem_application_plugin_model_io_t::get_mut(plugin) { + plugin.function_index = index; + } println!( "{}", serde_json::to_string(&Output { @@ -202,10 +219,15 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOSetInputModelData( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginModelIOExecute( - _plugin: *mut nanoem_application_plugin_model_io_t, + plugin: *mut nanoem_application_plugin_model_io_t, status_ptr: *mut nanoem_application_plugin_status_t, ) { let mut arguments = HashMap::new(); + if let Some(plugin) = nanoem_application_plugin_model_io_t::get_mut(plugin) { + if plugin.function_index == 1 { + *status_ptr = -1; + } + } arguments.insert("status".to_owned(), json!(*status_ptr)); println!( "{}", @@ -285,7 +307,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIOGetFailureReason( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginModelIODestroy( - _plugin: *mut nanoem_application_plugin_model_io_t, + plugin: *mut nanoem_application_plugin_model_io_t, ) { println!( "{}", @@ -294,7 +316,10 @@ pub unsafe extern "C" fn nanoemApplicationPluginModelIODestroy( ..Default::default() }) .unwrap() - ) + ); + if !plugin.is_null() { + let _: Box = std::mem::transmute(plugin); + } } /// # Safety diff --git a/rust/plugin_wasm_test_motion_full/src/lib.rs b/rust/plugin_wasm_test_motion_full/src/lib.rs index 6a5b1133..7963bbfd 100644 --- a/rust/plugin_wasm_test_motion_full/src/lib.rs +++ b/rust/plugin_wasm_test_motion_full/src/lib.rs @@ -6,14 +6,27 @@ use serde_derive::{Deserialize, Serialize}; use serde_json::{json, Value}; -use std::os::raw::{c_void, c_char}; -use std::{collections::HashMap, ffi::CStr, ptr::null_mut}; +use std::os::raw::{c_char, c_void}; +use std::{collections::HashMap, ffi::CStr}; #[allow(non_camel_case_types)] pub type nanoem_application_plugin_status_t = i32; #[allow(non_camel_case_types)] -pub struct nanoem_application_plugin_motion_io_t {} +#[derive(Default)] +pub struct nanoem_application_plugin_motion_io_t { + function_index: i32, +} + +impl nanoem_application_plugin_motion_io_t { + pub(self) unsafe fn get_mut(plugin: *mut Self) -> Option<&'static mut Self> { + if !plugin.is_null() { + Some(&mut (*plugin)) + } else { + None + } + } +} macro_rules! function { () => {{ @@ -83,7 +96,8 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOCreate( }) .unwrap() ); - null_mut() + let plugin = Box::new(nanoem_application_plugin_motion_io_t::default()); + std::mem::transmute(plugin) } /// # Safety @@ -175,7 +189,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOCountAllFunctions( }) .unwrap() ); - 1 + 2 } /// # Safety @@ -204,13 +218,16 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOGetFunctionName( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginMotionIOSetFunction( - _plugin: *mut nanoem_application_plugin_motion_io_t, + plugin: *mut nanoem_application_plugin_motion_io_t, index: i32, status_ptr: *mut nanoem_application_plugin_status_t, ) { let mut arguments = HashMap::new(); arguments.insert("index".to_owned(), json!(index)); arguments.insert("status".to_owned(), json!(*status_ptr)); + if let Some(plugin) = nanoem_application_plugin_motion_io_t::get_mut(plugin) { + plugin.function_index = index; + } println!( "{}", serde_json::to_string(&Output { @@ -557,10 +574,15 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOSetInputActiveModelData( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginMotionIOExecute( - _plugin: *mut nanoem_application_plugin_motion_io_t, + plugin: *mut nanoem_application_plugin_motion_io_t, status_ptr: *mut nanoem_application_plugin_status_t, ) { let mut arguments = HashMap::new(); + if let Some(plugin) = nanoem_application_plugin_motion_io_t::get_mut(plugin) { + if plugin.function_index == 1 { + *status_ptr = -1; + } + } arguments.insert("status".to_owned(), json!(*status_ptr)); println!( "{}", @@ -752,7 +774,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOGetRecoverySuggestion( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginMotionIODestroy( - _plugin: *mut nanoem_application_plugin_motion_io_t, + plugin: *mut nanoem_application_plugin_motion_io_t, ) { println!( "{}", @@ -761,7 +783,10 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIODestroy( ..Default::default() }) .unwrap() - ) + ); + if !plugin.is_null() { + let _: Box = std::mem::transmute(plugin); + } } /// # Safety diff --git a/rust/plugin_wasm_test_motion_minimum/src/lib.rs b/rust/plugin_wasm_test_motion_minimum/src/lib.rs index 0a48026b..37e5b120 100644 --- a/rust/plugin_wasm_test_motion_minimum/src/lib.rs +++ b/rust/plugin_wasm_test_motion_minimum/src/lib.rs @@ -6,14 +6,27 @@ use serde_derive::{Deserialize, Serialize}; use serde_json::{json, Value}; +use std::collections::HashMap; use std::os::raw::c_void; -use std::{collections::HashMap, ptr::null_mut}; #[allow(non_camel_case_types)] pub type nanoem_application_plugin_status_t = i32; #[allow(non_camel_case_types)] -pub struct nanoem_application_plugin_motion_io_t {} +#[derive(Default)] +pub struct nanoem_application_plugin_motion_io_t { + function_index: i32, +} + +impl nanoem_application_plugin_motion_io_t { + pub(self) unsafe fn get_mut(plugin: *mut Self) -> Option<&'static mut Self> { + if !plugin.is_null() { + Some(&mut (*plugin)) + } else { + None + } + } +} macro_rules! function { () => {{ @@ -52,7 +65,8 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOCreate( }) .unwrap() ); - null_mut() + let plugin = Box::new(nanoem_application_plugin_motion_io_t::default()); + std::mem::transmute(plugin) } /// # Safety @@ -144,7 +158,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOCountAllFunctions( }) .unwrap() ); - 1 + 2 } /// # Safety @@ -173,13 +187,16 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOGetFunctionName( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginMotionIOSetFunction( - _plugin: *mut nanoem_application_plugin_motion_io_t, + plugin: *mut nanoem_application_plugin_motion_io_t, index: i32, status_ptr: *mut nanoem_application_plugin_status_t, ) { let mut arguments = HashMap::new(); arguments.insert("index".to_owned(), json!(index)); arguments.insert("status".to_owned(), json!(*status_ptr)); + if let Some(plugin) = nanoem_application_plugin_motion_io_t::get_mut(plugin) { + plugin.function_index = index; + } println!( "{}", serde_json::to_string(&Output { @@ -220,10 +237,15 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOSetInputMotionData( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginMotionIOExecute( - _plugin: *mut nanoem_application_plugin_motion_io_t, + plugin: *mut nanoem_application_plugin_motion_io_t, status_ptr: *mut nanoem_application_plugin_status_t, ) { let mut arguments = HashMap::new(); + if let Some(plugin) = nanoem_application_plugin_motion_io_t::get_mut(plugin) { + if plugin.function_index == 1 { + *status_ptr = -1; + } + } arguments.insert("status".to_owned(), json!(*status_ptr)); println!( "{}", @@ -303,7 +325,7 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIOGetFailureReason( /// This function should be called from nanoem via plugin loader #[no_mangle] pub unsafe extern "C" fn nanoemApplicationPluginMotionIODestroy( - _plugin: *mut nanoem_application_plugin_motion_io_t, + plugin: *mut nanoem_application_plugin_motion_io_t, ) { println!( "{}", @@ -312,7 +334,10 @@ pub unsafe extern "C" fn nanoemApplicationPluginMotionIODestroy( ..Default::default() }) .unwrap() - ) + ); + if !plugin.is_null() { + let _: Box = std::mem::transmute(plugin); + } } /// # Safety diff --git a/rust/scripts/build.bat b/rust/scripts/build.bat new file mode 100644 index 00000000..178cc717 --- /dev/null +++ b/rust/scripts/build.bat @@ -0,0 +1,11 @@ +@echo off + +rustup target add wasm32-wasi +cargo install cargo-deny +cargo deny check +cargo build --profile release-lto --package plugin_wasm_test_model_minimum --target wasm32-wasi +cargo build --profile release-lto --package plugin_wasm_test_motion_minimum --target wasm32-wasi +cargo build --profile release-lto --package plugin_wasm_test_model_full --target wasm32-wasi +cargo build --profile release-lto --package plugin_wasm_test_motion_full --target wasm32-wasi +cargo build --profile release-lto +cargo test --profile release-lto diff --git a/rust/scripts/build.sh b/rust/scripts/build.sh new file mode 100755 index 00000000..fa1ea650 --- /dev/null +++ b/rust/scripts/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash -eu + +rustup target add wasm32-wasi +cargo install cargo-deny +cargo deny check +cargo build --profile release-lto --package plugin_wasm_test_model_minimum --target wasm32-wasi +cargo build --profile release-lto --package plugin_wasm_test_motion_minimum --target wasm32-wasi +cargo build --profile release-lto --package plugin_wasm_test_model_full --target wasm32-wasi +cargo build --profile release-lto --package plugin_wasm_test_motion_full --target wasm32-wasi +cargo build --profile release-lto +cargo test --profile release-lto diff --git a/rust/scripts/test.bat b/rust/scripts/test.bat deleted file mode 100644 index 0f8cec67..00000000 --- a/rust/scripts/test.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo off - -rustup target add wasm32-wasi -cargo install cargo-deny -cargo deny check -cargo build --release --package plugin_wasm_test_model_minimum --target wasm32-wasi -cargo build --release --package plugin_wasm_test_motion_minimum --target wasm32-wasi -cargo build --release --package plugin_wasm_test_model_full --target wasm32-wasi -cargo build --release --package plugin_wasm_test_motion_full --target wasm32-wasi -cargo build --release -cargo test --release diff --git a/rust/scripts/test.sh b/rust/scripts/test.sh deleted file mode 100755 index b0f6d300..00000000 --- a/rust/scripts/test.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -eu - -rustup target add wasm32-wasi -cargo install cargo-deny -cargo deny check -cargo build --release --package plugin_wasm_test_model_minimum --target wasm32-wasi -cargo build --release --package plugin_wasm_test_motion_minimum --target wasm32-wasi -cargo build --release --package plugin_wasm_test_model_full --target wasm32-wasi -cargo build --release --package plugin_wasm_test_motion_full --target wasm32-wasi -cargo build --release -cargo test --release