From 62f517ff481678f40044adc5ee4df205eabc7f51 Mon Sep 17 00:00:00 2001 From: Graham Kelly Date: Wed, 14 Aug 2024 18:34:48 -0400 Subject: [PATCH] fixes and struct pits --- Cargo.lock | 344 +++++++++++++++++++++------------- Cargo.toml | 2 +- isovariant/Cargo.toml | 8 + isovariant/src/lib.rs | 7 + wars-component/src/lib.rs | 8 +- wars-macro/src/lib.rs | 18 +- wars-macro/tests/b.rs | 5 +- wars-rt/Cargo.toml | 5 + wars-rt/src/func.rs | 44 ++++- wars-rt/src/func/unsync.rs | 63 ++++--- wars-rt/src/lib.rs | 215 +++++++++++++++------ wars-rt/src/wasix.rs | 5 + wars-rt/src/wrl.rs | 55 +++++- wars-test/src/lib.rs | 4 +- wars/Cargo.toml | 3 + wars/src/lib.rs | 330 ++++++++++++++++++++++++++++---- wasm-compile-layer/Cargo.toml | 15 ++ wasm-compile-layer/src/lib.rs | 16 ++ 18 files changed, 883 insertions(+), 264 deletions(-) create mode 100644 isovariant/Cargo.toml create mode 100644 isovariant/src/lib.rs create mode 100644 wasm-compile-layer/Cargo.toml create mode 100644 wasm-compile-layer/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ca22fdc..d5a06d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,9 +55,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -70,33 +70,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys", @@ -154,9 +154,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "blake2" @@ -190,18 +190,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "castaway" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" dependencies = [ "rustversion", ] [[package]] name = "cc" -version = "1.0.98" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" [[package]] name = "cfg-if" @@ -226,9 +226,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "convert_case" @@ -245,6 +245,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + [[package]] name = "cranelift-bforest" version = "0.104.3" @@ -400,15 +409,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -424,9 +433,9 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encoding_rs" @@ -439,9 +448,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", "regex", @@ -449,9 +458,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", @@ -478,16 +487,17 @@ dependencies = [ [[package]] name = "expander" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e83c02035136f1592a47964ea60c05a50e4ed8b5892cfac197063850898d4d" +checksum = "e2c470c71d91ecbd179935b24170459e926382eaaa86b590b78814e180d8a8e2" dependencies = [ "blake2", + "file-guard", "fs-err", - "prettier-please", + "prettyplease", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -496,6 +506,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" +[[package]] +name = "file-guard" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ef72acf95ec3d7dbf61275be556299490a245f017cf084bd23b4f68cf9407c" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "fixedbitset" version = "0.2.0" @@ -593,6 +613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", + "serde", ] [[package]] @@ -619,12 +640,33 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "ic-stable-structures" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03f3044466a69802de74e710dc0300b706a05696a0531c942ca856751a13b0db" +dependencies = [ + "ic_principal", +] + +[[package]] +name = "ic_principal" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1762deb6f7c8d8c2bdee4b6c5a47b60195b74e9b5280faa5ba29692f8e17429c" + [[package]] name = "id-arena" version = "2.2.1" @@ -654,9 +696,13 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "isovariant" +version = "0.1.0" [[package]] name = "itertools" @@ -674,10 +720,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] -name = "lazy_static" -version = "1.4.0" +name = "keccak" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -699,9 +754,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logos" @@ -723,7 +778,7 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax 0.6.29", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -752,9 +807,9 @@ checksum = "204651f31b0a6a7b2128d2b92c372cd94607b210c3a6b6e542c57a8cfd4db996" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memfd" @@ -785,9 +840,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -831,7 +886,7 @@ dependencies = [ [[package]] name = "portal-pc-waffle" version = "0.0.27+portal" -source = "git+https://github.com/portal-co/waffle-.git?branch=pr/changes2#3f9e7a560f40c29c1de6389f1f6371cde261adb7" +source = "git+https://github.com/portal-co/waffle-.git?branch=pr/changes2#8db8a0234782a612db040282dda2ee177ff36f28" dependencies = [ "addr2line", "anyhow", @@ -841,22 +896,24 @@ dependencies = [ "lazy_static", "libc", "log", + "paste", "rayon", + "serde", "smallvec", "stacker", "structopt", - "wasm-encoder 0.202.0", - "wasmparser 0.202.0", + "wasm-encoder 0.212.0", + "wasmparser 0.212.0", ] [[package]] -name = "prettier-please" -version = "0.2.0" +name = "prettyplease" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22020dfcf177fcc7bf5deaf7440af371400c67c0de14c399938d8ed4fb4645d3" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -885,9 +942,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -969,7 +1026,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -987,25 +1044,25 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] @@ -1016,9 +1073,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "relooper" @@ -1057,7 +1114,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1095,35 +1152,46 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "slice-group-by" version = "0.3.1" @@ -1208,9 +1276,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -1225,9 +1293,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -1236,9 +1304,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" +checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2" [[package]] name = "textwrap" @@ -1251,22 +1319,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -1323,9 +1391,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vec_map" @@ -1335,9 +1403,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "waffle-func-reloop" @@ -1351,13 +1419,15 @@ dependencies = [ name = "wars" version = "0.1.0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", + "hex", "portal-pc-waffle", "proc-macro2", "quasiquote", "quote", "relooper", - "syn 2.0.66", + "sha3", + "syn 2.0.72", "waffle-func-reloop", "witx", ] @@ -1370,7 +1440,7 @@ dependencies = [ "proc-macro2", "quasiquote", "quote", - "syn 2.0.66", + "syn 2.0.72", "wars", ] @@ -1381,7 +1451,7 @@ dependencies = [ "expander", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", "wars", "wars-rt", "wat", @@ -1394,6 +1464,8 @@ dependencies = [ "anyhow", "castaway", "derive_more", + "either", + "ic-stable-structures", "paste", "tramp", "tuple_list", @@ -1405,6 +1477,21 @@ dependencies = [ name = "wars-test" version = "0.1.0" +[[package]] +name = "wasm-compile-layer" +version = "0.1.0" +dependencies = [ + "anyhow", + "portal-pc-waffle", + "proc-macro2", + "quasiquote", + "quote", + "relooper", + "syn 2.0.72", + "waffle-func-reloop", + "wars", +] + [[package]] name = "wasm-encoder" version = "0.38.1" @@ -1425,18 +1512,18 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.202.0" +version = "0.212.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd106365a7f5f7aa3c1916a98cbb3ad477f5ff96ddb130285a91c6e7429e67a" +checksum = "501940df4418b8929eb6d52f1aade1fdd15a5b86c92453cb696e3c906bd3fc33" dependencies = [ "leb128", ] [[package]] name = "wasm-encoder" -version = "0.209.1" +version = "0.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4a05336882dae732ce6bd48b7e11fe597293cb72c13da4f35d7d5f8d53b2a7" +checksum = "ff694f02a8d7a50b6922b197ae03883fbf18cdb2ae9fbee7b6148456f5f44041" dependencies = [ "leb128", ] @@ -1498,20 +1585,23 @@ version = "0.121.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "indexmap 2.2.6", "semver", ] [[package]] name = "wasmparser" -version = "0.202.0" +version = "0.212.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6998515d3cf3f8b980ef7c11b29a9b1017d4cf86b99ae93b546992df9931413" +checksum = "8d28bc49ba1e5c5b61ffa7a2eace10820443c4b7d1c0b144109261d14570fdf8" dependencies = [ - "bitflags 2.5.0", + "ahash", + "bitflags 2.6.0", + "hashbrown 0.14.5", "indexmap 2.2.6", "semver", + "serde", ] [[package]] @@ -1574,7 +1664,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", "wasmtime-component-util", "wasmtime-wit-bindgen", "wit-parser", @@ -1732,7 +1822,7 @@ checksum = "e04682ce587aa8fa9311d3c95148381f08a1db274ad6bcd3553f7c97c8c2debb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -1781,24 +1871,24 @@ dependencies = [ [[package]] name = "wast" -version = "209.0.1" +version = "214.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fffef2ff6147e4d12e972765fd75332c6a11c722571d4ab7a780d81ffc8f0a4" +checksum = "694bcdb24c49c8709bd8713768b71301a11e823923eee355d530f1d8d0a7f8e9" dependencies = [ "bumpalo", "leb128", "memchr", "unicode-width", - "wasm-encoder 0.209.1", + "wasm-encoder 0.214.0", ] [[package]] name = "wat" -version = "1.209.1" +version = "1.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42203ec0271d113f8eb1f77ebc624886530cecb35915a7f63a497131f16e4d24" +checksum = "347249eb56773fa728df2656cfe3a8c19437ded61a922a0b5e0839d9790e278e" dependencies = [ - "wast 209.0.1", + "wast 214.0.0", ] [[package]] @@ -1850,9 +1940,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -1866,51 +1956,51 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wit-parser" @@ -1942,20 +2032,20 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] diff --git a/Cargo.toml b/Cargo.toml index 8440bb2..620b2e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members=[ "waffle-func-reloop", "wars", "wars-component", "wars-macro","wars-rt", "wars-test"] +members=[ "waffle-func-reloop", "wars", "wars-component", "wars-macro","wars-rt", "wars-test","isovariant", "wasm-compile-layer"] resolver="2" [workspace.dependencies] diff --git a/isovariant/Cargo.toml b/isovariant/Cargo.toml new file mode 100644 index 0000000..b66dba1 --- /dev/null +++ b/isovariant/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "isovariant" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/isovariant/src/lib.rs b/isovariant/src/lib.rs new file mode 100644 index 0000000..3227e51 --- /dev/null +++ b/isovariant/src/lib.rs @@ -0,0 +1,7 @@ +pub trait Iso>: Into {} +impl, U: Into> Iso for T {} +pub trait TryIso>>: + TryInto> +{ +} +impl>, U: TryInto>> TryIso for U {} diff --git a/wars-component/src/lib.rs b/wars-component/src/lib.rs index 39f4634..90dad0d 100644 --- a/wars-component/src/lib.rs +++ b/wars-component/src/lib.rs @@ -1,6 +1,2 @@ -pub trait Component{ - -} -impl Component for Opts{ - -} \ No newline at end of file +pub trait Component {} +impl Component for Opts {} diff --git a/wars-macro/src/lib.rs b/wars-macro/src/lib.rs index ba1b671..3c2f8a9 100644 --- a/wars-macro/src/lib.rs +++ b/wars-macro/src/lib.rs @@ -14,6 +14,7 @@ struct O { pub flags: Flags, pub embed: proc_macro2::TokenStream, pub data: BTreeMap, // pub cfg: Arc, + pub roots: BTreeMap, } // struct NoopCfg {} // impl ImportCfg for NoopCfg { @@ -32,6 +33,7 @@ impl Parse for O { flags: Default::default(), embed: Default::default(), data: BTreeMap::new(), + roots: BTreeMap::new(), // cfg: Arc::new(NoopCfg {}), }; while input.lookahead1().peek(Ident) { @@ -80,7 +82,20 @@ impl Parse for O { o.flags &= Flags::LEGACY.complement(); } } - _ => return Err(syn::Error::new(i.span(), "unexpected type")), + _ => { + match i + .to_string() + .as_str() + .strip_suffix("_path") + .map(|a| a.to_owned()) + { + None => return Err(syn::Error::new(i.span(), "unexpected type")), + Some(a) => { + let s: syn::LitStr = input.parse()?; + o.roots.insert(a, s.parse()?); + } + } + } }; let _comma: Token![,] = input.parse()?; } @@ -102,6 +117,7 @@ pub fn wars(a: TokenStream) -> TokenStream { flags: o.flags, embed: o.embed, data: o.data, + roots: o.roots, // cfg: o.cfg, } .to_mod(), diff --git a/wars-macro/tests/b.rs b/wars-macro/tests/b.rs index a25ffe7..aae4976 100644 --- a/wars-macro/tests/b.rs +++ b/wars-macro/tests/b.rs @@ -3,7 +3,4 @@ wars_macro::wars!( r#async = true, ); -fn x(){ - -} - +fn x() {} diff --git a/wars-rt/Cargo.toml b/wars-rt/Cargo.toml index 247ea37..7b74e34 100644 --- a/wars-rt/Cargo.toml +++ b/wars-rt/Cargo.toml @@ -9,8 +9,13 @@ edition = "2021" anyhow = "1.0.86" castaway = "0.2.2" derive_more = "0.99.17" +either = "1.13.0" +ic-stable-structures = { version = "0.6.5", optional = true } paste = "1.0.15" tramp = "0.3.0" tuple_list = "0.1.3" wars-macro = { version = "0.1.0", path = "../wars-macro" } wasm_runtime_layer = "0.4.0" + +[features] +ic-stable-structures = ["dep:ic-stable-structures"] diff --git a/wars-rt/src/func.rs b/wars-rt/src/func.rs index b2e5b11..5c89fad 100644 --- a/wars-rt/src/func.rs +++ b/wars-rt/src/func.rs @@ -1,14 +1,16 @@ -use std::sync::Arc; +use std::{ + iter::{empty, once}, + sync::Arc, +}; use anyhow::Context; use tramp::{tramp, BorrowRec, Thunk}; pub mod unsync; -pub fn ret<'a,T>(a: T) -> BorrowRec<'a,T>{ +pub fn ret<'a, T>(a: T) -> BorrowRec<'a, T> { BorrowRec::Ret(a) } -pub trait CtxSpec: Sized { - type ExternRef: Clone; -} +pub use crate::CtxSpec; +use crate::Traverse; pub enum Value { I32(u32), I64(u64), @@ -20,15 +22,34 @@ pub enum Value { &'a mut C, Vec>, ) -> tramp::BorrowRec<'a, anyhow::Result>>> - + Send + Sync + 'static, + + Send + + Sync + + 'static, >, ), Null, ExRef(C::ExternRef), } +impl Traverse for Value { + fn traverse<'a>(&'a self) -> Box::ExternRef> + 'a> { + match self { + Value::ExRef(e) => Box::new(once(e)), + _ => Box::new(empty()), + } + } + + fn traverse_mut<'a>( + &'a mut self, + ) -> Box::ExternRef> + 'a> { + match self { + Value::ExRef(e) => Box::new(once(e)), + _ => Box::new(empty()), + } + } +} pub fn call_ref<'a, A: CoeVec + 'static, B: CoeVec + 'static, C: CtxSpec + 'static>( ctx: &'a mut C, - go: Df, + go: Df, a: A, ) -> tramp::BorrowRec<'a, anyhow::Result> { // let go: Df = cast(go); @@ -143,8 +164,9 @@ pub fn map_rec<'a, T: 'a, U>( })), } } -pub type Df = - Arc Fn(&'a mut C, A) -> tramp::BorrowRec<'a, anyhow::Result> + Send + Sync + 'static>; +pub type Df = Arc< + dyn for<'a> Fn(&'a mut C, A) -> tramp::BorrowRec<'a, anyhow::Result> + Send + Sync + 'static, +>; pub fn da< A, @@ -153,7 +175,7 @@ pub fn da< F: for<'a> Fn(&'a mut C, A) -> tramp::BorrowRec<'a, anyhow::Result> + Send + Sync + 'static, >( f: F, -) -> Df { +) -> Df { Arc::new(f) } @@ -165,6 +187,8 @@ impl + 'static, B: CoeVec + 'static> Coe>, ) -> tramp::BorrowRec<'a, anyhow::Result>>> + + Send + + Sync + 'static, >( a: T, diff --git a/wars-rt/src/func/unsync.rs b/wars-rt/src/func/unsync.rs index a038dc6..a05a445 100644 --- a/wars-rt/src/func/unsync.rs +++ b/wars-rt/src/func/unsync.rs @@ -1,27 +1,31 @@ -use std::{future::Future, pin::Pin, sync::Arc}; +use std::{ + future::Future, + iter::{empty, once}, + pin::Pin, + sync::Arc, +}; use anyhow::Context; // use tramp::{tramp, BorrowRec, Thunk}; -pub fn ret<'a,T>(a: T) -> AsyncRec<'a,T>{ +pub fn ret<'a, T>(a: T) -> AsyncRec<'a, T> { AsyncRec::Ret(a) } -pub enum AsyncRec<'a,T>{ +pub enum AsyncRec<'a, T> { Ret(T), - Async(Pin> + Send + Sync + 'a>>) + Async(Pin> + Send + Sync + 'a>>), } -impl<'a,T> AsyncRec<'a,T>{ - pub async fn go(mut self) -> T{ - loop{ - self = match self{ +impl<'a, T> AsyncRec<'a, T> { + pub async fn go(mut self) -> T { + loop { + self = match self { AsyncRec::Ret(r) => return r, AsyncRec::Async(a) => a.await, } } } } -pub trait CtxSpec: Sized { - type ExternRef: Clone; -} +pub use crate::CtxSpec; +use crate::Traverse; pub enum Value { I32(u32), I64(u64), @@ -29,19 +33,35 @@ pub enum Value { F64(f64), FunRef( Arc< - dyn for<'a> Fn( - &'a mut C, - Vec>, - ) -> AsyncRec<'a, anyhow::Result>>> - + Send + Sync + 'static, + dyn for<'a> Fn(&'a mut C, Vec>) -> AsyncRec<'a, anyhow::Result>>> + + Send + + Sync + + 'static, >, ), Null, ExRef(C::ExternRef), } +impl Traverse for Value { + fn traverse<'a>(&'a self) -> Box::ExternRef> + 'a> { + match self { + Value::ExRef(e) => Box::new(once(e)), + _ => Box::new(empty()), + } + } + + fn traverse_mut<'a>( + &'a mut self, + ) -> Box::ExternRef> + 'a> { + match self { + Value::ExRef(e) => Box::new(once(e)), + _ => Box::new(empty()), + } + } +} pub fn call_ref<'a, A: CoeVec + 'static, B: CoeVec + 'static, C: CtxSpec + 'static>( ctx: &'a mut C, - go: Df, + go: Df, a: A, ) -> AsyncRec<'a, anyhow::Result> { // let go: Df = cast(go); @@ -150,7 +170,7 @@ pub fn map_rec<'a, T: 'a, U>( ) -> AsyncRec<'a, U> { match r { AsyncRec::Ret(x) => AsyncRec::Ret(go(x)), - AsyncRec::Async(a) => AsyncRec::Async(Box::pin(async move{ + AsyncRec::Async(a) => AsyncRec::Async(Box::pin(async move { let v = a.await; map_rec(v, go) })), @@ -166,7 +186,7 @@ pub fn da< F: for<'a> Fn(&'a mut C, A) -> AsyncRec<'a, anyhow::Result> + Send + Sync + 'static, >( f: F, -) -> Df { +) -> Df { Arc::new(f) } @@ -174,10 +194,7 @@ impl + 'static, B: CoeVec + 'static> Coe Value { pub fn x< C: CtxSpec, - T: for<'a> Fn( - &'a mut C, - Vec>, - ) -> AsyncRec<'a, anyhow::Result>>> + T: for<'a> Fn(&'a mut C, Vec>) -> AsyncRec<'a, anyhow::Result>>> + 'static, >( a: T, diff --git a/wars-rt/src/lib.rs b/wars-rt/src/lib.rs index 71a379c..c6c5519 100644 --- a/wars-rt/src/lib.rs +++ b/wars-rt/src/lib.rs @@ -1,84 +1,187 @@ pub mod func; -pub mod wrl; pub mod wasix; -use std::sync::{Arc, Mutex}; - -// use as_ref::AsSlice; -use func::CtxSpec; -pub use func::Value; -pub trait Memory { - fn read<'a>(&'a self, a: usize, s: usize) -> anyhow::Result + 'a>>; - fn write(&mut self, a: usize, x: &[u8]) -> anyhow::Result<()>; - fn size(&self) -> anyhow::Result; - fn grow(&mut self, x: usize) -> anyhow::Result<()>; +pub mod wrl; +use std::{ + iter::empty, + sync::{Arc, Mutex}, +}; +pub type AnyCell = ::std::sync::Arc<::std::cell::UnsafeCell>>; +pub fn any_cell(a: T) -> AnyCell{ + return ::std::sync::Arc::new(::std::cell::UnsafeCell::new(Box::new(a))); } -impl Memory for Vec { - fn read<'a>(&'a self, a: usize, s: usize) -> anyhow::Result + 'a>>{ - Ok(Box::new(&self[a..][..s])) +pub unsafe fn get_cell(a: &AnyCell) -> Option<&mut T>{ + let r = unsafe{ + &mut *a.get() + }; + return r.downcast_mut(); +} +#[derive(Clone)] +pub struct Pit{ + pub id: [u8; 32], + pub x: X, + pub s: [u8;32], +} +// use as_ref::AsSlice; +// use func::CtxSpec; +pub use func::Value; +pub trait CtxSpec: Sized { + type ExternRef: Clone; +} +pub trait Traverse { + fn traverse<'a>(&'a self) -> Box + 'a>; + fn traverse_mut<'a>(&'a mut self) -> Box + 'a>; +} +impl> Traverse for Vec { + fn traverse<'a>(&'a self) -> Box::ExternRef> + 'a> { + Box::new(self.iter().flat_map(|a| a.traverse())) } - fn write(&mut self, a: usize, x: &[u8]) -> anyhow::Result<()> { - self[a..][..x.len()].copy_from_slice(x); + fn traverse_mut<'a>( + &'a mut self, + ) -> Box::ExternRef> + 'a> { + Box::new(self.iter_mut().flat_map(|x| x.traverse_mut())) + } +} +impl Traverse for u32 { + fn traverse<'a>(&'a self) -> Box::ExternRef> + 'a> { + Box::new(empty()) + } + + fn traverse_mut<'a>( + &'a mut self, + ) -> Box::ExternRef> + 'a> { + Box::new(empty()) + } +} +impl Traverse for u64 { + fn traverse<'a>(&'a self) -> Box::ExternRef> + 'a> { + Box::new(empty()) + } + + fn traverse_mut<'a>( + &'a mut self, + ) -> Box::ExternRef> + 'a> { + Box::new(empty()) + } +} +pub trait Memory { + fn read<'a>(&'a self, a: u64, s: u64) -> anyhow::Result + 'a>>; + fn write(&mut self, a: u64, x: &[u8]) -> anyhow::Result<()>; + fn size(&self) -> anyhow::Result; + fn grow(&mut self, x: u64) -> anyhow::Result<()>; +} +#[cfg(feature = "ic-stable-structures")] +pub mod ic{ + #[repr(transparent)] + pub struct Stable(pub T); + + impl super::Memory for Stable{ + fn read<'a>(&'a self, a: u64, s: u64) -> anyhow::Result + 'a>> { + let mut v = vec![0u8;s as usize]; + self.0.read(a, &mut v); + Ok(Box::new(v)) + } + + fn write(&mut self, a: u64, x: &[u8]) -> anyhow::Result<()> { + self.0.write(a,x); + Ok(()) + } + + fn size(&self) -> anyhow::Result { + let s = self.0.size(); + Ok(s * 65536) + } + + fn grow(&mut self, x: u64) -> anyhow::Result<()> { + if self.0.grow((x + 65535) / 65536) == -1{ + anyhow::bail!("stable growth failed") + } + Ok(()) + } + } +} +impl Memory for Vec { + fn read<'a>(&'a self, a: u64, s: u64) -> anyhow::Result + 'a>> { + Ok(Box::new(&self[(a as usize)..][..(s as usize)])) + } + + fn write(&mut self, a: u64, x: &[u8]) -> anyhow::Result<()> { + self[(a as usize)..][..x.len()].copy_from_slice(x); Ok(()) } - fn size(&self) -> anyhow::Result { - Ok(self.len()) + fn size(&self) -> anyhow::Result { + Ok(self.len() as u64) } - fn grow(&mut self, x: usize) -> anyhow::Result<()> { + fn grow(&mut self, x: u64) -> anyhow::Result<()> { self.extend((0..x).map(|a| 0u8)); Ok(()) } } -impl Memory for Arc>{ - fn read<'a>(&'a self, a: usize, s: usize) -> anyhow::Result + 'a>> { +impl Memory for Box { + fn read<'a>(&'a self, a: u64, s: u64) -> anyhow::Result + 'a>> { + self.as_ref().read(a, s) + } + + fn write(&mut self, a: u64, x: &[u8]) -> anyhow::Result<()> { + self.as_mut().write(a, x) + } + + fn size(&self) -> Result { + self.as_ref().size() + } + + fn grow(&mut self, x: u64) -> anyhow::Result<()> { + self.as_mut().grow(x) + } +} +impl Memory for Arc> { + fn read<'a>(&'a self, a: u64, s: u64) -> anyhow::Result + 'a>> { let l = self.lock().unwrap(); let r = l.read(a, s)?; return Ok(Box::new(r.as_ref().as_ref().to_vec())); } - fn write(&mut self, a: usize, x: &[u8]) -> anyhow::Result<()> { + fn write(&mut self, a: u64, x: &[u8]) -> anyhow::Result<()> { let mut l = self.lock().unwrap(); return l.write(a, x); } - fn size(&self) -> anyhow::Result { + fn size(&self) -> Result { let l = self.lock().unwrap(); return l.size(); } - fn grow(&mut self, x: usize) -> anyhow::Result<()> { + fn grow(&mut self, x: u64) -> anyhow::Result<()> { let mut l = self.lock().unwrap(); - return l.grow(x) + return l.grow(x); } } -pub unsafe fn host_memory() -> impl Memory{ - struct W{} - impl Memory for W{ - fn read<'a>(&'a self, a: usize, s: usize) -> anyhow::Result + 'a>> { - return Ok(Box::new(unsafe{ - std::slice::from_raw_parts(a as *const u8, s) - })) +pub unsafe fn host_memory() -> impl Memory { + struct W {} + impl Memory for W { + fn read<'a>(&'a self, a: u64, s: u64) -> anyhow::Result + 'a>> { + return Ok(Box::new(unsafe { + std::slice::from_raw_parts(a as usize as *const u8, s as usize) + })); } - - fn write(&mut self, a: usize, x: &[u8]) -> anyhow::Result<()> { - let n = unsafe{ - std::slice::from_raw_parts_mut(a as *mut u8, x.len()) - }; + + fn write(&mut self, a: u64, x: &[u8]) -> anyhow::Result<()> { + let n = unsafe { std::slice::from_raw_parts_mut(a as usize as *mut u8, x.len()) }; n.copy_from_slice(x); return Ok(()); } - - fn size(&self) -> anyhow::Result { + + fn size(&self) -> Result { anyhow::bail!("host memory cannot use size") } - - fn grow(&mut self, x: usize) -> anyhow::Result<()> { + + fn grow(&mut self, x: u64) -> anyhow::Result<()> { anyhow::bail!("host memory cannot use grow") } } - return W{}; + return W {}; } pub mod _rexport { pub use anyhow; @@ -213,59 +316,59 @@ macro_rules! int_ty{ Ok(tuple_list::tuple_list!(a.wrapping_sub(b))) } //LOADS and STORES - pub fn [<$p load>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ - let r = a.read(b.try_into()?,std::mem::size_of::<$int>())?; + pub fn [<$p load>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ + let r = a.read(b.try_into()?,std::mem::size_of::<$int>().try_into()?)?; Ok(tuple_list::tuple_list!($int::from_ne_bytes(r.as_ref().as_ref().try_into()?))) } - pub fn [<$p store>],M: Memory + ?Sized>(a: &mut M, b: T, c: $int) -> anyhow::Result<()> where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p store>],M: Memory + ?Sized>(a: &mut M, b: T, c: $int) -> anyhow::Result<()> where T::Error: std::error::Error + Send + Sync + 'static{ // let mut r = &mut a[b.try_into()?..][..std::mem::size_of::<$int>()]; // r.copy_from_slice(&c.to_ne_bytes()); a.write(b.try_into()?,&c.to_ne_bytes())?; Ok(()) } //8 BIT - pub fn [<$p load8u>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p load8u>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ let r = a.read(b.try_into()?,1)?.as_ref().as_ref()[0]; Ok(tuple_list::tuple_list!(r as $int)) } - pub fn [<$p load8s>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p load8s>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ let r = a.read(b.try_into()?,1)?.as_ref().as_ref()[0]; Ok(tuple_list::tuple_list!(r as i8 as $p as $int)) } - pub fn [<$p store8>],M: Memory + ?Sized>(a: &mut M, b: T, c: $int) -> anyhow::Result<()> where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p store8>],M: Memory + ?Sized>(a: &mut M, b: T, c: $int) -> anyhow::Result<()> where T::Error: std::error::Error + Send + Sync + 'static{ // let mut r = &mut a[b.try_into()?..][..1]; // r[0] = (c & 0xff) as u8; a.write(b.try_into()?,&[(c & 0xff) as u8])?; Ok(()) } //16 BIT - pub fn [<$p load16u>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p load16u>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ let r = a.read(b.try_into()?,2)?; let r = u16::from_ne_bytes(r.as_ref().as_ref().try_into()?); Ok(tuple_list::tuple_list!(r as $int)) } - pub fn [<$p load16s>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p load16s>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ let r = a.read(b.try_into()?,2)?; let r = u16::from_ne_bytes(r.as_ref().as_ref().try_into()?); Ok(tuple_list::tuple_list!(r as i16 as $p as $int)) } - pub fn [<$p store16>],M: Memory + ?Sized>(a: &mut M, b: T, c: $int) -> anyhow::Result<()> where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p store16>],M: Memory + ?Sized>(a: &mut M, b: T, c: $int) -> anyhow::Result<()> where T::Error: std::error::Error + Send + Sync + 'static{ // let mut r = &mut a[b.try_into()?..][..2]; a.write(b.try_into()?,&((c & 0xffff) as u16).to_ne_bytes())?; Ok(()) } //32 BIT - pub fn [<$p load32u>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p load32u>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ let r = a.read(b.try_into()?,4)?; let r = u32::from_ne_bytes(r.as_ref().as_ref().try_into()?); Ok(tuple_list::tuple_list!(r as $int)) } - pub fn [<$p load32s>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p load32s>],M: Memory + ?Sized>(a: &mut M, b: T) -> anyhow::Result where T::Error: std::error::Error + Send + Sync + 'static{ let r = a.read(b.try_into()?,4)?; let r = u32::from_ne_bytes(r.as_ref().as_ref().try_into()?); Ok(tuple_list::tuple_list!(r as i32 as $p as $int)) } - pub fn [<$p store32>],M: Memory + ?Sized>(a: &mut M, b: T, c: $int) -> anyhow::Result<()> where T::Error: std::error::Error + Send + Sync + 'static{ + pub fn [<$p store32>],M: Memory + ?Sized>(a: &mut M, b: T, c: $int) -> anyhow::Result<()> where T::Error: std::error::Error + Send + Sync + 'static{ // let mut r = &mut a[b.try_into()?..][..4]; a.write(b.try_into()?,&((c & 0xffffffff) as u32).to_ne_bytes())?; Ok(()) @@ -281,6 +384,6 @@ pub fn select(u: u32, t: T, t2: T) -> anyhow::Result anyhow::Result { return Ok(tuple_list::tuple_list!((a & 0xffffffff) as u32)); } -pub fn i64extend132u(a: u32) -> anyhow::Result{ +pub fn i64extend132u(a: u32) -> anyhow::Result { Ok(tuple_list::tuple_list!(a as u64)) -} \ No newline at end of file +} diff --git a/wars-rt/src/wasix.rs b/wars-rt/src/wasix.rs index e69de29..f051b14 100644 --- a/wars-rt/src/wasix.rs +++ b/wars-rt/src/wasix.rs @@ -0,0 +1,5 @@ +use crate::{CtxSpec, Memory}; + +pub trait XSpec: CtxSpec { + fn wasix_memory<'a>(&'a mut self) -> &'a mut (dyn Memory + 'a); +} diff --git a/wars-rt/src/wrl.rs b/wars-rt/src/wrl.rs index 443c963..1358454 100644 --- a/wars-rt/src/wrl.rs +++ b/wars-rt/src/wrl.rs @@ -27,6 +27,57 @@ impl MetaType { } } } +pub trait Native: Sized { + fn to_val(&self, v: &mut wasm_runtime_layer::Value); + fn val(&self) -> wasm_runtime_layer::Value { + let mut x = wasm_runtime_layer::Value::I32(0); + self.to_val(&mut x); + return x; + } + fn from_val(v: &wasm_runtime_layer::Value) -> anyhow::Result; +} +pub trait Natives: Sized { + fn to_val(&self, v: &mut [wasm_runtime_layer::Value]); + fn from_val(v: &[wasm_runtime_layer::Value]) -> anyhow::Result; +} +impl Natives for () { + fn to_val(&self, v: &mut [wasm_runtime_layer::Value]) {} + + fn from_val(v: &[wasm_runtime_layer::Value]) -> anyhow::Result { + Ok(()) + } +} +impl Natives for (T, U) { + fn to_val(&self, v: &mut [wasm_runtime_layer::Value]) { + self.0.to_val(&mut v[0]); + self.1.to_val(&mut v[1..]); + } + + fn from_val(v: &[wasm_runtime_layer::Value]) -> anyhow::Result { + Ok((T::from_val(&v[0])?, U::from_val(&v[1..])?)) + } +} +macro_rules! native { + ($t:ty as $i:ident) => { + impl Native for $t { + fn to_val(&self, v: &mut wasm_runtime_layer::Value) { + *v = wasm_runtime_layer::Value::$i(self.clone()); + } + fn from_val(v: &wasm_runtime_layer::Value) -> anyhow::Result { + match v { + wasm_runtime_layer::Value::$i(w) => Ok(w.clone()), + _ => anyhow::bail!("invalid value"), + } + } + } + }; +} +native!(i32 as I32); +native!(i64 as I64); +native!(f32 as F32); +native!(f64 as F64); +native!(Option as FuncRef); +native!(Option as ExternRef); pub fn translate_in + 'static, D: AsMut>( val: &crate::func::Value, ctx: &mut C, @@ -69,10 +120,10 @@ where }, ))) } - crate::Value::Null => match wrl_ty{ + crate::Value::Null => match wrl_ty { MetaType::ExternRef => wasm_runtime_layer::Value::ExternRef(None), MetaType::FunRef { params, returns } => wasm_runtime_layer::Value::FuncRef(None), - _ => anyhow::bail!("invalid null") + _ => anyhow::bail!("invalid null"), }, crate::Value::ExRef(e) => { wasm_runtime_layer::Value::ExternRef(Some(ExternRef::new(ctx, e.clone()))) diff --git a/wars-test/src/lib.rs b/wars-test/src/lib.rs index 5b68b78..223de07 100644 --- a/wars-test/src/lib.rs +++ b/wars-test/src/lib.rs @@ -3,6 +3,6 @@ pub fn add(left: usize, right: usize) -> usize { left + right } #[no_mangle] -pub fn memory_op(a: &str) -> String{ +pub fn memory_op(a: &str) -> String { return a.to_owned(); -} \ No newline at end of file +} diff --git a/wars/Cargo.toml b/wars/Cargo.toml index ec17fac..12b958b 100644 --- a/wars/Cargo.toml +++ b/wars/Cargo.toml @@ -7,11 +7,14 @@ edition = "2021" [dependencies] bitflags = "2.5.0" +hex = "0.4.3" + portal-pc-waffle.workspace = true proc-macro2 = "1.0.85" quasiquote = "0.1.1" quote = "1.0.36" relooper = "0.1.0" +sha3 = "0.10.8" syn = "2.0.66" waffle-func-reloop = { version = "0.1.0", path = "../waffle-func-reloop" } witx = {git="https://github.com/wasix-org/wasix-witx.git",branch="main"} diff --git a/wars/src/lib.rs b/wars/src/lib.rs index 8632030..c9291d9 100644 --- a/wars/src/lib.rs +++ b/wars/src/lib.rs @@ -1,12 +1,21 @@ -use std::{collections::BTreeMap, convert::Infallible, iter::once, sync::Arc}; +use std::{ + collections::{BTreeMap, BTreeSet}, + convert::Infallible, + f32::consts::E, + iter::once, + sync::Arc, +}; + use proc_macro2::{Span, TokenStream}; use quasiquote::quasiquote; use quote::{format_ident, quote, ToTokens}; use relooper::{reloop, BranchMode, ShapedBlock}; +use sha3::Digest; use syn::{Ident, Lifetime}; use waffle::{ - cfg::CFGInfo, entity::EntityRef, Block, BlockTarget, Export, ExportKind, Func, ImportKind, Memory, Module, Operator, Signature, SignatureData, Type, Value + cfg::CFGInfo, entity::EntityRef, Block, BlockTarget, Export, ExportKind, Func, ImportKind, + Memory, Module, Operator, Signature, SignatureData, Type, Value, }; bitflags::bitflags! { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] @@ -14,7 +23,9 @@ bitflags::bitflags! { const HOST_MEMORY = 0x1; const ASYNC = 0x2; const LEGACY = 0x4; - // const WASIX = 0x8; + const WASIX = 0x8; + const BIND = 0x10; + const PIT = 0x20; // const UNSANDBOXED = 0x2; } } @@ -70,6 +81,15 @@ impl Opts> { } }; } + if self.flags.contains(Flags::WASIX) { + if i.module == "wasi_snapshot_preview1" || i.module == "wasix_32v1" { + if i.name == "memory" { + return quote! { + ctx.wasix_memory() + }; + } + } + } } let m2 = format_ident!("{m}"); quote! { @@ -91,6 +111,36 @@ impl Opts> { } } } + if self.flags.contains(Flags::WASIX) { + if module == "wasi_snapshot_preview1" || module == "wasix_32v1" { + return quasiquote! { + #root::wasix::#{format_ident!("{name}")}(#(#params),*) + }; + } + } + if self.flags.contains(Flags::BIND) { + if module == "wars/bind" { + if name == "!!drop" { + return quasiquote! { + { + let v = self.data().rust_table.remove(#(#params),*).unwrap(); + Ok(()) + } + }; + } + let params = params.collect::>(); + return quasiquote! { + { + let v = #{syn::parse_str::(&name).unwrap()}(#(unsafe{#root::get_cell(self.data().rust_table.get(&#params)).unwrap()}),*)#{if self.flags.contains(Flags::ASYNC){ + quote!{.await} + }else{ + quote!{} + }}; + v.map(|x|(alloc(&mut self.data().rust_table,#root::any_cell(x)),())) + } + }; + } + } // if a == "fs" { // match name { // "open" => { @@ -156,6 +206,114 @@ impl Opts> { // } // } // } + if self.flags.contains(Flags::PIT) { + if let Some(i) = module.strip_prefix("pit/") { + let x: [u8; 32] = hex::decode(i).unwrap().try_into().unwrap(); + if let Some(s) = name.strip_prefix("~") { + let s = { + let mut h = sha3::Sha3_256::default(); + h.update(s); + h.finalize() + }; + return quasiquote! { + #{self.fp()}::ret(Ok(#{self.fp()}::Value::::ExternRef(#root::Pit{ + id: [#(#x),*], + x: #{self.fp()}::CoeVec::coe(#root::tuple_list::tuple_list!(#(#params),*)), + s: [#(#s),*], + }.into()))) + }; + } + + let mut f = params.next().unwrap(); + // let id = format_ident!("{}", bindname(&format!("pit/{i}/~{PIT_NS}/{name}"))); + // ctx.#id(x.x,#(#params),*) + let params = params.collect::>(); + let cases = self + .module + .exports + .iter() + .filter_map(|x| x.name.strip_prefix(&format!("pit/{i}/~"))) + .filter_map(|x| x.strip_suffix(&format!("/{name}"))) + .map(|s| { + let id = format_ident!("{}", bindname(&format!("pit/{i}/~{s}/{name}"))); + let s = { + let mut h = sha3::Sha3_256::default(); + h.update(s); + h.finalize() + }; + quasiquote! { + [#(#s),*] => { + let mut y = #{self.fp()}::CoeVec::coe(#root::tuple_list::tuple_list!(#(#params),*)); + y.extend(&mut x.x.clone()); + ctx.#id(#{self.fp()}::CoeVec::uncoe(y)) + } + } + }); + return quasiquote! { + 'a: { + let x = #f; + let #{self.fp()}::Value::::ExternRef(x) = x else{ + break 'a #{self.fp()}::ret(Err(#root::_rexport::anyhow::anyhow!("not an externref"))) + }; + let Ok(x) = x.try_into() else{ + break 'a #{self.fp()}::ret(Err(#root::_rexport::anyhow::anyhow!("not a pit externref"))) + }; + let x: #root::Pit = x; + match x.s{ + #(#cases),*, + _ => break 'a #{self.fp()}::ret(Err(#root::_rexport::anyhow::anyhow!("invalid target"))) + } + } + }; + } + if module == "pit" && name == "drop" { + let mut f = params.next().unwrap(); + let cases = self + .module + .exports + .iter() + .filter_map(|x| { + let x = x.name.as_str(); + let x = x.strip_prefix("pit/")?; + let (a, x) = x.split_once("/~")?; + let s = x.strip_suffix(".drop")?; + return Some((a, s)); + }) + .map(|(a, s)| { + let x = hex::decode(a).unwrap(); + let id = format_ident!("{}", bindname(&format!("pit/{a}/~{s}.drop"))); + let s = { + let mut h = sha3::Sha3_256::default(); + h.update(s); + h.finalize() + }; + // let id = format_ident!( + // "{}", + // bindname(&format!("pit/{}/~{PIT_NS}.drop", i.rid_str())) + // ); ctx.#id(x.x) + quasiquote!( + ([#(#x),*],[#(#s),*]) => ctx.#id(#{self.fp()}::CoeVec::uncoe(x.x)) + ) + }); + return quasiquote! { + 'a: { + let x = #f; + let #{self.fp()}::Value::::ExternRef(x) = x else{ + break 'a #{self.fp()}::ret(Ok(())); + }; + if let Ok(x) = x.try_into(){ + let x: #root::Pit = x; + break 'a match (x.id,x.s){ + #(#cases),*, + _ => #{self.fp()}::ret(Ok(())) + } + }else{ + break 'a #{self.fp()}::ret(Ok(())) + } + } + }; + } + }; let id = format_ident!("{}_{}", bindname(module), bindname(name)); return quote! { ctx.#id(#(#params),*) @@ -220,7 +378,7 @@ impl Opts> { .enumerate() .map(|(a, _)| format_ident!("p{a}")); let returns = data.returns.iter().map(|x| self.render_ty(&ctx, *x)); - if self.flags.contains(Flags::ASYNC) { + let mut x = if self.flags.contains(Flags::ASYNC) { quote! { fn #name<'a,C: #base + 'static>(ctx: &'a mut C, #root::_rexport::tuple_list::tuple_list!(#(#param_ids),*): #root::_rexport::tuple_list::tuple_list_type!(#(#params),*)) -> #root::func::unsync::AsyncRec<'a,#root::_rexport::anyhow::Result<#root::_rexport::tuple_list::tuple_list_type!(#(#returns),*)>> } @@ -228,7 +386,17 @@ impl Opts> { quote! { fn #name<'a,C: #base + 'static>(ctx: &'a mut C, #root::_rexport::tuple_list::tuple_list!(#(#param_ids),*): #root::_rexport::tuple_list::tuple_list_type!(#(#params),*)) -> #root::_rexport::tramp::BorrowRec<'a,#root::_rexport::anyhow::Result<#root::_rexport::tuple_list::tuple_list_type!(#(#returns),*)>> } + }; + if let Some(t) = self.roots.get("tracing") { + x = quote! { + #[#t::instrument] + #x + }; } + return x; + } + pub fn fname(&self, a: Func) -> Ident { + format_ident!("{a}_{}", bindname(self.module.funcs[a].name())) } pub fn render_fun_ref(&self, ctx: &TokenStream, x: Func) -> TokenStream { let root = self.crate_path.clone(); @@ -239,7 +407,7 @@ impl Opts> { } let generics = self.render_generics(ctx, &self.module.signatures[self.module.funcs[x].sig()]); - let x = format_ident!("{x}"); + let x = self.fname(x); quasiquote! { #{self.fp()}::da::<#generics,C,_>(|ctx,arg|#x(ctx,arg)) } @@ -387,7 +555,7 @@ impl Opts> { Operator::Call { function_index } => { match self.module.funcs[*function_index].body(){ Some(_) => { - let func = format_ident!("{function_index}"); + let func = self.fname(*function_index); let vals = vals.iter().map(|a|format_ident!("{a}")); quasiquote! { { @@ -523,7 +691,7 @@ impl Opts> { Ok(a) => a, Err(e) => return #{self.fp()}::ret(Err(e)) }) / 65536; - match #root::Memory::grow(ctx.#m(),(#a .clone() as usize) * 65536){ + match #root::Memory::grow(ctx.#m(),(#a .clone() as u64) * 65536){ Ok(a) => a, Err(e) => return #{self.fp()}::ret(Err(e)) }; @@ -539,8 +707,8 @@ impl Opts> { let len = format_ident!("{}",vals[2].to_string()); quote!{ { - let m = #src[(#src_ptr as usize)..][..(#len as usize)].to_owned(); - #dst[(#dst_ptr as usize)..][..(#len as usize)].copy_from_slice(&m); + let m = #src.read(#src_ptr as u64,#len as u64)?.as_ref().as_ref().to_owned(); + #dst.write(#dst_ptr as u64,&m)?; () } } @@ -779,7 +947,7 @@ impl Opts> { #{self.fp()}::cast::<_,_,C>(#a) } }); - let func = format_ident!("{func}"); + let func = self.fname(*func); if self.flags.contains(Flags::ASYNC) { quote! { #func(ctx,#root::_rexport::tuple_list::tuple_list!(#(#values),*)) @@ -948,7 +1116,7 @@ impl Opts> { } } pub fn render_fn(&self, f: Func) -> TokenStream { - let name = format_ident!("{f}"); + let name = self.fname(f); let sig = self.render_fn_sig( name.clone(), &self.module.signatures[self.module.funcs[f].sig()], @@ -1075,6 +1243,7 @@ impl Opts> { } } } +#[derive(Clone)] pub struct Opts { pub crate_path: syn::Path, pub module: B, @@ -1082,6 +1251,7 @@ pub struct Opts { pub flags: Flags, pub embed: TokenStream, pub data: BTreeMap, + pub roots: BTreeMap, // pub cfg: Arc, } impl> Opts { @@ -1104,6 +1274,7 @@ impl> Opts { flags: opts.flags, embed: opts.embed.clone(), data: opts.data.clone(), + roots: opts.roots.clone(), // cfg: opts.cfg.clone(), }; return opts; @@ -1115,6 +1286,20 @@ impl ToTokens for Opts> { } } pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { + // let mut opts = opts.clone(); + // let is = if opts.flags.contains(Flags::PIT) { + // pit_patch::get_interfaces(&opts.module) + // .unwrap() + // .into_iter() + // .collect::>() + // } else { + // Default::default() + // }; + // if opts.flags.contains(Flags::PIT) { + // for x in is.iter() { + // pit_patch::canon::canon(&mut opts.module, &x.rid_str(), PIT_NS).unwrap(); + // } + // } // let mut module = waffle::Module::from_wasm_bytes(&opts.module, &Default::default()).unwrap(); // module.expand_all_funcs().unwrap(); // let mut module = module.without_orig_bytes(); @@ -1135,6 +1320,7 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { let funcs = opts.module.funcs.iter().map(|a| opts.render_fn(a)); let mut z = vec![]; let mut fields = vec![]; + let mut sfields = vec![]; let mut fs = vec![]; fs.push(opts.embed.clone()); for (k, v) in opts.data.iter() { @@ -1143,6 +1329,13 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { #k : #v }); } + if (opts.flags.contains(Flags::BIND)) { + let k = format_ident!("rust_table"); + fields.push(k.clone()); + z.push(quote! { + #k: ::std::collections::BTreeMap, + }) + } let mut init = vec![]; for (t, d) in opts.module.tables.entries() { // let dty = opts.render_ty("e! {Target}, d.ty.clone()); @@ -1151,6 +1344,7 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { #n: Vec<#{opts.fp()}::Value> }); fields.push(n.clone()); + sfields.push(n.clone()); if let Some(e) = d.func_elements.as_ref() { let e = e.iter().map(|x| opts.render_fun_ref("e! {C}, *x)); init.push(if opts.flags.contains(Flags::ASYNC) { @@ -1177,6 +1371,7 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { #n : #t }); fields.push(n.clone()); + sfields.push(n.clone()); fs.push(quote! { fn #n<'a>(&'a mut self) -> &'a mut #t{ return &mut self.data().#n; @@ -1208,32 +1403,50 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { let n = Ident::new(&me.to_string(), Span::call_site()); match import { None => { + let mut t = quote! { + Vec + }; + if d.shared { + t = quote! { + ::std::sync::Arc<::std::lock::Mutex<#t>> + }; + }; z.push(quote! { - #n : Vec + #n : #t }); fields.push(n.clone()); fs.push(quote! { - fn #n<'a>(&'a mut self) -> &'a mut Vec{ + fn #n<'a>(&'a mut self) -> &'a mut #t{ return &mut self.data().#n; } }); } Some((a, b)) => { if a == "!!unsafe" && b == "host" && opts.flags.contains(Flags::HOST_MEMORY) { + } else if (a == "wasi_snapshot_preview1" || a == "wasix_32v1") + && b == "memory" + && opts.flags.contains(Flags::WASIX) + { + } else if a.starts_with("pit") && opts.flags.contains(Flags::PIT) { } else { // let a = bindname(&a); // let b = bindname(&b); let m = Ident::new(&format!("{a}_{b}"), Span::call_site()); - let p = if opts.flags.contains(Flags::LEGACY) { - quote! {dyn #root::Memory} + let mut p = if opts.flags.contains(Flags::LEGACY) { + quote! {dyn #root::Memory + 'a} } else { quote! { - impl #root::Memory + impl #root::Memory + 'a } }; + if d.shared { + p = quote! { + ::std::sync::Arc<::std::lock::Mutex<#p>> + }; + }; fs.push(quote! { - fn #m<'a>(&'a mut self) -> &'a mut #p; - fn #n<'a>(&'a mut self) -> &'a mut #p{ + fn #m<'a>(&'a mut self) -> &'a mut (#p); + fn #n<'a>(&'a mut self) -> &'a mut (#p){ return self.#m(); } }); @@ -1242,8 +1455,9 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { } let pk = d.initial_pages * 65536; init.push(quote! { - let l = #pk.max(ctx.#n().len()); - ctx.#n().resize(l,0); + let l = #pk.max(ctx.#n().size()?); + let s = ctx.#n().size()?; + ctx.#n().grow(l - s)?; }); for s in d.segments.clone() { for (i, d) in s.data.chunks(65536).enumerate() { @@ -1260,22 +1474,22 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { // let out_str = out.to_str().unwrap().to_owned(); // eprintln!("emuitting data"); init.push(quote! { - ctx.#n()[#o..#pk].copy_from_slice(&[#(#d),*]) + ctx.#n().write(#o,&[#(#d),*])? }); } } } for xp in opts.module.exports.iter() { - let xp = Export{ + let xp = Export { name: bindname(&xp.name), - kind: xp.kind.clone() + kind: xp.kind.clone(), }; match &xp.kind { ExportKind::Func(f) => { let f = *f; let d = opts.render_self_sig( format_ident!("{}", xp.name), - format_ident!("{f}"), + opts.fname(f), &opts.module.signatures[opts.module.funcs[f].sig()], ); fs.push(quote! { @@ -1310,13 +1524,21 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { let x = Ident::new(&m.to_string(), Span::call_site()); let mn = Ident::new(&xp.name, Span::call_site()); let i = quasiquote! { - fn #mn(&mut self) -> &mut #{if opts.flags.contains(Flags::LEGACY) { - quote! {dyn #root::Memory} - } else { - quote! { - impl #root::Memory - } - }}{ + fn #mn<'a>(&'a mut self) -> &'a mut (#{ + let mut p = if opts.flags.contains(Flags::LEGACY) { + quote! {dyn #root::Memory + 'a} + } else { + quote! { + impl #root::Memory + 'a + } + }; + if opts.module.memories[*m].shared{ + p = quote!{ + ::std::sync::Arc<::std::lock::Mutex<#p>> + }; + }; + p + }){ return self.#x() } }; @@ -1328,6 +1550,21 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { if i.module.starts_with(INTRINSIC) { continue; } + if opts.flags.contains(Flags::WASIX) { + if i.module == "wasi_snapshot_preview1" || i.module == "wasix_32v1" { + continue; + } + } + if opts.flags.contains(Flags::BIND) { + if i.module == "wars/bind" { + continue; + } + } + if opts.flags.contains(Flags::PIT) { + if i.module.starts_with("pit") { + continue; + } + } if let ImportKind::Func(f) = &i.kind { let name = format_ident!("{}_{}", bindname(&i.module), bindname(&i.name)); fs.push(opts.render_self_sig_import( @@ -1370,6 +1607,8 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { quasiquote! { mod #internal_path{ #(#funcs)* + use #root::Memory; + use #root::AnyCell; pub fn alloc(m: &mut ::std::collections::BTreeMap, x: T) -> u32{ let mut u = 0; while m.contains_key(&u){ @@ -1381,11 +1620,38 @@ pub fn go(opts: &Opts>) -> proc_macro2::TokenStream { pub struct #data{ #(#z),* } - pub trait #name: #{opts.fp()}::CtxSpec #{if opts.flags.contains(Flags::ASYNC){ + impl #root::Traverse for #data{ + fn traverse<'a>(&'a self) -> Box + 'a>{ + return #{ + let x = sfields.iter().map(|a|quote!{#root::Traverse::::traverse(&self.#a)}); + quote!{ + Box::new(::std::iter::empty()#(.chain(#x))*) + } + } + } + fn traverse_mut<'a>(&'a mut self) -> Box + 'a>{ + return #{ + let x = sfields.iter().map(|a|quote!{#root::Traverse::::traverse_mut(&mut self.#a)}); + quote!{ + Box::new(::std::iter::empty()#(.chain(#x))*) + } + } + } + } + pub trait #name: #{opts.fp()}::CtxSpec #{if opts.flags.contains(Flags::ASYNC){ quote! {+ Send + Sync} }else{ quote! {} + }} #{if opts.flags.contains(Flags::WASIX){ + quote!{+ #root::wasix::XSpec} + }else{ + quote! {} }}{ + type _ExternRef: Clone #{if opts.flags.contains(Flags::PIT){ + quote!{+ From<#root::Pit>>> + TryInto<#root::Pit>>>} + }else{ + quote!{} + }}; fn data(&mut self) -> &mut #data; #(#fs)* diff --git a/wasm-compile-layer/Cargo.toml b/wasm-compile-layer/Cargo.toml new file mode 100644 index 0000000..a481bab --- /dev/null +++ b/wasm-compile-layer/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "wasm-compile-layer" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.86" +portal-pc-waffle.workspace = true +proc-macro2 = "1.0.86" +quasiquote = "0.1.1" +quote = "1.0.36" +relooper = "0.1.0" +syn = "2.0.67" +waffle-func-reloop = { version = "0.1.0", path = "../waffle-func-reloop" } +wars = { version = "0.1.0", path = "../wars" } diff --git a/wasm-compile-layer/src/lib.rs b/wasm-compile-layer/src/lib.rs new file mode 100644 index 0000000..5acac0c --- /dev/null +++ b/wasm-compile-layer/src/lib.rs @@ -0,0 +1,16 @@ +use quote::format_ident; +use syn::Ident; +use waffle::{entity::EntityRef, Block, Func, Module}; + +pub fn mangle(m: &Module, f: Func, mut b: Block) -> Ident { + if let Some(d) = m.funcs[f].body() { + if d.entry == b { + b = Block::invalid() + } + } + format_ident!("{f}_{b}") +} + +pub struct Compiler<'a> { + pub module: &'a Module<'static>, +}