systemwebassemblywasi

Stack space in WebAssembly (& WASI)


I'm writing small programs in WebAssembly text format (.wat). I've looked at Wasm code compiled from C and it looks like the common practice is to maintain a global stack pointer, and when we enter a function, to create a stack frame by subtracting the stack pointer by some multiple of 4 (e.g. 16):

    (global.set $g0
      (local.tee $l1
        (i32.sub
          (global.get $g0)
          (i32.const 16))))

;; --snip--

  (global $g0 (mut i32) (i32.const 67088))

I need to implement a very basic malloc to do dynamic memory management. In this implementation, I think I need to grow the memory with memory.grow if I run out of memory.

My question:

What should I do with the stack space when I grow the memory? AFAIK if I don't do anything the memory looks like this:

+-----------------------+  high memory
| Newly acquired memory |
|                       |
+-----------------------+
| Stack space           |
+-----------------------+
| Heap (managed with    |
|       malloc)         |
+-----------------------+  low memory

Solution

  • wasm-ld (the llvm linker for WebAssembly) lays out memory by default with the stack first (at a lower address). This allows for sbrk (or indeed your custom malloc) to use memory.grow to extent the heap region. The location of the start of the heap can be found by taking the address of the linker-created symbols __heap_base.