diff --git a/AstSemantics.md b/AstSemantics.md index 43d562ac..288c8da8 100644 --- a/AstSemantics.md +++ b/AstSemantics.md @@ -267,9 +267,9 @@ Other control constructs may yield values if their subexpressions yield values: ### Tableswitch -A `tableswitch` consists of a zero-based array of targets, a *default* target, an index +A `tableswitch` consists of a zero-based array of targets, an index operand, and a list of `case` nodes. Targets may be either labels or `case` nodes. -A `tableswitch` jumps to the target indexed in the array or the default target if the index is out of bounds. +A `tableswitch` jumps to the target indexed in the array, or traps if the index is out of bounds. A `case` node consists of an expression and may be referenced multiple times by the parent `tableswitch`. Unless exited explicitly, control falls through a `case` diff --git a/Rationale.md b/Rationale.md index c73f8993..1e650088 100644 --- a/Rationale.md +++ b/Rationale.md @@ -138,6 +138,14 @@ Also, [more expressive control flow constructs](FutureFeatures.md#more-expressive-control-flow) may be added in the future. +The `tableswitch` instruction traps if the index is out of bounds rather than +having a builtin "default" destination. Applications can perform their own +range check if they require one. This does oblidge optimizing JITs to do more +work to optimize away its own range checks, but the upside of making +`tableswitch` be conceptually just a jump table, and not a jump table with an +extra branch folded in, and it enables engines that have ways of doing the +range check without using a branch to emit switches that have no branching at +all in situations where the application itself doesn't need a default. ## Locals