Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Exchange data via WebAssembly linear memory

wasmtime-badge cat-wasm-badge

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