WebAssembly lacks the stack manipulation instructions (dup, swap, over, rot) that define real stack machines, making it closer to a register machine with RPN-encoded compound expressions.
Key Takeaways
Real stack machines like JVM provide dup, swap, pop, and over; Wasm ships only drop, which exists solely to discard unwanted function return values.
Without dup/swap, Wasm cannot perform common subexpression elimination or rewrite expr^2 as expr * expr without introducing local variables.
The moment any non-trivial value reuse is needed, Wasm code falls back to locals, collapsing the “stack machine” abstraction entirely.
Binary Wasm encodes expressions in Reverse Polish notation for interpreter simplicity; textual WAT uses S-expressions – both are just encodings of a register model, not evidence of a stack model.
Until the multi-value extension, control flow blocks (if, block) could not read values from the outer stack and could only return one value, further breaking the stack-machine model.
Hacker News Comment Review
One implementor building a Wasm-to-C compiler confirms the self-contained expression property: because Wasm locals absorb all reuse, each function’s stack never needs external discard or reset logic.
The observation that WAT’s S-expression syntax reflects the true register-with-compound-expressions model – not a stack model – is treated as a practical convenience, not a workaround.
Notable Comments
@stevefan1999: implementing Wasm-to-C; notes the non-stack behavior means expressions are fully self-contained per function – “I don’t have to discard or reset stack value” – and credits this for WAT’s clean S-expression representation.