Skip to content

Commit 9888037

Browse files
committed
Add prose for reduction rules involving thrown exceptions,
i.e., explaining some execution steps for `THROWadm`, `CATCHadm`, `DELEGATEadm`. The parts of this commit that involve `DELEGATEadm` may change once PR WebAssembly#220 is settled. Nonetheless, in this commit the typing rule and the reduction rule for `DELEGATEadm` are both tentatively changed to match the current [formal overview](https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions-formal-overview.md).
1 parent 76732ae commit 9888037

File tree

2 files changed

+88
-9
lines changed

2 files changed

+88
-9
lines changed

document/core/appendix/properties.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ To that end, all previous typing judgements :math:`C \vdash \X{prop}` are genera
624624
625625
626626
.. index:: delegate, throw context
627+
.. _valid-delegate-admin:
627628

628629
:math:`\DELEGATEadm\{l\}~\instr^\ast~\END`
629630
..........................................
@@ -633,11 +634,11 @@ To that end, all previous typing judgements :math:`C \vdash \X{prop}` are genera
633634

634635
.. math::
635636
\frac{
636-
S; C,\CLABELS\,[t^\ast] \vdashinstrseq \instr^\ast : [] \to [t^\ast]
637+
S; C \vdashinstrseq \instr^\ast : [] \to [t^\ast]
637638
\qquad
638-
C.\CLABELS[l] = [t_0^\ast]
639+
C.\CLABELS[l+1] = [t_0^\ast]
639640
}{
640-
S; C,\CLABELS\,[t^\ast] \vdashadmininstr \DELEGATEadm\{l\}~\instr^\ast~\END : [] \to [t^\ast]
641+
S; C \vdashadmininstr \DELEGATEadm\{l\}~\instr^\ast~\END : [] \to [t^\ast]
641642
}
642643
643644

document/core/exec/instructions.rst

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3016,26 +3016,104 @@ When the end of a :ref:`try <syntax-try>` instruction is reached without a jump,
30163016
Throwing an exception with :ref:`tag address <syntax-tagaddr>` :math:`a`
30173017
........................................................................
30183018

3019+
When an administrative throw occurs, then values, labels, |CAUGHTadm| instructions,
3020+
and call frames are popped if necessary, until an appropriate exception handler is found
3021+
on the top of the stack.
3022+
3023+
1. Assert: due to validation, :math:`S.\STAGS[a]` exists.
3024+
3025+
2. Let :math:`[t^n] \to []` be the :ref:`tag type <syntax-tagtype>` :math:`S.\STAGS[a].\TAGITYPE`.
3026+
3027+
3. Assert: due to :ref:`validation <valid-throw>`, there are :math:`n` values on the top of the stack.
3028+
3029+
4. Pop the :math:`n` values :math:`\val^n` from the stack.
3030+
3031+
5. While the stack is not empty and the top of the stack is not an :ref:`exception handler <syntax-handler>`, do:
3032+
3033+
a. Pop the top element from the stack, prepending it to the :ref:`throw context <syntax-ctxt-throw>` of the exception: :math:`\XT[\val^n~(\THROWadm~a)]`.
3034+
3035+
6. Assert: The stack is now either empty, or there is an exception handler on the top of the stack.
3036+
3037+
7. If the stack is empty, then:
3038+
3039+
a. **TODO** *Return a result value representing the uncaught exception (will probably just be the same as 11.a.i. below).*
3040+
30193041
.. todo::
3020-
Add prose for the following execution steps.
3042+
After PR #221 is resolved, this step should be filled in with a PR to specify uncaught exception results.
3043+
3044+
8. Else there is an :ref:`exception handler <syntax-handler>` :math:`H` on the top of the stack.
3045+
3046+
9. Pop the exception handler :math:`H` from the stack.
3047+
3048+
10. Assert: :math:`H` is either of the form :math:`\CATCHadm\{a^?~\instr^\ast\}^k` or :math:`\DELEGATEadm\{l\}.`
3049+
3050+
11. If :math:`H` is of the form :math:`\CATCHadm\{a^?~\instr^\ast\}^k`, then:
3051+
3052+
a. If :math:`k = 0`, then:
3053+
3054+
i. Push the throw context that we collected so far :math:`\XT[\val^n~(\THROWadm~a)]` onto the stack.
3055+
3056+
b. Else :math:`H` is of the form :math:`\CATCHadm\{a_1^?~\instr^\ast\}\{a'^?~\instr'^\ast\}^\ast`.
3057+
3058+
c. If :math:`a_1^? = \epsilon`, then:
3059+
3060+
i. Push :math:`\CAUGHTadm\{a~\val^n\}` onto the stack.
30213061

