use wasmtime::{Config, Engine};
use crate::plugin::error::PluginError;
pub struct WasmEngine {
inner: Engine,
}
impl WasmEngine {
pub fn new_sync() -> Result<Self, PluginError> {
let mut config = Config::new();
config
.target("pulley64")
.map_err(|err| PluginError::Init(format!("pulley64 target unsupported: {err}")))?;
let inner = Engine::new(&config)
.map_err(|err| PluginError::Init(format!("wasmtime Engine::new failed: {err}")))?;
Ok(Self { inner })
}
pub fn new() -> Result<Self, PluginError> {
Self::new_sync()
}
#[cfg(feature = "plugin-wasm-async")]
pub fn new_async() -> Result<Self, PluginError> {
Self::new_sync()
}
pub fn inner(&self) -> &Engine {
&self.inner
}
}
#[cfg(test)]
mod tests {
use super::*;
use wasmtime::{Instance, Module, Store};
const ADD_WAT: &str = r#"
(module
(func (export "add") (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add))
"#;
#[test]
fn wasm_engine_compiles_and_runs_pulley_core_module() {
let engine = WasmEngine::new().expect("Pulley engine must construct on this target");
let module = Module::new(engine.inner(), ADD_WAT).expect("module compile must succeed");
let mut store = Store::new(engine.inner(), ());
let instance = Instance::new(&mut store, &module, &[]).expect("instantiation must succeed");
let add = instance
.get_typed_func::<(i32, i32), i32>(&mut store, "add")
.expect("module must export add");
let result = add.call(&mut store, (1, 2)).expect("add must run");
assert_eq!(result, 3);
}
}