diff --git a/Cargo.lock b/Cargo.lock index 7026136..3ab8836 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,7 +372,7 @@ dependencies = [ [[package]] name = "componentize-go" -version = "0.4.0" +version = "0.4.1" dependencies = [ "anyhow", "bzip2", @@ -386,7 +386,7 @@ dependencies = [ "which", "wit-bindgen-go", "wit-component", - "wit-parser 0.252.0", + "wit-parser 0.253.0", ] [[package]] @@ -2272,7 +2272,7 @@ dependencies = [ [[package]] name = "tests" -version = "0.4.0" +version = "0.4.1" dependencies = [ "anyhow", "bzip2", @@ -2740,16 +2740,26 @@ dependencies = [ "wasmparser 0.252.0", ] +[[package]] +name = "wasm-encoder" +version = "0.253.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59972d6cd272259de647b7c1f1912e45e289c75ffd4be04e10695507cd7e1b59" +dependencies = [ + "leb128fmt", + "wasmparser 0.253.0", +] + [[package]] name = "wasm-metadata" -version = "0.252.0" +version = "0.253.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b7e08e02a3cd55bf778009d4cd6faae50da011f293644daf78a531a32d6d142" +checksum = "b3f45816ef616806f48498bcd831377de578c4fa51db0c83ab8ceb78cc13523b" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.252.0", - "wasmparser 0.252.0", + "wasm-encoder 0.253.0", + "wasmparser 0.253.0", ] [[package]] @@ -2770,6 +2780,17 @@ name = "wasmparser" version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3eb099dcadcde5be9eef55e3a337128efd4e44b4c93122487e4d2e4e1c6627c" +dependencies = [ + "bitflags", + "indexmap", + "semver", +] + +[[package]] +name = "wasmparser" +version = "0.253.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19db11f87d2486580e1e8b6f494c54df7e0566b87d0b599db843c24019667339" dependencies = [ "bitflags", "hashbrown 0.17.1", @@ -3532,22 +3553,22 @@ checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "wit-bindgen-core" -version = "0.58.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=4642b6bcc4283361b5d85eb00b00addf618458a9#4642b6bcc4283361b5d85eb00b00addf618458a9" +version = "0.59.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=50b799afcb886551565cb29c190371026aa55a30#50b799afcb886551565cb29c190371026aa55a30" dependencies = [ "anyhow", "heck", - "wit-parser 0.252.0", + "wit-parser 0.253.0", ] [[package]] name = "wit-bindgen-go" -version = "0.58.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=4642b6bcc4283361b5d85eb00b00addf618458a9#4642b6bcc4283361b5d85eb00b00addf618458a9" +version = "0.59.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=50b799afcb886551565cb29c190371026aa55a30#50b799afcb886551565cb29c190371026aa55a30" dependencies = [ "anyhow", "heck", - "wasm-encoder 0.252.0", + "wasm-encoder 0.253.0", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -3555,9 +3576,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.252.0" +version = "0.253.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76db0662b590f45d33d0e363fa13539a5a1eecd35d5a12fe208c335461c1053d" +checksum = "dbbd2500ac3488489ee8c6e59b79d7e47e6da5bfb019efd35d5dca57b78af624" dependencies = [ "anyhow", "bitflags", @@ -3566,10 +3587,10 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.252.0", + "wasm-encoder 0.253.0", "wasm-metadata", - "wasmparser 0.252.0", - "wit-parser 0.252.0", + "wasmparser 0.253.0", + "wit-parser 0.253.0", ] [[package]] @@ -3593,9 +3614,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.252.0" +version = "0.253.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4266bea110371c620ccf3201c5023676046bc4556e5c7cfb5d500bda5ebc162d" +checksum = "4d997b8e5920fcbeec742b58e583325d6419a6aca617ae8075c406a61c65ba8a" dependencies = [ "anyhow", "hashbrown 0.17.1", @@ -3607,7 +3628,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-ident", - "wasmparser 0.252.0", + "wasmparser 0.253.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 75f4f6d..15fe545 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ reqwest = { version = "0.13.4", features = ["blocking"] } tar = "0.4.46" [workspace.package] -version = "0.4.0" +version = "0.4.1" edition = "2024" [workspace.lints.clippy] @@ -46,8 +46,8 @@ clap = { version = "4.6.1", features = ["derive"] } regex = "1.12.4" serde = { version = "1.0.228", features = ["derive"] } toml = "1.1.0" -wit-bindgen-go = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "4642b6bcc4283361b5d85eb00b00addf618458a9" } -wit-component = "0.252.0" -wit-parser = "0.252.0" +wit-bindgen-go = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "50b799afcb886551565cb29c190371026aa55a30" } +wit-component = "0.253.0" +wit-parser = "0.253.0" which = "8.0.4" dirs = "6.0.0" diff --git a/main.go b/main.go index b908530..e94d401 100644 --- a/main.go +++ b/main.go @@ -24,7 +24,7 @@ import ( // Although `componentize-go` is written in Rust, we can use this wrapper to // make it available using e.g. `go install` and/or `go tool`. func main() { - release := "v0.4.0" + release := "v0.4.1" directories := userdirs.ForApp( "componentize-go", diff --git a/tests/fixtures/named-implements/export_wit_world/wit_bindings.go b/tests/fixtures/named-implements/export_wit_world/wit_bindings.go new file mode 100644 index 0000000..63b59e2 --- /dev/null +++ b/tests/fixtures/named-implements/export_wit_world/wit_bindings.go @@ -0,0 +1,17 @@ +package export_wit_world + +import ( + "fmt" + + "wit_component/foo_baz_store" + "wit_component/primary" + "wit_component/secondary" +) + +// Run calls the same `store.get` function through the two named imports and +// the bare import, proving each routes to its own host instance. +func Run() { + fmt.Println(primary.Get("color")) + fmt.Println(secondary.Get("color")) + fmt.Println(foo_baz_store.Get("color")) +} diff --git a/tests/fixtures/named-implements/foo_baz_store/empty.s b/tests/fixtures/named-implements/foo_baz_store/empty.s new file mode 100644 index 0000000..308ab60 --- /dev/null +++ b/tests/fixtures/named-implements/foo_baz_store/empty.s @@ -0,0 +1,3 @@ +// This file exists for testing this package without WebAssembly, +// allowing empty function bodies with a //go:wasmimport directive. +// See https://pkg.go.dev/cmd/compile for more information. \ No newline at end of file diff --git a/tests/fixtures/named-implements/foo_baz_store/wit_bindings.go b/tests/fixtures/named-implements/foo_baz_store/wit_bindings.go new file mode 100644 index 0000000..ac31a35 --- /dev/null +++ b/tests/fixtures/named-implements/foo_baz_store/wit_bindings.go @@ -0,0 +1,30 @@ +// Generated by `wit-bindgen` 0.59.0. DO NOT EDIT! +// +// This code was generated from the following packages: +// foo:baz@0.1.0 + +package foo_baz_store + +import ( + witRuntime "go.bytecodealliance.org/pkg/wit/runtime" +"unsafe" +"runtime" +) + + +//go:wasmimport foo:baz/store@0.1.0 get +func wasm_import_get(arg0 uintptr, arg1 uint32, arg2 uintptr) + +func Get(key string) string { + pinner := &runtime.Pinner{} +defer pinner.Unpin() + + returnArea := uintptr(witRuntime.Allocate(pinner, (2*4), 4)) + utf8 := unsafe.Pointer(unsafe.StringData(key)) +pinner.Pin(utf8) +wasm_import_get(uintptr(utf8), uint32(len(key)), returnArea) +value := unsafe.String((*uint8)(unsafe.Pointer(uintptr(*(*uint32)(unsafe.Add(unsafe.Pointer(returnArea), 0))))), *(*uint32)(unsafe.Add(unsafe.Pointer(returnArea), 4))) +result := value; +return result + +} diff --git a/tests/fixtures/named-implements/primary/empty.s b/tests/fixtures/named-implements/primary/empty.s new file mode 100644 index 0000000..308ab60 --- /dev/null +++ b/tests/fixtures/named-implements/primary/empty.s @@ -0,0 +1,3 @@ +// This file exists for testing this package without WebAssembly, +// allowing empty function bodies with a //go:wasmimport directive. +// See https://pkg.go.dev/cmd/compile for more information. \ No newline at end of file diff --git a/tests/fixtures/named-implements/primary/wit_bindings.go b/tests/fixtures/named-implements/primary/wit_bindings.go new file mode 100644 index 0000000..e162485 --- /dev/null +++ b/tests/fixtures/named-implements/primary/wit_bindings.go @@ -0,0 +1,30 @@ +// Generated by `wit-bindgen` 0.59.0. DO NOT EDIT! +// +// This code was generated from the following packages: +// foo:baz@0.1.0 + +package primary + +import ( + witRuntime "go.bytecodealliance.org/pkg/wit/runtime" +"unsafe" +"runtime" +) + + +//go:wasmimport primary get +func wasm_import_get(arg0 uintptr, arg1 uint32, arg2 uintptr) + +func Get(key string) string { + pinner := &runtime.Pinner{} +defer pinner.Unpin() + + returnArea := uintptr(witRuntime.Allocate(pinner, (2*4), 4)) + utf8 := unsafe.Pointer(unsafe.StringData(key)) +pinner.Pin(utf8) +wasm_import_get(uintptr(utf8), uint32(len(key)), returnArea) +value := unsafe.String((*uint8)(unsafe.Pointer(uintptr(*(*uint32)(unsafe.Add(unsafe.Pointer(returnArea), 0))))), *(*uint32)(unsafe.Add(unsafe.Pointer(returnArea), 4))) +result := value; +return result + +} diff --git a/tests/fixtures/named-implements/secondary/empty.s b/tests/fixtures/named-implements/secondary/empty.s new file mode 100644 index 0000000..308ab60 --- /dev/null +++ b/tests/fixtures/named-implements/secondary/empty.s @@ -0,0 +1,3 @@ +// This file exists for testing this package without WebAssembly, +// allowing empty function bodies with a //go:wasmimport directive. +// See https://pkg.go.dev/cmd/compile for more information. \ No newline at end of file diff --git a/tests/fixtures/named-implements/secondary/wit_bindings.go b/tests/fixtures/named-implements/secondary/wit_bindings.go new file mode 100644 index 0000000..83af910 --- /dev/null +++ b/tests/fixtures/named-implements/secondary/wit_bindings.go @@ -0,0 +1,30 @@ +// Generated by `wit-bindgen` 0.59.0. DO NOT EDIT! +// +// This code was generated from the following packages: +// foo:baz@0.1.0 + +package secondary + +import ( + witRuntime "go.bytecodealliance.org/pkg/wit/runtime" +"unsafe" +"runtime" +) + + +//go:wasmimport secondary get +func wasm_import_get(arg0 uintptr, arg1 uint32, arg2 uintptr) + +func Get(key string) string { + pinner := &runtime.Pinner{} +defer pinner.Unpin() + + returnArea := uintptr(witRuntime.Allocate(pinner, (2*4), 4)) + utf8 := unsafe.Pointer(unsafe.StringData(key)) +pinner.Pin(utf8) +wasm_import_get(uintptr(utf8), uint32(len(key)), returnArea) +value := unsafe.String((*uint8)(unsafe.Pointer(uintptr(*(*uint32)(unsafe.Add(unsafe.Pointer(returnArea), 0))))), *(*uint32)(unsafe.Add(unsafe.Pointer(returnArea), 4))) +result := value; +return result + +} diff --git a/tests/fixtures/named-implements/wit/world.wit b/tests/fixtures/named-implements/wit/world.wit new file mode 100644 index 0000000..8e2717d --- /dev/null +++ b/tests/fixtures/named-implements/wit/world.wit @@ -0,0 +1,15 @@ +package foo:baz@0.1.0; + +interface store { + get: func(key: string) -> string; +} + +world named-implements { + // Import the same interface under separate names to exercise named + // `implements` imports. + import primary: store; + import secondary: store; + // Ensure a bare import alongside the named ones still works. + import store; + export run: func(); +} diff --git a/tests/src/examples.rs b/tests/src/examples.rs index 2c4e654..5f4bdf0 100644 --- a/tests/src/examples.rs +++ b/tests/src/examples.rs @@ -105,7 +105,7 @@ async fn example_sdk() -> Result<()> { break; } Err(e) => { - if start.elapsed() > Duration::from_secs(5) { + if start.elapsed() > Duration::from_secs(30) { return Err(anyhow!("Unable to reach the app: {e}")); } } diff --git a/tests/src/fixtures.rs b/tests/src/fixtures.rs index 5d6c90f..082a2ce 100644 --- a/tests/src/fixtures.rs +++ b/tests/src/fixtures.rs @@ -28,6 +28,53 @@ async fn fixture_multiple_worlds() -> Result<()> { Ok(()) } +#[test] +fn fixture_named_implements() -> Result<()> { + // Build the app with componentize-go + let app_dir = app_dir("named-implements")?; + let app = App::new( + &app_dir, + &[&app_dir.join("wit")], + &["named-implements"], + None, + true, + ); + app.build_component().expect("failed to build app"); + + // Link the same `store` interface under three import names, each backed + // by a distinct host implementation, to verify that named `implements` + // imports route to their own instances. + let engine = engine()?; + let component = Component::from_file(&engine, app_dir.join("main.wasm"))?; + + let mut linker = Linker::::new(&engine); + wasmtime_wasi::p2::add_to_linker_sync(&mut linker)?; + + for (import, prefix) in [ + ("primary", "primary"), + ("secondary", "secondary"), + ("foo:baz/store@0.1.0", "bare"), + ] { + linker + .instance(import)? + .func_wrap("get", move |_store, (key,): (String,)| { + Ok((format!("{prefix}:{key}"),)) + })?; + } + + let mut store = Store::new(&engine, State::new()); + let instance = linker.instantiate(&mut store, &component)?; + let run = instance.get_typed_func::<(), ()>(&mut store, "run")?; + run.call(&mut store, ())?; + + assert_eq!( + store.data().stdout(), + b"primary:color\nsecondary:color\nbare:color\n" + ); + + Ok(()) +} + #[test] fn fixture_memory_pressure() -> Result<()> { // Build the app with componentize-go diff --git a/tests/src/harness.rs b/tests/src/harness.rs index cda4e8c..9eae495 100644 --- a/tests/src/harness.rs +++ b/tests/src/harness.rs @@ -314,7 +314,7 @@ impl App { return Ok(()); } Err(e) => { - if start.elapsed() > Duration::from_secs(5) { + if start.elapsed() > Duration::from_secs(30) { return Err(anyhow!("Unable to reach the app: {e}")); } } diff --git a/tests/src/wasmtime.rs b/tests/src/wasmtime.rs index 9801073..7a24a8a 100644 --- a/tests/src/wasmtime.rs +++ b/tests/src/wasmtime.rs @@ -43,5 +43,6 @@ pub fn engine() -> anyhow::Result { let mut config = Config::new(); config.wasm_component_model(true); config.wasm_component_model_async(true); + config.wasm_component_model_implements(true); Engine::new(&config).map_err(|e| anyhow!(e)) }