Skip to content

Loops: loop and br_if

A loop in WebAssembly does not iterate automatically. It is simply a labeled construct whose beginning is a branch target. You create iteration by placing a br_if at the bottom of the body that branches back to the loop label when the condition is still true.

(loop $label ...) marks the beginning of a loop. A br $label inside the body jumps back to the start — the opposite direction from br in a block. To exit the loop you either let execution reach the closing end (fall-through) or branch to an outer label.

(module
(func (export "countDown") (param $n i32)
(loop $again
;; body here
local.get $n
i32.const 1
i32.sub
local.tee $n ;; decrement $n and keep value on stack
i32.const 0
i32.gt_s
br_if $again))) ;; repeat while $n > 0
flowchart LR
  A["init locals"] --> B["loop $again (start)"]
  B --> C["body: update acc, increment i"]
  C --> D["i <= n?"]
  D -->|yes| B
  D -->|no| E["exit: return acc"]
Counted loop flow: br_if creates the back-edge

The function below sums the integers from 1 to n using a loop. Local $i is the counter; local $acc accumulates the total.

(module
(func (export "sumTo") (param $n i32) (result i32)
(local $i i32)
(local $acc i32)
i32.const 1
local.set $i ;; i = 1
i32.const 0
local.set $acc ;; acc = 0
(loop $again
local.get $i
local.get $acc
i32.add
local.set $acc ;; acc += i
local.get $i
i32.const 1
i32.add
local.set $i ;; i++
local.get $i
local.get $n
i32.le_s
br_if $again) ;; repeat while i <= n
local.get $acc)) ;; return acc
WebAssembly
In WAT, what does `br $l` do when `$l` is a `loop` label?
How do you EXIT a WAT loop?
What is the initial value of a local variable declared with `(local $x i32)`?