@@ -274,10 +274,10 @@ try label and delegates exception handling to a `catch`/`catch_all`/`delegate`
274
274
specified by the ` try ` label. For example, consider this code:
275
275
276
276
```
277
- try $l1
277
+ try $l0
278
278
try
279
279
call $foo
280
- delegate $l1 ;; (= delegate 0)
280
+ delegate $l0 (= delegate 0)
281
281
catch
282
282
...
283
283
catch_all
@@ -288,28 +288,104 @@ end
288
288
If ` call $foo ` throws, searching for a catching block first finds ` delegate ` ,
289
289
and because it delegates exception handling to catching instructions associated
290
290
with ` $l1 ` , it will be next checked by the outer ` catch ` and then ` catch_all `
291
- instructions. When the specified label within a ` delegate ` instruction does not
292
- correspond to a ` try ` instruction, it is a validation failure.
291
+ instructions.
292
+
293
+ ` delegate ` can also target ` catch ` -less ` try ` s or non-` try ` block constructs
294
+ like ` block ` s or ` loop ` s, in which case the delegated exception is assumed to
295
+ propagate to the outer scope and will be caught by the next matching
296
+ try-catches. In the examples, catches are annotated with ` ($label_name) ` to
297
+ clarify which ` try ` it belongs to for clarification; it is not the official
298
+ syntax.
299
+ ```
300
+ try $l0
301
+ block $l1
302
+ try
303
+ call $foo
304
+ delegate $l1 ;; delegates to 'catch ($l0)'
305
+ end
306
+ catch ($l0)
307
+ end
308
+ ```
293
309
294
- Note that the example below is a validation failure:
310
+ ` delegate ` can only target ` catch ` /` catch_all ` s that are below the current
311
+ instruction, i.e., it can only delegate downwards. It also targets all
312
+ ` catch ` /` catch_all ` s of a ` try ` as a whole and does not target individual
313
+ ` catch ` /` catch_all ` within a ` try ` . Here is another example:
295
314
```
296
- try $l1
297
- catch
315
+ try $l0
316
+ try $l1
317
+ catch ($l1)
318
+ try
319
+ call $foo
320
+ delegate $l1 ;; delegates to 'catch ($l0)'
321
+ catch_all
322
+ ...
323
+ end
324
+ catch ($l0)
325
+ ```
326
+
327
+ Here the ` delegate ` is targeting ` catch ($l1) ` , which exists before the
328
+ ` delegate ` . So in case an exception occurs, it propagates out and ends up
329
+ targetting ` catch ($l0) ` , if the catch has a matching tag. If not, it will
330
+ propagate further out. Even if the ` catch_all ` is below the ` delegate ` ,
331
+ ` delegate ` targets catches of a ` try ` as a whole and does not target an
332
+ individual ` catch ` /` catch_all ` , so it doesn't apply.
333
+
334
+ If ` delegate ` 's immediate argument is (the depth of the outermost block + 1), it
335
+ is considered to target the function-level block, so it in effect delegates the
336
+ exception to the caller of the current function. For example:
337
+ ```
338
+ (func $test
298
339
try
299
- call $foo
300
- delegate $l1 ;; (= delegate 0)
301
- catch_all
302
- ...
303
- end
340
+ try
341
+ call $foo
342
+ delegate 1 ;; delegates to the caller
343
+ catch
344
+ ...
345
+ catch_all
346
+ ...
347
+ end
348
+ )
349
+ ```
350
+ In case ` foo ` throws, ` delegate 1 ` here delegates the exception handling to the
351
+ caller, i.e., the exception escapes the current function. If the immediate is
352
+ greater than the depth of the outermost block + 1, it is a validation failure.
353
+
354
+ The below is an example that includes all the cases explained. The numbers
355
+ within ` () ` after ` delegate ` s are the label operands in immediate values.
356
+ ```
357
+ (func $test
358
+ try $lA
359
+ block $lB
360
+ try $lC
361
+ try
362
+ delegate $lC (0) ;; delegates to 'catch ($lC)'
363
+ try
364
+ delegate $lB (1) ;; $lB is a block, so delegates to 'catch ($lA)'
365
+ try
366
+ delegate $lA (2) ;; delegates to 'catch ($lA)'
367
+ try
368
+ delegate 3 ;; propagates to the caller
369
+ try
370
+ delegate 4 ;; validation failure
371
+ catch ($lC)
372
+ try
373
+ delegate $lC (0) ;; 'catch ($lC)' is above this instruction,
374
+ ;; so delegates to 'catch ($lA)'
375
+ try
376
+ delegate $lB (1) ;; $lB is a block, so delegates to 'catch ($lA)'
377
+ try
378
+ delegate $lA (2) ;; delegates to 'catch ($lA)'
379
+ try
380
+ delegate 3 ;; propagates to the caller
381
+ try
382
+ delegate 4 ;; validation failure
383
+ end ;; try $lC
384
+ end ;; block $lB
385
+ catch ($lA)
386
+ end ;; try $lA
387
+ )
304
388
```
305
- Here ` delegate ` is trying to delegate to ` catch ` , which exists before the
306
- ` delegate ` . The ` delegate ` instruction can only target ` try ` label whose
307
- catching instructions (` catch ` /` catch_all ` /` delegate ` ) come after the
308
- ` delegate ` instruction.
309
-
310
- ` delegate ` can also target ` catch ` -less ` try ` , in which case the effect is the
311
- same as if the ` try ` has catches but none of the catches are able to handle the
312
- exception.
313
389
314
390
### JS API
315
391
0 commit comments