From f7f169cc66616795480c1b212877c4bf94ee43fa Mon Sep 17 00:00:00 2001 From: Brian H Date: Thu, 2 Mar 2023 16:30:41 -0500 Subject: [PATCH] feat: preliminary support for WIT templates This is a minimum viable implementation of WIT templates per https://github.com/WebAssembly/component-model/issues/172. It supports interfaces with at most one wildcard function, which may be expanded (i.e. monomorphized) with a set of substitutions provided by the application developer when generating guest bindings. Signed-off-by: Joel Dice --- Cargo.lock | 274 +++++++++++++-------- Cargo.toml | 14 +- crates/rust-macro/Cargo.toml | 1 + crates/rust-macro/src/lib.rs | 52 +++- crates/test-rust-wasm/Cargo.toml | 4 + crates/test-rust-wasm/src/bin/wildcards.rs | 3 + src/bin/wit-bindgen.rs | 17 +- tests/runtime/main.rs | 1 + tests/runtime/wildcards.rs | 52 ++++ tests/runtime/wildcards/substitutions.toml | 3 + tests/runtime/wildcards/wasm.rs | 21 ++ tests/runtime/wildcards/world.wit | 8 + 12 files changed, 334 insertions(+), 116 deletions(-) create mode 100644 crates/test-rust-wasm/src/bin/wildcards.rs create mode 100644 tests/runtime/wildcards.rs create mode 100644 tests/runtime/wildcards/substitutions.toml create mode 100644 tests/runtime/wildcards/wasm.rs create mode 100644 tests/runtime/wildcards/world.wit diff --git a/Cargo.lock b/Cargo.lock index 5df37f3b0..42560fe5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,18 +187,16 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862eb053fc21f991db27c73bc51494fe77aadfa09ea257cb43b62a2656fd4cc1" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038a74bc85da2f6f9e237c51b7998b47229c0f9da69b4c6b0590cf6621c45d46" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "bumpalo", "cranelift-bforest", @@ -216,33 +214,29 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fb720a7955cf7cc92c58f3896952589062e6f12d8eb35ef4337e708ed2e738" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0954f9426cf0fa7ad57910ea5822a09c5da590222a767a6c38080a8534a0af8" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" [[package]] name = "cranelift-entity" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c7096c1a66cfa73899645f0a46a6f5c91641e678eeafb0fc47a19ab34069ca" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697f2fdaceb228fea413ea91baa7c6b8533fc2e61ac5a08db7acc1b31e673a2a" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cranelift-codegen", "log", @@ -252,15 +246,13 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41037f4863e0c6716dbe60e551d501f4197383cb43d75038c0170159fc8fb5b" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" [[package]] name = "cranelift-native" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "797c6e5643eb654bb7bf496f1f03518323a89b937b84020b786620f910364a52" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cranelift-codegen", "libc", @@ -269,9 +261,8 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.94.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b5fae12cefda3a2c43837e562dd525ab1d75b27989eece66de5b2c8fe120f9" +version = "0.95.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -279,7 +270,7 @@ dependencies = [ "itertools", "log", "smallvec", - "wasmparser 0.100.0", + "wasmparser 0.102.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmtime-types", ] @@ -1001,6 +992,15 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_spanned" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + [[package]] name = "sha2" version = "0.10.6" @@ -1071,8 +1071,8 @@ name = "test-helpers" version = "0.0.0" dependencies = [ "codegen-macro", - "wasm-encoder 0.25.0", - "wat", + "wasm-encoder 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wat 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", "wit-bindgen-core", "wit-component", "wit-parser", @@ -1139,6 +1139,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "typenum" version = "1.16.0" @@ -1237,9 +1271,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.23.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c3e4bc09095436c8e7584d86d33e6c3ee67045af8fb262cbb9cc321de553428" +checksum = "4eff853c4f09eec94d76af527eddad4e9de13b11d6286a1ef7134bc30135a2b7" dependencies = [ "leb128", ] @@ -1247,8 +1281,7 @@ dependencies = [ [[package]] name = "wasm-encoder" version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eff853c4f09eec94d76af527eddad4e9de13b11d6286a1ef7134bc30135a2b7" +source = "git+https://github.com/dicej/wasm-tools?branch=wit-templates#8095934efc132fbdc4db82b7f0882a78a97817a5" dependencies = [ "leb128", ] @@ -1256,21 +1289,20 @@ dependencies = [ [[package]] name = "wasm-metadata" version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6956efd8a1a2c48a707e9a1b2da729834a0f8e4c58117493b0d9d089cee468" +source = "git+https://github.com/dicej/wasm-tools?branch=wit-templates#8095934efc132fbdc4db82b7f0882a78a97817a5" dependencies = [ "anyhow", "indexmap", "serde", - "wasm-encoder 0.25.0", - "wasmparser 0.102.0", + "wasm-encoder 0.25.0 (git+https://github.com/dicej/wasm-tools?branch=wit-templates)", + "wasmparser 0.102.0 (git+https://github.com/dicej/wasm-tools?branch=wit-templates)", ] [[package]] name = "wasmparser" -version = "0.100.0" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b20236ab624147dfbb62cf12a19aaf66af0e41b8398838b66e997d07d269d4" +checksum = "48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b" dependencies = [ "indexmap", "url", @@ -1279,8 +1311,7 @@ dependencies = [ [[package]] name = "wasmparser" version = "0.102.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b" +source = "git+https://github.com/dicej/wasm-tools?branch=wit-templates#8095934efc132fbdc4db82b7f0882a78a97817a5" dependencies = [ "indexmap", "url", @@ -1288,19 +1319,18 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.2.53" +version = "0.2.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa44d546e4e4479f2e91035fa497c0a05cffbf22413ad05bf0b06a789b9118f" +checksum = "2dc17ae63836d010a2bf001c26a5fedbb9a05e5f71117fb63e0ab878bfbe1ca3" dependencies = [ "anyhow", - "wasmparser 0.102.0", + "wasmparser 0.102.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmtime" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d137f87df6e037b2bcb960c2db7ea174e04fb897051380c14b5e5475a870669e" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "anyhow", "async-trait", @@ -1317,7 +1347,7 @@ dependencies = [ "rayon", "serde", "target-lexicon", - "wasmparser 0.100.0", + "wasmparser 0.102.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmtime-cache", "wasmtime-component-macro", "wasmtime-component-util", @@ -1326,24 +1356,22 @@ dependencies = [ "wasmtime-fiber", "wasmtime-jit", "wasmtime-runtime", - "wat", + "wat 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", "windows-sys", ] [[package]] name = "wasmtime-asm-macros" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad63d4175d6af44af2046186c87deae4e9a8150b92de2d4809c6f745d5ee9b38" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-cache" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3055fb327f795b4639f47b9dadad9d3d9b185fd3001adf8db08f5fa06d07032" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "anyhow", "base64", @@ -1354,16 +1382,15 @@ dependencies = [ "rustix", "serde", "sha2", - "toml", + "toml 0.5.11", "windows-sys", "zstd", ] [[package]] name = "wasmtime-component-macro" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cf4906f990d6ab3065d042cf5a15eb7a2a5406d1c001a45ab9615de876458a" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "anyhow", "proc-macro2", @@ -1376,15 +1403,13 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ccf49c18c1ce3f682310e642dcdc00ffc67f1ce0767c89a16fc8fcf5eaeb97" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" [[package]] name = "wasmtime-cranelift" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "274590ecbb1179d45a5c8d9f54b9d236e9414d9ca3b861cd8956cec085508eb0" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "anyhow", "cranelift-codegen", @@ -1397,15 +1422,29 @@ dependencies = [ "object", "target-lexicon", "thiserror", - "wasmparser 0.100.0", + "wasmparser 0.102.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmtime-cranelift-shared", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-cranelift-shared" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-native", + "gimli", + "object", + "target-lexicon", "wasmtime-environ", ] [[package]] name = "wasmtime-environ" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b4a897e6ce1f2567ba98e7b1948c0e12cae1202fd88e7639f901b8ce9203f7" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "anyhow", "cranelift-entity", @@ -1416,8 +1455,8 @@ dependencies = [ "serde", "target-lexicon", "thiserror", - "wasm-encoder 0.23.0", - "wasmparser 0.100.0", + "wasm-encoder 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.102.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmprinter", "wasmtime-component-util", "wasmtime-types", @@ -1425,9 +1464,8 @@ dependencies = [ [[package]] name = "wasmtime-fiber" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b1192624694399f601de28db78975ed20fa859da8e048bf8250bd3b38d302b" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cc", "cfg-if", @@ -1438,9 +1476,8 @@ dependencies = [ [[package]] name = "wasmtime-jit" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f035bfe27ce5129c9d081d6288480f2e6ae9d16d0eb035a5d9e3b5b6c36658" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "addr2line", "anyhow", @@ -1463,9 +1500,8 @@ dependencies = [ [[package]] name = "wasmtime-jit-debug" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17e35d335dd2461c631ba24d2326d993bd3a4bdb4b0217e5bda4f518ba0e29f3" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "object", "once_cell", @@ -1474,9 +1510,8 @@ dependencies = [ [[package]] name = "wasmtime-jit-icache-coherence" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8c01a070f55343f7afd309a9609c12378548b26c3f53c599bc711bb1ce42ee" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cfg-if", "libc", @@ -1485,9 +1520,8 @@ dependencies = [ [[package]] name = "wasmtime-runtime" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac02cc14c8247f6e4e48c7653a79c226babac8f2cacdd933d3f15ca2a6ab20b" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "anyhow", "cc", @@ -1511,21 +1545,19 @@ dependencies = [ [[package]] name = "wasmtime-types" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8dc0062ab053e1aa22d2355a2de4df482a0007fecae82ea02cc596c2329971d" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "cranelift-entity", "serde", "thiserror", - "wasmparser 0.100.0", + "wasmparser 0.102.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmtime-wit-bindgen" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd2cf93f3c8a6f443d8a9098fddc5fd887783c0fe725dc10c54ca9280546421d" +version = "8.0.0" +source = "git+https://github.com/dicej/wasmtime?branch=wit-templates-minimal#46e1c2af9132beb51354f286703f1de64d5df566" dependencies = [ "anyhow", "heck", @@ -1541,7 +1573,18 @@ dependencies = [ "leb128", "memchr", "unicode-width", - "wasm-encoder 0.25.0", + "wasm-encoder 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wast" +version = "55.0.0" +source = "git+https://github.com/dicej/wasm-tools?branch=wit-templates#8095934efc132fbdc4db82b7f0882a78a97817a5" +dependencies = [ + "leb128", + "memchr", + "unicode-width", + "wasm-encoder 0.25.0 (git+https://github.com/dicej/wasm-tools?branch=wit-templates)", ] [[package]] @@ -1550,7 +1593,15 @@ version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af2b53f4da14db05d32e70e9c617abdf6620c575bd5dd972b7400037b4df2091" dependencies = [ - "wast", + "wast 55.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wat" +version = "1.0.61" +source = "git+https://github.com/dicej/wasm-tools?branch=wit-templates#8095934efc132fbdc4db82b7f0882a78a97817a5" +dependencies = [ + "wast 55.0.0 (git+https://github.com/dicej/wasm-tools?branch=wit-templates)", ] [[package]] @@ -1650,6 +1701,15 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "winnow" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.4.0" @@ -1666,7 +1726,7 @@ dependencies = [ "clap", "heck", "test-helpers", - "wasm-encoder 0.25.0", + "wasm-encoder 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -1680,9 +1740,10 @@ dependencies = [ "clap", "heck", "test-artifacts", - "wasm-encoder 0.25.0", + "toml 0.7.3", + "wasm-encoder 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmtime", - "wat", + "wat 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", "wit-bindgen-c", "wit-bindgen-core", "wit-bindgen-go", @@ -1754,6 +1815,7 @@ dependencies = [ "anyhow", "proc-macro2", "syn", + "toml 0.7.3", "wit-bindgen-core", "wit-bindgen-rust", "wit-component", @@ -1773,27 +1835,25 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e93680c292afbad08ec462c901714ba53e5109076003e53a82e584f3aa319bc" +version = "0.7.4" +source = "git+https://github.com/dicej/wasm-tools?branch=wit-templates#8095934efc132fbdc4db82b7f0882a78a97817a5" dependencies = [ "anyhow", "bitflags", "indexmap", "log", "url", - "wasm-encoder 0.25.0", + "wasm-encoder 0.25.0 (git+https://github.com/dicej/wasm-tools?branch=wit-templates)", "wasm-metadata", - "wasmparser 0.102.0", - "wat", + "wasmparser 0.102.0 (git+https://github.com/dicej/wasm-tools?branch=wit-templates)", + "wat 1.0.61 (git+https://github.com/dicej/wasm-tools?branch=wit-templates)", "wit-parser", ] [[package]] name = "wit-parser" version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f887c3da527a51b321076ebe6a7513026a4757b6d4d144259946552d6fc728b3" +source = "git+https://github.com/dicej/wasm-tools?branch=wit-templates#8095934efc132fbdc4db82b7f0882a78a97817a5" dependencies = [ "anyhow", "id-arena", diff --git a/Cargo.toml b/Cargo.toml index e1b29a49d..283efcde7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,8 +32,8 @@ indexmap = "1.9.1" wasm-encoder = "0.25.0" wasm-metadata = "0.3.1" wat = "1.0.61" -wit-parser = "0.6.3" -wit-component = "0.7.2" +wit-parser = "0.6.4" +wit-component = "0.7.3" wit-bindgen-core = { path = 'crates/core', version = '0.4.0' } wit-bindgen-c = { path = 'crates/c', version = '0.4.0' } @@ -60,6 +60,7 @@ wit-bindgen-go = { workspace = true, features = ['clap'], optional = true } wat = { workspace = true } wit-component = { workspace = true } wasm-encoder = { workspace = true } +toml = "0.7.2" [features] default = ['c', 'rust', 'markdown', 'teavm-java', 'go'] @@ -71,6 +72,13 @@ go = ['dep:wit-bindgen-go'] [dev-dependencies] heck = { workspace = true } -wasmtime = { version = "7", features = ['component-model'] } +wasmtime = { version = "8", features = ['component-model'] } test-artifacts = { path = 'crates/test-rust-wasm/artifacts' } wit-parser = { workspace = true } + +[patch.crates-io] +wit-component = { git = "https://github.com/dicej/wasm-tools", branch = "wit-templates" } +wit-parser = { git = "https://github.com/dicej/wasm-tools", branch = "wit-templates" } +wasm-metadata = { git = "https://github.com/dicej/wasm-tools", branch = "wit-templates" } +wasmtime = { git = "https://github.com/dicej/wasmtime", branch = "wit-templates-minimal" } +wasmtime-wit-bindgen = { git = "https://github.com/dicej/wasmtime", branch = "wit-templates-minimal" } diff --git a/crates/rust-macro/Cargo.toml b/crates/rust-macro/Cargo.toml index 45c47406c..4e5ce17a1 100644 --- a/crates/rust-macro/Cargo.toml +++ b/crates/rust-macro/Cargo.toml @@ -22,3 +22,4 @@ wit-bindgen-core = { workspace = true } wit-bindgen-rust = { workspace = true } wit-component = { workspace = true } anyhow = { workspace = true } +toml = "0.7.2" diff --git a/crates/rust-macro/src/lib.rs b/crates/rust-macro/src/lib.rs index aec0f050c..f0cf10ac6 100644 --- a/crates/rust-macro/src/lib.rs +++ b/crates/rust-macro/src/lib.rs @@ -1,9 +1,10 @@ use proc_macro2::{Span, TokenStream}; +use std::fs; use std::path::{Path, PathBuf}; use syn::parse::{Error, Parse, ParseStream, Result}; use syn::punctuated::Punctuated; use syn::{token, Token}; -use wit_bindgen_core::wit_parser::{PackageId, Resolve, UnresolvedPackage, WorldId}; +use wit_bindgen_core::wit_parser::{self, PackageId, Resolve, UnresolvedPackage, WorldId}; use wit_bindgen_rust::Opts; #[proc_macro] @@ -32,6 +33,7 @@ impl Parse for Config { let mut opts = Opts::default(); let mut world = None; let mut source = None; + let mut substitutions = None; if input.peek(token::Brace) { let content; @@ -57,6 +59,24 @@ impl Parse for Config { } source = Some(Source::Inline(s.value())); } + Opt::SubstitutionsPath(s) => { + if substitutions.is_some() { + return Err(Error::new( + s.span(), + "cannot specify second substitutions", + )); + } + substitutions = Some(Source::Path(s.value())); + } + Opt::SubstitutionsInline(s) => { + if substitutions.is_some() { + return Err(Error::new( + s.span(), + "cannot specify second substitutions", + )); + } + substitutions = Some(Source::Inline(s.value())); + } Opt::UseStdFeature => opts.std_feature = true, Opt::RawStrings => opts.raw_strings = true, Opt::MacroExport => opts.macro_export = true, @@ -71,8 +91,8 @@ impl Parse for Config { source = Some(Source::Path(input.parse::()?.value())); } } - let (resolve, pkg, files) = - parse_source(&source).map_err(|err| Error::new(call_site, format!("{err:?}")))?; + let (resolve, pkg, files) = parse_source(&source, &substitutions) + .map_err(|err| Error::new(call_site, format!("{err:?}")))?; let world = resolve .select_world(pkg, world.as_deref()) .map_err(|e| Error::new(call_site, format!("{e:?}")))?; @@ -85,7 +105,10 @@ impl Parse for Config { } } -fn parse_source(source: &Option) -> anyhow::Result<(Resolve, PackageId, Vec)> { +fn parse_source( + source: &Option, + substitutions: &Option, +) -> anyhow::Result<(Resolve, PackageId, Vec)> { let mut resolve = Resolve::default(); let mut files = Vec::new(); let root = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); @@ -108,7 +131,14 @@ fn parse_source(source: &Option) -> anyhow::Result<(Resolve, PackageId, Some(Source::Path(s)) => parse(&root.join(&s))?, None => parse(&root.join("wit"))?, }; - + match substitutions { + Some(Source::Inline(s)) => wit_parser::expand(&mut resolve, toml::from_str(s)?)?, + Some(Source::Path(s)) => wit_parser::expand( + &mut resolve, + toml::from_str(&fs::read_to_string(&root.join(&s))?)?, + )?, + None => (), + } Ok((resolve, pkg, files)) } @@ -146,12 +176,16 @@ mod kw { syn::custom_keyword!(world); syn::custom_keyword!(path); syn::custom_keyword!(inline); + syn::custom_keyword!(substitutions_path); + syn::custom_keyword!(substitutions_inline); } enum Opt { World(syn::LitStr), Path(syn::LitStr), Inline(syn::LitStr), + SubstitutionsPath(syn::LitStr), + SubstitutionsInline(syn::LitStr), UseStdFeature, RawStrings, MacroExport, @@ -171,6 +205,14 @@ impl Parse for Opt { input.parse::()?; input.parse::()?; Ok(Opt::Inline(input.parse()?)) + } else if l.peek(kw::substitutions_path) { + input.parse::()?; + input.parse::()?; + Ok(Opt::SubstitutionsPath(input.parse()?)) + } else if l.peek(kw::substitutions_inline) { + input.parse::()?; + input.parse::()?; + Ok(Opt::SubstitutionsInline(input.parse()?)) } else if l.peek(kw::world) { input.parse::()?; input.parse::()?; diff --git a/crates/test-rust-wasm/Cargo.toml b/crates/test-rust-wasm/Cargo.toml index c8e149160..e2d321ea8 100644 --- a/crates/test-rust-wasm/Cargo.toml +++ b/crates/test-rust-wasm/Cargo.toml @@ -47,3 +47,7 @@ test = false [[bin]] name = "results" test = false + +[[bin]] +name = "wildcards" +test = false diff --git a/crates/test-rust-wasm/src/bin/wildcards.rs b/crates/test-rust-wasm/src/bin/wildcards.rs new file mode 100644 index 000000000..9f0328961 --- /dev/null +++ b/crates/test-rust-wasm/src/bin/wildcards.rs @@ -0,0 +1,3 @@ +include!("../../../../tests/runtime/wildcards/wasm.rs"); + +fn main() {} diff --git a/src/bin/wit-bindgen.rs b/src/bin/wit-bindgen.rs index 3698721b5..ab1ee2f6e 100644 --- a/src/bin/wit-bindgen.rs +++ b/src/bin/wit-bindgen.rs @@ -1,7 +1,7 @@ use anyhow::{bail, Context, Result}; use clap::Parser; use std::path::PathBuf; -use std::str; +use std::{fs, str}; use wit_bindgen_core::{wit_parser, Files, WorldGenerator}; use wit_parser::{Resolve, UnresolvedPackage}; @@ -78,6 +78,10 @@ struct Common { /// they're up-to-date with the source files. #[clap(long)] check: bool, + + /// Path to template substitutions for expansion. + #[clap(long)] + expand: Option, } fn main() -> Result<()> { @@ -143,6 +147,15 @@ fn gen_world( opts: &Common, files: &mut Files, ) -> Result<()> { + let substitutions = match &opts.expand { + Some(path) => { + let input = + fs::read_to_string(path).context("failed to read substitutions from file")?; + toml::from_str(&input).context("failed to parse substitutions from TOML")? + } + None => Default::default(), + }; + let mut resolve = Resolve::default(); let pkg = if opts.wit.is_dir() { resolve.push_dir(&opts.wit)?.0 @@ -152,6 +165,8 @@ fn gen_world( &Default::default(), )? }; + + wit_parser::expand(&mut resolve, substitutions)?; let world = resolve.select_world(pkg, opts.world.as_deref())?; generator.generate(&resolve, world, files); Ok(()) diff --git a/tests/runtime/main.rs b/tests/runtime/main.rs index bea89e6d3..120867b19 100644 --- a/tests/runtime/main.rs +++ b/tests/runtime/main.rs @@ -18,6 +18,7 @@ mod smoke; mod strings; mod unions; mod variants; +mod wildcards; wasmtime::component::bindgen!("testwasi" in "crates/wasi_snapshot_preview1/wit"); diff --git a/tests/runtime/wildcards.rs b/tests/runtime/wildcards.rs new file mode 100644 index 000000000..3fab4f281 --- /dev/null +++ b/tests/runtime/wildcards.rs @@ -0,0 +1,52 @@ +use anyhow::Result; +use wasmtime::Store; + +wasmtime::component::bindgen!(in "tests/runtime/wildcards"); + +#[derive(Default)] +struct Host; + +impl imports::Host for Host {} + +struct Match(u32); + +impl imports::WildcardMatch for Match { + fn call(&self, _host: &mut Host, _name: &str) -> Result { + Ok(self.0) + } +} + +#[test] +fn run() -> Result<()> { + eprintln!("yossa hello"); + crate::run_test( + "wildcards", + |linker| { + eprintln!("yossa add to linker"); + Wildcards::add_to_linker( + linker, + WildcardMatches { + imports: vec![("a", Match(42)), ("b", Match(43)), ("c", Match(44))], + }, + |x| &mut x.0, + ) + }, + |store, component, linker| Wildcards::instantiate(store, component, linker), + run_test, + ) +} + +fn run_test(wildcards: Wildcards, store: &mut Store>) -> Result<()> { + for (name, value) in [("x", 42), ("y", 43), ("z", 44)] { + assert_eq!( + value, + wildcards + .exports + .get_wildcard_match(name) + .unwrap() + .call(&mut *store)? + ); + } + + Ok(()) +} diff --git a/tests/runtime/wildcards/substitutions.toml b/tests/runtime/wildcards/substitutions.toml new file mode 100644 index 000000000..f37f539f4 --- /dev/null +++ b/tests/runtime/wildcards/substitutions.toml @@ -0,0 +1,3 @@ +[wildcards] +imports = ["a", "b", "c"] +exports = ["x", "y", "z"] diff --git a/tests/runtime/wildcards/wasm.rs b/tests/runtime/wildcards/wasm.rs new file mode 100644 index 000000000..5ceb381ed --- /dev/null +++ b/tests/runtime/wildcards/wasm.rs @@ -0,0 +1,21 @@ +wit_bindgen::generate!({ + world: "world", + path: "../../tests/runtime/wildcards", + substitutions_path: "../../tests/runtime/wildcards/substitutions.toml", +}); + +struct Exports; + +export_wildcards!(Exports); + +impl exports::Exports for Exports { + fn x() -> u32 { + imports::a() + } + fn y() -> u32 { + imports::b() + } + fn z() -> u32 { + imports::c() + } +} diff --git a/tests/runtime/wildcards/world.wit b/tests/runtime/wildcards/world.wit new file mode 100644 index 000000000..04d6529d4 --- /dev/null +++ b/tests/runtime/wildcards/world.wit @@ -0,0 +1,8 @@ +interface foo { + *: func() -> u32 +} + +default world wildcards { + import imports: self.foo + export exports: self.foo +}