Skip to content

Calls and Recursion

Functions in WebAssembly call each other with the call instruction. Arguments are pushed onto the stack before the call; the return value (if any) is left on the stack when the callee returns. Wasm fully supports direct recursion — a function may call itself — and mutual recursion between functions defined in the same module.

call $funcname invokes the named function. You can also call by index (call 0) but named references are far easier to read. Before executing call, push all arguments in left-to-right order:

(module
(func $double (param $n i32) (result i32)
local.get $n
i32.const 2
i32.mul)
(func (export "quadruple") (param $x i32) (result i32)
local.get $x
call $double ;; passes $x; result replaces it on stack
call $double)) ;; doubles again

quadruple(3) calls $double twice, producing 3 → 6 → 12.

WAT allows a function to call itself. The pattern mirrors every other language: push arguments, call self, combine results. The base case uses if to return directly without a recursive call.

(module
(func $factorial (export "factorial") (param $n i32) (result i32)
local.get $n
i32.const 1
i32.le_s ;; n <= 1?
if (result i32)
i32.const 1 ;; base case: 0! = 1! = 1
else
local.get $n
local.get $n
i32.const 1
i32.sub
call $factorial ;; factorial(n-1)
i32.mul ;; n * factorial(n-1)
end))

The function is given both an internal name ($factorial) so it can call itself and an export name so JavaScript can invoke it.

Two recursive calls in the else arm work the same way — push arguments, call, then add the two results:

(module
(func $fib (export "fib") (param $n i32) (result i32)
local.get $n
i32.const 1
i32.le_s ;; n <= 1?
if (result i32)
local.get $n ;; fib(0)=0, fib(1)=1
else
local.get $n
i32.const 1
i32.sub
call $fib ;; fib(n-1)
local.get $n
i32.const 2
i32.sub
call $fib ;; fib(n-2)
i32.add
end))
WebAssembly
How do you call a function named `$add` in WAT?
What must be on the stack before a `call $fn` that takes two i32 parameters?
Does basic WebAssembly optimize tail calls automatically?