Hi,
I'm struggling with making a very basic guest & host setup with a shared WIT definition work smoothly.
I've based my code mostly on the content of https://github.com/bytecodealliance/wit-bindgen/tree/main/tests, specifically the "smoke" test.
everything compiles successfully, however during runtime of the host I get the following error message, when using cargo run
for the host:
Error: import `wasi-stderr` has the wrong type
Caused by:
0: instance export `print` has the wrong type
1: expected func found nothing
Hopefully, someone would be able to point out what I'm doing wrong.
WIT (smoke.wit):
interface imports {
thunk: func()
}
default world smoke {
import imports: self.imports
export thunk: func()
}
guest Cargo.toml:
[package]
name = "guest"
version = "0.1.0"
edition = "2021"
[dependencies]
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen" }
[lib]
crate-type = ["cdylib"]
guest lib.rs:
wit_bindgen::generate!("smoke");
struct Exports;
export_smoke!(Exports);
impl Smoke for Exports {
fn thunk() {
imports::thunk();
}
}
i'm building the guest component using the following commands:
cargo build --target wasm-wasi32
wasm-tools component new <...>/guest.wasm -o <...>/guest.wasm" --adapt <...>/wasi_snapshot_preview1.wasm"
host Cargo.toml:
[package]
name = "host"
version = "0.1.0"
edition = "2021"
[dependencies]
wasmtime = { git = 'https://github.com/bytecodealliance/wasmtime', features = ['component-model'] }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen" }
anyhow = "1.0.69"
host main.rs:
use anyhow::Result;
use std::error::Error;
use wasmtime::component::{Component, Instance, Linker};
use wasmtime::{Config, Engine, Store};
wasmtime::component::bindgen!("smoke");
#[derive(Default)]
struct Wasi<T>(T);
#[derive(Default)]
pub struct MyImports {
hit: bool,
}
impl imports::Imports for MyImports {
fn thunk(&mut self) -> Result<()> {
self.hit = true;
println!("in the host");
Ok(())
}
}
fn main() -> Result<(), Box<dyn Error>> {
let wasm = "<...>/guest.wasm";
run(
wasm,
|linker| Smoke::add_to_linker(linker, |x| &mut x.0),
|store, component, linker| Smoke::instantiate(store, component, linker),
run_test,
)?;
Ok(())
}
fn run<T, U>(
wasm: &str,
add_to_linker: fn(&mut Linker<Wasi<T>>) -> Result<()>,
instantiate: fn(&mut Store<Wasi<T>>, &Component, &Linker<Wasi<T>>) -> Result<(U, Instance)>,
test: fn(U, &mut Store<Wasi<T>>) -> Result<()>,
) -> Result<()>
where
T: Default,
{
let mut config = Config::new();
config.cache_config_load_default()?;
config.wasm_backtrace_details(wasmtime::WasmBacktraceDetails::Enable);
config.wasm_component_model(true);
let engine = Engine::new(&config)?;
let component = Component::from_file(&engine, &wasm)?;
let mut linker = Linker::new(&engine);
add_to_linker(&mut linker)?;
let mut store = Store::new(&engine, Wasi::default());
let (exports, _) = instantiate(&mut store, &component, &linker)?;
println!("testing {wasm:?}");
test(exports, &mut store)?;
Ok(())
}
fn run_test(exports: Smoke, store: &mut Store<crate::Wasi<MyImports>>) -> Result<()> {
exports.call_thunk(&mut *store)?;
assert!(store.data().0.hit);
Ok(())
}
The error is saying that "wasi-stderr" has the wrong type.
When you compile your guest program to wasm32-wasi
targeted Wasm component, the component will import some WASI functions. To see what functions are imported, you can do wasm-tools component wit guest.wasm
where guest.wasm
is the output of wasm-tools component new
.
The command will print a WIT file that has all the WASi imports and you are able to see what's the function signature in wasi-stderr
interface. My guess is that it looks like
interface wasi-stderr {
print: func(message: string)
}
Once you were able to verify that, the missing part is in your host implementation. Your host should meet the requirements of the guest by implementing all the imports
of the WIT file. Specifically you need to implement functions in wasi-stderr
in the host and added them to the Linker
.
This is all is too much, I'd recommend using WasiCtxBuilder
from wasi-common in preview2-prototyping repo.
Here is an example repo of how you can use preview2-prototyping host
implementation https://github.com/Mossaka/wit-bindgen-go-template/blob/main/Cargo.toml#L16-L23
Thank you very much @Mossaka (Joe) , these references have helped resolve my issue.
Mossaka (Joe) has marked this topic as resolved.
Last updated: Dec 23 2024 at 12:05 UTC