Skip to content

Commit 417a927

Browse files
committed
Factor a multiblock node out of tableswitch.
This also updates the wording around control flow operators in several areas.
1 parent f92c671 commit 417a927

File tree

1 file changed

+39
-27
lines changed

1 file changed

+39
-27
lines changed

AstSemantics.md

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -232,54 +232,66 @@ Since all AST nodes are expressions in WebAssembly, control constructs may yield
232232
a value and may appear as children of other expressions.
233233

234234
* `nop`: an empty operator that does not yield a value
235-
* `block`: a fixed-length sequence of expressions with a label at the end
235+
* `block`: a sequence of expressions with a label at the end
236236
* `loop`: a block with an additional label at the beginning which may be used to form loops
237+
* `multiblock`: a mixed sequence of expressions and `label` nodes, with a label at the end
238+
* `label`: a node which defines a label and must be an immediate child of `multiblock`
237239
* `if`: if expression with a *then* expression
238240
* `if_else`: if expression with *then* and *else* expressions
239-
* `br`: branch to a given label in an enclosing construct
240-
* `br_if`: conditionally branch to a given label in an enclosing construct
241-
* `tableswitch`: a jump table which may jump either to an immediate `case`
242-
child or to a label in an enclosing construct
243-
* `case`: a case which must be an immediate child of `tableswitch`
241+
* `br`: branch to a given in-scope label
242+
* `br_if`: conditionally branch to a given in-scope label
243+
* `tableswitch`: branch using a "jump table" of in-scope labels
244244
* `return`: return zero or more values from this function
245245

246246
### Branches and nesting
247247

248-
The `br` and `br_if` constructs express low-level branching.
249-
Branches that exit a `block`, `loop`, or `tableswitch` may take a subexpression
250-
that yields a value for the exited construct.
251-
Branches may only reference labels defined by an outer *enclosing construct*.
252-
This means that, for example, references to a `block`'s label can only occur
253-
within the `block`'s body.
254-
255-
In practice, outer `block`s can be used to place labels for any given branching
256-
pattern, except for one restriction: one can't branch into the middle of a loop
257-
from outside it. This restriction ensures all control flow graphs are well-structured
248+
The `br`, `br_if`, and `tableswitch` constructs express low-level branching. The
249+
`block`, `loop`, and `multiblock` constructs provide labels that may be branched
250+
to.
251+
252+
Branches may only reference labels that are *in scope*. The labels in `block`
253+
and `loop` nodes are in scope only within their subtrees. The labels in
254+
`multiblock` nodes are only in scope only within their subtrees, and only in
255+
subtrees earlier in the `multiblock` than their definition. This restriction
256+
ensures all control flow graphs are
257+
[reducible](http://dl.acm.org/citation.cfm?id=804919).
258+
259+
In terms of control flow graphs, the reducible requirement imposes
260+
only one effective restriction: loops can only be entered from the
261+
top, and not from a branch into the middle. This restriction ensures
262+
all control flow graphs are well-structured
258263
in the exact sense as in high-level languages like Java, JavaScript, Rust and Go. To
259264
further see the parallel, note that a `br` to a `block`'s label is functionally
260265
equivalent to a labeled `break` in high-level languages in that a `br` simply
261266
breaks out of a `block`.
262267

268+
Branches may take a subexpression as an optional first operand (before any
269+
other operands). When a `block`, `multiblock`, or `loop` is exited by a branch,
270+
or when a `label` is branched to by a branch, this operand of the branch is
271+
yielded as the result. When `br_if`'s condition is false, this operand is
272+
yielded as `br_if`'s result.
273+
263274
### Yielding values from control constructs
264275

265-
The `nop`, `if`, `br`, `br_if`, `case`, and `return` constructs do not yield values.
276+
The `nop` and `if` constructs do not yield values.
266277
Other control constructs may yield values if their subexpressions yield values:
267278

268-
* `block`: yields either the value of the last expression in the block or the result of an inner `br` that targeted the label of the block
269-
* `loop`: yields either the value of the last expression in the loop or the result of an inner `br` that targeted the end label of the loop
279+
* `block`: yields either the value of the last expression in the block or the
280+
result of an inner branch that branched to the label of the `block`
281+
* `loop`: yields either the value of the last expression in the loop or the
282+
result of an inner branch that branched to the end label of the `loop`
283+
* `multiblock`: yields either the value of the last expression in the
284+
`multiblock` or the result of an inner branch that branched to the end label
285+
of the `multiblock`
286+
* `label`: yields either the value of the prior expression in the parent `multiblock` or the result of a branch that branched to the `label`
270287
* `if_else`: yields either the value of the true expression or the false expression
271-
* `tableswitch`: yields either the value of the last case or the result of an inner `br` that targeted the tableswitch
272288

273289

274290
### Tableswitch
275291

276-
A `tableswitch` consists of a zero-based array of targets, a *default* target, an index
277-
operand, and a list of `case` nodes. Targets may be either labels or `case` nodes.
278-
A `tableswitch` jumps to the target indexed in the array or the default target if the index is out of bounds.
279-
280-
A `case` node consists of an expression and may be referenced multiple times
281-
by the parent `tableswitch`. Unless exited explicitly, control falls through a `case`
282-
to the next `case` or the end of the `tableswitch`.
292+
A `tableswitch` consists of a zero-based array of labels, a *default* label, and an
293+
index operand. A `tableswitch` branches to the label indexed in the array or the
294+
default label if the index is out of bounds.
283295

284296

285297
## Calls

0 commit comments

Comments
 (0)