diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3ea1112..439d297 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,6 @@ jobs: name: Build and Test runs-on: ubuntu-latest env: - WIT_BINDGEN_VERSION: 0.55.0 WAC_VERSION: 0.9.0 VICEROY_VERSION: 0.16.4 steps: @@ -21,10 +20,6 @@ jobs: components: rustfmt, clippy toolchain: 1.93.1 # Pin to 1.93 to use WASI 0.2.6, before viceroy catches up to 0.2.9 - uses: bytecodealliance/actions/wasmtime/setup@v1 - - uses: bytecodealliance/actions/wasm-tools/setup@v1 - - uses: bytecodealliance/actions/wit-bindgen/setup@v1 - with: - version: ${{ env.WIT_BINDGEN_VERSION }} - name: Install wac run: | tmp=$(mktemp -d) diff --git a/Cargo.lock b/Cargo.lock index 3784148..16510bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,7 +102,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -119,9 +119,9 @@ checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" [[package]] name = "bitmaps" @@ -298,7 +298,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -560,7 +560,7 @@ name = "debug" version = "0.1.0" dependencies = [ "getrandom 0.3.4", - "wit-bindgen 0.52.0", + "wit-bindgen 0.62.0", ] [[package]] @@ -642,7 +642,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -912,6 +912,12 @@ name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" dependencies = [ "foldhash 0.2.0", ] @@ -1070,12 +1076,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -1248,7 +1254,7 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax", - "syn", + "syn 2.0.117", ] [[package]] @@ -1417,7 +1423,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.117", +] + +[[package]] +name = "prettyplease" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfe0f4c752e450fc2faf62654f1c134747922825d5b04ca717b8874f41a40c0" +dependencies = [ + "proc-macro2", + "syn 3.0.6", ] [[package]] @@ -1438,16 +1454,17 @@ dependencies = [ "ctrlc", "dialog", "heck", - "prettyplease", + "prettyplease 0.2.37", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "tempfile", "trace", "wasmtime", "wasmtime-wasi", - "wit-bindgen-core 0.53.1", - "wit-component 0.245.1", + "wit-bindgen-core 0.62.0", + "wit-bindgen-rust 0.62.0", + "wit-component 0.259.0", ] [[package]] @@ -1470,7 +1487,7 @@ checksum = "c3f210c61b6ecfaebbba806b6d9113a222519d4e5cc4ab2d5ecca047bb7927ae" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1553,7 +1570,7 @@ version = "0.1.0" dependencies = [ "serde_json", "trace", - "wit-bindgen 0.52.0", + "wit-bindgen 0.62.0", ] [[package]] @@ -1684,7 +1701,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1803,6 +1820,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -1811,7 +1839,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1884,7 +1912,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1895,7 +1923,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1988,7 +2016,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2126,7 +2154,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -2180,6 +2208,16 @@ dependencies = [ "wasmparser 0.245.1", ] +[[package]] +name = "wasm-encoder" +version = "0.259.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d0246511d901aacf25d2dc9111f0054947de5e093fe662099e709ff7530dc3" +dependencies = [ + "leb128fmt", + "wasmparser 0.259.0", +] + [[package]] name = "wasm-metadata" version = "0.244.0" @@ -2194,14 +2232,14 @@ dependencies = [ [[package]] name = "wasm-metadata" -version = "0.245.1" +version = "0.259.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da55e60097e8b37b475a0fa35c3420dd71d9eb7bd66109978ab55faf56a57efb" +checksum = "4e7bf119eb01f4a246864c10bd87c8f26c566350abb25aa4d5273c415bbab338" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.245.1", - "wasmparser 0.245.1", + "wasm-encoder 0.259.0", + "wasmparser 0.259.0", ] [[package]] @@ -2245,7 +2283,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" dependencies = [ "bitflags", - "hashbrown 0.16.1", + "indexmap", + "semver", +] + +[[package]] +name = "wasmparser" +version = "0.259.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f7c12eac7bb587801590f6a67ff0bc84d0748513864b71108e4b311cc3df694" +dependencies = [ + "bitflags", + "hashbrown 0.17.1", "indexmap", "semver", ] @@ -2373,7 +2422,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wasmtime-internal-component-util", "wasmtime-internal-wit-bindgen", "wit-parser 0.244.0", @@ -2482,7 +2531,7 @@ checksum = "9a6948b56bb00c62dbd205ea18a4f1ceccbe1e4b8479651fdb0bab2553790f20" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2612,7 +2661,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wasmtime-environ", "witx", ] @@ -2625,7 +2674,7 @@ checksum = "91a267096e48857096f035fffca29e22f0bbe840af4d74a6725eb695e1782110" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wiggle-generate", ] @@ -2700,7 +2749,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2711,7 +2760,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2921,12 +2970,12 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.52.0" +version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e048f41ef90f0b5dd61f1059c35f5636252e56813bf616d0803aa3739867230" +checksum = "53cb4b5556c3a791e86838ea287782bdafa704d55b0e68b5b81a3a16b9ea5f4b" dependencies = [ "bitflags", - "wit-bindgen-rust-macro 0.52.0", + "wit-bindgen-rust-macro 0.62.0", ] [[package]] @@ -2942,24 +2991,13 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.52.0" +version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15e7a56641cc9040480a26526a3229cbc4e8065adf98c9755d21c4c9b446c4c" +checksum = "72ad22a37ecbc0e1fdca34d2b670ba41368cb0920735643e00fdf39a16ee5431" dependencies = [ "anyhow", "heck", - "wit-parser 0.244.0", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3deda4b7e9f522d994906f6e6e0fc67965ea8660306940a776b76732be8f3933" -dependencies = [ - "anyhow", - "heck", - "wit-parser 0.245.1", + "wit-parser 0.259.0", ] [[package]] @@ -2971,8 +3009,8 @@ dependencies = [ "anyhow", "heck", "indexmap", - "prettyplease", - "syn", + "prettyplease 0.2.37", + "syn 2.0.117", "wasm-metadata 0.244.0", "wit-bindgen-core 0.51.0", "wit-component 0.244.0", @@ -2980,18 +3018,18 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.52.0" +version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd81b0ae1ec492bfe91683f1da6db6492ebc682e72d4f2715619dba783b066ca" +checksum = "84ba5213d4332c260a0d4e69e34b0f7e4b85ddae10b6ebfbac00d9c185ba628a" dependencies = [ "anyhow", "heck", "indexmap", - "prettyplease", - "syn", - "wasm-metadata 0.244.0", - "wit-bindgen-core 0.52.0", - "wit-component 0.244.0", + "prettyplease 0.3.0", + "syn 3.0.6", + "wasm-metadata 0.259.0", + "wit-bindgen-core 0.62.0", + "wit-component 0.259.0", ] [[package]] @@ -3001,27 +3039,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" dependencies = [ "anyhow", - "prettyplease", + "prettyplease 0.2.37", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wit-bindgen-core 0.51.0", "wit-bindgen-rust 0.51.0", ] [[package]] name = "wit-bindgen-rust-macro" -version = "0.52.0" +version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e6ce04c549e7149b66a70d34fc5a2a01b374bf49ca61db65d16e3ae922866e" +checksum = "8f19d63da8e478a370ef8192d90ccb517965b7747d6b46cd2d831dd0ef4d2541" dependencies = [ "anyhow", - "prettyplease", + "prettyplease 0.3.0", "proc-macro2", "quote", - "syn", - "wit-bindgen-core 0.52.0", - "wit-bindgen-rust 0.52.0", + "syn 3.0.6", + "wit-bindgen-core 0.62.0", + "wit-bindgen-rust 0.62.0", ] [[package]] @@ -3045,9 +3083,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.245.1" +version = "0.259.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4894f10d2d5cbc17c77e91f86a1e48e191a788da4425293b55c98b44ba3fcac9" +checksum = "092f783dee3253265fcde131475055f8c275ac0176a9c0396db1dc7b5544bfb4" dependencies = [ "anyhow", "bitflags", @@ -3056,10 +3094,10 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.245.1", - "wasm-metadata 0.245.1", - "wasmparser 0.245.1", - "wit-parser 0.245.1", + "wasm-encoder 0.259.0", + "wasm-metadata 0.259.0", + "wasmparser 0.259.0", + "wit-parser 0.259.0", ] [[package]] @@ -3082,12 +3120,12 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.245.1" +version = "0.259.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330698718e82983499419494dd1e3d7811a457a9bf9f69734e8c5f07a2547929" +checksum = "6390f4f02493ce678d509c859cf1698e38929fb75c8012a6ee2f7d6b6cb66cd7" dependencies = [ "anyhow", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "id-arena", "indexmap", "log", @@ -3095,8 +3133,8 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "unicode-xid", - "wasmparser 0.245.1", + "unicode-ident", + "wasmparser 0.259.0", ] [[package]] @@ -3136,7 +3174,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -3157,7 +3195,7 @@ checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -3177,7 +3215,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -3211,7 +3249,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 03056ff..0c87833 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = [ "components/recorder" , "crates/dialog", "crates/trace"] [workspace.dependencies] -wit-bindgen = { version = "0.52.0", default-features = false, features = ["bitflags", "std", "macros"] } +wit-bindgen = { version = "0.62.0", default-features = false, features = ["bitflags", "std", "macros"] } serde = { version = "1.0.226", features = ["derive"] } serde_json = "1.0.145" wasm-wave = { git = "https://github.com/chenyan2002/wasm-tools.git", branch = "extend-wave", version = "0.239.0", default-features = false } @@ -24,8 +24,9 @@ quote = "1.0.41" proc-macro2 = "1.0.103" syn = { version = "2.0.108", features = ["visit-mut"] } tempfile = "3.20.0" -wit-bindgen-core = "0.53.1" -wit-component = "0.245.0" +wit-bindgen-core = "0.62.0" +wit-bindgen-rust = "0.62.0" +wit-component = "0.259.0" wasmtime = { version = "42.0.0", features = ["wave"], optional = true } wasmtime-wasi = { version = "42.0.0", optional = true } diff --git a/assets/debug.wasm b/assets/debug.wasm index d22efa2..2fadde9 100644 Binary files a/assets/debug.wasm and b/assets/debug.wasm differ diff --git a/assets/recorder.wasm b/assets/recorder.wasm index 3a7c079..ca37010 100644 Binary files a/assets/recorder.wasm and b/assets/recorder.wasm differ diff --git a/assets/workspace_cargo.toml b/assets/workspace_cargo.toml index 1eedad2..debc838 100644 --- a/assets/workspace_cargo.toml +++ b/assets/workspace_cargo.toml @@ -3,7 +3,7 @@ members = ["record_imports", "record_exports"] resolver = "2" [workspace.dependencies] -wit-bindgen = { version = "0.55.0", default-features = false, features = ["bitflags", "std"] } +wit-bindgen = { version = "0.62.0", default-features = false, features = ["bitflags", "std"] } wasm-wave = { git = "https://github.com/chenyan2002/wasm-tools.git", branch = "extend-wave", version = "0.239.0", default-features = false } #wasm-wave = { path = "/Users/chenyan/src/bytecodealliance/wasm-tools/crates/wasm-wave", default-features = false } arbitrary = "1.4.2" diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 9de3718..ff13656 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -138,7 +138,10 @@ impl State { methods.push(syn::ImplItem::Type(impl_item)); } TraitItem::Fn(method) => { - if method.sig.ident.to_string().starts_with("_resource_") { + let method_name = method.sig.ident.to_string(); + if method_name.starts_with("_resource_") + || (method_name.starts_with("resource") && method_name.ends_with("_")) + { continue; } let mut sig = method.sig.clone(); diff --git a/src/instrument.rs b/src/instrument.rs index e137be6..a5435e4 100644 --- a/src/instrument.rs +++ b/src/instrument.rs @@ -5,6 +5,7 @@ use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; use wit_bindgen_core::{Files, wit_parser}; +use wit_component::{ComponentEncoder, embed_component_metadata}; use wit_parser::{Resolve, WorldId}; #[derive(Parser)] @@ -30,16 +31,9 @@ pub fn run(args: InstrumentArgs) -> Result<()> { let tmp_dir = init_rust_project()?; let wit_dir = tmp_dir.join("wit"); - // 2. run `wasm-tools component wit {wasm_file from CLI} --out-dir {tmp_dir/wit}` - let status = Command::new("wasm-tools") - .arg("component") - .arg("wit") - .arg(&args.wasm_file) - .arg("--out-dir") - .arg(&wit_dir) - .status() - .context("Failed to execute wasm-tools. Is it installed and in your PATH?")?; - assert!(status.success()); + // 2. Extract WIT from the wasm component into {tmp_dir/wit} + // TODO: no need to write to disk + crate::util::extract_wit(&args.wasm_file, &wit_dir)?; // 3. Parse the main wit file from tmp_dir/wit and feed into opts.generate_component let (resolve, world) = parse_wit(&wit_dir, None)?; @@ -130,19 +124,7 @@ fn bindgen( dest_name: &str, ) -> Result<()> { let out_dir = tmp_dir.join(dest_name); - let status = Command::new("wit-bindgen") - //let status = - // Command::new("/Users/chenyan/src/bytecodealliance/wit-bindgen/target/debug/wit-bindgen") - .arg("rust") - .arg(wit_dir) - .arg("--world") - .arg(world_name) - .arg("--generate-all") - .arg("--merge-structurally-equal-types=true") - .arg("--out-dir") - .arg(&out_dir) - .status()?; - assert!(status.success()); + crate::util::generate_bindings(wit_dir, world_name, &out_dir)?; let binding_file = out_dir.join(world_name.to_owned() + ".rs"); let codegen_mode = match mode { Mode::Record => codegen::GenerateMode::Record, @@ -156,11 +138,7 @@ fn bindgen( mode: codegen_mode, }; codegen_opt.generate()?; - let status = Command::new("mv") - .arg(&binding_file) - .arg(out_dir.join("bindings.rs")) - .status()?; - assert!(status.success()); + fs::rename(&binding_file, out_dir.join("bindings.rs"))?; Ok(()) } fn component_new( @@ -173,25 +151,21 @@ fn component_new( .join("target/wasm32-unknown-unknown/") .join(wasm_file); let world = "component:proxy/".to_string() + world_name; - let status = Command::new("wasm-tools") - .arg("component") - .arg("embed") - .arg(wit_dir) - .arg(&wasm_path) - .arg("-o") - .arg(&wasm_path) - .arg("--world") - .arg(&world) - .status()?; - assert!(status.success()); - let status = Command::new("wasm-tools") - .arg("component") - .arg("new") - .arg(&wasm_path) - .arg("-o") - .arg(&wasm_path) - .status()?; - assert!(status.success()); + // embed component type metadata + let mut wasm = fs::read(&wasm_path)?; + let (resolve, world_id) = parse_wit(wit_dir, Some(&world))?; + embed_component_metadata( + &mut wasm, + &resolve, + world_id, + wit_component::StringEncoding::UTF8, + )?; + // create component from the embedded module + let component = ComponentEncoder::default() + .module(&wasm)? + .encode() + .context("failed to encode a component from module")?; + fs::write(&wasm_path, component)?; Ok(wasm_path) } fn init_rust_project() -> Result { diff --git a/src/traits/proxy.rs b/src/traits/proxy.rs index 1141dca..fd3d97a 100644 --- a/src/traits/proxy.rs +++ b/src/traits/proxy.rs @@ -62,7 +62,7 @@ impl Trait for ProxyTrait<'_> { impl<'a> ToProxy for &'a #resource_path { type Output = #export_borrow; fn to_proxy(self) -> Self::Output { - unsafe { Self::Output::lift(self as *const _ as usize) } + unsafe { Self::Output::lift(self as *const _ as *const u8) } } }}); } diff --git a/src/util.rs b/src/util.rs index 435e397..6e7daae 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,10 +1,13 @@ use crate::codegen::{self, ItemFlag, TypeInfo}; +use anyhow::{Context, Result}; use heck::ToKebabCase; use quote::ToTokens; use std::borrow::Cow; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::{BTreeMap, BTreeSet, HashMap}; +use std::path::Path; use syn::{FnArg, Ident, Item, Signature, Type, Visibility, parse_quote, visit_mut::VisitMut}; use wit_bindgen_core::wit_parser::{PackageId, Resolve}; +use wit_component::WitPrinter; pub struct FullTypePath<'a> { pub module_path: &'a [String], } @@ -435,6 +438,86 @@ fn is_keyword(name: &str) -> bool { ) } +/// Extract WIT definitions from a wasm component and write them to `out_dir`. +/// Equivalent to `wasm-tools component wit --out-dir `. +pub fn extract_wit(wasm_file: &Path, out_dir: &Path) -> Result<()> { + let wasm = std::fs::read(wasm_file) + .with_context(|| format!("failed to read {}", wasm_file.display()))?; + let decoded = wit_component::decode(&wasm) + .with_context(|| format!("failed to decode component {}", wasm_file.display()))?; + let resolve = decoded.resolve(); + let main_pkg = decoded.package(); + + std::fs::create_dir_all(out_dir)?; + + let mut names: HashMap<&str, HashMap<&str, usize>> = HashMap::new(); + for (_id, pkg) in resolve.packages.iter() { + *names + .entry(&pkg.name.name) + .or_default() + .entry(&pkg.name.namespace) + .or_insert(0) += 1; + } + + for (id, pkg) in resolve.packages.iter() { + let is_main = id == main_pkg; + let mut printer = WitPrinter::default(); + printer.print(resolve, id, &[])?; + let output = printer.output.to_string(); + let dir = if is_main { + out_dir.to_path_buf() + } else { + out_dir.join("deps") + }; + let packages_with_same_name = &names[pkg.name.name.as_str()]; + let packages_with_same_namespace = packages_with_same_name[pkg.name.namespace.as_str()]; + let stem = if packages_with_same_name.len() == 1 { + if packages_with_same_namespace == 1 { + pkg.name.name.clone() + } else { + pkg.name + .version + .as_ref() + .map(|ver| format!("{}@{}", pkg.name.name, ver)) + .unwrap_or_else(|| pkg.name.name.clone()) + } + } else if packages_with_same_namespace == 1 { + format!("{}:{}", pkg.name.namespace, pkg.name.name) + } else { + pkg.name.to_string() + }; + std::fs::create_dir_all(&dir)?; + let path = dir.join(format!("{stem}.wit")); + std::fs::write(&path, &output)?; + } + Ok(()) +} + +/// Generate Rust bindings from WIT definitions. +/// Equivalent to `wit-bindgen rust --world --generate-all --merge-structurally-equal-types=true --out-dir `. +pub fn generate_bindings(wit_dir: &Path, world_name: &str, out_dir: &Path) -> Result<()> { + use wit_bindgen_core::{Files, WorldGenerator}; + let mut resolve = Resolve::default(); + let (pkg, _) = resolve.push_dir(wit_dir)?; + let world = resolve.select_world(&[pkg], Some(world_name))?; + + let opts = wit_bindgen_rust::Opts { + generate_all: true, + merge_structurally_equal_types: Some(Some(true)), + ..Default::default() + }; + let mut generator = opts.build(); + let mut files = Files::default(); + generator.generate(&mut resolve, world, &mut files)?; + + std::fs::create_dir_all(out_dir)?; + for (name, content) in files.iter() { + let path = out_dir.join(name); + std::fs::write(&path, content)?; + } + Ok(()) +} + /// Return the set of package ids that will have version suffix in the wit-bindgen /// Use the same logic as in https://github.com/bytecodealliance/wit-bindgen/blob/main/crates/core/src/path.rs pub fn package_with_version(resolve: &Resolve) -> BTreeSet {