diff --git a/Cargo.lock b/Cargo.lock index c8c56ec17aae..c50e6c70634e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3639,8 +3639,7 @@ dependencies = [ [[package]] name = "wasm-encoder" version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77053dc709db790691d3732cfc458adc5acc881dec524965c608effdcd9c581" +source = "git+https://github.com/alexcrichton/wasm-tools?branch=wit-changes#9a557e0e9abdcdb4aa7eb3844c241980b8664fbc" dependencies = [ "leb128", ] @@ -3661,8 +3660,7 @@ dependencies = [ [[package]] name = "wasm-mutate" version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b8c74fd20d97b9ba8b1a6e3ccc6ec715e6c6d4605668926e582e88580180d96" +source = "git+https://github.com/alexcrichton/wasm-tools?branch=wit-changes#9a557e0e9abdcdb4aa7eb3844c241980b8664fbc" dependencies = [ "egg", "log", @@ -3675,8 +3673,7 @@ dependencies = [ [[package]] name = "wasm-smith" version = "0.12.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c11c745f6f4ff2f953d8a94ef056b04b468fc021285cfaf614e77791c05499" +source = "git+https://github.com/alexcrichton/wasm-tools?branch=wit-changes#9a557e0e9abdcdb4aa7eb3844c241980b8664fbc" dependencies = [ "arbitrary", "flagset", @@ -3746,11 +3743,9 @@ dependencies = [ [[package]] name = "wasmparser" version = "0.105.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83be9e0b3f9570dc1979a33ae7b89d032c73211564232b99976553e5c155ec32" +source = "git+https://github.com/alexcrichton/wasm-tools?branch=wit-changes#9a557e0e9abdcdb4aa7eb3844c241980b8664fbc" dependencies = [ "indexmap", - "url", ] [[package]] @@ -3765,8 +3760,7 @@ dependencies = [ [[package]] name = "wasmprinter" version = "0.2.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b0e5ed7a74a065637f0d7798ce5f29cadb064980d24b0c82af5200122fa0d8" +source = "git+https://github.com/alexcrichton/wasm-tools?branch=wit-changes#9a557e0e9abdcdb4aa7eb3844c241980b8664fbc" dependencies = [ "anyhow", "wasmparser 0.105.0", @@ -4306,8 +4300,7 @@ dependencies = [ [[package]] name = "wast" version = "58.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372eecae2d10a5091c2005b32377d7ecd6feecdf2c05838056d02d8b4f07c429" +source = "git+https://github.com/alexcrichton/wasm-tools?branch=wit-changes#9a557e0e9abdcdb4aa7eb3844c241980b8664fbc" dependencies = [ "leb128", "memchr", @@ -4318,8 +4311,7 @@ dependencies = [ [[package]] name = "wat" version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d47446190e112ab1579ab40b3ad7e319d859d74e5134683f04e9f0747bf4173" +source = "git+https://github.com/alexcrichton/wasm-tools?branch=wit-changes#9a557e0e9abdcdb4aa7eb3844c241980b8664fbc" dependencies = [ "wast 58.0.0", ] @@ -4733,8 +4725,7 @@ dependencies = [ [[package]] name = "wit-parser" version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca2581061573ef6d1754983d7a9b3ed5871ef859d52708ea9a0f5af32919172" +source = "git+https://github.com/alexcrichton/wasm-tools?branch=wit-changes#9a557e0e9abdcdb4aa7eb3844c241980b8664fbc" dependencies = [ "anyhow", "id-arena", diff --git a/Cargo.toml b/Cargo.toml index 4a60137e7269..ee0f9d885cfe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -225,7 +225,8 @@ default = [ "vtune", "wasi-nn", "wasi-threads", - "wasi-http", + # TODO: the WIT needs to be updated + #"wasi-http", "pooling-allocator", ] jitdump = ["wasmtime/jitdump"] @@ -288,3 +289,12 @@ debug-assertions = false # string initializers. overflow-checks = false +[patch.crates-io] +wasm-encoder = { git = 'https://github.com/alexcrichton/wasm-tools', branch = 'wit-changes' } +wasm-mutate = { git = 'https://github.com/alexcrichton/wasm-tools', branch = 'wit-changes' } +wasm-smith = { git = 'https://github.com/alexcrichton/wasm-tools', branch = 'wit-changes' } +wasmparser = { git = 'https://github.com/alexcrichton/wasm-tools', branch = 'wit-changes' } +wasmprinter = { git = 'https://github.com/alexcrichton/wasm-tools', branch = 'wit-changes' } +wast = { git = 'https://github.com/alexcrichton/wasm-tools', branch = 'wit-changes' } +wat = { git = 'https://github.com/alexcrichton/wasm-tools', branch = 'wit-changes' } +wit-parser = { git = 'https://github.com/alexcrichton/wasm-tools', branch = 'wit-changes' } diff --git a/ci/run-tests.sh b/ci/run-tests.sh index 67e53eb87b51..cee988e138d2 100755 --- a/ci/run-tests.sh +++ b/ci/run-tests.sh @@ -1,8 +1,10 @@ #!/bin/bash +# TODO: add this flag back in +#--features "test-programs/test_programs_http" \ + cargo test \ --features "test-programs/test_programs" \ - --features "test-programs/test_programs_http" \ --features wasi-threads \ --workspace \ --exclude 'wasmtime-wasi-*' \ diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs index 030fe43c3b44..4b02d16ca286 100644 --- a/cranelift/wasm/src/code_translator.rs +++ b/cranelift/wasm/src/code_translator.rs @@ -2348,7 +2348,7 @@ pub fn translate_operator( )); } Operator::I31New | Operator::I31GetS | Operator::I31GetU => { - unimplemented!("GC operators not yet implemented") + return Err(wasm_unsupported!("proposed GC operator {:?}", op)); } }; Ok(()) diff --git a/crates/component-macro/src/bindgen.rs b/crates/component-macro/src/bindgen.rs index 02865920458e..e41e0fa2abcf 100644 --- a/crates/component-macro/src/bindgen.rs +++ b/crates/component-macro/src/bindgen.rs @@ -78,7 +78,16 @@ impl Parse for Config { if inline.is_some() { return Err(Error::new(s.span(), "cannot specify a second source")); } - inline = Some(format!("default world interfaces {{ {} }}", s.value())); + inline = Some(format!( + " + package wasmtime:component-macro-synthesized + + world interfaces {{ + {} + }} + ", + s.value() + )); if world.is_some() { return Err(Error::new( @@ -86,7 +95,7 @@ impl Parse for Config { "cannot specify a world with `interfaces`", )); } - world = Some("macro-input.interfaces".to_string()); + world = Some("interfaces".to_string()); opts.only_interfaces = true; } @@ -130,7 +139,7 @@ fn parse_source( } else { let pkg = UnresolvedPackage::parse_file(path)?; files.extend(pkg.source_files().map(|s| s.to_owned())); - resolve.push(pkg, &Default::default()) + resolve.push(pkg) } }; @@ -141,16 +150,7 @@ fn parse_source( }; let inline_pkg = if let Some(inline) = inline { - let deps = resolve - .packages - .iter() - .map(|(id, p)| (p.name.clone(), id)) - .collect(); - - Some(resolve.push( - UnresolvedPackage::parse("macro-input".as_ref(), &inline)?, - &deps, - )?) + Some(resolve.push(UnresolvedPackage::parse("macro-input".as_ref(), &inline)?)?) } else { None }; diff --git a/crates/component-macro/tests/codegen.rs b/crates/component-macro/tests/codegen.rs index ac39534022c0..616f3253c614 100644 --- a/crates/component-macro/tests/codegen.rs +++ b/crates/component-macro/tests/codegen.rs @@ -4,9 +4,6 @@ macro_rules! gentest { mod sugar { wasmtime::component::bindgen!(in $path); } - mod normal { - wasmtime::component::bindgen!($name in $path); - } mod async_ { wasmtime::component::bindgen!({ path: $path, @@ -16,15 +13,12 @@ macro_rules! gentest { mod tracing { wasmtime::component::bindgen!({ path: $path, - world: $name, tracing: true, duplicate_if_necessary: true, }); } } - // ... }; - } component_macro_test_helpers::foreach!(gentest); diff --git a/crates/component-macro/tests/codegen/char.wit b/crates/component-macro/tests/codegen/char.wit index 01b20f70077f..b49947b38abb 100644 --- a/crates/component-macro/tests/codegen/char.wit +++ b/crates/component-macro/tests/codegen/char.wit @@ -1,3 +1,5 @@ +package foo:foo + interface chars { /// A function that accepts a character take-char: func(x: char) @@ -5,7 +7,7 @@ interface chars { return-char: func() -> char } -default world the-world { - import imports: self.chars - export exports: self.chars +world the-world { + import chars + export chars } diff --git a/crates/component-macro/tests/codegen/conventions.wit b/crates/component-macro/tests/codegen/conventions.wit index 2c5645c66313..a96b5afd3444 100644 --- a/crates/component-macro/tests/codegen/conventions.wit +++ b/crates/component-macro/tests/codegen/conventions.wit @@ -1,4 +1,5 @@ // hello 🐱 world +package foo:foo interface conventions { kebab-case: func() @@ -32,7 +33,7 @@ interface conventions { %bool: func() } -default world the-world { - import imports: self.conventions - export exports: self.conventions +world the-world { + import conventions + export conventions } diff --git a/crates/component-macro/tests/codegen/direct-import.wit b/crates/component-macro/tests/codegen/direct-import.wit index d2b612d6de71..67d252a4a898 100644 --- a/crates/component-macro/tests/codegen/direct-import.wit +++ b/crates/component-macro/tests/codegen/direct-import.wit @@ -1,3 +1,5 @@ -default world foo { +package foo:foo + +world foo { import foo: func() } diff --git a/crates/component-macro/tests/codegen/empty.wit b/crates/component-macro/tests/codegen/empty.wit index 1f99081f58cb..b720c27d628e 100644 --- a/crates/component-macro/tests/codegen/empty.wit +++ b/crates/component-macro/tests/codegen/empty.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world empty {} diff --git a/crates/component-macro/tests/codegen/flags.wit b/crates/component-macro/tests/codegen/flags.wit index b5a2fa2d1c83..8c9c1437169d 100644 --- a/crates/component-macro/tests/codegen/flags.wit +++ b/crates/component-macro/tests/codegen/flags.wit @@ -1,3 +1,5 @@ +package foo:foo + interface flegs { flags flag1 { b0, @@ -47,7 +49,7 @@ interface flegs { roundtrip-flag64: func(x: flag64) -> flag64 } -default world the-flags { - import import-flags: self.flegs - export export-flags: self.flegs +world the-flags { + import flegs + export flegs } diff --git a/crates/component-macro/tests/codegen/floats.wit b/crates/component-macro/tests/codegen/floats.wit index 4a0c67ce2c29..6cd720a8dc39 100644 --- a/crates/component-macro/tests/codegen/floats.wit +++ b/crates/component-macro/tests/codegen/floats.wit @@ -1,3 +1,5 @@ +package foo:foo + interface floats { float32-param: func(x: float32) float64-param: func(x: float64) @@ -5,7 +7,7 @@ interface floats { float64-result: func() -> float64 } -default world the-world { - import imports: self.floats - export exports: self.floats +world the-world { + import floats + export floats } diff --git a/crates/component-macro/tests/codegen/function-new.wit b/crates/component-macro/tests/codegen/function-new.wit index fed79c6633c6..2f4e407566cd 100644 --- a/crates/component-macro/tests/codegen/function-new.wit +++ b/crates/component-macro/tests/codegen/function-new.wit @@ -1,3 +1,4 @@ -default world foo { +package foo:foo +world foo { export new: func() } diff --git a/crates/component-macro/tests/codegen/integers.wit b/crates/component-macro/tests/codegen/integers.wit index bfad272882d0..2f5866bb2ae6 100644 --- a/crates/component-macro/tests/codegen/integers.wit +++ b/crates/component-macro/tests/codegen/integers.wit @@ -1,3 +1,5 @@ +package foo:foo + interface integers { a1: func(x: u8) a2: func(x: s8) @@ -32,7 +34,7 @@ interface integers { pair-ret: func() -> tuple } -default world the-world { - import imports: self.integers - export exports: self.integers +world the-world { + import integers + export integers } diff --git a/crates/component-macro/tests/codegen/lists.wit b/crates/component-macro/tests/codegen/lists.wit index 19b946068706..256a1cdf8fcf 100644 --- a/crates/component-macro/tests/codegen/lists.wit +++ b/crates/component-macro/tests/codegen/lists.wit @@ -1,3 +1,5 @@ +package foo:foo + interface lists { list-u8-param: func(x: list) list-u16-param: func(x: list) @@ -77,7 +79,7 @@ interface lists { load-store-everything: func(a: load-store-all-sizes) -> load-store-all-sizes } -default world the-lists { - import import-lists: self.lists - export export-lists: self.lists +world the-lists { + import lists + export lists } diff --git a/crates/component-macro/tests/codegen/many-arguments.wit b/crates/component-macro/tests/codegen/many-arguments.wit index a5b67b2184b1..cbfc123144fa 100644 --- a/crates/component-macro/tests/codegen/many-arguments.wit +++ b/crates/component-macro/tests/codegen/many-arguments.wit @@ -1,3 +1,5 @@ +package foo:foo + interface manyarg { many-args: func( a1: u64, @@ -44,7 +46,7 @@ interface manyarg { big-argument: func(x: big-struct) } -default world the-world { - import imports: self.manyarg - export exports: self.manyarg +world the-world { + import manyarg + export manyarg } diff --git a/crates/component-macro/tests/codegen/multi-return.wit b/crates/component-macro/tests/codegen/multi-return.wit index 716e77a6c850..69951b2c3393 100644 --- a/crates/component-macro/tests/codegen/multi-return.wit +++ b/crates/component-macro/tests/codegen/multi-return.wit @@ -1,3 +1,5 @@ +package foo:foo + interface multi-return { mra: func() mrb: func() -> () @@ -6,7 +8,7 @@ interface multi-return { mre: func() -> (a: u32, b: float32) } -default world the-world { - import imports: self.multi-return - export exports: self.multi-return +world the-world { + import multi-return + export multi-return } diff --git a/crates/component-macro/tests/codegen/records.wit b/crates/component-macro/tests/codegen/records.wit index 39d5e81694e8..f51bb8f28f75 100644 --- a/crates/component-macro/tests/codegen/records.wit +++ b/crates/component-macro/tests/codegen/records.wit @@ -1,3 +1,5 @@ +package foo:foo + interface records { tuple-arg: func(x: tuple) tuple-result: func() -> tuple @@ -53,7 +55,7 @@ interface records { typedef-inout: func(e: tuple-typedef2) -> s32 } -default world the-world { - import imports: self.records - export exports: self.records +world the-world { + import records + export records } diff --git a/crates/component-macro/tests/codegen/rename.wit b/crates/component-macro/tests/codegen/rename.wit index d60d4f6f9f43..8bfc7f36862b 100644 --- a/crates/component-macro/tests/codegen/rename.wit +++ b/crates/component-macro/tests/codegen/rename.wit @@ -1,5 +1,7 @@ +package foo:foo + interface red { - use self.green.{thing} + use green.{thing} foo: func() -> thing } @@ -8,7 +10,7 @@ interface green { type thing = s32 } -default world neptune { - import blue: self.red - import orange: self.green +world neptune { + import red + import green } diff --git a/crates/component-macro/tests/codegen/share-types.wit b/crates/component-macro/tests/codegen/share-types.wit index 106ee70936d9..8d36d1b0aa88 100644 --- a/crates/component-macro/tests/codegen/share-types.wit +++ b/crates/component-macro/tests/codegen/share-types.wit @@ -1,3 +1,5 @@ +package foo:foo + interface http-types{ record request { method: string @@ -7,13 +9,13 @@ interface http-types{ } } -default world http-interface { +world http-interface { export http-handler: interface { - use self.http-types.{request,response} + use http-types.{request,response} handle-request: func(request: request) -> response } import http-fetch: interface { - use self.http-types.{request,response} + use http-types.{request,response} fetch-request: func(request: request) -> response } } diff --git a/crates/component-macro/tests/codegen/simple-functions.wit b/crates/component-macro/tests/codegen/simple-functions.wit index cdb1183790fa..2593d199e565 100644 --- a/crates/component-macro/tests/codegen/simple-functions.wit +++ b/crates/component-macro/tests/codegen/simple-functions.wit @@ -1,3 +1,5 @@ +package foo:foo + interface simple { f1: func() f2: func(a: u32) @@ -9,7 +11,7 @@ interface simple { f6: func(a: u32, b: u32, c: u32) -> tuple } -default world the-world { - import imports: self.simple - export exports: self.simple +world the-world { + import simple + export simple } diff --git a/crates/component-macro/tests/codegen/simple-lists.wit b/crates/component-macro/tests/codegen/simple-lists.wit index 885cdeb74305..8e082b6e34e7 100644 --- a/crates/component-macro/tests/codegen/simple-lists.wit +++ b/crates/component-macro/tests/codegen/simple-lists.wit @@ -1,3 +1,5 @@ +package foo:foo + interface simple-lists { simple-list1: func(l: list) simple-list2: func() -> list @@ -5,7 +7,7 @@ interface simple-lists { simple-list4: func(l: list>) -> list> } -default world my-world { - import imports: self.simple-lists - export exports: self.simple-lists +world my-world { + import simple-lists + export simple-lists } diff --git a/crates/component-macro/tests/codegen/simple-wasi.wit b/crates/component-macro/tests/codegen/simple-wasi.wit index 02c47dc9b8f4..60192473d99e 100644 --- a/crates/component-macro/tests/codegen/simple-wasi.wit +++ b/crates/component-macro/tests/codegen/simple-wasi.wit @@ -1,3 +1,5 @@ +package foo:foo + interface wasi-filesystem { record descriptor-stat { } @@ -15,7 +17,7 @@ interface wall-clock { } } -default world wasi { - import wasi-filesystem: self.wasi-filesystem - import wall-clock: self.wall-clock +world wasi { + import wasi-filesystem + import wall-clock } diff --git a/crates/component-macro/tests/codegen/small-anonymous.wit b/crates/component-macro/tests/codegen/small-anonymous.wit index 96436091344d..ad9c67287d4e 100644 --- a/crates/component-macro/tests/codegen/small-anonymous.wit +++ b/crates/component-macro/tests/codegen/small-anonymous.wit @@ -1,3 +1,5 @@ +package foo:foo + interface anon { enum error { success, @@ -7,7 +9,7 @@ interface anon { option-test: func() -> result, error> } -default world the-world { - import imports: self.anon - export exports: self.anon +world the-world { + import anon + export anon } diff --git a/crates/component-macro/tests/codegen/smoke-default.wit b/crates/component-macro/tests/codegen/smoke-default.wit index 0d269359063f..90be0b1e3cdc 100644 --- a/crates/component-macro/tests/codegen/smoke-default.wit +++ b/crates/component-macro/tests/codegen/smoke-default.wit @@ -1,3 +1,5 @@ -default world the-world { +package foo:foo + +world the-world { export y: func() } diff --git a/crates/component-macro/tests/codegen/smoke-export.wit b/crates/component-macro/tests/codegen/smoke-export.wit index cefdc19823a0..983f1c35066e 100644 --- a/crates/component-macro/tests/codegen/smoke-export.wit +++ b/crates/component-macro/tests/codegen/smoke-export.wit @@ -1,4 +1,6 @@ -default world the-world { +package foo:foo + +world the-world { export the-name: interface { y: func() } diff --git a/crates/component-macro/tests/codegen/smoke.wit b/crates/component-macro/tests/codegen/smoke.wit index 6d8e80ccea86..0476bd988ec1 100644 --- a/crates/component-macro/tests/codegen/smoke.wit +++ b/crates/component-macro/tests/codegen/smoke.wit @@ -1,4 +1,6 @@ -default world the-world { +package foo:foo + +world the-world { import imports: interface { y: func() } diff --git a/crates/component-macro/tests/codegen/strings.wit b/crates/component-macro/tests/codegen/strings.wit index 7fc1885529bc..650300acfb9d 100644 --- a/crates/component-macro/tests/codegen/strings.wit +++ b/crates/component-macro/tests/codegen/strings.wit @@ -1,10 +1,12 @@ +package foo:foo + interface strings { a: func(x: string) b: func() -> string c: func(a: string, b: string) -> string } -default world the-world { - import imports: self.strings - export exports: self.strings +world the-world { + import strings + export strings } diff --git a/crates/component-macro/tests/codegen/unions.wit b/crates/component-macro/tests/codegen/unions.wit index 07e0f380a0d0..252f513f2de8 100644 --- a/crates/component-macro/tests/codegen/unions.wit +++ b/crates/component-macro/tests/codegen/unions.wit @@ -1,3 +1,5 @@ +package foo:foo + interface unions { /// A union of all of the integral types union all-integers { @@ -58,7 +60,7 @@ interface unions { identify-distinguishable-num: func(num: distinguishable-num) -> u8 } -default world the-unions { - import import-unions: self.unions - export export-unions: self.unions +world the-unions { + import unions + export unions } diff --git a/crates/component-macro/tests/codegen/use-paths.wit b/crates/component-macro/tests/codegen/use-paths.wit index 1e877379caf4..dab6646afac8 100644 --- a/crates/component-macro/tests/codegen/use-paths.wit +++ b/crates/component-macro/tests/codegen/use-paths.wit @@ -1,3 +1,5 @@ +package foo:foo + interface a { record foo {} @@ -5,22 +7,22 @@ interface a { } interface b { - use self.a.{foo} + use a.{foo} a: func() -> foo } interface c { - use self.b.{foo} + use b.{foo} a: func() -> foo } -default world d { - import a: self.a - import b: self.b +world d { + import a + import b import d: interface { - use self.c.{foo} + use c.{foo} b: func() -> foo } diff --git a/crates/component-macro/tests/codegen/variants.wit b/crates/component-macro/tests/codegen/variants.wit index 590675dcf6c0..b6c47d89650e 100644 --- a/crates/component-macro/tests/codegen/variants.wit +++ b/crates/component-macro/tests/codegen/variants.wit @@ -1,3 +1,5 @@ +package foo:foo + interface variants { enum e1 { a, @@ -139,7 +141,7 @@ interface variants { return-named-result: func() -> (a: result) } -default world my-world { - import imports: self.variants - export exports: self.variants +world my-world { + import variants + export variants } diff --git a/crates/component-macro/tests/codegen/worlds-with-types.wit b/crates/component-macro/tests/codegen/worlds-with-types.wit index 25db9036da12..dc4cbddcbabe 100644 --- a/crates/component-macro/tests/codegen/worlds-with-types.wit +++ b/crates/component-macro/tests/codegen/worlds-with-types.wit @@ -1,9 +1,11 @@ +package foo:foo + interface i { type t = u16 } -default world foo { - use self.i.{t as u} +world foo { + use i.{t as u} type t = u32 diff --git a/crates/environ/src/component/translate.rs b/crates/environ/src/component/translate.rs index 5b91622703a1..8ac64ad31286 100644 --- a/crates/environ/src/component/translate.rs +++ b/crates/environ/src/component/translate.rs @@ -7,7 +7,7 @@ use anyhow::{bail, Result}; use indexmap::IndexMap; use std::collections::HashMap; use std::mem; -use wasmparser::{Chunk, Encoding, Parser, Payload, Validator}; +use wasmparser::{Chunk, ComponentImportName, Encoding, Parser, Payload, Validator}; mod adapt; pub use self::adapt::*; @@ -163,7 +163,7 @@ struct Translation<'data> { #[allow(missing_docs)] enum LocalInitializer<'data> { // imports - Import(&'data str, TypeDef), + Import(ComponentImportName<'data>, TypeDef), // canonical function sections Lower(ComponentFuncIndex, LocalCanonicalOptions), @@ -623,7 +623,7 @@ impl<'a, 'data> Translator<'a, 'data> { for export in s { let export = export?; let item = self.kind_to_item(export.kind, export.index); - let prev = self.result.exports.insert(export.name, item); + let prev = self.result.exports.insert(export.name.as_str(), item); assert!(prev.is_none()); self.result .initializers @@ -832,9 +832,9 @@ impl<'a, 'data> Translator<'a, 'data> { ComponentItem::Type(ty) => Some(ComponentItemType::Type(ty)), ComponentItem::Module(_) => None, }; - map.insert(export.name, idx); + map.insert(export.name.as_str(), idx); if let Some(ty) = ty { - types.insert(export.name, ty); + types.insert(export.name.as_str(), ty); } } @@ -901,15 +901,15 @@ impl<'a, 'data> Translator<'a, 'data> { // An imported component instance is being aliased, so the type of // the aliased item is directly available from the instance type. ComponentInstanceType::Index(ty) => { - let (_url, ty) = &self.types[ty].exports[name]; - self.push_typedef(*ty); + let ty = self.types[ty].exports[name]; + self.push_typedef(ty); } // An imported component was instantiated so the type of the aliased // export is available through the type of the export on the // original component. ComponentInstanceType::InstantiatedIndex(ty) => { - let (_, ty) = self.types[ty].exports[name]; + let ty = self.types[ty].exports[name]; self.push_typedef(ty); } diff --git a/crates/environ/src/component/translate/inline.rs b/crates/environ/src/component/translate/inline.rs index 95aa449c1e9b..62a7d007a318 100644 --- a/crates/environ/src/component/translate/inline.rs +++ b/crates/environ/src/component/translate/inline.rs @@ -82,9 +82,12 @@ pub(super) fn run( LocalInitializer::Import(name, ty) => (name, ty), _ => continue, }; - let index = inliner.result.import_types.push((name.to_string(), ty)); + let index = inliner + .result + .import_types + .push((name.as_str().to_string(), ty)); let path = ImportPath::root(index); - args.insert(name, ComponentItemDef::from_import(path, ty)?); + args.insert(name.as_str(), ComponentItemDef::from_import(path, ty)?); } // This will run the inliner to completion after being seeded with the @@ -376,7 +379,7 @@ impl<'a> Inliner<'a> { // but for sub-components this will do resolution to connect what // was provided as an import at the instantiation-site to what was // needed during the component's instantiation. - Import(name, _ty) => match &frame.args[name] { + Import(name, _ty) => match &frame.args[name.as_str()] { ComponentItemDef::Module(i) => { frame.modules.push(i.clone()); } @@ -674,7 +677,7 @@ impl<'a> Inliner<'a> { ComponentInstanceDef::Import(path, ty) => { let mut path = path.clone(); path.path.push(name); - match self.types[*ty].exports[*name].1 { + match self.types[*ty].exports[*name] { TypeDef::ComponentFunc(_) => { frame.component_funcs.push(ComponentFuncDef::Import(path)); } @@ -939,7 +942,7 @@ impl<'a> Inliner<'a> { // Note that for now this would only work with // module-exporting instances. ComponentInstanceDef::Import(path, ty) => { - for (name, (_url, ty)) in self.types[ty].exports.iter() { + for (name, ty) in self.types[ty].exports.iter() { let mut path = path.clone(); path.path.push(name); let def = ComponentItemDef::from_import(path, *ty)?; diff --git a/crates/environ/src/component/types.rs b/crates/environ/src/component/types.rs index 7668cdde3e4d..9ddfb75fa442 100644 --- a/crates/environ/src/component/types.rs +++ b/crates/environ/src/component/types.rs @@ -552,17 +552,13 @@ impl ComponentTypesBuilder { ComponentTypeDeclaration::Type(ty) => self.type_declaration_type(ty)?, ComponentTypeDeclaration::CoreType(ty) => self.type_declaration_core_type(ty)?, ComponentTypeDeclaration::Alias(alias) => self.type_declaration_alias(alias)?, - ComponentTypeDeclaration::Export { name, url, ty } => { + ComponentTypeDeclaration::Export { name, ty } => { let ty = self.type_declaration_define(ty); - result - .exports - .insert(name.to_string(), (url.to_string(), ty)); + result.exports.insert(name.as_str().to_string(), ty); } ComponentTypeDeclaration::Import(import) => { let ty = self.type_declaration_define(&import.ty); - result - .imports - .insert(import.name.to_string(), (import.url.to_string(), ty)); + result.imports.insert(import.name.as_str().to_string(), ty); } } } @@ -584,11 +580,9 @@ impl ComponentTypesBuilder { InstanceTypeDeclaration::Type(ty) => self.type_declaration_type(ty)?, InstanceTypeDeclaration::CoreType(ty) => self.type_declaration_core_type(ty)?, InstanceTypeDeclaration::Alias(alias) => self.type_declaration_alias(alias)?, - InstanceTypeDeclaration::Export { name, url, ty } => { + InstanceTypeDeclaration::Export { name, ty } => { let ty = self.type_declaration_define(ty); - result - .exports - .insert(name.to_string(), (url.to_string(), ty)); + result.exports.insert(name.as_str().to_string(), ty); } } } @@ -635,7 +629,7 @@ impl ComponentTypesBuilder { } => { let ty = self.type_scopes.last().unwrap().instances [ComponentInstanceIndex::from_u32(*instance_index)]; - let (_, ty) = self.component_types[ty].exports[*name]; + let ty = self.component_types[ty].exports[*name]; self.push_component_typedef(ty); } a => unreachable!("invalid alias {a:?}"), @@ -1018,9 +1012,9 @@ pub struct TypeModule { #[derive(Serialize, Deserialize, Default)] pub struct TypeComponent { /// The named values that this component imports. - pub imports: IndexMap, + pub imports: IndexMap, /// The named values that this component exports. - pub exports: IndexMap, + pub exports: IndexMap, } /// The type of a component instance in the component model, or an instantiated @@ -1030,7 +1024,7 @@ pub struct TypeComponent { #[derive(Serialize, Deserialize, Default)] pub struct TypeComponentInstance { /// The list of exports that this component has along with their types. - pub exports: IndexMap, + pub exports: IndexMap, } /// A component function type in the component model. diff --git a/crates/test-programs/Cargo.toml b/crates/test-programs/Cargo.toml index a45cb7587944..703dfe2fda2e 100644 --- a/crates/test-programs/Cargo.toml +++ b/crates/test-programs/Cargo.toml @@ -11,6 +11,9 @@ license = "Apache-2.0 WITH LLVM-exception" cfg-if = "1.0" cargo_metadata = "0.15.3" +[dependencies] +wasmtime-wasi-http = { workspace = true, optional = true } + [dev-dependencies] wasi-common = { workspace = true } wasi-cap-std-sync = { workspace = true } @@ -24,7 +27,6 @@ anyhow = { workspace = true } wat = { workspace = true } cap-std = { workspace = true } tokio = { version = "1.8.0", features = ["net", "rt-multi-thread"] } -wasmtime-wasi-http = { workspace = true } hyper = { version = "1.0.0-rc.3", features = ["full"] } http = { version = "0.2.9" } http-body = "1.0.0-rc.2" @@ -32,4 +34,4 @@ http-body-util = "0.1.0-rc.2" [features] test_programs = [] -test_programs_http = [ "wasmtime/component-model" ] +test_programs_http = [ "wasmtime/component-model", "dep:wasmtime-wasi-http" ] diff --git a/crates/wasi-http/Cargo.toml b/crates/wasi-http/Cargo.toml index d3d2e0957231..1325a33285cd 100644 --- a/crates/wasi-http/Cargo.toml +++ b/crates/wasi-http/Cargo.toml @@ -8,6 +8,10 @@ license = "Apache-2.0 WITH LLVM-exception" description = "Experimental HTTP library for WebAssembly in Wasmtime" readme = "readme.md" +[lib] +test = false +doctest = false + [dependencies] anyhow = { workspace = true } bytes = "1.1.0" diff --git a/crates/wasmtime/src/component/matching.rs b/crates/wasmtime/src/component/matching.rs index 6f2cb5549baa..0f843032b97c 100644 --- a/crates/wasmtime/src/component/matching.rs +++ b/crates/wasmtime/src/component/matching.rs @@ -72,7 +72,7 @@ impl TypeChecker<'_> { // Like modules, every export in the expected type must be present in // the actual type. It's ok, though, to have extra exports in the actual // type. - for (name, (_url, expected)) in expected.exports.iter() { + for (name, expected) in expected.exports.iter() { // Interface types may be exported from a component in order to give them a name, but // they don't have a definition in the sense that this search is interested in, so // ignore them. diff --git a/crates/wasmtime/src/component/mod.rs b/crates/wasmtime/src/component/mod.rs index 671cce9d0bd8..f2066843e44a 100644 --- a/crates/wasmtime/src/component/mod.rs +++ b/crates/wasmtime/src/component/mod.rs @@ -73,7 +73,9 @@ pub(crate) use self::store::ComponentStoreData; /// ```text,ignore /// // wit/my-component.wit /// -/// default world hello-world { +/// package my:project +/// +/// world hello-world { /// import name: func() -> string /// export greet: func() /// } @@ -150,13 +152,15 @@ pub(crate) use self::store::ComponentStoreData; /// ```text,ignore /// // wit/my-component.wit /// +/// package my:project +/// /// interface host { /// gen-random-integer: func() -> u32 /// sha256: func(bytes: list) -> string /// } /// /// default world hello-world { -/// import host: self.host +/// import host /// /// export demo: interface { /// run: func() @@ -169,6 +173,7 @@ pub(crate) use self::store::ComponentStoreData; /// ```rust,ignore /// use wasmtime::component::*; /// use wasmtime::{Config, Engine, Store}; +/// use my::project::host::Host; /// /// bindgen!(); /// @@ -177,7 +182,7 @@ pub(crate) use self::store::ComponentStoreData; /// } /// /// // Note that the trait here is per-interface and within a submodule now. -/// impl host::Host for MyState { +/// impl Host for MyState { /// fn gen_random_integer(&mut self) -> wasmtime::Result { /// Ok(rand::thread_rng().gen()) /// } @@ -228,18 +233,12 @@ pub(crate) use self::store::ComponentStoreData; /// bindgen!(); /// /// // Parse the `wit/` folder adjacent to this crate's `Cargo.toml` and look -/// // for the document `foo`, which must have a `default world` contained -/// // within it. +/// // for the world `foo` contained in it. /// bindgen!("foo"); /// -/// // Parse the `wit/` folder adjacent to `Cargo.toml` and look up the document -/// // `foo` and the world named `bar`. -/// bindgen!("foo.bar"); -/// /// // Parse the folder `other/wit/folder` adjacent to `Cargo.toml`. /// bindgen!(in "other/wit/folder"); /// bindgen!("foo" in "other/wit/folder"); -/// bindgen!("foo.bar" in "other/wit/folder"); /// /// // Parse the file `foo.wit` as a single-file WIT package with no /// // dependencies. @@ -250,8 +249,7 @@ pub(crate) use self::store::ComponentStoreData; /// /// ```rust,ignore /// bindgen!({ -/// world: "foo", // or "foo.bar", same as in `bindgen!("foo")` -/// // not needed if `path` has one `default world` +/// world: "foo", // not needed if `path` has one `world` /// /// // same as in `bindgen!(in "other/wit/folder") /// path: "other/wit/folder", @@ -259,7 +257,9 @@ pub(crate) use self::store::ComponentStoreData; /// // Instead of `path` the WIT document can be provided inline if /// // desired. /// inline: " -/// default world foo { +/// package my:inline +/// +/// world foo { /// // ... /// } /// ", @@ -295,7 +295,7 @@ pub(crate) use self::store::ComponentStoreData; /// // Restrict the code generated to what's needed for the interface /// // imports in the inlined WIT document fragment. /// interfaces: " -/// import foo: package.foo; +/// import package.foo /// ", /// /// // Remap interface names to module names, imported from elsewhere. diff --git a/crates/wit-bindgen/src/lib.rs b/crates/wit-bindgen/src/lib.rs index a935912aab86..41868b64ce5c 100644 --- a/crates/wit-bindgen/src/lib.rs +++ b/crates/wit-bindgen/src/lib.rs @@ -31,28 +31,35 @@ struct InterfaceName { remapped: bool, /// The string name for this interface. - name: String, + path: String, } #[derive(Default)] struct Wasmtime { src: Source, opts: Opts, - imports: Vec, + import_interfaces: BTreeMap, Vec>, + import_functions: Vec, exports: Exports, types: Types, sizes: SizeAlign, interface_names: HashMap, + with_name_counter: usize, } -enum Import { - Interface { snake: String }, - Function { add_to_linker: String, sig: String }, +struct ImportInterface { + snake: String, + module: String, +} +struct ImportFunction { + add_to_linker: String, + sig: String, } #[derive(Default)] struct Exports { fields: BTreeMap, + modules: BTreeMap, Vec>, funcs: Vec, } @@ -111,16 +118,33 @@ impl Opts { } impl Wasmtime { - fn name_interface(&mut self, id: InterfaceId, name: String) -> bool { - let entry = if let Some(remapped_name) = self.opts.with.get(&name) { + fn name_interface(&mut self, resolve: &Resolve, id: InterfaceId, name: &WorldKey) -> bool { + let with_name = resolve.name_world_key(name); + let entry = if let Some(remapped_path) = self.opts.with.get(&with_name) { + let name = format!("__with_name{}", self.with_name_counter); + self.with_name_counter += 1; + uwriteln!(self.src, "use {remapped_path} as {name};"); InterfaceName { remapped: true, - name: remapped_name.clone(), + path: name, } } else { + let path = match name { + WorldKey::Name(name) => name.to_snake_case(), + WorldKey::Interface(_) => { + let iface = &resolve.interfaces[id]; + let pkgname = &resolve.packages[iface.package.unwrap()].name; + format!( + "{}::{}::{}", + pkgname.namespace.to_snake_case(), + pkgname.name.to_snake_case(), + iface.name.as_ref().unwrap().to_snake_case() + ) + } + }; InterfaceName { remapped: false, - name, + path, } }; @@ -146,30 +170,38 @@ impl Wasmtime { self.finish(resolve, id) } - fn import(&mut self, resolve: &Resolve, name: &str, item: &WorldItem) { - let snake = name.to_snake_case(); + fn import(&mut self, resolve: &Resolve, name: &WorldKey, item: &WorldItem) { let mut gen = InterfaceGenerator::new(self, resolve); - let import = match item { + match item { WorldItem::Function(func) => { gen.generate_function_trait_sig(TypeOwner::None, func); let sig = mem::take(&mut gen.src).into(); gen.generate_add_function_to_linker(TypeOwner::None, func, "linker"); let add_to_linker = gen.src.into(); - Import::Function { sig, add_to_linker } + self.import_functions + .push(ImportFunction { sig, add_to_linker }); } WorldItem::Interface(id) => { - if gen.gen.name_interface(*id, snake.clone()) { + if gen.gen.name_interface(resolve, *id, name) { return; } - gen.current_interface = Some(*id); + gen.current_interface = Some((*id, name, false)); gen.types(*id); gen.generate_trappable_error_types(TypeOwner::Interface(*id)); - gen.generate_add_to_linker(*id, name); + let key_name = resolve.name_world_key(name); + gen.generate_add_to_linker(*id, &key_name); let module = &gen.src[..]; - uwriteln!( - self.src, + let snake = match name { + WorldKey::Name(s) => s.to_snake_case(), + WorldKey::Interface(id) => resolve.interfaces[*id] + .name + .as_ref() + .unwrap() + .to_snake_case(), + }; + let module = format!( " #[allow(clippy::all)] pub mod {snake} {{ @@ -180,40 +212,55 @@ impl Wasmtime { }} " ); - Import::Interface { snake } + let pkg = resolve.interfaces[*id].package.unwrap(); + let pkgname = match name { + WorldKey::Name(_) => None, + WorldKey::Interface(_) => Some(resolve.packages[pkg].name.clone()), + }; + self.import_interfaces + .entry(pkgname) + .or_insert(Vec::new()) + .push(ImportInterface { snake, module }); } WorldItem::Type(ty) => { + let name = match name { + WorldKey::Name(name) => name, + WorldKey::Interface(_) => unreachable!(), + }; gen.define_type(name, *ty); let body = mem::take(&mut gen.src); self.src.push_str(&body); - return; } }; - - self.imports.push(import); } - fn export(&mut self, resolve: &Resolve, name: &str, item: &WorldItem) { - let snake = name.to_snake_case(); + fn export(&mut self, resolve: &Resolve, name: &WorldKey, item: &WorldItem) { let mut gen = InterfaceGenerator::new(self, resolve); - let (ty, getter) = match item { + let (field, ty, getter) = match item { WorldItem::Function(func) => { - gen.define_rust_guest_export(None, func); + gen.define_rust_guest_export(resolve, None, func); let body = mem::take(&mut gen.src).into(); let (_name, getter) = gen.extract_typed_function(func); assert!(gen.src.is_empty()); self.exports.funcs.push(body); - ("wasmtime::component::Func".to_string(), getter) + ( + func.name.to_snake_case(), + "wasmtime::component::Func".to_string(), + getter, + ) } WorldItem::Type(_) => unreachable!(), WorldItem::Interface(id) => { - gen.gen.name_interface(*id, snake.clone()); - gen.current_interface = Some(*id); + gen.gen.name_interface(resolve, *id, name); + gen.current_interface = Some((*id, name, true)); gen.types(*id); gen.generate_trappable_error_types(TypeOwner::Interface(*id)); let iface = &resolve.interfaces[*id]; - - let camel = to_rust_upper_camel_case(name); + let iface_name = match name { + WorldKey::Name(name) => name, + WorldKey::Interface(_) => iface.name.as_ref().unwrap(), + }; + let camel = to_rust_upper_camel_case(iface_name); uwriteln!(gen.src, "pub struct {camel} {{"); for (_, func) in iface.functions.iter() { uwriteln!( @@ -246,14 +293,14 @@ impl Wasmtime { uwriteln!(gen.src, "}})"); uwriteln!(gen.src, "}}"); for (_, func) in iface.functions.iter() { - gen.define_rust_guest_export(Some(name), func); + gen.define_rust_guest_export(resolve, Some(name), func); } uwriteln!(gen.src, "}}"); let module = &gen.src[..]; + let snake = iface_name.to_snake_case(); - uwriteln!( - self.src, + let module = format!( " #[allow(clippy::all)] pub mod {snake} {{ @@ -264,26 +311,54 @@ impl Wasmtime { }} " ); - + let pkgname = match name { + WorldKey::Name(_) => None, + WorldKey::Interface(_) => { + Some(resolve.packages[iface.package.unwrap()].name.clone()) + } + }; + self.exports + .modules + .entry(pkgname.clone()) + .or_insert(Vec::new()) + .push(module); + + let name = resolve.name_world_key(name); + let (path, method_name) = match pkgname { + Some(pkgname) => ( + format!( + "exports::{}::{}::{snake}::{camel}", + pkgname.namespace.to_snake_case(), + pkgname.name.to_snake_case(), + ), + format!( + "{}_{}_{snake}", + pkgname.namespace.to_snake_case(), + pkgname.name.to_snake_case() + ), + ), + None => (format!("exports::{snake}::{camel}"), snake.clone()), + }; let getter = format!( "\ - {snake}::{camel}::new( + {path}::new( &mut __exports.instance(\"{name}\") .ok_or_else(|| anyhow::anyhow!(\"exported instance `{name}` not present\"))? )?\ " ); + let field = format!("interface{}", self.exports.fields.len()); self.exports.funcs.push(format!( " - pub fn {snake}(&self) -> &{snake}::{camel} {{ - &self.{snake} + pub fn {method_name}(&self) -> &{path} {{ + &self.{field} }} - " + ", )); - (format!("{snake}::{camel}"), getter) + (field, path, getter) } }; - let prev = self.exports.fields.insert(snake.clone(), (ty, getter)); + let prev = self.exports.fields.insert(field, (ty, getter)); assert!(prev.is_none()); } @@ -375,6 +450,47 @@ impl Wasmtime { self.build_struct(resolve, world) } + for (pkg, imports) in self.import_interfaces.iter() { + match pkg { + Some(pkg) => { + uwriteln!(self.src, "pub mod {} {{", pkg.namespace.to_snake_case()); + uwriteln!(self.src, "pub mod {} {{", pkg.name.to_snake_case()); + for import in imports { + uwriteln!(self.src, "{}", import.module); + } + uwriteln!(self.src, "}}"); + uwriteln!(self.src, "}}"); + } + None => { + for import in imports { + uwriteln!(self.src, "{}", import.module); + } + } + } + } + if !self.exports.modules.is_empty() { + uwriteln!(self.src, "pub mod exports {{"); + for (pkg, modules) in self.exports.modules.iter() { + match pkg { + Some(pkg) => { + uwriteln!(self.src, "pub mod {} {{", pkg.namespace.to_snake_case()); + uwriteln!(self.src, "pub mod {} {{", pkg.name.to_snake_case()); + for module in modules { + uwriteln!(self.src, "{}", module); + } + uwriteln!(self.src, "}}"); + uwriteln!(self.src, "}}"); + } + None => { + for module in modules { + uwriteln!(self.src, "{}", module); + } + } + } + } + uwriteln!(self.src, "}}"); + } + let mut src = mem::take(&mut self.src); if self.opts.rustfmt { let mut child = Command::new("rustfmt") @@ -406,17 +522,7 @@ impl Wasmtime { impl Wasmtime { fn toplevel_import_trait(&mut self, resolve: &Resolve, world: WorldId) { - let mut functions = Vec::new(); - for import in self.imports.iter() { - match import { - Import::Interface { .. } => continue, - Import::Function { - sig, - add_to_linker: _, - } => functions.push(sig), - } - } - if functions.is_empty() { + if self.import_functions.is_empty() { return; } @@ -425,26 +531,29 @@ impl Wasmtime { uwriteln!(self.src, "#[wasmtime::component::__internal::async_trait]") } uwriteln!(self.src, "pub trait {world_camel}Imports {{"); - for sig in functions { - self.src.push_str(sig); + for f in self.import_functions.iter() { + self.src.push_str(&f.sig); self.src.push_str("\n"); } uwriteln!(self.src, "}}"); } fn toplevel_add_to_linker(&mut self, resolve: &Resolve, world: WorldId) { - if self.imports.is_empty() { + if self.import_interfaces.is_empty() && self.import_functions.is_empty() { return; } - let mut functions = Vec::new(); let mut interfaces = Vec::new(); - for import in self.imports.iter() { - match import { - Import::Interface { snake } => interfaces.push(snake), - Import::Function { - add_to_linker, - sig: _, - } => functions.push(add_to_linker), + for (pkg, imports) in self.import_interfaces.iter() { + for import in imports { + let mut path = String::new(); + if let Some(pkg) = pkg { + path.push_str(&pkg.namespace.to_snake_case()); + path.push_str("::"); + path.push_str(&pkg.name.to_snake_case()); + path.push_str("::"); + } + path.push_str(&import.snake); + interfaces.push(path) } } @@ -463,7 +572,7 @@ impl Wasmtime { for (i, name) in interfaces .iter() .map(|n| format!("{n}::Host")) - .chain(if functions.is_empty() { + .chain(if self.import_functions.is_empty() { None } else { Some(world_trait.clone()) @@ -485,11 +594,11 @@ impl Wasmtime { for name in interfaces.iter() { uwriteln!(self.src, "{name}::add_to_linker(linker, get)?;"); } - if !functions.is_empty() { + if !self.import_functions.is_empty() { uwriteln!(self.src, "Self::add_root_to_linker(linker, get)?;"); } uwriteln!(self.src, "Ok(())\n}}"); - if functions.is_empty() { + if self.import_functions.is_empty() { return; } @@ -505,8 +614,8 @@ impl Wasmtime { let mut linker = linker.root(); ", ); - for add_to_linker in functions { - self.src.push_str(add_to_linker); + for f in self.import_functions.iter() { + self.src.push_str(&f.add_to_linker); self.src.push_str("\n"); } uwriteln!(self.src, "Ok(())\n}}"); @@ -517,7 +626,7 @@ struct InterfaceGenerator<'a> { src: Source, gen: &'a mut Wasmtime, resolve: &'a Resolve, - current_interface: Option, + current_interface: Option<(InterfaceId, &'a WorldKey, bool)>, } impl<'a> InterfaceGenerator<'a> { @@ -1263,7 +1372,12 @@ impl<'a> InterfaceGenerator<'a> { ret } - fn define_rust_guest_export(&mut self, ns: Option<&str>, func: &Function) { + fn define_rust_guest_export( + &mut self, + resolve: &Resolve, + ns: Option<&WorldKey>, + func: &Function, + ) { let (async_, async__, await_) = if self.gen.opts.async_ { ("async", "_async", ".await") } else { @@ -1292,17 +1406,20 @@ impl<'a> InterfaceGenerator<'a> { } if self.gen.opts.tracing { + let ns = match ns { + Some(key) => resolve.name_world_key(key), + None => "default".to_string(), + }; self.src.push_str(&format!( " let span = tracing::span!( tracing::Level::TRACE, \"wit-bindgen export\", - module = \"{}\", + module = \"{ns}\", function = \"{}\", ); let _enter = span.enter(); ", - ns.unwrap_or("default"), func.name, )); } @@ -1466,17 +1583,26 @@ impl<'a> RustGenerator<'a> for InterfaceGenerator<'a> { } fn path_to_interface(&self, interface: InterfaceId) -> Option { - match self.current_interface { - Some(id) if id == interface => None, - _ => { - let InterfaceName { remapped, name } = &self.gen.interface_names[&interface]; - Some(if self.current_interface.is_some() && !remapped { - format!("super::{name}") - } else { - name.clone() - }) + let mut path_to_root = String::new(); + if let Some((cur, key, is_export)) = self.current_interface { + if cur == interface { + return None; + } + match key { + WorldKey::Name(_) => { + path_to_root.push_str("super::"); + } + WorldKey::Interface(_) => { + path_to_root.push_str("super::super::super::"); + } + } + if is_export { + path_to_root.push_str("super::"); } } + let InterfaceName { path, .. } = &self.gen.interface_names[&interface]; + path_to_root.push_str(path); + Some(path_to_root) } fn push_str(&mut self, s: &str) { diff --git a/src/commands/run.rs b/src/commands/run.rs index 95c5fc43ef0b..ea127c743a73 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -844,6 +844,7 @@ fn generate_coredump(err: &anyhow::Error, source_name: &str, coredump_path: &str instanceidx, f.func_index(), u32::try_from(f.func_offset().unwrap_or(0)).unwrap(), + 0, // TODO: this is probably wrong // We don't currently have access to locals/stack values [], [], diff --git a/tests/all/component_model/bindgen.rs b/tests/all/component_model/bindgen.rs index d8c8f3023cd4..c377f08a6579 100644 --- a/tests/all/component_model/bindgen.rs +++ b/tests/all/component_model/bindgen.rs @@ -14,7 +14,9 @@ mod no_imports { wasmtime::component::bindgen!({ inline: " - default world no-imports { + package foo:foo + + world no-imports { export foo: interface { foo: func() } @@ -59,7 +61,9 @@ mod one_import { wasmtime::component::bindgen!({ inline: " - default world one-import { + package foo:foo + + world one-import { import foo: interface { foo: func() } diff --git a/tests/all/component_model/bindgen/results.rs b/tests/all/component_model/bindgen/results.rs index eaec5cc3ac4c..d0c49e40245e 100644 --- a/tests/all/component_model/bindgen/results.rs +++ b/tests/all/component_model/bindgen/results.rs @@ -9,7 +9,8 @@ mod empty_error { use super::*; wasmtime::component::bindgen!({ inline: " - default world result-playground { + package inline:inline + world result-playground { import imports: interface { empty-error: func(a: float64) -> result } @@ -109,7 +110,8 @@ mod string_error { use super::*; wasmtime::component::bindgen!({ inline: " - default world result-playground { + package inline:inline + world result-playground { import imports: interface { string-error: func(a: float64) -> result } @@ -219,14 +221,18 @@ mod string_error { mod enum_error { use super::*; + use exports::foo; + use inline::inline::imports; + wasmtime::component::bindgen!({ inline: " + package inline:inline interface imports { enum e1 { a, b, c } enum-error: func(a: float64) -> result } - default world result-playground { - import imports: self.imports + world result-playground { + import imports export foo: interface { enum e1 { a, b, c } enum-error: func(a: float64) -> result @@ -244,7 +250,7 @@ mod enum_error { r#" (component (type $err' (enum "a" "b" "c")) - (import "imports" (instance $i + (import (interface "inline:inline/imports") (instance $i (export $err "err" (type (eq $err'))) (export "enum-error" (func (param "a" float64) (result (result float64 (error $err))))) )) @@ -357,7 +363,7 @@ mod enum_error { .expect("no trap") .err() .expect("error returned"); - assert_eq!(e, enum_error::foo::E1::A); + assert_eq!(e, foo::E1::A); let e = results .foo() @@ -377,14 +383,18 @@ mod enum_error { mod record_error { use super::*; + use exports::foo; + use inline::inline::imports; + wasmtime::component::bindgen!({ inline: " + package inline:inline interface imports { record e2 { line: u32, col: u32 } record-error: func(a: float64) -> result } - default world result-playground { - import imports: self.imports + world result-playground { + import imports export foo: interface { record e2 { line: u32, col: u32 } record-error: func(a: float64) -> result @@ -407,7 +417,7 @@ mod record_error { (field "line" u32) (field "col" u32) )) - (import "imports" (instance $i + (import (interface "inline:inline/imports") (instance $i (export $e2 "e2" (type (eq $e2'))) (type $result (result float64 (error $e2))) (export "record-error" (func (param "a" float64) (result $result))) @@ -525,16 +535,20 @@ mod record_error { mod variant_error { use super::*; + use exports::foo; + use inline::inline::imports; + wasmtime::component::bindgen!({ inline: " + package inline:inline interface imports { enum e1 { a, b, c } record e2 { line: u32, col: u32 } variant e3 { E1(e1), E2(e2) } variant-error: func(a: float64) -> result } - default world result-playground { - import imports: self.imports + world result-playground { + import imports export foo: interface { enum e1 { a, b, c } record e2 { line: u32, col: u32 } @@ -559,7 +573,7 @@ mod variant_error { (case "E1" $e1') (case "E2" $e2') )) - (import "imports" (instance $i + (import (interface "inline:inline/imports") (instance $i (export $e1 "e1" (type (eq $e1'))) (export $e2 "e2" (type (eq $e2'))) (type $e3' (variant @@ -710,7 +724,8 @@ mod with_remapping { wasmtime::component::bindgen!({ inline: " - default world result-playground { + package inline:inline + world result-playground { import imports: interface { empty-error: func(a: float64) -> result }