Course contentsShow
← Rust
Lesson 1832 of 1,91016. Specialized Runtime TargetsFree lesson

Wasm Memory Model Fundamentals

Explain how linear memory in Wasm maps to Rust's memory architecture and heap management.

In this lesson, you will learn how WebAssembly’s linear memory acts as a contiguous, sandbox-isolated address space that bridges the gap between Rust’s ownership model and a flat byte array.

The Linear Memory Abstraction

Unlike a native system where the OS manages virtual memory pages via an MMU, Wasm provides a linear memory—a single, contiguous array of raw bytes. To Rust, this linear memory is effectively the entire "physical" world. When you compile Rust to Wasm, the compiler treats this giant array as the heap, the stack, and the static data segment combined.

Mapping Rust to Bytes

Because Wasm has no concept of "pointers" to outside memory, every address in your Rust code is simply an offset (an integer index) into this byte array. When you define a struct or allocate a Box, the Rust compiler—specifically through its wasm32-unknown-unknown target—translates those high-level structures into offsets within the WebAssembly.Memory object.

Consider this memory layout conceptually:

// A simplified view of how Rust perceives the Linear Memory
// [ Static Data | Stack | Heap ]
// All these live in the same byte array, indexed by i32 offsets.

When you allocate memory in Rust (e.g., using Vec), the wasm-bindgen or wee_alloc allocator performs "pointer arithmetic" by incrementing a pointer index within this array. If the heap grows, the Wasm runtime expands the total number of 64KB pages available to the module via the memory.grow instruction.

Safety and Boundaries

Since the Rust compiler generates the code, it ensures that your Rust references (&T) point to valid offsets within these bounds. However, because Wasm linear memory is just a flat array, there is no "hardware" protection between your stack and your heap like you might find in an embedded MMU-based system. If a buffer overflow occurs, it doesn't trigger a segment fault in the traditional sense; it simply overwrites adjacent data within the same Wasm module instance. The "sandbox" exists only at the boundary between the Wasm module and the host (e.g., JavaScript or a Rust host runtime), preventing the Wasm code from accessing memory outside its assigned array.

Key Takeaway: Wasm linear memory is a raw, flat array of bytes where Rust’s memory management is implemented entirely through index-based offsets and cooperative heap allocation.