Changeset 4260566 for doc


Ignore:
Timestamp:
Mar 24, 2021, 6:31:02 PM (3 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
8d4c9f4
Parents:
4150779
Message:

Andrew MMath: Clean-up of features.tex. Put more general EHM information in the opening and started updating the virtual section.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/andrew_beach_MMath/features.tex

    r4150779 r4260566  
    22
    33This chapter covers the design and user interface of the \CFA
    4 exception-handling mechanism.
    5 
    6 \section{Virtuals}
    7 Virtual types and casts are not part of the exception system nor are they
    8 required for an exception system. But an object-oriented style hierarchy is a
    9 great way of organizing exceptions so a minimal virtual system has been added
    10 to \CFA.
    11 
    12 The pattern of a simple hierarchy was borrowed from object-oriented
    13 programming was chosen for several reasons.
    14 The first is that it allows new exceptions to be added in user code
    15 and in libraries independently of each other. Another is it allows for
    16 different levels of exception grouping (all exceptions, all IO exceptions or
    17 a particular IO exception). Also it also provides a simple way of passing
    18 data back and forth across the throw.
    19 
    20 Virtual types and casts are not required for a basic exception-system but are
    21 useful for advanced exception features. However, \CFA is not object-oriented so
    22 there is no obvious concept of virtuals. Hence, to create advanced exception
    23 features for this work, I needed to design and implement a virtual-like
    24 system for \CFA.
    25 
    26 % NOTE: Maybe we should but less of the rational here.
    27 Object-oriented languages often organized exceptions into a simple hierarchy,
    28 \eg Java.
     4exception-handling mechanism (EHM). % or exception system.
     5
     6% We should cover what is an exception handling mechanism and what is an
     7% exception before this. Probably in the introduction. Some of this could
     8% move there.
     9\paragraph{Raise / Handle}
     10An exception operation has two main parts: raise and handle.
     11These are the two parts that the user will write themselves and so
     12might be the only two pieces of the EHM that have any syntax.
     13These terms are sometimes also known as throw and catch but this work uses
     14throw/catch as a particular kind of raise/handle.
     15
     16\subparagraph{Raise}
     17The raise is the starting point for exception handling and usually how
     18Some well known examples include the throw statements of \Cpp and Java and
     19the raise statement from Python.
     20
     21For this overview a raise does nothing more kick off the handling of an
     22exception, which is called raising the exception. This is inexact but close
     23enough for the broad strokes of the overview.
     24
     25\subparagraph{Handle}
     26The purpose of most exception operations is to run some sort of handler that
     27contains user code.
     28The try statement of \Cpp illistrates the common features
     29Handlers have three common features: a region of code they apply to, an
     30exception label that describes what exceptions they handle and code to run
     31when they handle an exception.
     32Each handler can handle exceptions raised in that region that match their
     33exception label. Different EHMs will have different rules to pick a handler
     34if multipe handlers could be used such as ``best match" or ``first found".
     35
     36\paragraph{Propagation}
     37After an exception is raised comes what is usually the biggest step for the
     38EHM, finding and setting up the handler. This can be broken up into three
     39different tasks: searching for a handler, matching against the handler and
     40installing the handler.
     41
     42First the EHM must search for possible handlers that could be used to handle
     43the exception. Searching is usually independent of the exception that was
     44thrown and instead depends on the call stack, the current function, its caller
     45and repeating down the stack.
     46
     47Second it much match the exception with each handler to see which one is the
     48best match and hence which one should be used to handle the exception.
     49In languages where the best match is the first match these two are often
     50intertwined, a match check is preformed immediately after the search finds
     51a possible handler.
     52
     53Third, after a handler is chosen it must be made ready to run.
     54What this actually involves can vary widely to fit with the rest of the
     55design of the EHM. The installation step might be trivial or it could be
     56the most expensive step in handling an exception. The latter tends to be the
     57case when stack unwinding is involved.
     58
     59As an alternate third step if no appropriate handler is found then some sort
     60of recovery has to be preformed. This is only required with unchecked
     61exceptions as checked exceptions can promise that a handler is found. It also
     62is also installing a handler but it is a special default that may be
     63installed differently.
     64
     65\subparagraph{Hierarchy}
     66In \CFA the EHM uses a hierarchial system to organise its exceptions.
     67This stratagy is borrowed from object-orientated languages where the
     68exception hierarchy is a natural extension of the object hierarchy.
     69
     70Consider the following hierarchy of exceptions:
    2971\begin{center}
    3072\setlength{\unitlength}{4000sp}%
     
    4385\end{picture}%
    4486\end{center}
    45 The hierarchy provides the ability to handle an exception at different degrees
    46 of specificity (left to right). Hence, it is possible to catch a more general
    47 exception-type in higher-level code where the implementation details are
    48 unknown, which reduces tight coupling to the lower-level implementation.
    49 Otherwise, low-level code changes require higher-level code changes, \eg,
    50 changing from raising @underflow@ to @overflow@ at the low level means changing
    51 the matching catch at the high level versus catching the general @arithmetic@
    52 exception. In detail, each virtual type may have a parent and can have any
    53 number of children. A type's descendants are its children and its children's
    54 descendants. A type may not be its own descendant.
    55 
    56 The exception hierarchy allows a handler (@catch@ clause) to match multiple
    57 exceptions, \eg a base-type handler catches both base and derived
    58 exception-types.
    59 \begin{cfa}
    60 try {
    61         ...
    62 } catch(arithmetic &) {
    63         ... // handle arithmetic, underflow, overflow, zerodivide
    64 }
    65 \end{cfa}
    66 Most exception mechanisms perform a linear search of the handlers and select
    67 the first matching handler, so the order of handers is now important because
    68 matching is many to one.
    69 
    70 Each virtual type needs an associated virtual table. A virtual table is a
    71 structure with fields for all the virtual members of a type. A virtual type has
    72 all the virtual members of its parent and can add more. It may also update the
    73 values of the virtual members and often does.
     87
     88A handler labelled with any given exception can handle exceptions of that
     89type or any child type of that exception. The root of the exception hierarchy
     90(here \texttt{exception}) acts as a catch-all, leaf types catch single types
     91and the exceptions in the middle can be used to catch different groups of
     92related exceptions.
     93
     94This system has some notable advantages, such as multiple levels of grouping,
     95the ability for libraries to add new exception types and the isolation
     96between different sub-hierarchies. So the design was adapted for a
     97non-object-orientated language.
     98
     99% Could I cite the rational for the Python IO exception rework?
     100
     101\paragraph{Completion}
     102After the handler has finished the entire exception operation has to complete
     103and continue executing somewhere else. This step is usually very simple
     104both logically and in its implementation as the installation of the handler
     105usually does the heavy lifting.
     106
     107The EHM can return control to many different places.
     108However, the most common is after the handler definition and the next most
     109common is after the raise.
     110
     111\paragraph{Communication}
     112For effective exception handling, additional information is usually required
     113as this base model only communicates the exception's identity. Common
     114additional methods of communication are putting fields on an exception and
     115allowing a handler to access the lexical scope it is defined in (usually
     116a function's local variables).
     117
     118\paragraph{Other Features}
     119Any given exception handling mechanism is free at add other features on top
     120of this. This is an overview of the base that all EHMs use but it is not an
     121exaustive list of everything an EHM can do.
     122
     123\section{Virtuals}
     124Virtual types and casts are not part of the exception system nor are they
     125required for an exception system. But an object-oriented style hierarchy is a
     126great way of organizing exceptions so a minimal virtual system has been added
     127to \CFA.
     128
     129The virtual system supports multiple ``trees" of types. Each tree is
     130a simple hierarchy with a single root type. Each type in a tree has exactly
     131one parent - except for the root type which has zero parents - and any
     132number of children.
     133Any type that belongs to any of these trees is called a virtual type.
     134
     135% A type's ancestors are its parent and its parent's ancestors.
     136% The root type has no ancestors.
     137% A type's decendents are its children and its children's decendents.
     138
     139Every virtual type also has a list of virtual members. Children inherit
     140their parent's list of virtual members but may add new members to it.
     141It is important to note that these are virtual members, not virtual methods.
     142However as function pointers are allowed they can be used to mimic virtual
     143methods as well.
     144
     145The unique id for the virtual type and all the virtual members are combined
     146into a virtual table type. Each virtual type has a pointer to a virtual table
     147as a hidden field.
     148
     149\todo{Open/Closed types and how that affects the virtual design.}
    74150
    75151While much of the virtual infrastructure is created, it is currently only used
     
    83159\Cpp syntax for special casts. Both the type of @EXPRESSION@ and @TYPE@ must be
    84160a pointer to a virtual type.
    85 The cast dynamically checks if the @EXPRESSION@ type is the same or a subtype
     161The cast dynamically checks if the @EXPRESSION@ type is the same or a sub-type
    86162of @TYPE@, and if true, returns a pointer to the
    87163@EXPRESSION@ object, otherwise it returns @0p@ (null pointer).
     
    107183
    108184The function @get_exception_vtable@ is actually a constant function.
    109 Recardless of the value passed in (including the null pointer) it should
     185Regardless of the value passed in (including the null pointer) it should
    110186return a reference to the virtual table instance for that type.
    111187The reason it is a function instead of a constant is that it make type
     
    139215and their use will be detailed there.
    140216
    141 However all three of these traits can be trickly to use directly.
     217However all three of these traits can be tricky to use directly.
    142218There is a bit of repetition required but
    143219the largest issue is that the virtual table type is mangled and not in a user
     
    152228list will be passed to both types.
    153229In the current set-up the base name and the polymorphic arguments have to
    154 match so these macros can be used without losing flexability.
     230match so these macros can be used without losing flexibility.
    155231
    156232For example consider a function that is polymorphic over types that have a
     
    185261It is dynamic, non-local goto. If a throw is successful then the stack will
    186262be unwound and control will (usually) continue in a different function on
    187 the call stack. They are commonly used when an error has occured and recovery
     263the call stack. They are commonly used when an error has occurred and recovery
    188264is impossible in the current function.
    189265
     
    196272\end{cfa}
    197273The expression must return a reference to a termination exception, where the
    198 termination exception is any type that satifies @is_termination_exception@
     274termination exception is any type that satisfies @is_termination_exception@
    199275at the call site.
    200276Through \CFA's trait system the functions in the traits are passed into the
     
    203279
    204280The throw will copy the provided exception into managed memory. It is the
    205 user's responcibility to ensure the original exception is cleaned up if the
     281user's responsibility to ensure the original exception is cleaned up if the
    206282stack is unwound (allocating it on the stack should be sufficient).
    207283
     
    220296}
    221297\end{cfa}
    222 When viewed on its own a try statement will simply exceute the statements in
     298When viewed on its own a try statement will simply execute the statements in
    223299@GUARDED_BLOCK@ and when those are finished the try statement finishes.
    224300
     
    232308Exception matching checks the representation of the thrown exception-type is
    233309the same or a descendant type of the exception types in the handler clauses. If
    234 it is the same of a descendent of @EXCEPTION_TYPE@$_i$ then @NAME@$_i$ is
     310it is the same of a descendant of @EXCEPTION_TYPE@$_i$ then @NAME@$_i$ is
    235311bound to a pointer to the exception and the statements in @HANDLER_BLOCK@$_i$
    236312are executed. If control reaches the end of the handler, the exception is
     
    255331closure will be taken from up the stack and executed, after which the throwing
    256332function will continue executing.
    257 These are most often used when an error occured and if the error is repaired
     333These are most often used when an error occurred and if the error is repaired
    258334then the function can continue.
    259335
     
    263339\end{cfa}
    264340The semantics of the @throwResume@ statement are like the @throw@, but the
    265 expression has return a reference a type that satifies the trait
     341expression has return a reference a type that satisfies the trait
    266342@is_resumption_exception@. The assertions from this trait are available to
    267343the exception system while handling the exception.
    268344
    269 At runtime, no copies are made. As the stack is not unwound the exception and
     345At run-time, no copies are made. As the stack is not unwound the exception and
    270346any values on the stack will remain in scope while the resumption is handled.
    271347
     
    331407search and match the handler in the @catchResume@ clause. This will be
    332408call and placed on the stack on top of the try-block. The second throw then
    333 throws and will seach the same try block and put call another instance of the
     409throws and will search the same try block and put call another instance of the
    334410same handler leading to an infinite loop.
    335411
     
    337413can form with multiple handlers and different exception types.
    338414
    339 To prevent all of these cases we mask sections of the stack, or equvilantly
    340 the try statements on the stack, so that the resumption seach skips over
     415To prevent all of these cases we mask sections of the stack, or equivalently
     416the try statements on the stack, so that the resumption search skips over
    341417them and continues with the next unmasked section of the stack.
    342418
     
    373449The symmetry with termination is why this pattern was picked. Other patterns,
    374450such as marking just the handlers that caught, also work but lack the
    375 symmetry whih means there is more to remember.
     451symmetry which means there is more to remember.
    376452
    377453\section{Conditional Catch}
     
    396472}
    397473\end{cfa}
    398 Note, catching @IOFailure@, checking for @f1@ in the handler, and reraising the
    399 exception if not @f1@ is different because the reraise does not examine any of
     474Note, catching @IOFailure@, checking for @f1@ in the handler, and re-raising the
     475exception if not @f1@ is different because the re-raise does not examine any of
    400476remaining handlers in the current try statement.
    401477
     
    448524@return@ that causes control to leave the finally block. Other ways to leave
    449525the finally block, such as a long jump or termination are much harder to check,
    450 and at best requiring additional run-time overhead, and so are mearly
     526and at best requiring additional run-time overhead, and so are mealy
    451527discouraged.
    452528
     
    506582this point.}
    507583
    508 The recommended way to avoid the abort is to handle the intial resumption
     584The recommended way to avoid the abort is to handle the initial resumption
    509585from the implicate join. If required you may put an explicate join inside a
    510586finally clause to disable the check and use the local
Note: See TracChangeset for help on using the changeset viewer.