truls opened issue #6523:
Hi,
I'm trying to instantiate a component compiled using tinygo from wasmtime in rust
The components implements the following WIT interface
package producer:host world producer-interface { export hello-world: interface { record hello-request { name: string } record hello-reply { message: string } say-hello: func(reqyest: hello-request) -> result<hello-reply, s32> init-component: func() } }
I generate the component using the commands
go generate tinygo build -target=wasi -o main.wasm component.go wasm-tools component embed --world producer-interface ./wit main.wasm -o main.embed.wasm wasm-tools component new main.embed.wasm --adapt wasi_snapshot_preview1.wasm -o main.component.wasm wasm-tools validate main.component.wasm --features component-model
where the
`wasi_snapshot_preview1.wasm
build comes from https://github.com/bytecodealliance/wasmtime/releases/download/dev/wasi_snapshot_preview1.command.wasmI am instantiating the component using the following rust code
use wasmtime::component::{*, self}; use wasmtime::{Config, Engine, Store}; use crate::exports::hello_world::{HelloRequest}; bindgen!(in "../producer/component/wit"); struct MyState {} fn main() -> wasmtime::Result<()> { let mut config = Config::new(); config.wasm_component_model(true); let engine = Engine::new(&config)?; let component = Component::from_file(&engine, "../producer/component/main.component.wasm")?; let linker = Linker::new(&engine); let mut store = Store::new( &engine, MyState { /* ... */ }, ); let (bindings, _) = ProducerInterface::instantiate(&mut store, &component, &linker)?; let interf = bindings.hello_world(); interf.call_init_component(&mut store)?; let arg = HelloRequest{name: &"foo"}; let res = interf.call_say_hello(&mut store, arg)?; println!("{:?}", res); Ok(()) }
However, when running the above program I get the following message
$ target/debug/wrapper Error: import `wasi:clocks/wall-clock` has the wrong type Caused by: 0: instance export `now` has the wrong type 1: expected func found nothing
Can anyone give me some hints about what the problem is?
Package versions::
wit-bindgen: 0.7.0
wasmtime crate: 10,0,0
tinygo: 0.27.0
wasm-tools: 1.0.35
pchickey commented on issue #6523:
I'm not sure where the type mismatch is. I believe, since my understanding is that tinygo is not using component model imports directly, that the wall-clock import is coming from the wasi_snapshot_preview1.component.wasm adapter, and not from any of your go source code.
In that case, I'd check whether the adapter from the wasmtime 10.0.0 release assets, or using a git dep on wasmtime (and wasmtime-wasi) crate matching the git commit where you downloaded the adapter, resolves the problem - both construction and our test suite should verify that the component adapter and host have matching interfaces at any given release (or commit in wasmtime
main
), but the interfaces are changing somewhat frequently so we can't expect any stability between different versions yet.
pchickey edited a comment on issue #6523:
I'm not sure where the type mismatch is. I believe, since my understanding is that tinygo is not using component model imports directly, that the wall-clock import is coming from the wasi_snapshot_preview1.component.wasm adapter, and not from any of your go source code.
In that case, I'd check whether the adapter from the wasmtime 10.0.0 release assets, or using a git dep on wasmtime (and wasmtime-wasi) crate matching the git commit where you downloaded the adapter, resolves the problem - both construction and our test suite should ensure that the component adapter and host have matching interfaces at any given release (or commit in wasmtime
main
), but the interfaces are changing somewhat frequently so we can't expect any stability between different versions yet.
truls commented on issue #6523:
Thank you for your reply. Yes the wall-clock import was coming for wasi_snapshot_preview1 and not my code. I tried changing my toolchain to use the versions that are supposed to be supported according to the component model compatibility matrix (https://bytecodealliance.org/articles/component-model-tooling-compatibility) but it didn't change anything.
I just got it working using the following code and the toolchain versions from my original issue.
use wasmtime::component::*; use wasmtime::{Config, Engine, Store}; use wasmtime_wasi::preview2::{WasiCtx, WasiCtxBuilder, Table, WasiView}; use wasmtime_wasi::preview2; use crate::exports::hello_world::HelloRequest; bindgen!({ path:"../producer/component/wit", async: true }); struct MyState { table: Table, wasi: WasiCtx, } impl WasiView for MyState { fn table(&self) -> &Table { &self.table } fn table_mut(&mut self) -> &mut Table { &mut self.table } fn ctx(&self) -> &WasiCtx { &self.wasi } fn ctx_mut(&mut self) -> &mut WasiCtx { &mut self.wasi } } #[tokio::main] async fn main() -> wasmtime::Result<()> { let mut config = Config::new(); config.wasm_component_model(true); config.async_support(true); let engine = Engine::new(&config)?; let component = Component::from_file(&engine, "../producer/component/main-component.wasm")?; let mut linker = Linker::new(&engine); let mut table = Table::new(); let wasi = WasiCtxBuilder::new().inherit_stdio().set_args(&[""]).build(&mut table)?; preview2::wasi::filesystem::filesystem::add_to_linker(&mut linker, |x| x)?; preview2::wasi::io::streams::add_to_linker(&mut linker, |x| x)?; preview2::wasi::cli_base::environment::add_to_linker(&mut linker, |x| x)?; preview2::wasi::cli_base::preopens::add_to_linker(&mut linker, |x| x)?; preview2::wasi::cli_base::exit::add_to_linker(&mut linker, |x| x)?; preview2::wasi::cli_base::stdin::add_to_linker(&mut linker, |x| x)?; preview2::wasi::cli_base::stdout::add_to_linker(&mut linker, |x| x)?; preview2::wasi::cli_base::stderr::add_to_linker(&mut linker, |x| x)?; preview2::wasi::clocks::wall_clock::add_to_linker(&mut linker, |x| x)?; preview2::wasi::clocks::monotonic_clock::add_to_linker(&mut linker, |x| x)?; let mut store = Store::new( &engine, MyState { table, wasi }, ); let (bindings, _) = ProducerInterface::instantiate_async(&mut store, &component, &linker).await?; let interf = bindings.hello_world(); interf.call_test(&mut store).await?; interf.call_init_component(&mut store).await?; let arg = HelloRequest{name: &"foo"}; let res = interf.call_say_hello(&mut store, arg).await?; println!("{:?}", res); Ok(()) }
If the preview2 WASI ABI implementation is supposed to be provided by the host without explicitly adding it to the linker, then I'm still doing something wrong.
pchickey commented on issue #6523:
Oh, I missed that, yes you are expected to explicitly add all of the wasi modules that you are using to the component Linker.
pchickey closed issue #6523:
Hi,
I'm trying to instantiate a component compiled using tinygo from wasmtime in rust
The components implements the following WIT interface
package producer:host world producer-interface { export hello-world: interface { record hello-request { name: string } record hello-reply { message: string } say-hello: func(reqyest: hello-request) -> result<hello-reply, s32> init-component: func() } }
I generate the component using the commands
go generate tinygo build -target=wasi -o main.wasm component.go wasm-tools component embed --world producer-interface ./wit main.wasm -o main.embed.wasm wasm-tools component new main.embed.wasm --adapt wasi_snapshot_preview1.wasm -o main.component.wasm wasm-tools validate main.component.wasm --features component-model
where the
`wasi_snapshot_preview1.wasm
build comes from https://github.com/bytecodealliance/wasmtime/releases/download/dev/wasi_snapshot_preview1.command.wasmI am instantiating the component using the following rust code
use wasmtime::component::{*, self}; use wasmtime::{Config, Engine, Store}; use crate::exports::hello_world::{HelloRequest}; bindgen!(in "../producer/component/wit"); struct MyState {} fn main() -> wasmtime::Result<()> { let mut config = Config::new(); config.wasm_component_model(true); let engine = Engine::new(&config)?; let component = Component::from_file(&engine, "../producer/component/main.component.wasm")?; let linker = Linker::new(&engine); let mut store = Store::new( &engine, MyState { /* ... */ }, ); let (bindings, _) = ProducerInterface::instantiate(&mut store, &component, &linker)?; let interf = bindings.hello_world(); interf.call_init_component(&mut store)?; let arg = HelloRequest{name: &"foo"}; let res = interf.call_say_hello(&mut store, arg)?; println!("{:?}", res); Ok(()) }
However, when running the above program I get the following message
$ target/debug/wrapper Error: import `wasi:clocks/wall-clock` has the wrong type Caused by: 0: instance export `now` has the wrong type 1: expected func found nothing
Can anyone give me some hints about what the problem is?
Package versions::
wit-bindgen: 0.7.0
wasmtime crate: 10,0,0
tinygo: 0.27.0
wasm-tools: 1.0.35
pchickey edited a comment on issue #6523:
Oh, I missed that, yes you are expected to explicitly add all of the wasi modules that you are using to the component Linker.
As a shortcut for listing them all, you can use wasmtime_wasi::preview2::wasi::command::add_to_linker, if the set in there is sufficient. (It provides all the ones you did, plus timezone, which has a bogus implementation so isnt very useful right now)
Last updated: Nov 22 2024 at 17:03 UTC