1 //! Example of instantiating a wasm module which uses WASI preview1 imports 2 //! implemented through the async preview2 WASI implementation. 3 4 /* 5 You can execute this example with: 6 cmake examples/ 7 cargo run --example wasip2-async 8 */ 9 10 use wasmtime::component::{Component, Linker, ResourceTable}; 11 use wasmtime::*; 12 use wasmtime_wasi::p2::bindings::Command; 13 use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView}; 14 15 pub struct ComponentRunStates { 16 // These two are required basically as a standard way to enable the impl of IoView and 17 // WasiView. 18 // impl of WasiView is required by [`wasmtime_wasi::p2::add_to_linker_sync`] 19 pub wasi_ctx: WasiCtx, 20 pub resource_table: ResourceTable, 21 // You can add other custom host states if needed 22 } 23 24 impl WasiView for ComponentRunStates { 25 fn ctx(&mut self) -> WasiCtxView<'_> { 26 WasiCtxView { 27 ctx: &mut self.wasi_ctx, 28 table: &mut self.resource_table, 29 } 30 } 31 } 32 33 #[tokio::main] 34 async fn main() -> Result<()> { 35 let engine = Engine::default(); 36 let mut linker = Linker::new(&engine); 37 wasmtime_wasi::p2::add_to_linker_async(&mut linker)?; 38 39 // Create a WASI context and put it in a Store; all instances in the store 40 // share this context. `WasiCtx` provides a number of ways to 41 // configure what the target program will have access to. 42 let wasi = WasiCtx::builder().inherit_stdio().inherit_args().build(); 43 let state = ComponentRunStates { 44 wasi_ctx: wasi, 45 resource_table: ResourceTable::new(), 46 }; 47 let mut store = Store::new(&engine, state); 48 49 // Instantiate our component with the imports we've created, and run it. 50 let component = Component::from_file(&engine, "target/wasm32-wasip2/debug/wasi.wasm")?; 51 let command = Command::instantiate_async(&mut store, &component, &linker).await?; 52 let program_result = command.wasi_cli_run().call_run(&mut store).await?; 53 match program_result { 54 Ok(()) => Ok(()), 55 Err(()) => std::process::exit(1), 56 } 57 } 58