From 69b4b80ff9a95d51b5e5e5ba7f0cec738f39418f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 8 Aug 2023 20:30:30 +0200 Subject: [PATCH] Update to Wasmtime 12 (#124) This commit updates the Wasmtime dependency to the, currently unreleased, Wasmtime 12.0.0 branch. A number of changes happened to component translation in Wasmtime 12 to account for resources which required changes here as well. Additionally Wasmtime 12 disallows empty types in components which WASI was previously using, so this additionally updates the preview1 shims and test components. --- Cargo.lock | 176 +++++------------- Cargo.toml | 21 ++- .../src/transpile_bindgen.rs | 112 ++++++----- 3 files changed, 122 insertions(+), 187 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42c4e821a..2f5df24b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,9 +51,8 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-entity" -version = "0.97.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6565198b5684367371e2b946ceca721eb36965e75e3592fad12fc2e15f65d7b" +version = "0.99.0" +source = "git+https://github.com/bytecodealliance/wasmtime?branch=release-12.0.0#de4ede08265e8e984a8fd34be5c0986e13b646b0" dependencies = [ "serde", ] @@ -153,7 +152,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -179,7 +177,7 @@ version = "0.10.1" dependencies = [ "anyhow", "js-component-bindgen", - "wit-component 0.13.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", + "wit-component", ] [[package]] @@ -189,10 +187,10 @@ dependencies = [ "anyhow", "base64", "heck", - "indexmap 1.9.3", + "indexmap 2.0.0", "wasmtime-environ", - "wit-component 0.13.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", - "wit-parser 0.9.2 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", + "wit-component", + "wit-parser", ] [[package]] @@ -225,9 +223,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "object" -version = "0.30.4" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "crc32fast", "hashbrown 0.13.2", @@ -457,15 +455,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasm-encoder" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881" -dependencies = [ - "leb128", -] - [[package]] name = "wasm-encoder" version = "0.31.1" @@ -475,14 +464,6 @@ dependencies = [ "leb128", ] -[[package]] -name = "wasm-encoder" -version = "0.31.1" -source = "git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd#5605721e5373015e70401962a5d381f6968e3fbd" -dependencies = [ - "leb128", -] - [[package]] name = "wasm-metadata" version = "0.10.1" @@ -494,22 +475,8 @@ dependencies = [ "serde", "serde_json", "spdx", - "wasm-encoder 0.31.1 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmparser 0.110.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-metadata" -version = "0.10.1" -source = "git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd#5605721e5373015e70401962a5d381f6968e3fbd" -dependencies = [ - "anyhow", - "indexmap 2.0.0", - "serde", - "serde_json", - "spdx", - "wasm-encoder 0.31.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", - "wasmparser 0.110.0 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", + "wasm-encoder", + "wasmparser", ] [[package]] @@ -517,24 +484,14 @@ name = "wasm-tools-js" version = "0.1.0" dependencies = [ "anyhow", - "wasm-encoder 0.31.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", - "wasm-metadata 0.10.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", - "wasmparser 0.110.0 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", - "wasmprinter 0.2.62 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wasmprinter", "wat", "wit-bindgen", - "wit-component 0.13.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", - "wit-parser 0.9.2 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", -] - -[[package]] -name = "wasmparser" -version = "0.107.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e3ac9b780c7dda0cac7a52a5d6d2d6707cc6e3451c9db209b6c758f40d7acb" -dependencies = [ - "indexmap 1.9.3", - "semver", + "wit-component", + "wit-parser", ] [[package]] @@ -547,15 +504,6 @@ dependencies = [ "semver", ] -[[package]] -name = "wasmparser" -version = "0.110.0" -source = "git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd#5605721e5373015e70401962a5d381f6968e3fbd" -dependencies = [ - "indexmap 2.0.0", - "semver", -] - [[package]] name = "wasmprinter" version = "0.2.62" @@ -563,73 +511,63 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cd12ed4d96a984e4b598a17457f1126d01640cc7461afbb319642111ff9e7f" dependencies = [ "anyhow", - "wasmparser 0.110.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasmprinter" -version = "0.2.62" -source = "git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd#5605721e5373015e70401962a5d381f6968e3fbd" -dependencies = [ - "anyhow", - "wasmparser 0.110.0 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", + "wasmparser", ] [[package]] name = "wasmtime-component-util" -version = "10.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f20a5135ec5ef01080e674979b02d6fa5eebaa2b0c2d6660513ee9956a1bf624" +version = "12.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime?branch=release-12.0.0#de4ede08265e8e984a8fd34be5c0986e13b646b0" [[package]] name = "wasmtime-environ" -version = "10.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f9e58e0ee7d43ff13e75375c726b16bce022db798d3a099a65eeaa7d7a544b" +version = "12.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime?branch=release-12.0.0#de4ede08265e8e984a8fd34be5c0986e13b646b0" dependencies = [ "anyhow", "cranelift-entity", "gimli", - "indexmap 1.9.3", + "indexmap 2.0.0", "log", "object", "serde", "target-lexicon", "thiserror", - "wasm-encoder 0.29.0", - "wasmparser 0.107.0", - "wasmprinter 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-encoder", + "wasmparser", + "wasmprinter", "wasmtime-component-util", "wasmtime-types", ] [[package]] name = "wasmtime-types" -version = "10.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbb7c138f797192f46afdd3ec16f85ef007c3bb45fa8e5174031f17b0be4c4a" +version = "12.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime?branch=release-12.0.0#de4ede08265e8e984a8fd34be5c0986e13b646b0" dependencies = [ "cranelift-entity", "serde", "thiserror", - "wasmparser 0.107.0", + "wasmparser", ] [[package]] name = "wast" version = "62.0.1" -source = "git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd#5605721e5373015e70401962a5d381f6968e3fbd" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ae06f09dbe377b889fbd620ff8fa21e1d49d1d9d364983c0cdbf9870cb9f1f" dependencies = [ "leb128", "memchr", "unicode-width", - "wasm-encoder 0.31.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", + "wasm-encoder", ] [[package]] name = "wat" version = "1.0.69" -source = "git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd#5605721e5373015e70401962a5d381f6968e3fbd" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "842e15861d203fb4a96d314b0751cdeaf0f6f8b35e8d81d2953af2af5e44e637" dependencies = [ "wast", ] @@ -649,8 +587,8 @@ version = "0.9.0" source = "git+https://github.com/bytecodealliance/wit-bindgen#bf318b8ae4703586ae236a232f62813efc946df3" dependencies = [ "anyhow", - "wit-component 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "wit-parser 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wit-component", + "wit-parser", ] [[package]] @@ -660,10 +598,10 @@ source = "git+https://github.com/bytecodealliance/wit-bindgen#bf318b8ae4703586ae dependencies = [ "anyhow", "heck", - "wasm-metadata 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-metadata", "wit-bindgen-core", "wit-bindgen-rust-lib", - "wit-component 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wit-component", ] [[package]] @@ -686,7 +624,7 @@ dependencies = [ "wit-bindgen-core", "wit-bindgen-rust", "wit-bindgen-rust-lib", - "wit-component 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wit-component", ] [[package]] @@ -699,26 +637,11 @@ dependencies = [ "bitflags 2.3.3", "indexmap 2.0.0", "log", - "wasm-encoder 0.31.1 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-metadata 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmparser 0.110.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wit-parser 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wit-component" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd#5605721e5373015e70401962a5d381f6968e3fbd" -dependencies = [ - "anyhow", - "bitflags 2.3.3", - "indexmap 2.0.0", - "log", - "wasm-encoder 0.31.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", - "wasm-metadata 0.10.1 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", - "wasmparser 0.110.0 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", + "wasm-encoder", + "wasm-metadata", + "wasmparser", "wat", - "wit-parser 0.9.2 (git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd)", + "wit-parser", ] [[package]] @@ -736,18 +659,3 @@ dependencies = [ "unicode-xid", "url", ] - -[[package]] -name = "wit-parser" -version = "0.9.2" -source = "git+https://github.com/bytecodealliance/wasm-tools?rev=5605721e5373015e70401962a5d381f6968e3fbd#5605721e5373015e70401962a5d381f6968e3fbd" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.0.0", - "log", - "pulldown-cmark", - "semver", - "unicode-xid", - "url", -] diff --git a/Cargo.toml b/Cargo.toml index 93f58861b..eac30db4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,13 +30,16 @@ version = "0.10.1" anyhow = "1.0.71" base64 = "0.21.2" heck = { version = "0.4", features = ["unicode"] } -indexmap = "1.9" -wasm-encoder = { git = "https://github.com/bytecodealliance/wasm-tools", rev = "5605721e5373015e70401962a5d381f6968e3fbd" } -wasm-metadata = { git = "https://github.com/bytecodealliance/wasm-tools", rev = "5605721e5373015e70401962a5d381f6968e3fbd" } -wasmparser = { git = "https://github.com/bytecodealliance/wasm-tools", rev = "5605721e5373015e70401962a5d381f6968e3fbd" } -wasmprinter = { git = "https://github.com/bytecodealliance/wasm-tools", rev = "5605721e5373015e70401962a5d381f6968e3fbd" } -wasmtime-environ = { version = "10.0.1", features = ["component-model"] } -wat = { git = "https://github.com/bytecodealliance/wasm-tools", rev = "5605721e5373015e70401962a5d381f6968e3fbd" } +indexmap = "2.0" +wasm-encoder = "0.31.1" +wasm-metadata = "0.10.1" +wasmparser = "0.110.0" +wasmprinter = "0.2.62" +wasmtime-environ = { version = "12.0.0", features = ["component-model"] } +wat = "1.0.69" wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen" } -wit-component = { git = "https://github.com/bytecodealliance/wasm-tools", features = ["dummy-module"], rev = "5605721e5373015e70401962a5d381f6968e3fbd" } -wit-parser = { git = "https://github.com/bytecodealliance/wasm-tools", rev = "5605721e5373015e70401962a5d381f6968e3fbd" } +wit-component = { version = "0.13.1", features = ["dummy-module"] } +wit-parser = "0.9.2" + +[patch.crates-io] +wasmtime-environ = { git = 'https://github.com/bytecodealliance/wasmtime', branch = 'release-12.0.0' } diff --git a/crates/js-component-bindgen/src/transpile_bindgen.rs b/crates/js-component-bindgen/src/transpile_bindgen.rs index cf7501edf..f3533025a 100644 --- a/crates/js-component-bindgen/src/transpile_bindgen.rs +++ b/crates/js-component-bindgen/src/transpile_bindgen.rs @@ -14,8 +14,9 @@ use std::mem; use wasmtime_environ::{ component, component::{ - CanonicalOptions, Component, CoreDef, CoreExport, Export, ExportItem, GlobalInitializer, - InstantiateModule, LowerImport, RuntimeInstanceIndex, StaticModuleIndex, Transcoder, + CanonicalOptions, Component, ComponentTranslation, CoreDef, CoreExport, Export, ExportItem, + GlobalInitializer, InstantiateModule, LoweredIndex, RuntimeImportIndex, + RuntimeInstanceIndex, StaticModuleIndex, Trampoline, TrampolineIndex, }, }; use wasmtime_environ::{EntityIndex, ModuleTranslation, PrimaryMap}; @@ -71,7 +72,7 @@ struct JsBindgen<'a> { pub fn transpile_bindgen( name: &str, - component: &Component, + component: &ComponentTranslation, modules: &PrimaryMap>, resolve: &Resolve, id: WorldId, @@ -114,9 +115,11 @@ pub fn transpile_bindgen( instances: Default::default(), resolve, world: id, - component, + translation: component, + component: &component.component, imports, exports, + lowering_options: Default::default(), }; instantiator.sizes.fill(resolve); instantiator.instantiate(); @@ -297,17 +300,24 @@ struct Instantiator<'a, 'b> { world: WorldId, sizes: SizeAlign, component: &'a Component, + translation: &'a ComponentTranslation, exports: BTreeMap, imports: BTreeMap, + lowering_options: PrimaryMap, } -impl Instantiator<'_, '_> { +impl<'a> Instantiator<'a, '_> { fn instantiate(&mut self) { - // To avoid uncaught promise rejection errors, we attach an intermediate - // Promise.all with a rejection handler, if there are multiple promises. for i in 0..self.component.num_runtime_component_instances { uwriteln!(self.src.js_init, "const instanceFlags{i} = new WebAssembly.Global({{ value: \"i32\", mutable: true }}, {});", wasmtime_environ::component::FLAG_MAY_LEAVE | wasmtime_environ::component::FLAG_MAY_ENTER); } + + for (i, trampoline) in self.translation.trampolines.iter() { + self.trampoline(i, trampoline); + } + + // To avoid uncaught promise rejection errors, we attach an intermediate + // Promise.all with a rejection handler, if there are multiple promises. if self.modules.len() > 1 { self.src.js_init.push_str("Promise.all(["); for i in 0..self.modules.len() { @@ -331,6 +341,45 @@ impl Instantiator<'_, '_> { self.exports(&self.component.exports) } + fn trampoline(&mut self, i: TrampolineIndex, trampoline: &'a Trampoline) { + match trampoline { + // This is only used for a "degenerate component" which internally + // has a function that always traps. While this should be trivial to + // implement (generate a JS function that always throws) there's no + // way to test this at this time so leave this unimplemented. + Trampoline::AlwaysTrap => unimplemented!(), + + // This is required when strings pass between components within a + // component and may change encodings. This is left unimplemented + // for now since it can't be tested and additionally JS doesn't + // support multi-memory which transcoders rely on anyway. + Trampoline::Transcoder { + op: _, + from: _, + from64: _, + to: _, + to64: _, + } => unimplemented!(), + + Trampoline::LowerImport { + index, + lower_ty: _, + options, + } => { + let i = self.lowering_options.push((options, i)); + assert_eq!(i, *index); + } + + Trampoline::ResourceNew(_) => unimplemented!(), + Trampoline::ResourceRep(_) => unimplemented!(), + Trampoline::ResourceDrop(_) => unimplemented!(), + Trampoline::ResourceTransferOwn => unimplemented!(), + Trampoline::ResourceTransferBorrow => unimplemented!(), + Trampoline::ResourceEnterCall => unimplemented!(), + Trampoline::ResourceExitCall => unimplemented!(), + } + } + fn instantiation_global_initializer(&mut self, init: &GlobalInitializer) { match init { GlobalInitializer::InstantiateModule(m) => match m { @@ -340,8 +389,8 @@ impl Instantiator<'_, '_> { // test at this time so it's left unimplemented. InstantiateModule::Import(..) => unimplemented!(), }, - GlobalInitializer::LowerImport(i) => { - self.lower_import(i); + GlobalInitializer::LowerImport { index, import } => { + self.lower_import(*index, *import); } GlobalInitializer::ExtractMemory(m) => { let def = self.core_export(&m.export); @@ -362,31 +411,7 @@ impl Instantiator<'_, '_> { uwriteln!(self.src.js_init, "postReturn{idx} = {def};"); } - // This is only used for a "degenerate component" which internally - // has a function that always traps. While this should be trivial to - // implement (generate a JS function that always throws) there's no - // way to test this at this time so leave this unimplemented. - GlobalInitializer::AlwaysTrap(_) => unimplemented!(), - - // This is only used when the component exports core wasm modules, - // but that's not possible to test right now so leave these as - // unimplemented. - GlobalInitializer::SaveStaticModule(_) => unimplemented!(), - GlobalInitializer::SaveModuleImport(_) => unimplemented!(), - - // This is required when strings pass between components within a - // component and may change encodings. This is left unimplemented - // for now since it can't be tested and additionally JS doesn't - // support multi-memory which transcoders rely on anyway. - GlobalInitializer::Transcoder(Transcoder { - index: _, - op: _, - from: _, - from64: _, - to: _, - to64: _, - signature: _, - }) => unimplemented!(), + GlobalInitializer::Resource(_) => unimplemented!(), } } @@ -431,8 +456,8 @@ impl Instantiator<'_, '_> { ); } - fn lower_import(&mut self, import: &LowerImport) { - let (import_index, path) = &self.component.imports[import.import]; + fn lower_import(&mut self, index: LoweredIndex, import: RuntimeImportIndex) { + let (import_index, path) = &self.component.imports[import]; let (import_name, _) = &self.component.import_types[*import_index]; let world_key = &self.imports[import_name]; @@ -453,13 +478,13 @@ impl Instantiator<'_, '_> { ( func, &path[0], - Some(iface.name.as_ref().unwrap_or_else(|| import_name)), + Some(iface.name.as_deref().unwrap_or_else(|| import_name)), ) } WorldItem::Type(_) => unreachable!(), }; - let index = import.index.as_u32(); + let (options, trampoline) = self.lowering_options[index]; // note, the same function can be lowered into multiple sub-components let callee_name = self @@ -468,7 +493,7 @@ impl Instantiator<'_, '_> { .get_or_create(&format!("import:{}-{}", import_name, func_name), func_name) .to_string(); - uwrite!(self.src.js, "\nfunction lowering{index}"); + uwrite!(self.src.js, "\nfunction trampoline{}", trampoline.as_u32()); let nparams = self .resolve .wasm_signature(AbiVariant::GuestImport, func) @@ -477,7 +502,7 @@ impl Instantiator<'_, '_> { self.bindgen( nparams, &callee_name, - &import.options, + options, func, AbiVariant::GuestImport, ); @@ -595,12 +620,10 @@ impl Instantiator<'_, '_> { fn core_def(&self, def: &CoreDef) -> String { match def { CoreDef::Export(e) => self.core_export(e), - CoreDef::Lowered(i) => format!("lowering{}", i.as_u32()), - CoreDef::AlwaysTrap(_) => unimplemented!(), + CoreDef::Trampoline(i) => format!("trampoline{}", i.as_u32()), CoreDef::InstanceFlags(i) => { format!("instance_flags{}", i.as_u32()) } - CoreDef::Transcoder(_) => unimplemented!(), } } @@ -682,7 +705,8 @@ impl Instantiator<'_, '_> { Export::Type(_) => {} // This can't be tested at this time so leave it unimplemented - Export::Module(_) => unimplemented!(), + Export::ModuleStatic(_) => unimplemented!(), + Export::ModuleImport(_) => unimplemented!(), } } self.gen.esm_bindgen.populate_export_aliases();