[MLton] SXML Exceptions
Matthew Fluet
fluet@cs.cornell.edu
Thu, 1 Jun 2006 15:12:29 -0400 (EDT)
> I'm having a hard time understanding how exceptions work in the SXML
> phase.
There is one trickiness to exceptions in the SXML intermediate
representation, as one of the program transformations on that IL is to
(partially) implement exceptions; see
mlton/xml/implement-exceptions.{sig,fun}.
It is this pass that transforms the program from having exception
declarations scattered through the program to having a single exception
datatype; having the whole program allows the extensible exception
datatype to be implemented with a (non-extensible) datatype, as all
possible variants may be identified. The transformation does other things
as well, including implementing exception history.
> Specifically, can I get an explanation of the fields of
> Raise of {exn: VarExp.t, extend: bool}?
The exn field is simply the variable to which the exception to be raised
is bound. The extend field determines whether or not this raise
expression should extend the exception history or start a new exception
history. The reason to distinguish these cases is that a source SML
expression like
e handle Overflow => eo | Match => em
is first translated to something like:
e handle exn => (case exn of Overflow => eo | Match => em
| _ => raise exn)
We don't want the implicit re-raising of an exception to start a new
exception history; so the re-raising 'raise' has extend = true.
> My current understanding is that exceptions are declared in decs of an
> Exp, and any Raise must occur in the try field of a Handle. I'm not sure
> of the purpose of extend. Is this on the right track?
Before the implement exceptions pass, exceptions are declared as decs in
an expression, but after that pass, the Exception variant of the Dec.t
datatype is not allowed. (However, this is not checked by the XML/SXML
type checker.)
Before and after the implement exceptions pass, Raise may occur anywhere,
not necessarily in the static (or dynamic) scope of a Handle expression.
The dynamic behavior matches that of SML -- a raise transfers control to
the nearest dynamically enclosing handler, which then either handles the
exception or re-raises.