Skip to content

Commit ca9fc75

Browse files
committed
Merge pull request #427 from WebAssembly/new-control-flow
Flexible control-flow operators.
2 parents 9b38ba1 + 74c21c8 commit ca9fc75

File tree

2 files changed

+50
-34
lines changed

2 files changed

+50
-34
lines changed

AstSemantics.md

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -237,39 +237,43 @@ others, etc.
237237

238238
## Control flow structures
239239

240-
WebAssembly offers basic structured control flow. All control flow structures
241-
are statements.
242-
243-
* `block`: a fixed-length sequence of statements
244-
* `if`: if statement
245-
* `do_while`: do while statement, basically a loop with a conditional branch
246-
(back to the top of the loop)
247-
* `forever`: infinite loop statement (like `while (1)`), basically an
248-
unconditional branch (back to the top of the loop)
249-
* `continue`: continue to start of nested loop
250-
* `break`: break to end from nested loop or block
251-
* `return`: return zero or more values from this function
252-
* `switch`: switch statement with fallthrough
253-
254-
Loops (`do_while` and `forever`) may only be entered via fallthrough at the top.
255-
In particular, loops may not be entered directly via a `break`, `continue`, or
256-
`switch` destination. Break and continue statements can only target blocks or
257-
loops in which they are nested. These rules guarantee that all control flow
258-
graphs are well-structured.
259-
260-
Structured control flow provides simple and size-efficient binary encoding and
261-
compilation. Any control flow—even irreducible—can be transformed into structured
262-
control flow with the
263-
[Relooper](https://github.com/kripken/emscripten/raw/master/docs/paper.pdf)
264-
[algorithm](http://dl.acm.org/citation.cfm?id=2048224&CFID=670868333&CFTOKEN=46181900),
265-
with guaranteed low code size overhead, and typically minimal throughput
266-
overhead (except for pathological cases of irreducible control
267-
flow). Alternative approaches can generate reducible control flow via node
268-
splitting, which can reduce throughput overhead, at the cost of increasing
269-
code size (potentially very significantly in pathological cases).
270-
Also,
271-
[more expressive control flow constructs](FutureFeatures.md#more-expressive-control-flow)
272-
may be added in the future.
240+
WebAssembly offers basic structured control flow with the following constructs.
241+
All control flow structures, except `case`, are statements.
242+
243+
* `block`: a fixed-length sequence of statements with a label at the end
244+
* `loop`: a fixed-length sequence of statements with a label at the end
245+
and a loop header label at the top
246+
* `if`: if statement with then body
247+
* `if_else`: if statement with then and else bodies
248+
* `br`: branch to a given label in an enclosing construct (see below)
249+
* `br_if`: conditionally branch to a given label in an enclosing construct
250+
* `tableswitch`: a jump table transferring which may jump either to enclosed
251+
`case` blocks or to labels in enclosing constructs (see below
252+
for a more detailed description)
253+
* `case`: must be an immediate child of `tableswitch`; has a label declared
254+
in the `tableswitch`'s table and a body (as above, see below)
255+
* `return`: return zero or more values from this function
256+
257+
References to labels must occur within an *enclosing construct* that defined
258+
the label. This means that references to an AST node's label can only happen
259+
within descendents of the node in the tree. For example, references to a
260+
`block`'s label can only occur within the `block`'s body. In practice,
261+
one can arrange `block`s to put labels wherever one wants to jump to, except
262+
for one restriction: one can't jump into the middle of a loop from outside
263+
it. This restriction ensures the well-structured property discussed below.
264+
265+
`tableswitch` instructions have a zero-based array of labels, a label index,
266+
a "default" label, an index operand, and a list of `case` nodes. A `tableswitch`
267+
selects which label to branch to by looking up the index value in the label
268+
array, and transferring control to that label. If the index is out of bounds,
269+
it transfers control to the "default" label.
270+
271+
`case` nodes can only appear as immediate children of `tableswitch` statements.
272+
They have a label, which must be declared in the immediately enclosing
273+
`tableswitch`'s array, and a body which can contain arbitrary code. Control
274+
falls through the end of a `case` block into the following `case` block, or
275+
the end of the `tableswitch` in the case of the last `case`.
276+
273277

274278
## Calls
275279

Rationale.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,19 @@ See [#107](https://github.com/WebAssembly/spec/pull/107).
119119

120120
## Control Flow
121121

122-
See [#299](https://github.com/WebAssembly/design/pull/299).
122+
Structured control flow provides simple and size-efficient binary encoding and
123+
compilation. Any control flow—even irreducible—can be transformed into structured
124+
control flow with the
125+
[Relooper](https://github.com/kripken/emscripten/raw/master/docs/paper.pdf)
126+
[algorithm](http://dl.acm.org/citation.cfm?id=2048224&CFID=670868333&CFTOKEN=46181900),
127+
with guaranteed low code size overhead, and typically minimal throughput
128+
overhead (except for pathological cases of irreducible control
129+
flow). Alternative approaches can generate reducible control flow via node
130+
splitting, which can reduce throughput overhead, at the cost of increasing
131+
code size (potentially very significantly in pathological cases).
132+
Also,
133+
[more expressive control flow constructs](FutureFeatures.md#more-expressive-control-flow)
134+
may be added in the future.
123135

124136

125137
## Locals

0 commit comments

Comments
 (0)