Files
simple-rust-tests/__wasm/wit-bindgen-sample/wit-bindgen/crates/gen-wasmtime/tests/runtime.rs

111 lines
3.7 KiB
Rust

use anyhow::{Context as _, Result};
use wasmtime::{Config, Engine, Instance, Linker, Module, Store};
test_helpers::runtime_tests_wasmtime!();
fn default_config() -> Result<Config> {
// Create an engine with caching enabled to assist with iteration in this
// project.
let mut config = Config::new();
config.cache_config_load_default()?;
config.wasm_backtrace_details(wasmtime::WasmBacktraceDetails::Enable);
Ok(config)
}
fn default_wasi() -> wasmtime_wasi::WasiCtx {
wasmtime_wasi::sync::WasiCtxBuilder::new()
.inherit_stdio()
.build()
}
struct Context<I, E> {
wasi: wasmtime_wasi::WasiCtx,
imports: I,
exports: E,
}
fn instantiate<I: Default, E: Default, T>(
wasm: &str,
add_imports: impl FnOnce(&mut Linker<Context<I, E>>) -> Result<()>,
mk_exports: impl FnOnce(
&mut Store<Context<I, E>>,
&Module,
&mut Linker<Context<I, E>>,
) -> Result<(T, Instance)>,
) -> Result<(T, Store<Context<I, E>>)> {
let engine = Engine::new(&default_config()?)?;
let module = Module::from_file(&engine, wasm)?;
let mut linker = Linker::new(&engine);
add_imports(&mut linker)?;
wasmtime_wasi::add_to_linker(&mut linker, |cx| &mut cx.wasi)?;
let mut store = Store::new(
&engine,
Context {
wasi: default_wasi(),
imports: I::default(),
exports: E::default(),
},
);
let (exports, _instance) = mk_exports(&mut store, &module, &mut linker)?;
Ok((exports, store))
}
// TODO: This function needs to be updated to use the component model once it's ready. See
// https://github.com/bytecodealliance/wit-bindgen/issues/259 for details.
//
// Also, rename the ignore_host.rs files under the tests/runtime/smw_{functions|lists|strings} to host.rs and
// remove the leading underscore from this function's name to re-enable the Spidermonkey tests.
fn _instantiate_smw<I: Default, E: Default, T>(
wasm: &str,
add_imports: impl FnOnce(&mut Linker<Context<I, E>>) -> Result<()>,
mk_exports: impl FnOnce(
&mut Store<Context<I, E>>,
&Module,
&mut Linker<Context<I, E>>,
) -> Result<(T, Instance)>,
) -> Result<(T, Store<Context<I, E>>)> {
let mut config = default_config()?;
config.wasm_multi_memory(true);
let engine = Engine::new(&config)?;
println!("reading wasms...");
let wasm = std::fs::read(wasm).context(format!("failed to read {}", wasm))?;
let smw = std::fs::read("../gen-spidermonkey/spidermonkey-wasm/spidermonkey.wasm")
.context("failed to read `spidermonkey.wasm`")?;
println!("compiling input wasm...");
let module = Module::new(&engine, &wasm)?;
println!("compiling spidermonkey.wasm...");
let smw = Module::new(&engine, &smw)?;
let mut linker = Linker::new(&engine);
add_imports(&mut linker)?;
wasmtime_wasi::add_to_linker(&mut linker, |cx| &mut cx.wasi)?;
let mut store = Store::new(
&engine,
Context {
wasi: default_wasi(),
imports: I::default(),
exports: E::default(),
},
);
println!("instantiating spidermonkey.wasm...");
let _smw_instance = linker
.instantiate(&mut store, &smw)
.context("failed to instantiate `spidermonkey.wasm`")?;
// TODO: replace this with a component model equivalent:
// linker.define_name("spidermonkey", smw_instance)?;
println!("instantiating input wasm...");
let (exports, instance) = mk_exports(&mut store, &module, &mut linker)?;
println!("running wizer.initialize");
let init = instance.get_typed_func::<(), (), _>(&mut store, "wizer.initialize")?;
init.call(&mut store, ())
.context("failed to call wizer.initialize")?;
Ok((exports, store))
}