Hi everyone! Before asking for help, I would really like to express my appreciation for all the hard work y'all are doing. Thank you!
I am trying to run a very simple (vanilla) Rust host/guest component, both Host and Guest compile, but my problem is when I try to instantiate()
my default world named transformer
, the following line returns None
let (bindings, _) = Transformer::instantiate(&mut store, &component, &linker)?;
I am guessing that I am generating something wrong in the guest lib/code or, I might be running the wasm-tools
incorrectly.
My wit file looks like this:
default world transformer {
export payload: func(name: string) -> string
}
And my component code in src/lib.rs
looks like:
wit_bindgen::generate!("transformer");
struct MyTransformer;
impl Transformer for MyTransformer {
fn payload(name: String) -> String {
println!("running transformer");
format!("payload {}", name)
}
}
export_transformer!(MyTransformer);
I will try to upload everything to a git repo but I thought I would start here and see if anyone is around to guide me. Thanks again :)
I also ran the validate command inside the wasm-tools
and it seems valid:
$ wasm-tools validate transformer.wasm --features component-model -vv
[2023-05-15T23:00:44Z INFO ] module structure validated in 449.331µs
[2023-05-15T23:00:44Z INFO ] functions validated in 891.386µs
But as I mentioned, when loading the component from the Host via the instantiate()
func, I get back None
. :thinking:
The host code looks like this (very vanilla):
let mut config = Config::new();
config.wasm_component_model(true);
let engine = Engine::new(&config)?;
let component = Component::from_file(&engine, "./transformer.wasm")?;
let linker = Linker::new(&engine);
println!("Creating Store");
let mut store = Store::new(&engine, ());
println!("Binding Transformer");
let (bindings, _) = Transformer::instantiate(&mut store, &component, &linker)?;
println!("Calling Transformer payload()");
let response = bindings.call_payload(&mut store, "{}")?;
println!("{}", response);
Ok(())
Did a bit more troubleshooting and got the error coming from the instantiate()
func:
import `streams` has the wrong type
Caused by:
0: instance export `drop-input-stream` has the wrong type
1: expected func found nothing
I am guessing that my component has some extra imports that I didn't define but the framework adds:
$ wasm-tools component wit transformer.wasm
... suppressed output ...
default world transformer {
import streams: self.streams
import filesystem: self.filesystem
import environment: self.environment
import preopens: self.preopens
import exit: self.exit
export payload: func(name: string) -> string
}
I wonder how can I disable them? :thinking:
Which rust target did you compile the wasm module for?
For wasm32-wasi
, I used cargo build --target wasm32-wasi
.
I followed the instructions at https://github.com/bytecodealliance/wit-bindgen/tree/main#guest-rust
That will pull in the entirety of wasi-libc. Also because you used println!()
, the streams and stdio parts of wasi are required to handle printing to stdout. This means that you have to add a wasi-preview2 implementation to the linker to satisfy the imports.
See https://github.com/bytecodealliance/preview2-prototyping for the official wasmtime implementation of wasi-preview2.
I used that adapter via:
$ wasm-tools component new ./target/wasm32-wasi/debug/wit_rust.wasm -o transformer.wasm --adapt wasi_snapshot_preview1=./adapters/wasi_preview1_component_adapter.wasm -vv
Should I do something else on the Host?
That wrapper implements wasi-preview1 (which isn't compatible with wasm components) in terms of wasi-preview2 (which is). It still requires the host to implement wasi-preview2.
I think the wasi-common dir of https://github.com/bytecodealliance/preview2-prototyping has a wasi-preview2 impl.
See also https://github.com/bytecodealliance/wasmtime/issues/6370 for adding wasi-preview2 support directly to wasmtime.
@bjorn3 thank you so much for your responses, I really appreciate them.
Is there any way I can us preview1 on both, Host and Guest?
wasi-preview1 is not compatible with wasm components, so no I don't think you can.
Alright so I am pretty much stuck until https://github.com/bytecodealliance/wasmtime/issues/6370 is solved. There is no other way to start using the new wasm component model on a Host/Guest setup. Right? :sob:
The wasi-common crate at https://github.com/bytecodealliance/preview2-prototyping should allow using wasi-preview2 using wasi_common::wasi::command::add_to_linker(&mut linker)?;
after you implemented the WasiView
trait on the data you stored in the Store
. For example https://github.com/bytecodealliance/preview2-prototyping/blob/5be99d645c177198b9f5e4d76561669796f7b379/host/src/main.rs#L91-L138
@bjorn3 It worked! :raised_hands:🏽🤩
Screen-Shot-2023-05-17-at-3.35.44-PM.png
Thank you so much!!
Salim Afiune Maya has marked this topic as resolved.
Last updated: Dec 23 2024 at 12:05 UTC