Tail Calls, Typed Function References and Stack Switching
25.1 Tail Calls (Wasm 3.0)
return_call, return_call_indirect, return_call_ref. Essential for functional languages (Scheme, Haskell, OCaml), interpreters, and continuation-passing style.
(func $loop_sum (param $n i64) (param $acc i64) (result i64)
(if (result i64) (i64.eqz (local.get $n))
(then (local.get $acc))
(else (return_call $loop_sum ;; constant stack space
(i64.sub (local.get $n) (i64.const 1))
(i64.add (local.get $acc) (local.get $n))))))25.2 Typed Function References
Typed (non-nullable) function references with call_ref, ref.as_non_null, br_on_null, and br_on_non_null. Faster than call_indirect (no table lookup or signature check), and the foundation for WasmGC.
(module
(type $i2i (func (param i32) (result i32)))
(func $inc (type $i2i) (i32.add (local.get 0) (i32.const 1)))
(elem declare func $inc)
(func (export "apply_twice") (param $x i32) (result i32)
(local $f (ref $i2i))
(local.set $f (ref.func $inc))
(call_ref $i2i (call_ref $i2i (local.get $x) (local.get $f)) (local.get $f))))25.3 Stack Switching (Proposal)
Lets Wasm suspend and resume computations (cont.new, resume, suspend). It enables coroutines, generators, async/await, green threads, and effect handlers without whole-program transforms like Asyncify. It's in active standardization (phase 3); JSPI (Module 28) covers the JS-promise use case already.