4 ms·
I've updated my comment to add more clarification, but let me elaborate a bit more here. If you have the following code: int powi(int n, int m) { int s
by lifthrasiir 4y ago
I've updated my comment to add more clarification, but let me elaborate a bit more here. If you have the following code:
int powi(int n, int m) {
int s = 1;
while (--m >= 0) s *= n;
return s;
}
The compiled WebAssembly code would look like this (the actual textual format):
(func $powi (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(set_local $2 (i32.const 1))
(block $break
(loop $continue
(br_if $break (i32.ge_s (tee_local $1 (i32.sub (get_local $1) (i32.const 1)))
(i32.const 0)))
(set_local $2 (i32.mul (get_local $2) (get_local $0)))
(br $continue)
)
)
(get_local $2)
)
Note the clear resemblance between the original code and the compiled binary. The main difference is two branch labels, because WebAssembly distinguishes forward and backward jumps by block types (`block` vs. `loop`). The binary retains all parameters and local variables.
When we say WebAssembly is a stack machine, it means that this gets serialized like this: (The textual format allows both forms, while the binary format is a direct translation of the latter.)
(func $powi (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
i32.const 1
set_local $2
block $break
loop $continue
get_local $1
i32.const 1
i32.sub
tee_local $1
i32.const 0
i32.ge_s
br_if $break
get_local $2
get_local $0
i32.mul
set_local $2
br $continue
end
end
get_local $2
)
In principle you can execute this just like a stack machine with variables, but optimizing implementations will translate this into machine codes, which wouldn't look much like either forms. So the stack machine representation doesn't imply the stack machine execution.
- whizzter 4y agoIirc WASM was initially explicitly designed to be translate-able to Asm.JS (that in turn translated to JS), basically they continued the way Asm.JS had retained backwards compatiblity with JS to either force other browsers to play along in implementing the standard or just look bad in benchmarks. (I think they've relaxed on back-compat now but it was a tool for getting everyone on board and once that had happened it was easier to break it). This is why WASM kind-of-is a stack machine. Basically the opcode sequences should be possible to easily re-translate back into a syntax tree for a back-compat JS generator. This is also why you have these block/loop branches.. it basically is translateable to labelled while loops and if blocks.