First taken from stack as block, then augmented with inline param.
(func $x (param i32 i32 i32))
...
(i32.const 0)(i32.const 1) (call $x (i32.const 3))
;; converts to
(call $x (i32.const 0)(i32.const 1)(i32.const 3))
Function call pops value from stack. Stack doesn't have to match fn signature - it should only have enough elements for the call.
...
(i32.const 0)(i32.const 1)(i32.const 2)
(call $log)(call $log)(call $log)
;; 2, 1, 0
They pick args from the stack, not enforce it. But they pick it only once, at the moment of entry. Single loop cannot be used to flush stack.
(func $x
(i32.const 0)(i32.const 1)
(loop (param i32)
(call $log) ;; prints 1
)
)
Numerated from 0 after params
(func $x (param i32 i32) (result i32) (local i32)
(local.get 0) ;; first param
(local.get 1) ;; second param
(local.get 2) ;; local
)
Starts from 0
(func
(return)
)
(export "x" (func 0))
Branching index counts structured controls blocks, like
(func
(local i32)
(block (;2;)
(loop (;1;)
(if (...) (;0;)
(then
(br_if 0 (i32.const 1))
;; (br 1) here would be the same as
)
)
;; (br 0) here
)
)
)
Return be called within blocks/loops/conditions & that breaks function with last value from stack, it ignores any con
(func $x (result f64)
(f64.convert_i32_s
(if (xxx) (then
(block
(return (f64.const 3.14))
)
))
(i32.const 1)
)
)
Main thread buffer is limited to 4kb:
// sync instance - limits buffer size to 4kb
const mod = new WebAssembly.Module(buffer)
const instance = new WebAssembly.Instance(mod, config)
// async instance - buffer size can be any but compiles slower
const instance WebAssembly.instantiate(buffer, config)
That's 1000. If return is more that 1000 it throws error : return count of 1001 exceeds internal limit of 1000 @+14
(func $x (result i32 i32 ...i32x1001)
(return)
)