wasmedge-hs-0.17.1.0: Haskell bindings for the WasmEdge WebAssembly runtime
Copyright(c) 2026 Tushar Adhatrao
LicenseMIT
Stabilityexperimental
Safe HaskellNone
LanguageGHC2021

WasmEdge.Function.Memory

Description

Provides utilities for writing host functions that work with complex Haskell types by automatically marshalling them through Wasm linear memory.

The problem

WebAssembly functions can only pass numeric values (i32, i64, f32, f64) across the FFI boundary. To call a host function with a Text argument or return a [Double], the convention is:

  • The guest writes the data into its linear memory.
  • The guest passes the (ptr: i32, len: i32) pair as function arguments.
  • The host reads the bytes from the calling frame's memory and deserialises.

liftMemFunc automates this entire read-deserialise-compute-serialise-write pipeline for host functions.

Usage

-- A host function that takes Text input and returns Text output:
myGreeter :: Text -> IO (Either WasmEdgeError Text)
myGreeter name = pure (Right ("Hello, " <> name <> "!"))

-- Register it as a host function with signature (i32, i32) -> i64:
fn <- liftMemFunc myGreeter
withFunction someType fn $ \hostFn -> ...

The Wasm guest calls it as: let ptr = alloc(len); store_str(ptr, input_str); let result_packed = greet(ptr, len); let ret_ptr = (result_packed >> 32) as i32; let ret_len = (result_packed & 0xFFFFFFFF) as i32;

Result encoding

Return values are packed as a single i64: upper 32 bits = output pointer, lower 32 bits = output length. The output buffer is written into a scratch region of Wasm linear memory.

For host functions that do not return data (only side effects), use liftMemFunc_.

Synopsis

Lifting host functions

liftMemFunc #

Arguments

:: (WasmMemory a, WasmMemory b) 
=> (a -> IO (Either WasmEdgeError b))

The Haskell function to lift

-> CallingFrame 
-> [WasmVal] 
-> IO (WasmResult [WasmVal]) 

Lift a Haskell function a -> IO (Either WasmEdgeError b) into a raw HostFunc that marshals arguments through Wasm linear memory.

The generated host function:

  • Expects two i32 arguments: (ptr, len) — the pointer and length of the input buffer in Wasm linear memory.
  • Reads and deserialises a from that buffer using wasmPeek.
  • Runs the user function.
  • Serialises b into a scratch region of Wasm linear memory at 1 MiB offset.
  • Returns a single i64 with (retPtr << 32 | retLen).

The function type to register with createFunction is [I32, I32] -> [I64].

Note: The scratch-region approach works for output up to ~63 MiB. For larger outputs or when the Wasm module manages its own heap, use liftMemFuncWith instead.

liftMemFunc_ :: WasmMemory a => (a -> IO (Either WasmEdgeError ())) -> CallingFrame -> [WasmVal] -> IO (WasmResult [WasmVal]) #

Like liftMemFunc but for functions with no return value (pure side-effects).

The generated host function returns no values. The function type for createFunction is [I32, I32] -> [].

liftMemFuncWith #

Arguments

:: (WasmMemory a, WasmMemory b) 
=> VM

The VM (used to call the guest's alloc export)

-> String

Module name (identifies which module's alloc to call)

-> AllocConvention

Allocation convention (names the alloc / dealloc exports)

-> (a -> IO (Either WasmEdgeError b)) 
-> CallingFrame 
-> [WasmVal] 
-> IO (WasmResult [WasmVal]) 

Advanced variant of liftMemFunc that uses the AllocConvention to call the guest's alloc export for output buffer management.

This is the production-grade approach: the guest controls the heap, and the host allocates an output buffer via alloc before writing the result. The VM reference is needed to call back into the guest's alloc export.

The generated host function signature is [I32, I32] -> [I64] (same as liftMemFunc).

Helper: get memory from calling frame

callingFrameMemory :: CallingFrame -> IO (WasmResult MemoryInstance) #

Get the linear memory instance from a CallingFrame.

The calling frame always has memory index 0 available if the guest module declares linear memory, which all practical Wasm modules do.

Returns Left if no linear memory is available (null pointer from C API).