The VM
trace-vm-while

Walk through the VM executing a while loop. Here's the WAT for var i: i64 = 0; while (i < 3) { i = i + 1; } i:

  (local $i i64)
  i64.const 0
  local.set $i
  block
  loop
    local.get $i
    i64.const 3
    i64.lt_s
    i64.eqz
    br_if 1
    local.get $i
    i64.const 1
    i64.add
    local.set $i
    br 0
  end
  end
  local.get $i

Trace the first two iterations and the exit. Write down $i, the stack, and pc at each key point.

Iteration 1: $i = 0. Push 0, push 3, lt_s -> 1 (true), eqz -> 0, br_if 1 -- 0 is not nonzero, don't branch. Continue into body. Push 0, push 1, add -> 1, set $i. Now $i = 1. br 0 -- jump back to loop.

Iteration 2: $i = 1. Push 1, push 3, lt_s -> 1, eqz -> 0, br_if 1 -- don't branch. Body: 1 + 1 = 2, set $i. $i = 2. br 0 -- back to loop.

Iteration 3: $i = 2. Same. $i = 3. br 0.

Exit: $i = 3. Push 3, push 3, lt_s -> 0 (false), eqz -> 1, br_if 1 -- 1 is nonzero, branch! Jump to block target + 1 (past the outer end). Push $i -> 3. Result: 3.

The eqz flip is doing exactly what we predicted in Problem 45. Without it, the loop would exit on the first iteration.