Memory Basics
WebAssembly modules can declare a block of raw bytes called linear memory. Unlike the JavaScript heap, this memory is a flat, untyped array of bytes that both the Wasm module and JavaScript can read and write directly. It is the primary mechanism for passing complex data — strings, arrays, structs — between WebAssembly and the host.
Declaring memory with (memory N)
Section titled “Declaring memory with (memory N)”The (memory N) declaration reserves N pages of memory, where each page is exactly 64 KiB (65 536 bytes). The minimum useful size is one page:
(memory 1)This gives your module 65 536 bytes of addressable memory, all initialised to zero at instantiation time.
Loading and storing integers
Section titled “Loading and storing integers”WebAssembly provides typed load and store instructions for reading and writing values at specific byte addresses.
i32.store— pops an address and a 32-bit integer from the stack, writes 4 bytes at that addressi32.load— pops an address from the stack, reads 4 bytes and pushes ani32result
Both instructions accept an optional static offset attribute that is added to the runtime address, which is useful for accessing fields within a struct.
Exporting memory to JavaScript
Section titled “Exporting memory to JavaScript”JavaScript cannot access Wasm memory unless the module exports it. Use the inline export syntax:
(memory (export "mem") 1)On the JavaScript side you can also create a WebAssembly.Memory object and pass it in as an import:
const memory = new WebAssembly.Memory({ initial: 1 });Store and load example
Section titled “Store and load example”Here is a complete module that stores an i32 value at byte address 100 and immediately loads it back:
(module (memory (export "mem") 1) (func (export "storeAndLoad") (param $val i32) (result i32) i32.const 100 ;; address local.get $val ;; value to store i32.store i32.const 100 ;; address i32.load)) ;; load backThe stack discipline here is: push address, push value, call i32.store (consumes both). Then push address again, call i32.load (consumes address, pushes result).
Run it
Section titled “Run it”The runner below stores 999 at offset 100, reads it back, and also reads mem[0] (which should be 0 since nothing was written there).