WASI
You can also browse this source code online and clone the wasmtime repository to run the example locally.
This example shows how to use the wasmtime-wasi
crate to define WASI
functions within a Linker
which can then be used to instantiate a
WebAssembly module.
Wasm Source code
fn main() { println!("Hello, world!"); }
wasi.rs
//! Example of instantiating a wasm module which uses WASI imports.
/*
You can execute this example with:
cmake example/
cargo run --example wasi
*/
use anyhow::Result;
use wasmtime::*;
use wasmtime_wasi::sync::WasiCtxBuilder;
fn main() -> Result<()> {
// Define the WASI functions globally on the `Config`.
let engine = Engine::default();
let mut linker = Linker::new(&engine);
wasmtime_wasi::add_to_linker(&mut linker, |s| s)?;
// Create a WASI context and put it in a Store; all instances in the store
// share this context. `WasiCtxBuilder` provides a number of ways to
// configure what the target program will have access to.
let wasi = WasiCtxBuilder::new()
.inherit_stdio()
.inherit_args()?
.build();
let mut store = Store::new(&engine, wasi);
// Instantiate our module with the imports we've created, and run it.
let module = Module::from_file(&engine, "target/wasm32-wasi/debug/wasi.wasm")?;
linker.module(&mut store, "", &module)?;
linker
.get_default(&mut store, "")?
.typed::<(), ()>(&store)?
.call(&mut store, ())?;
Ok(())
}
WASI state with other custom host state
The add_to_linker
takes a second argument which is a closure to access &mut WasiCtx
from within the T
stored in the Store<T>
itself. In the above
example this is trivial because the T
in Store<T>
is WasiCtx
itself, but
you can also store other state in Store
like so:
extern crate wasmtime; extern crate wasmtime_wasi; extern crate anyhow; use anyhow::Result; use std::borrow::{Borrow, BorrowMut}; use wasmtime::*; use wasmtime_wasi::{WasiCtx, sync::WasiCtxBuilder}; struct MyState { message: String, wasi: WasiCtx, } fn main() -> Result<()> { let engine = Engine::default(); let mut linker = Linker::new(&engine); wasmtime_wasi::add_to_linker(&mut linker, |state: &mut MyState| &mut state.wasi)?; let wasi = WasiCtxBuilder::new() .inherit_stdio() .inherit_args()? .build(); let mut store = Store::new(&engine, MyState { message: format!("hello!"), wasi, }); // ... let _linker: Linker<MyState> = linker; Ok(()) }