Implement Wasmtime's new API as designed by RFC 11. This is quite a large commit which has had lots of discussion externally, so for more information it's best to read the RFC thread and the PR thread.
65 lines
2.4 KiB
Rust
65 lines
2.4 KiB
Rust
//! Small example of how to instantiate a wasm module that imports one function,
|
|
//! showing how you can fill in host functionality for a wasm module.
|
|
|
|
// You can execute this example with `cargo run --example hello`
|
|
|
|
use anyhow::Result;
|
|
use wasmtime::*;
|
|
|
|
struct MyState {
|
|
name: String,
|
|
count: usize,
|
|
}
|
|
|
|
fn main() -> Result<()> {
|
|
// First the wasm module needs to be compiled. This is done with a global
|
|
// "compilation environment" within an `Engine`. Note that engines can be
|
|
// further configured through `Config` if desired instead of using the
|
|
// default like this is here.
|
|
println!("Compiling module...");
|
|
let engine = Engine::default();
|
|
let module = Module::from_file(&engine, "examples/hello.wat")?;
|
|
|
|
// After a module is compiled we create a `Store` which will contain
|
|
// instantiated modules and other items like host functions. A Store
|
|
// contains an arbitrary piece of host information, and we use `MyState`
|
|
// here.
|
|
println!("Initializing...");
|
|
let mut store = Store::new(
|
|
&engine,
|
|
MyState {
|
|
name: "hello, world!".to_string(),
|
|
count: 0,
|
|
},
|
|
);
|
|
|
|
// Our wasm module we'll be instantiating requires one imported function.
|
|
// the function takes no parameters and returns no results. We create a host
|
|
// implementation of that function here, and the `caller` parameter here is
|
|
// used to get access to our original `MyState` value.
|
|
println!("Creating callback...");
|
|
let hello_func = Func::wrap(&mut store, |mut caller: Caller<'_, MyState>| {
|
|
println!("Calling back...");
|
|
println!("> {}", caller.data().name);
|
|
caller.data_mut().count += 1;
|
|
});
|
|
|
|
// Once we've got that all set up we can then move to the instantiation
|
|
// phase, pairing together a compiled module as well as a set of imports.
|
|
// Note that this is where the wasm `start` function, if any, would run.
|
|
println!("Instantiating module...");
|
|
let imports = [hello_func.into()];
|
|
let instance = Instance::new(&mut store, &module, &imports)?;
|
|
|
|
// Next we poke around a bit to extract the `run` function from the module.
|
|
println!("Extracting export...");
|
|
let run = instance.get_typed_func::<(), (), _>(&mut store, "run")?;
|
|
|
|
// And last but not least we can call it!
|
|
println!("Calling export...");
|
|
run.call(&mut store, ())?;
|
|
|
|
println!("Done.");
|
|
Ok(())
|
|
}
|