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
{{ message }}
This repository was archived by the owner on Apr 25, 2025. It is now read-only.
Copy file name to clipboardExpand all lines: proposals/Exceptions.md
+56-37Lines changed: 56 additions & 37 deletions
Original file line number
Diff line number
Diff line change
@@ -133,9 +133,10 @@ Exception indices are used by:
133
133
1. The `throw` instruction which creates a WebAssembly exception with the
134
134
corresponding exception tag, and then throws it.
135
135
136
-
2. The `if_except` instruction queries an exception to see if the corresponding
137
-
exception tag denoted by the exception index. If true it pushes the
138
-
corresponding values of the exception onto the stack.
136
+
2. The `br_on_exn` instruction queries an exception to see if it matches the
137
+
corresponding exception tag denoted by the exception index. If true it
138
+
branches to the given label and pushes the corresponding argument values of
139
+
the exception onto the stack.
139
140
140
141
### The exception reference data type
141
142
@@ -220,39 +221,58 @@ exception on top of the stack is popped and then thrown.
220
221
221
222
### Exception data extraction
222
223
223
-
The `if_except` block begins with an `if_except` instruction, and has two
224
-
instruction blocks,
225
-
226
-
That is, the forms of an if_except block is:
224
+
The `br_on_exn` instruction is a conditional branch that checks the exception
225
+
tag of an exception on top of the stack, in the form of:
227
226
228
227
```
229
-
if_except block_type except_index
230
-
Instruction*
231
-
end
228
+
br_on_exn label except_index
229
+
```
230
+
231
+
The `br_on_exn` instruction checks the exception tag of an `except_ref` on top
232
+
of the stack if it matches the given exception index. If it does, it branches
233
+
out to the label referenced by the instruction (In the binary form, the label
234
+
will be converted to a relative depth immediate, like other branch
235
+
instructions), and while doing that, pops the `except_ref` value from the stack
236
+
and instead pushes the exception's argument values on top of the stack. In order
237
+
to use these popped values, the block signature of the branch target has to
238
+
match the exception types - because it receives the exception arguments as
239
+
branch operands. If the exception tag does not match, the `except_ref` value
240
+
remains on the stack. For example, when an `except_ref` contains an exception of
241
+
type (i32 i64), the target block signature should be (i32 i64) as well, as in
242
+
the following example:
232
243
233
-
if_except block_type except_index
234
-
Instruction*
235
-
else
236
-
Instruction*
244
+
```
245
+
block $l (result i32 i64)
246
+
...
247
+
;; except_ref $e is on the stack at this point
248
+
br_on_exn $l ;; branch to $l with $e's arguments
249
+
...
237
250
end
238
251
```
239
252
240
-
In the first form, the instructions between the `if_except` and 'end' define the
241
-
`then block`. In the second form, the instructions between the `if_except` and
242
-
`else` define the `then block`, while the instructions between the `else` and
243
-
the `end` define the `else block`.
244
-
245
-
The conditional query of an exception checks the exception tag of exception on
246
-
top of the stack. It succeeds only if the exception index of the instruction
247
-
matches the corresponding exception tag. Once the query completes, the exception
248
-
is popped off the stack.
253
+
This can now be used to construct handler switches in the same way `br_table`
254
+
is used to construct regular switch:
249
255
250
-
If the query succeeds the values (associated with the popped exception) are
251
-
extracted and pushed onto the stack, and control transfers to the instructions
252
-
in the then block.
256
+
```
257
+
block $end
258
+
block $l1
259
+
...
260
+
block $lN
261
+
br_on_exn $l1
262
+
...
263
+
br_on_exn $lN
264
+
rethrow
265
+
end $lN
266
+
;; handler for $eN here
267
+
br $end
268
+
...
269
+
end $l1
270
+
;; handler for $e1
271
+
end $end
272
+
```
253
273
254
-
If the query fails, it either enters the else block, or transfer control to the
255
-
end of the if_except block if there is no else block.
274
+
If the query fails, the control flow falls through, and no values are pushed
275
+
onto the stack.
256
276
257
277
### Stack traces
258
278
@@ -274,15 +294,14 @@ The following rules are added to *instructions*:
274
294
try resulttype instruction* catch instruction* end |
275
295
throw except_index |
276
296
rethrow |
277
-
if_except resulttype except_index then instruction* end |
278
-
if_except resulttype except_index then instruction* else instruction* end
297
+
br_on_exn label except_index
279
298
```
280
299
281
-
Like the `block`, `loop`, and `if` instructions, the `try`and `if_except`
282
-
instructions are *structured* control flow instructions, and can be labeled.
283
-
This allows branch instructions to exit try and `if_except` blocks.
300
+
Like the `block`, `loop`, and `if` instructions, the `try`instruction is
301
+
*structured* control flow instruction, and can be labeled. This allows branch
302
+
instructions to exit try blocks.
284
303
285
-
The `except_index` of the `throw` and `if_except` instructions defines the
304
+
The `except_index` of the `throw` and `br_on_exn` instructions defines the
286
305
exception (and hence, exception tag) to create/extract from. See [exception
287
306
index space](#exception-index-space) for further clarification of exception
288
307
tags.
@@ -447,7 +466,7 @@ throws, and rethrows as follows:
447
466
|`catch`|`0x07`|| begins the catch block of the try block |
448
467
|`throw`|`0x08`| index : `varint32`| Creates an exception defined by the exception `index`and then throws it |
449
468
|`rethrow`|`0x09`|| Pops the `except_ref` on top of the stack and throws it |
450
-
|`if_except`|`0x0a`|index : `varuint32`, sig : `block_type`|Begin exception data extraction if exception on stack was created using the corresponding exception `index`|
469
+
|`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`|
451
470
452
-
The *sig* fields of `block`, `if`, `try`and `if_except` operators are block
453
-
signatures which describe their use of the operand stack.
471
+
The *sig* fields of `block`, `if`, and `try` operators are block signatures
0 commit comments