Embedding Wasm in Host Applications
31.1 Rust Host with Wasmtime
use wasmtime::*;
fn main() -> Result<()> {
let mut config = Config::new();
config.consume_fuel(true); // limit CPU usage
let engine = Engine::new(&config)?;
let module = Module::from_file(&engine, "plugin.wasm")?;
let mut store = Store::new(&engine, ());
store.set_fuel(1_000_000)?;
let mut linker = Linker::new(&engine);
linker.func_wrap("host", "log", |caller: Caller<'_, ()>, ptr: i32, len: i32| {
let mem = caller.get_export("memory").and_then(|e| e.into_memory()).unwrap();
let data = &mem.data(&caller)[ptr as usize..(ptr + len) as usize];
println!("plugin says: {}", String::from_utf8_lossy(data));
})?;
let instance = linker.instantiate(&mut store, &module)?;
let run = instance.get_typed_func::<(i32, i32), i32>(&mut store, "run")?;
let result = run.call(&mut store, (2, 3))?;
println!("result = {result}, fuel left = {}", store.get_fuel()?);
Ok(())
}31.2 Go Host with wazero
package main
import (
"context"
"fmt"
"os"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
)
func main() {
ctx := context.Background()
r := wazero.NewRuntime(ctx)
defer r.Close(ctx)
wasi_snapshot_preview1.MustInstantiate(ctx, r)
_, _ = r.NewHostModuleBuilder("host").
NewFunctionBuilder().
WithFunc(func(ctx context.Context, m api.Module, v uint32) { fmt.Println("host got", v) }).
Export("notify").
Instantiate(ctx)
wasmBytes, _ := os.ReadFile("plugin.wasm")
mod, err := r.Instantiate(ctx, wasmBytes)
if err != nil {
panic(err)
}
res, _ := mod.ExportedFunction("add").Call(ctx, 2, 3)
fmt.Println("add =", res[0])
}31.3 Python Host
from wasmtime import Store, Module, Instance
store = Store()
module = Module.from_file(store.engine, "add.wasm")
instance = Instance(store, module, [])
add = instance.exports(store)["add"]
print(add(store, 2, 3))31.4 Embedding Concerns
Resource limits: fuel/epoch interruption (CPU), StoreLimits (memory, tables, instances), timeouts.
Isolation: one Store per tenant/request, pooling allocators for fast instantiation (microseconds).
Host API design: keep imports small, versioned, and capability-oriented. Validate all pointers/lengths coming from the guest.
Precompilation and caching of modules for startup speed.