While loops are a common control flow pattern in programming languages. Lately I've been studying a new language called WebAssembly (WASM). It took me a while to wrap my head around how while loops can be translated to WASM. So I thought it might be helpful to share what I've learned in case someone else runs into similar confusion.
In WASM, there are two types of blocks. A standard block
and a loop
block. Both block
and loop
have a label and a set of instructions to execute. They also both only execute
their instructions once. That's right. A loop
block does not actually loop on its own. Instead,
we use branch instructions.
A branch instruction, such as br
or br_if
, is similar goto statement. Branch instructions are called
with a block label. If the label points to a loop
, the branch will act as a continue
and begin
executing instructions at the top of the loop. If the label points to a block
, the branch will act
as a break
and jump to the end of the block
without executing any instructions.
With that knowledge, a while loop can be described in pseudo wasm like this:
;; Labels start with a $
block $while
loop $loop
;; If the while condition is NOT true, we br to the $while block
;; Because $while is a block, this breaks the loop
br_if $while <NOT WHILE CONDITION>
<LOOP INSTRUCTIONS...>
;; Jump back to the beginning of the loop body
br $loop
end
end
Translating that to binaryen.js, we get this:
import binaryen from "binaryen";
const mod = new binaryen.Module();
mod.block("while", [
mod.loop("loop", [
// Break out of the loop to the bottom of the while block, if the while condition is false
mod.br("while", mod.i32.ne(
compileSomeCondition(),
mod.i32.const(1)
)),
/* Loop body instructions here */
// Continue at the top of the loop body
mod.br("loop")
])
]);
console.log(mod.emitText());
If you found this post helpful, consider following me on twitter @DrewYoungwerth. I'll post links to any new blog posts there, so you can stay up to date.
Note:
At the time of writing, the binaryen.js docs
call br
break
. Both br
and break
can be called and mean the same thing to binaryen. Although
I find their usage of the word break
confusing here, so I prefer br
.
References: