| Copyright | (c) 2026 Tushar Adhatrao |
|---|---|
| License | MIT |
| Stability | experimental |
| Safe Haskell | None |
| Language | GHC2021 |
WasmEdge.Memory.Codec
Description
WebAssembly's type system only has four numeric types and references.
Every complex value — Text, ByteString, a list, or any ADT — must be
transported through linear memory: the Wasm module's heap.
The canonical pattern (used by the Rust and Go SDKs) is:
- The guest (Wasm) module exports
alloc(size: i32) -> i32anddealloc(ptr: i32, len: i32). - The host passes a
(ptr: i32, len: i32)pair for every buffer argument. - Both sides serialise complex data to/from a flat byte representation.
WasmMemory standardises step 3 on the Haskell side.
Encoding conventions
- Primitive numeric types use little-endian binary encoding (matches Wasm's native byte order).
Textis encoded as UTF-8 bytes.ByteStringis passed as-is (zero-copy where possible).- Complex ADTs should implement
WasmMemoryusingjsonWasmPoke/jsonWasmPeek, which serialises viaaesonJSON — the same convention used bywit-bindgenand the WASI ecosystem.
Typical usage
-- Host reads a Text value from a Wasm linear memory buffer: txt <- wasmPeek @Text mem offset len -- Host writes an ADT back into linear memory (assuming a JSON instance): Right n <- wasmPoke mem retOffset myRecord
See Alloc for the high-level bracket that combines
allocation, marshalling, and function invocation in one call.
Synopsis
- class WasmMemory a where
- wasmPeek :: MemoryInstance -> Word32 -> Word32 -> IO (WasmResult a)
- wasmPoke :: MemoryInstance -> Word32 -> a -> IO (WasmResult Word32)
- class WasmMemory a => FixedWasmMemory a where
- wasmWidth :: Proxy a -> Word32
- serialise :: a -> ByteString
- deserialise :: ByteString -> Either String a
- fixedPoke :: FixedWasmMemory a => MemoryInstance -> Word32 -> a -> IO (WasmResult Word32)
- fixedPeek :: FixedWasmMemory a => MemoryInstance -> Word32 -> Word32 -> IO (WasmResult a)
- jsonWasmPoke :: ToJSON a => MemoryInstance -> Word32 -> a -> IO (WasmResult Word32)
- jsonWasmPeek :: FromJSON a => MemoryInstance -> Word32 -> Word32 -> IO (WasmResult a)
- newtype WasmJSON a = WasmJSON {
- unWasmJSON :: a
Core typeclass
class WasmMemory a where #
A type that can be serialised to and deserialised from a contiguous slice of WebAssembly linear memory.
Minimal complete definition: wasmPeek + wasmPoke.
For fixed-size types (primitives, fixed-size tuples), implement
FixedWasmMemory and use fixedPeek / fixedPoke as the default methods.
For JSON-serialisable ADTs use jsonWasmPeek / jsonWasmPoke.
Methods
Arguments
| :: MemoryInstance | The linear memory instance |
| -> Word32 | Byte offset in linear memory |
| -> Word32 | Byte length of the slice |
| -> IO (WasmResult a) |
Read a value of type a from len bytes of linear memory at offset.
Returns Left on out-of-bounds access or deserialisation failure.
Arguments
| :: MemoryInstance | The linear memory instance |
| -> Word32 | Byte offset to write at |
| -> a | The value to serialise |
| -> IO (WasmResult Word32) |
|
Write a value of type a into linear memory at offset.
Returns Right n where n is the number of bytes written, or Left on
out-of-bounds access.
Instances
Fixed-size subclass
class WasmMemory a => FixedWasmMemory a where #
A WasmMemory type with a statically-known byte width.
Implement this for all primitive types.
Methods
wasmWidth :: Proxy a -> Word32 #
Byte width of the serialised form.
serialise :: a -> ByteString #
Serialise to exactly wasmWidth bytes.
deserialise :: ByteString -> Either String a #
Deserialise from at least wasmWidth bytes.
Instances
fixedPoke :: FixedWasmMemory a => MemoryInstance -> Word32 -> a -> IO (WasmResult Word32) #
Default wasmPoke for any FixedWasmMemory instance.
fixedPeek :: FixedWasmMemory a => MemoryInstance -> Word32 -> Word32 -> IO (WasmResult a) #
Default wasmPeek for any FixedWasmMemory instance.
JSON codec helpers (for custom ADTs)
jsonWasmPoke :: ToJSON a => MemoryInstance -> Word32 -> a -> IO (WasmResult Word32) #
Write any ToJSON value into linear memory as a UTF-8 JSON blob.
Returns the number of bytes written.
jsonWasmPeek :: FromJSON a => MemoryInstance -> Word32 -> Word32 -> IO (WasmResult a) #
Read a UTF-8 JSON blob from linear memory and decode it as a FromJSON
value.
Newtype wrapper to derive WasmMemory for any type with ToJSON and FromJSON via DerivingVia.
data Person = Person { name :: Text, age :: Int }
deriving stock (Generic, Show, Eq)
deriving anyclass (ToJSON, FromJSON)
deriving (WasmMemory) via (WasmJSON Person)
Constructors
| WasmJSON | |
Fields
| |
Instances
| FromJSON a => FromJSON (WasmJSON a) # | |
Defined in WasmEdge.Memory.Codec | |
| ToJSON a => ToJSON (WasmJSON a) # | |
| Show a => Show (WasmJSON a) # | |
| Eq a => Eq (WasmJSON a) # | |
| (ToJSON a, FromJSON a) => WasmMemory (WasmJSON a) # | |
Defined in WasmEdge.Memory.Codec Methods wasmPeek :: MemoryInstance -> Word32 -> Word32 -> IO (WasmResult (WasmJSON a)) # wasmPoke :: MemoryInstance -> Word32 -> WasmJSON a -> IO (WasmResult Word32) # | |