Skip to content

Commit

Permalink
Model tableswitch in a more sparse way.
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfishcode committed Oct 24, 2015
1 parent 2e1ccb1 commit 6b70f43
Showing 1 changed file with 36 additions and 16 deletions.
52 changes: 36 additions & 16 deletions AstSemantics.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,17 @@ All control flow structures, except `case`, are statements.
* `br`: branch to a given label in an enclosing construct (see below)
* `br_if`: conditionally branch to a given label in an enclosing construct
* `tableswitch`: a jump table transferring which may jump either to enclosed
`case` blocks or to labels in enclosing constructs (see below
for a more detailed description)
* `case`: must be an immediate child of `tableswitch`; has a label declared
in the `tableswitch`'s table and a body (as above, see below)
`case` and `default` blocks or to labels in enclosing constructs
identified by enclosed `case_br` and `default_br` nodes (see
below for a more detailed description)
* `case`: must be an immediate child of `tableswitch`; has an immediate index
value and a body (as above, see below)
* `case_br`: must be an immediate child of `tableswitch`; has an immediate index
value and a label (as above, see below)
* `default`: must be an immediate child of `tableswitch`; has a body
(as above, see below)
* `default_br`: must be an immediate child of `tableswitch`; has a a label
(as above, see below)
* `return`: return zero or more values from this function

References to labels must occur within an *enclosing construct* that defined
Expand All @@ -272,18 +279,31 @@ one can arrange `block`s to put labels wherever one wants to jump to, except
for one restriction: one can't jump into the middle of a loop from outside
it. This restriction ensures the well-structured property discussed below.

`tableswitch` instructions have a zero-based array of labels, a label index,
a "default" label, an index operand, and a list of `case` nodes. A `tableswitch`
selects which label to branch to by looking up the index value in the label
array, and transferring control to that label. If the index is out of bounds,
it transfers control to the "default" label.

`case` nodes can only appear as immediate children of `tableswitch` statements.
They have a label, which must be declared in the immediately enclosing
`tableswitch`'s array, and a body which can contain arbitrary code. Control
falls through the end of a `case` block into the following `case` block, or
the end of the `tableswitch` in the case of the last `case`.

`tableswitch` instructions have a label index operand, and contain a sequence
of `case`, `case_br`, `default`, and `default_br` nodes. The following
restrictions apply to the sequence:

- There must be either exactly one `default` node or exactly one
`default_br` node.
- Each `case` and `case_br` must have a unique index immediate value
among all `case` and `case_br` nodes.
- For each `case` and `case_br` with a non-zero index immediate value,
there must also be a `case` or `case_br` present with an index
immediate value of one less.

A `tableswitch` first chooses a child node by selecting the `case` or
`case_br` node with the immediate index value equal to the `index` operand,
if there is such a `case` or `case_br` node present, or the `default` or
`default_br` node otherwise.

If the chosen child node is a `case`, or `default`, `tableswitch` transfers
control to the node's body. If the chosen child node is a `case_br` or
`default_br`, `tableswitch` transfers control directly to the node's label.

`case`, `case_br`, `default`, and `default_br` nodes can only appear as
immediate children of `tableswitch` statements. Control falls through the end
of `case` and `default` bodies, into the next `tableswitch` child node in AST
order, or exiting the `tableswitch` in the case of the last child node.

## Calls

Expand Down

0 comments on commit 6b70f43

Please sign in to comment.