Hacker News new | ask | show | jobs
by comex 3035 days ago
What you’re saying applies to interpreters, which execute the program opcode by opcode, and (in the case of stack machines) keep an actual stack at runtime. WebAssembly was designed to be the input for (at least mildly) optimizing JIT compilers. Since the stack is required to be at a fixed depth at each instruction, when the compiler reads the instruction, it can map each of the inputs it pops to a single earlier instruction that pushed it[1], and record a reference directly to that in its internal IR. After that it completely forgets about the stack. Later on it’ll do register allocation for the native architecture, so the generated native code makes efficient use of registers.

Or in other words, the “stack machine” is basically just a compact encoding of an AST.

(Note that the native “stack” is an entirely separate thing which does exist at runtime.)

[1] Actually, there can be multiple possible instructions from, e.g., inside the ‘if’ and ‘else’ sides of a prior if-block (which can push values that stay on the stack after the end of the block). But since both sides have to push the same number of values, this is still tractable; it turns into a phi node in SSA representation.

1 comments

Makes sense, thanks for the detailed response!