You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: proposals/Exceptions.md
+55-37Lines changed: 55 additions & 37 deletions
Original file line number
Diff line number
Diff line change
@@ -128,9 +128,10 @@ Exception indices are used by:
128
128
1. The `throw` instruction which creates a WebAssembly exception with the
129
129
corresponding exception tag, and then throws it.
130
130
131
-
2. The `if_except` instruction queries an exception to see if the corresponding
132
-
exception tag denoted by the exception index. If true it pushes the
133
-
corresponding values of the exception onto the stack.
131
+
2. The `br_on_exn` instruction queries an exception to see if the corresponding
132
+
exception tag denoted by the exception index. If true it branches to the
133
+
given label and pushes the corresponding values of the exception onto the
134
+
stack.
134
135
135
136
### The exception reference data type
136
137
@@ -215,39 +216,57 @@ exception on top of the stack is popped and then thrown.
215
216
216
217
### Exception data extraction
217
218
218
-
The `if_except` block begins with an `if_except` instruction, and has two
219
-
instruction blocks,
220
-
221
-
That is, the forms of an if_except block is:
219
+
The `br_on_exn` instruction is a conditional branch that checks the exception
220
+
tag of an exception on top of the stack, in the form of:
222
221
223
222
```
224
-
if_except block_type except_index
225
-
Instruction*
226
-
end
223
+
br_on_exn label except_index
224
+
```
225
+
226
+
The `br_on_exn` instruction checks the exception tag of an `except_ref` on top
227
+
of the stack if it matches the given exception index. If it does, it branches
228
+
out to the label referenced by the instruction (In the binary form, the label
229
+
will be converted to a relative depth immediate, like other branch
230
+
instructions), and while doing that, pops exception values from the `except_ref`
231
+
and places them on top of the stack. In order to use these popped values, the
232
+
block signature of the branch target has to match the exception types - because
233
+
it receives the exception arguments as branch operands. If the exception tag
234
+
does not match, the `except_ref` value remains on the stack. For example, when
235
+
an `except_ref` contains an exception of type (i32 i64), the target block
236
+
signature should be (i32 i64) as well, as in the following example:
227
237
228
-
if_except block_type except_index
229
-
Instruction*
230
-
else
231
-
Instruction*
238
+
```
239
+
block $l (result i32 i64)
240
+
...
241
+
;; except_ref $e is on the stack at this point
242
+
br_on_exn $l ;; branch to $l with $e's arguments
243
+
...
232
244
end
233
245
```
234
246
235
-
In the first form, the instructions between the `if_except` and 'end' define the
236
-
`then block`. In the second form, the instructions between the `if_except` and
237
-
`else` define the `then block`, while the instructions between the `else` and
238
-
the `end` define the `else block`.
239
-
240
-
The conditional query of an exception checks the exception tag of exception on
241
-
top of the stack. It succeeds only if the exception index of the instruction
242
-
matches the corresponding exception tag. Once the query completes, the exception
243
-
is popped off the stack.
247
+
This can now be used to construct handler switches in the same way `br_table`
248
+
is used to construct regular switch:
244
249
245
-
If the query succeeds the values (associated with the popped exception) are
246
-
extracted and pushed onto the stack, and control transfers to the instructions
247
-
in the then block.
250
+
```
251
+
block $end
252
+
block $l1
253
+
...
254
+
block $lN
255
+
br_on_exn $l1
256
+
...
257
+
br_on_exn $lN
258
+
rethrow
259
+
end $lN
260
+
;; handler for $eN here
261
+
br $end
262
+
...
263
+
end $l1
264
+
;; handler for $e1
265
+
end $end
266
+
```
248
267
249
-
If the query fails, it either enters the else block, or transfer control to the
250
-
end of the if_except block if there is no else block.
268
+
If the query fails, the control flow falls through, and no values are pushed
269
+
onto the stack.
251
270
252
271
### Stack traces
253
272
@@ -269,15 +288,14 @@ The following rules are added to *instructions*:
269
288
try resulttype instruction* catch instruction* end |
270
289
throw except_index |
271
290
rethrow |
272
-
if_except resulttype except_index then instruction* end |
273
-
if_except resulttype except_index then instruction* else instruction* end
291
+
br_on_exn label except_index
274
292
```
275
293
276
-
Like the `block`, `loop`, and `if` instructions, the `try`and `if_except`
277
-
instructions are *structured* control flow instructions, and can be labeled.
278
-
This allows branch instructions to exit try and `if_except` blocks.
294
+
Like the `block`, `loop`, and `if` instructions, the `try`instruction is
295
+
*structured* control flow instruction, and can be labeled. This allows branch
296
+
instructions to exit try blocks.
279
297
280
-
The `except_index` of the `throw` and `if_except` instructions defines the
298
+
The `except_index` of the `throw` and `br_on_exn` instructions defines the
281
299
exception (and hence, exception tag) to create/extract from. See [exception
282
300
index space](#exception-index-space) for further clarification of exception
283
301
tags.
@@ -442,7 +460,7 @@ throws, and rethrows as follows:
442
460
|`catch`|`0x07`|| begins the catch block of the try block |
443
461
|`throw`|`0x08`| index : `varint32`| Creates an exception defined by the exception `index`and then throws it |
444
462
|`rethrow`|`0x09`|| Pops the `except_ref` on top of the stack and throws it |
445
-
|`if_except`|`0x0a`|index : `varuint32`, sig : `block_type`|Begin exception data extraction if exception on stack was created using the corresponding exception `index`|
463
+
|`br_on_exn`|`0x0a`|relative_depth : `varuint32`, index : `varuint32`|Branches to the given label and extracts data within `except_ref`on top of stack if it was created using the corresponding exception `index`|
446
464
447
-
The *sig* fields of `block`, `if`, `try`and `if_except` operators are block
448
-
signatures which describe their use of the operand stack.
465
+
The *sig* fields of `block`, `if`, and `try` operators are block signatures
0 commit comments