Execution¶
Runtime Structure¶
Stack¶
Exception Handlers
Legacy exception handlers are installed by \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{try}}\) instructions. Instead of branch labels, their catch clauses have instruction blocks associated with them. Furthermore, a \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{delegate}}\) handler is associated with a label index to implicitly rewthrow to:
Administrative Instructions¶
Administrative instructions are extended with the \(\href{../exec/runtime.html#syntax-caught}{\mathsf{caught}}\) instruction that models exceptions caught by legacy exception handlers.
Block Contexts¶
Block contexts are extended to include \(\href{../exec/runtime.html#syntax-caught}{\mathsf{caught}}\) instructions:
Throw Contexts¶
Throw contexts are also extended to include \(\href{../exec/runtime.html#syntax-caught}{\mathsf{caught}}\) instructions:
Instructions¶
Control Instructions¶
\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{try}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_1^\ast~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch}}~x~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_2^\ast)^\ast~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch\_all}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_3^\ast)^?~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\)¶
Assert: due to validation, \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\) is defined.
Let \([t_1^m] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^n]\) be the function type \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\).
Let \(L\) be the label whose arity is \(n\) and whose continuation is the end of the \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{try}}\) instruction.
Assert: due to validation, there are at least \(m\) values on the top of the stack.
Pop the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\) from the stack.
Let \(F\) be the current frame.
For each catch clause \((\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch}}~x_i~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_{2i}^\ast)\) do:
Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tagaddrs}}[x_i]\) exists.
Let \(a_i\) be the tag address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tagaddrs}}[x_i]\).
Let \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_i\) be the catch clause \((\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch}}~a_i~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_{2i}^\ast)\).
If there is a catch-all clause \((\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch\_all}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_3^\ast)\), then:
Let \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}'^?\) be the handler \((\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch\_all}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_3^\ast)\).
Else:
Let \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}'^?\) be empty.
Let \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}^\ast\) be the concatenation of \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_i\) and \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}'^?\).
Enter the block \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_1^\ast\) with label \(L\) and exception handler \(\href{../exec/runtime.html#syntax-handler}{\mathsf{handler}}_n\{\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}^\ast\}^\ast\).
\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{try}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{delegate}}~l\)¶
Assert: due to validation, \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\) is defined.
Let \([t_1^m] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^n]\) be the function type \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\).
Let \(L\) be the label whose arity is \(n\) and whose continuation is the end of the \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{try}}\) instruction.
Let \(H\) be the exception handler \(l\), targeting the \(l\)-th surrounding block.
Assert: due to validation, there are at least \(m\) values on the top of the stack.
Pop the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\) from the stack.
Enter the block \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) with label \(L\) and exception handler HANDLER_n{DELEGATE~l}.
\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{throw\_ref}}\)¶
Let \(F\) be the current frame.
Assert: due to validation, a reference is on the top of the stack.
Pop the reference \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}\) from the stack.
If \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}\) is \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~\mathit{ht}\), then:
Trap.
Assert: due to validation, \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}\) is an exception reference.
Let \(\href{../exec/runtime.html#syntax-ref.exn-addr}{\mathsf{ref{.}exn}}~\mathit{ea}\) be \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}\).
Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{exns}}[\mathit{ea}]\) exists.
Let \(\mathit{exn}\) be the exception instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{exns}}[\mathit{ea}]\).
Let \(a\) be the tag address \(\mathit{exn}.\href{../exec/runtime.html#syntax-exninst}{\mathsf{tag}}\).
While the stack is not empty and the top of the stack is not an exception handler, do:
Pop the top element from the stack.
Assert: the stack is now either empty, or there is an exception handler on the top of the stack.
If the stack is empty, then:
Return the exception \((\href{../exec/runtime.html#syntax-ref.exn-addr}{\mathsf{ref{.}exn}}~a)\) as a result.
Assert: there is an exception handler on the top of the stack.
Pop the exception handler \(\href{../exec/runtime.html#syntax-handler}{\mathsf{handler}}_n\{\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}^\ast\}\) from the stack.
If \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}^\ast\) is empty, then:
Push the exception reference \(\href{../exec/runtime.html#syntax-ref.exn-addr}{\mathsf{ref{.}exn}}~\mathit{ea}\) back to the stack.
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{throw\_ref}}\) again.
Else:
Let \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_1\) be the first catch clause in \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}^\ast\) and \({\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}'}^\ast\) the remaining clauses.
If \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_1\) is of the form \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch}}~x~l\) and the exception address \(a\) equals \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tagaddrs}}[x]\), then:
Push the values \(\mathit{exn}.\href{../exec/runtime.html#syntax-exninst}{\mathsf{fields}}\) to the stack.
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l\).
Else if \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_1\) is of the form \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch\_ref}}~x~l\) and the exception address \(a\) equals \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tagaddrs}}[x]\), then:
Push the values \(\mathit{exn}.\href{../exec/runtime.html#syntax-exninst}{\mathsf{fields}}\) to the stack.
Push the exception reference \(\href{../exec/runtime.html#syntax-ref.exn-addr}{\mathsf{ref{.}exn}}~\mathit{ea}\) to the stack.
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l\).
Else if \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_1\) is of the form \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch\_all}}~l\), then:
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l\).
Else if \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_1\) is of the form \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch\_all\_ref}}~l\), then:
Push the exception reference \(\href{../exec/runtime.html#syntax-ref.exn-addr}{\mathsf{ref{.}exn}}~\mathit{ea}\) to the stack.
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l\).
Else if \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_1\) is of the form \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch}}~x~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) and the exception address \(a\) equals \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tagaddrs}}[x]\), then:
Push the caught exception \(\href{../exec/runtime.html#syntax-caught}{\mathsf{caught}}_n\{\mathit{ea}\}\) to the stack.
Push the values \(\mathit{exn}.\href{../exec/runtime.html#syntax-exninst}{\mathsf{fields}}\) to the stack.
Enter the catch block \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\).
Else if \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_1\) is of the form \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch\_all}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\), then:
Push the caught exception \(\href{../exec/runtime.html#syntax-caught}{\mathsf{caught}}_n\{\mathit{ea}\}\) to the stack.
Enter the catch block \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\).
Else if \(\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}_1\) is of the form \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{delegate}}~l\), then:
Assert: due to validation, the stack contains at least \(l\) labels.
Repeat \(l\) times:
While the top of the stack is not a label, do:
Pop the top element from the stack.
Assert: due to validation, the top of the stack now is a label.
Pop the label from the stack.
Push the exception reference \(\href{../exec/runtime.html#syntax-ref.exn-addr}{\mathsf{ref{.}exn}}~\mathit{ea}\) back to the stack.
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{throw\_ref}}\) again.
Else:
Push the modified handler \(\href{../exec/runtime.html#syntax-handler}{\mathsf{handler}}_n\{{\href{../syntax/instructions.html#syntax-catch}{\mathit{catch}}'}^\ast\}\) back to the stack.
Push the exception reference \(\href{../exec/runtime.html#syntax-ref.exn-addr}{\mathsf{ref{.}exn}}~\mathit{ea}\) back to the stack.
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{throw\_ref}}\) again.
\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{rethrow}}~l\)¶
Assert: due to validation, the stack contains at least \(l+1\) labels.
Let \(L\) be the \(l\)-th label appearing on the stack, starting from the top and counting from zero.
Assert: due to validation, \(L\) is a catch label, i.e., a label of the form \((\href{../valid/conventions.html#context}{\mathsf{catch}}~[t^\ast])\), which is a label followed by a caught exception in an active catch clause.
Let \(a\) be the caught exception address.
Push the value \(\href{../exec/runtime.html#syntax-ref.exn-addr}{\mathsf{ref{.}exn}}~a\) onto the stack.
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{throw\_ref}}\).
Entering a catch block¶
Jump to the start of the instruction sequence \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\).
Exiting a catch block¶
When the \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) of a catch block is reached without a jump, thrown exception, or trap, then the following steps are performed.
Let \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\) be the values on the top of the stack.
Pop the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\) from the stack.
Assert: due to validation, a caught exception is now on the top of the stack.
Pop the caught exception from the stack.
Push \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\) back to the stack.
Jump to the position after the \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) of the administrative instruction associated with the caught exception.
Note
A caught exception can only be rethrown from the scope of the administrative instruction associated with it, i.e., from the scope of the \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch}}\) or \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{catch\_all}}\) block of a legacy \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{try}}\) instruction. Upon exit from that block, the caught exception is discarded.