@@ -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,101 @@ 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.
293
292
294
- Note that the example below is a validation failure:
293
+ ` delegate ` can also target catchless trys or non-try block constructs like
294
+ ` block ` s or ` loop ` s, in which case the delegated exception is assumed to
295
+ propagate to outer scope and will be caught by the next matching try-catches. In
296
+ the examples, catches are annotated with '($label_name)' to clarify which ` try `
297
+ it belongs to.
295
298
```
296
- try $l1
297
- catch
298
- try
299
- call $foo
300
- delegate $l1 ;; (= delegate 0)
301
- catch_all
302
- ...
299
+ try $l0
300
+ block $l1
301
+ try
302
+ call $foo
303
+ delegate $l1 ;; delegates to 'catch ($l0)'
304
+ end
305
+ catch ($l0)
303
306
end
304
307
```
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.
308
+
309
+ ` delegate ` can only target ` catch ` /` catch_all ` s that is below the current
310
+ instruction, i.e., it can only delegate downwards. It also targets all
311
+ ` catch ` /` catch_all ` s of a ` try ` as a whole and does not target individual
312
+ ` catch ` /` catch_all ` within a ` try ` . Here is another example:
313
+ ```
314
+ try $l0
315
+ try $l1
316
+ catch ($l1)
317
+ try
318
+ call $foo
319
+ delegate $l1 ;; delegates to 'catch ($l0)'
320
+ catch_all
321
+ ...
322
+ end
323
+ catch ($l0)
324
+ ```
325
+
326
+ Here ` delegate ` is targeting ` catch ($l1) ` , which exists before the ` delegate ` .
327
+ So in case an exception occurs, it propagates out and ends up targetting `catch
328
+ ($l0)`, if the catch has a matching tag. If not, it will propagate further out.
329
+ Even if the ` catch_all ` is below the ` delegate ` , ` delegate ` targets catches of
330
+ a ` try ` as a whole and does not target an individual ` catch ` /` catch_all ` , so it
331
+ doesn't apply.
332
+
333
+ If ` delegate ` 's immediate argument is the depth of the outermost block + 1, it
334
+ is considered to target the function-level block, so it in effect delegates the
335
+ exception to the caller of the current function. For example:
336
+ ```
337
+ (func $test
338
+ try $l
339
+ try
340
+ call $foo
341
+ delegate 1 ;; delegates to the caller
342
+ catch
343
+ ...
344
+ catch_all
345
+ ...
346
+ end
347
+ )
348
+ ```
349
+ In case ` foo ` throws, ` delegate 1 ` here delegates the exception handling to the
350
+ caller, i.e., the exception escapes the current function. If the immediate is
351
+ greater than the depth of the outermost block + 1, it is a validation failure.
352
+
353
+ The below is an example that includes all the cases explained:
354
+ ```
355
+ (func $test
356
+ try $lA
357
+ block $lB
358
+ try $lC
359
+ try
360
+ delegate $lC (0) ;; delegates to 'catch ($lC)'
361
+ try
362
+ delegate $lB (1) ;; $lB is a block, so delegates to 'catch ($lA)'
363
+ try
364
+ delegate $lA (2) ;; delegates to 'catch ($lA)'
365
+ try
366
+ delegate 3 ;; propagates to the caller
367
+ try
368
+ delegate 4 ;; validation failure
369
+ catch ($lC)
370
+ try
371
+ delegate $lC (0) ;; 'catch ($lC)' is above this instruction, so delegates to 'catch ($lA)'
372
+ try
373
+ delegate $lB (1) ;; $lB is a block, so delegates to 'catch ($lA)'
374
+ try
375
+ delegate $lA (2) ;; delegates to 'catch ($lA)'
376
+ try
377
+ delegate 3 ;; propagates to the caller
378
+ try
379
+ delegate 4 ;; validation failure
380
+ end ;; try $lC
381
+ end ;; block $lB
382
+ catch ($lA)
383
+ end ;; try $lA
384
+ )
385
+ ```
313
386
314
387
### JS API
315
388
0 commit comments