Exchange data via WebAssembly linear memory
WebAssembly modules communicate with their host through linear
memory — a flat, byte-addressable array that both sides
can read and write. This recipe writes two i32 values into the WASM module’s
memory, calls a function that adds them, and reads the result back from the
return value.
get_memory retrieves the module’s exported memory object.
data_mut gives a mutable byte slice covering the entire linear
memory so the host can write inputs before the call.
use anyhow::{anyhow, Result};
use wasmtime::{Engine, Instance, Module, Store};
fn main() -> Result<()> {
let engine = Engine::default();
let module = Module::new(
&engine,
r#"
(module
(memory (export "memory") 1)
(func (export "add_from_memory") (result i32)
(i32.add
(i32.load (i32.const 0))
(i32.load (i32.const 4))))
)
"#,
)?;
let mut store = Store::new(&engine, ());
let instance = Instance::new(&mut store, &module, &[])?;
let memory = instance
.get_memory(&mut store, "memory")
.ok_or_else(|| anyhow!("memory export not found"))?;
let add = instance.get_typed_func::<(), i32>(&mut store, "add_from_memory")?;
let data = memory.data_mut(&mut store);
data[0..4].copy_from_slice(&17i32.to_le_bytes());
data[4..8].copy_from_slice(&25i32.to_le_bytes());
let result = add.call(&mut store, ())?;
println!("17 + 25 = {result}");
Ok(())
}
Run it:
cargo run --manifest-path crates/wasm/Cargo.toml --bin linear_memory
# 17 + 25 = 42