Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit f489a73

Browse files
authored
Remove unwind (#156)
It looks people have generally agreed on removing `unwind` in the MVP spec, as it overlaps with `catch_all` in functionality. Closes #153.
1 parent 7eff14a commit f489a73

File tree

1 file changed

+17
-67
lines changed

1 file changed

+17
-67
lines changed

proposals/exception-handling/Exceptions.md

Lines changed: 17 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ succeeding instructions to process the data.
3636
A WebAssembly exception is created when you throw it with the `throw`
3737
instruction. Thrown exceptions are handled as follows:
3838

39-
1. They can be caught by one of `catch`/`catch_all`/`unwind` blocks in an
40-
enclosing try block of a function body.
39+
1. They can be caught by one of `catch`/`catch_all` blocks in an enclosing try
40+
block of a function body.
4141

4242
1. Throws not caught within a function body continue up the call stack, popping
4343
call frames, until an enclosing try block is found.
@@ -59,8 +59,8 @@ may send values back to the suspended instruction, allowing the originating code
5959
to resume.
6060

6161
Exceptions are a special case of an event in that they never resume. Similarly,
62-
a `throw` instruction is the suspending event of an exception. The catch or
63-
unwind block associated with a try block defines how to handle the throw.
62+
a `throw` instruction is the suspending event of an exception. The catch block
63+
associated with a try block defines how to handle the throw.
6464

6565
WebAssembly events (i.e. exceptions) are defined by a new `event` section of a
6666
WebAssembly module. The event section is a list of declared events associated
@@ -152,32 +152,6 @@ exception is thrown, or the exception is successfully caught by the catch block.
152152
Because `try` and `end` instructions define a control-flow block, they can be
153153
targets for branches (`br` and `br_if`) as well.
154154

155-
### Try-unwind blocks
156-
157-
Try blocks can also be used with the `unwind` instruction. A try-unwind block
158-
contains an `unwind` block with the following form:
159-
160-
```
161-
try blocktype
162-
instruction*
163-
unwind
164-
instruction*
165-
end
166-
```
167-
168-
The `unwind` block is meant to contain cleanup instructions, such as
169-
destructors, in case any instruction in the corresponding try block throws. In
170-
case an exception is caught by the `unwind` block, it becomes the catching
171-
block.
172-
173-
The `end` instruction at the end of `unwind` block is special that it
174-
automatically rethrows the current exception.
175-
176-
When the program runs `br` within `unwind` block, the rest of the `unwind` block
177-
will not run and the program control will branch to the destination, as in
178-
normal blocks. Because we don't reach `end` of `unwind` block, rethrowing does
179-
not happen.
180-
181155
### Throwing an exception
182156

183157
The `throw` instruction takes an exception index as an immediate argument. That
@@ -203,8 +177,8 @@ flushed, the embedder defines how to handle uncaught exceptions. Otherwise, the
203177
found enclosing try block is the catching try block.
204178

205179
A throw inside the body of a catch block is never caught by the corresponding
206-
try block of the catch/unwind block, since instructions in the body of the
207-
catch/unwind block are not in the body of the try block.
180+
try block of the catch block, since instructions in the body of the catch block
181+
are not in the body of the try block.
208182

209183
Once a catching try block is found for the thrown exception, the operand stack
210184
is popped back to the size the operand stack had when the try block was entered
@@ -225,23 +199,16 @@ a `catch_all` block, the exception is rethrown.
225199
If control is transferred to the body of a catch block, and the last instruction
226200
in the body is executed, control then exits the try block.
227201

228-
In case of a try-unwind block, if an exception is thrown within the try block,
229-
the program control is transfered to the body of `unwind` block. After executing
230-
instructions within the `unwind` block, the exception is automatically rethrown
231-
when the control reaches the `end` instruction. As in the case of the
232-
`catch_all` block, the exception arguments are not copied onto the operand
233-
stack.
234-
235-
If the selected catch/unwind block does not throw an exception, it must yield
236-
the value(s) expected by the corresponding catching try block.
202+
If the selected catch block does not throw an exception, it must yield the
203+
value(s) specified by the type annotation on the corresponding catching try
204+
block.
237205

238206
Note that a caught exception can be rethrown using the `rethrow` instruction.
239207

240208
### Rethrowing an exception
241209

242-
The `rethrow` instruction can only appear in the body of a
243-
catch/catch_all/unwind block. It always re-throws the exception caught by an
244-
enclosing catch block.
210+
The `rethrow` instruction can only appear in the body of a catch/catch_all
211+
block. It always re-throws the exception caught by an enclosing catch block.
245212

246213
Associated with the `rethrow` instruction is a _label_. The label is used to
247214
disambiguate which exception is to be rethrown, when inside nested catch blocks.
@@ -298,21 +265,6 @@ end
298265
The `rethrow` here references `try $l2`, but the `rethrow` is not within its
299266
`catch` block.
300267

301-
Also, the `rethrow` instruction cannot rethrow an exception caught
302-
by an unwind block. For example:
303-
```
304-
try $l1
305-
unwind
306-
try $l2
307-
catch
308-
try $l3
309-
unwind
310-
rethrow label ;; only $l2 is valid
311-
end
312-
end
313-
end
314-
```
315-
316268
### Try-delegate blocks
317269

318270
Try blocks can also be used with the `delegate` instruction. A try-delegate
@@ -327,8 +279,8 @@ delegate label
327279
The `delegate` clause does not have an associated body, so try-delegate blocks
328280
don't have an `end` instruction at the end. The `delegate` instruction takes a
329281
label defined by a construct in which they are enclosed, and delegates exception
330-
handling to a catch/unwind block specified by the label. For example, consider
331-
this code:
282+
handling to a catch block specified by the label. For example, consider this
283+
code:
332284

333285
```
334286
try $l1
@@ -374,10 +326,10 @@ uncaught exceptions. However, the details of this are left to the embedder.
374326

375327
#### Traps
376328

377-
The `catch`/`catch_all`/`unwind` instruction catches exceptions generated by the
378-
`throw` instruction, but does not catch traps. The rationale for this is that in
379-
general traps are not locally recoverable and are not needed to be handled in
380-
local scopes like try-catch.
329+
The `catch`/`catch_all` instruction catches exceptions generated by the `throw`
330+
instruction, but does not catch traps. The rationale for this is that in general
331+
traps are not locally recoverable and are not needed to be handled in local
332+
scopes like try-catch.
381333

382334
The `catch` instruction catches foreign exceptions generated from calls to
383335
function imports as well, including JavaScript exceptions, with a few
@@ -407,7 +359,6 @@ The following rules are added to *instructions*:
407359

408360
```
409361
try blocktype instruction* (catch instruction*)* (catch_all instruction*)? end |
410-
try blocktype instruction* unwind instruction* end |
411362
try blocktype instruction* delegate label |
412363
throw (exception except_index) |
413364
rethrow label |
@@ -564,7 +515,6 @@ throws, and rethrows as follows:
564515
| `try` | `0x06` | sig : `blocktype` | begins a block which can handle thrown exceptions |
565516
| `catch` | `0x07` | index : `varint32` | begins the catch block of the try block |
566517
| `catch_all` | `0x19` | | begins the catch_all block of the try block |
567-
| `unwind` | `0x0a` | | begins the unwind block of the try block |
568518
| `delegate` | `0x18` | relative_depth : `varuint32` | begins the delegate block of the try block |
569519
| `throw` | `0x08` | index : `varint32` | Creates an exception defined by the exception `index`and then throws it |
570520
| `rethrow` | `0x09` | relative_depth : `varuint32` | Pops the `exnref` on top of the stack and throws it |

0 commit comments

Comments
 (0)