3062+
ii. Jump to the start of the instruction sequence :math:`\instr^\ast`.
3063+
3064+
d. Else if :math:`a_1 = a`, then:
3065+
3066+
i. Push :math:`\CAUGHTadm\{a~\val^n\}` onto the stack.
3067+
3068+
ii. Push the values :math:`\val^n` back to the stack.
3069+
3070+
iii. Jump to the start of the instruction sequence :math:`\instr^\ast`.
3071+
3072+
e. Else, repeat step 11 for :math:`H = \CATCHadm\{a'^?~\instr'^\ast\}^\ast`.
3073+
3074+
12. Else the handler :math:`H` has the form :math:`\DELEGATEadm\{l\}`.
3075+
3076+
13. Assert: due to :ref:`validation <valid-delegate-admin>`, the stack contains at least :math:`l+1` labels.
3077+
3078+
14. Let :math:`L` be the :math:`l`-th label appearing on the stack, starting from the top and counting from zero.
3079+
3080+
15. Repeat :math:`l+1` times:
3081+
3082+
a. While the instruction on the top of the stack is not a label, do:
3083+
3084+
i. Pop the instruction from the stack, without pushing it to |XT|.
3085+
3086+
b. Assert: due to :ref:`validation <valid-delegate-admin>`, the top of the stack now is a label.
3087+
3088+
c. Pop the label from the stack.
3089+
3090+
16. Push the throw context that we collected so far :math:`\XT[\val^n~(\THROWadm~a)]` onto the stack.
3091+
3092+
17. Jump to the continuation of :math:`L`.
30223093

30233094
.. math::
30243095
\begin{array}{rcl}
3025-
\CATCHadm\{a_1^?~\instr^\ast\}\{a'^?~\instr'^\ast\}^\ast~\XT[(\THROWadm~a)]~\END &\stepto&
3026-
\CATCHadm\{a'^?~\instr'^\ast\}^\ast~\XT[(\THROWadm~a)]~\END \\
3096+
\CATCHadm~\XT[\val^n~(\THROWadm~a)]~\END &\stepto&
3097+
\XT[\val^n~(\THROWadm~a)] \\
3098+
\CATCHadm\{a_1^?~\instr^\ast\}\{a'^?~\instr'^\ast\}^\ast~\XT[\val^n~(\THROWadm~a)]~\END &\stepto&
3099+
\CATCHadm\{a'^?~\instr'^\ast\}^\ast~\XT[\val^n~(\THROWadm~a)]~\END \\
30273100
&& (\iff a_1^? \neq \epsilon \land a_1^? \neq a) \\
30283101
S;~\CATCHadm\{a_1^?~\instr^\ast\}\{a'^?~\instr'^\ast\}^\ast~\XT[\val^n~(\THROWadm~a)]~\END &\stepto&
30293102
S;~\CAUGHTadm\{a~\val^n\}~(\val^n)?~\instr^\ast~\END \\
30303103
&& (\iff~(a_1^? = \epsilon \lor a_1^? = a)~\land\\
30313104
&& \ S.\STAGS[a].\TAGITYPE = [t^n]\to[]) \\
3032-
\LABEL_n\{\}~\XB^l[\DELEGATEadm\{l\}~\XT[(\THROWadm~a)]~\END]~\END &\stepto&
3033-
\XT[(\THROWadm~a)] \\
3105+
\LABEL_n\{\}~\XB^l[\DELEGATEadm\{l\}~\XT[\val^n~(\THROWadm~a)]~\END]~\END &\stepto&
3106+
\XT[\val^n~(\THROWadm~a)] \\
30343107
\end{array}
30353108
3109+
.. note::
3110+
Note that the reduction step resulting in a |CAUGHTadm| instruction is the only one that does not preserve the throw context.
3111+
While a |THROWadm| propagates through the stack, the throw context |XT| is collected
3112+
until the exception is caught inside a |CAUGHTadm| instruction, in which point it's discarded.
30363113

30373114
.. todo::
3038-
Add explainer note.
3115+
Add explainer note for the reduction of |DELEGATEadm|, when PR #221 is settled.
3116+
30393117

30403118
.. _exec-caughtadm:
30413119

0 commit comments

Comments
 (0)