Ignore:
Timestamp:
Sep 9, 2021, 3:56:32 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
d0b9247
Parents:
dd1cc02 (diff), d8d512e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

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

    rdd1cc02 r5a40e4e  
    1414\label{s:VirtualSystem}
    1515% Virtual table rules. Virtual tables, the pointer to them and the cast.
    16 While the \CFA virtual system currently has only one public feature, virtual
    17 cast (see the virtual cast feature \vpageref{p:VirtualCast}),
    18 substantial structure is required to support it,
     16While the \CFA virtual system currently has only one public features, virtual
     17cast and virtual tables,
     18% ??? refs (see the virtual cast feature \vpageref{p:VirtualCast}),
     19substantial structure is required to support them,
    1920and provide features for exception handling and the standard library.
    2021
    2122\subsection{Virtual Type}
    22 Virtual types only have one change to their structure: the addition of a
    23 pointer to the virtual table, which is called the \emph{virtual-table pointer}.
    24 Internally, the field is called \snake{virtual_table}.
    25 The field is fixed after construction. It is always the first field in the
     23A virtual type~(see \autoref{s:virtuals}) has a pointer to a virtual table,
     24called the \emph{virtual-table pointer},
     25which binds each instance of a virtual type to a virtual table.
     26Internally, the field is called \snake{virtual_table}
     27and is fixed after construction.
     28This pointer is also the table's id and how the system accesses the
     29virtual table and the virtual members there.
     30It is always the first field in the
    2631structure so that its location is always known.
    27 \todo{Talk about constructors for virtual types (after they are working).}
    28 
    29 The virtual table pointer binds an instance of a virtual type
    30 to a virtual table.
    31 The pointer is also the table's id and how the system accesses the
    32 virtual table and the virtual members there.
     32
     33% We have no special rules for these constructors.
     34Virtual table pointers are passed to the constructors of virtual types
     35as part of field-by-field construction.
    3336
    3437\subsection{Type Id}
    3538Every virtual type has a unique id.
    36 Type ids can be compared for equality,
    37 which checks if the types reperented are the same,
    38 or used to access the type's type information.
     39These are used in type equality, to check if the representation of two values
     40are the same, and to access the type's type information.
     41This uniqueness means across a program composed of multiple translation
     42units (TU), not uniqueness across all programs or even across multiple
     43processes on the same machine.
     44
     45Our approach for program uniqueness is using a static declaration for each
     46type id, where the run-time storage address of that variable is guaranteed to
     47be unique during program execution.
     48The type id storage can also be used for other purposes,
     49and is used for type information.
     50
     51The problem is that a type id may appear in multiple TUs that compose a
     52program (see \autoref{ss:VirtualTable}); so the initial solution would seem
     53to be make it external in each translation unit. Hovever, the type id must
     54have a declaration in (exactly) one of the TUs to create the storage.
     55No other declaration related to the virtual type has this property, so doing
     56this through standard C declarations would require the user to do it manually.
     57
     58Instead the linker is used to handle this problem.
     59% I did not base anything off of C++17; they are solving the same problem.
     60A new feature has been added to \CFA for this purpose, the special attribute
     61\snake{cfa_linkonce}, which uses the special section @.gnu.linkonce@.
     62When used as a prefix (\eg @.gnu.linkonce.example@) the linker does
     63not combine these sections, but instead discards all but one with the same
     64full name.
     65
     66So each type id must be given a unique section name with the linkonce
     67prefix. Luckily \CFA already has a way to get unique names, the name mangler.
     68For example, this could be written directly in \CFA:
     69\begin{cfa}
     70__attribute__((cfa_linkonce)) void f() {}
     71\end{cfa}
     72This is translated to:
     73\begin{cfa}
     74__attribute__((section(".gnu.linkonce._X1fFv___1"))) void _X1fFv___1() {}
     75\end{cfa}
     76This is done internally to access the name manglers.
     77This attribute is useful for other purposes, any other place a unique
     78instance required, and should eventually be made part of a public and
     79stable feature in \CFA.
     80
     81\subsection{Type Information}
     82
     83There is data stored at the type id's declaration, the type information.
    3984The type information currently is only the parent's type id or, if the
    4085type has no parent, the null pointer.
    41 
    42 The id's are implemented as pointers to the type's type information instance.
    43 Dereferencing the pointer gets the type information.
    4486The ancestors of a virtual type are found by traversing type ids through
    4587the type information.
    46 The information pushes the issue of creating a unique value (for
    47 the type id) to the problem of creating a unique instance (for type
    48 information), which the linker can solve.
    49 
    50 The advanced linker support is used here to avoid having to create
    51 a new declaration to attach this data to.
    52 With C/\CFA's header/implementation file divide for something to appear
    53 exactly once it must come from a declaration that appears in exactly one
    54 implementation file; the declarations in header files may exist only once
    55 they can be included in many different translation units.
    56 Therefore, structure's declaration will not work.
    57 Neither will attaching the type information to the virtual table -- although
    58 a vtable declarations are in implemention files they are not unique, see
    59 \autoref{ss:VirtualTable}.
    60 Instead the same type information is generated multiple times and then
    61 the new attribute \snake{cfa_linkone} is used to removed duplicates.
     88An example using helper macros looks like:
     89\begin{cfa}
     90struct INFO_TYPE(TYPE) {
     91        INFO_TYPE(PARENT) const * parent;
     92};
     93
     94__attribute__((cfa_linkonce))
     95INFO_TYPE(TYPE) const INFO_NAME(TYPE) = {
     96        &INFO_NAME(PARENT),
     97};
     98\end{cfa}
    6299
    63100Type information is constructed as follows:
    64 \begin{enumerate}
     101\begin{enumerate}[nosep]
    65102\item
    66 Use the type's name to generate a name for the type information structure.
    67 This is saved so it may be reused.
     103Use the type's name to generate a name for the type information structure,
     104which is saved so it can be reused.
    68105\item
    69106Generate a new structure definition to store the type
    70107information. The layout is the same in each case, just the parent's type id,
    71108but the types used change from instance to instance.
    72 The generated name is used for both this structure and, if relivant, the
     109The generated name is used for both this structure and, if relevant, the
    73110parent pointer.
    74111If the virtual type is polymorphic then the type information structure is
    75112polymorphic as well, with the same polymorphic arguments.
    76113\item
    77 A seperate name for instances is generated from the type's name.
     114A separate name for instances is generated from the type's name.
    78115\item
    79 The definition is generated and initialised.
     116The definition is generated and initialized.
    80117The parent id is set to the null pointer or to the address of the parent's
    81118type information instance. Name resolution handles the rest.
    82119\item
    83120\CFA's name mangler does its regular name mangling encoding the type of
    84 the declaration into the instance name. This gives a completely unique name
     121the declaration into the instance name.
     122This process gives a completely unique name
    85123including different instances of the same polymorphic type.
    86124\end{enumerate}
    87 \todo{The list is making me realise, some of this isn't ordered.}
    88125
    89126Writing that code manually, with helper macros for the early name mangling,
     
    100137\end{cfa}
    101138
     139\begin{comment}
    102140\subsubsection{\lstinline{cfa\_linkonce} Attribute}
    103 % I just realised: This is an extension of the inline keyword.
     141% I just realized: This is an extension of the inline keyword.
    104142% An extension of C's at least, it is very similar to C++'s.
    105143Another feature added to \CFA is a new attribute: \texttt{cfa\_linkonce}.
     
    126164everything that comes after the special prefix, then only one is used
    127165and the other is discarded.
     166\end{comment}
    128167
    129168\subsection{Virtual Table}
     
    136175below.
    137176
    138 The layout always comes in three parts.
    139 \todo{Add labels to the virtual table layout figure.}
     177The layout always comes in three parts (see \autoref{f:VirtualTableLayout}).
    140178The first section is just the type id at the head of the table. It is always
    141179there to ensure that it can be found even when the accessing code does not
     
    143181The second section are all the virtual members of the parent, in the same
    144182order as they appear in the parent's virtual table. Note that the type may
    145 change slightly as references to the ``this" will change. This is limited to
     183change slightly as references to the ``this" change. This is limited to
    146184inside pointers/references and via function pointers so that the size (and
    147185hence the offsets) are the same.
     
    150188
    151189\begin{figure}
     190\begin{center}
    152191\input{vtable-layout}
     192\end{center}
    153193\caption{Virtual Table Layout}
    154194\label{f:VirtualTableLayout}
    155 \todo*{Improve the Virtual Table Layout diagram.}
    156195\end{figure}
    157196
     
    176215type's alignment, is set using an @alignof@ expression.
    177216
    178 \subsubsection{Concurrency Integration}
     217Most of these tools are already inside the compiler. Using simple
     218code transformations early on in compilation, allows most of that work to be
     219handed off to the existing tools. \autoref{f:VirtualTableTransformation}
     220shows an example transformation, this example shows an exception virtual table.
     221It also shows the transformation on the full declaration.
     222For a forward declaration, the @extern@ keyword is preserved and the
     223initializer is not added.
     224
     225\begin{figure}[htb]
     226\begin{cfa}
     227vtable(example_type) example_name;
     228\end{cfa}
     229\transformline
     230% Check mangling.
     231\begin{cfa}
     232const struct example_type_vtable example_name = {
     233        .__cfavir_typeid : &__cfatid_example_type,
     234        .size : sizeof(example_type),
     235        .copy : copy,
     236        .^?{} : ^?{},
     237        .msg : msg,
     238};
     239\end{cfa}
     240\caption{Virtual Table Transformation}
     241\label{f:VirtualTableTransformation}
     242\end{figure}
     243
     244\subsection{Concurrency Integration}
    179245Coroutines and threads need instances of @CoroutineCancelled@ and
    180246@ThreadCancelled@ respectively to use all of their functionality. When a new
     
    183249at the definition of the main function.
    184250
    185 This is showned through code re-writing in
    186 \autoref{f:ConcurrencyTypeTransformation} and
    187 \autoref{f:ConcurrencyMainTransformation}.
    188 In both cases the original declaration is not modified,
     251These transformations are shown through code re-writing in
     252\autoref{f:CoroutineTypeTransformation} and
     253\autoref{f:CoroutineMainTransformation}.
     254Threads use the same pattern, with some names and types changed.
     255In both cases, the original declaration is not modified,
    189256only new ones are added.
    190257
    191 \begin{figure}
     258\begin{figure}[htb]
    192259\begin{cfa}
    193260coroutine Example {
     
    207274extern CoroutineCancelled_vtable & _default_vtable;
    208275\end{cfa}
    209 \caption{Concurrency Type Transformation}
    210 \label{f:ConcurrencyTypeTransformation}
     276\caption{Coroutine Type Transformation}
     277\label{f:CoroutineTypeTransformation}
    211278\end{figure}
    212279
    213 \begin{figure}
     280\begin{figure}[htb]
    214281\begin{cfa}
    215282void main(Example & this) {
     
    229296        &_default_vtable_object_declaration;
    230297\end{cfa}
    231 \caption{Concurrency Main Transformation}
    232 \label{f:ConcurrencyMainTransformation}
     298\caption{Coroutine Main Transformation}
     299\label{f:CoroutineMainTransformation}
    233300\end{figure}
    234301
     
    242309\begin{cfa}
    243310void * __cfa__virtual_cast(
    244         struct __cfavir_type_td parent,
    245         struct __cfavir_type_id const * child );
    246 \end{cfa}
    247 The type id of target type of the virtual cast is passed in as @parent@ and
     311        struct __cfavir_type_id * parent,
     312        struct __cfavir_type_id * const * child );
     313\end{cfa}
     314The type id for the target type of the virtual cast is passed in as
     315@parent@ and
    248316the cast target is passed in as @child@.
    249 
    250 For generated C code wraps both arguments and the result with type casts.
     317The generated C code wraps both arguments and the result with type casts.
    251318There is also an internal check inside the compiler to make sure that the
    252319target type is a virtual type.
     
    260327
    261328\section{Exceptions}
    262 % Anything about exception construction.
     329% The implementation of exception types.
     330
     331Creating exceptions can roughly divided into two parts,
     332the exceptions themselves and the virtual system interactions.
     333
     334Creating an exception type is just a matter of prepending the field 
     335with the virtual table pointer to the list of the fields
     336(see \autoref{f:ExceptionTypeTransformation}).
     337
     338\begin{figure}[htb]
     339\begin{cfa}
     340exception new_exception {
     341        // EXISTING FIELDS
     342};
     343\end{cfa}
     344\transformline
     345\begin{cfa}
     346struct new_exception {
     347        struct new_exception_vtable const * virtual_table;
     348        // EXISTING FIELDS
     349};
     350\end{cfa}
     351\caption{Exception Type Transformation}
     352\label{f:ExceptionTypeTransformation}
     353\end{figure}
     354
     355The integration between exceptions and the virtual system is a bit more
     356complex simply because of the nature of the virtual system prototype.
     357The primary issue is that the virtual system has no way to detect when it
     358should generate any of its internal types and data. This is handled by
     359the exception code, which tells the virtual system when to generate
     360its components.
     361
     362All types associated with a virtual type,
     363the types of the virtual table and the type id,
     364are generated when the virtual type (the exception) is first found.
     365The type id (the instance) is generated with the exception, if it is
     366a monomorphic type.
     367However, if the exception is polymorphic, then a different type id has to
     368be generated for every instance. In this case, generation is delayed
     369until a virtual table is created.
     370% There are actually some problems with this, which is why it is not used
     371% for monomorphic types.
     372When a virtual table is created and initialized, two functions are created
     373to fill in the list of virtual members.
     374The first is a copy function that adapts the exception's copy constructor
     375to work with pointers, avoiding some issues with the current copy constructor
     376interface.
     377Second is the msg function that returns a C-string with the type's name,
     378including any polymorphic parameters.
    263379
    264380\section{Unwinding}
     
    274390stack. On function entry and return, unwinding is handled directly by the
    275391call/return code embedded in the function.
    276 In many cases, the position of the instruction pointer (relative to parameter
    277 and local declarations) is enough to know the current size of the stack
    278 frame.
    279 
     392
     393% Discussing normal stack unwinding:
    280394Usually, the stack-frame size is known statically based on parameter and
    281 local variable declarations. Even with dynamic stack-size, the information
     395local variable declarations. Even for a dynamic stack-size, the information
    282396to determine how much of the stack has to be removed is still contained
    283397within the function.
     
    285399bumping the hardware stack-pointer up or down as needed.
    286400Constructing/destructing values within a stack frame has
    287 a similar complexity but can add additional work and take longer.
    288 
     401a similar complexity but larger constants.
     402
     403% Discussing multiple frame stack unwinding:
    289404Unwinding across multiple stack frames is more complex because that
    290405information is no longer contained within the current function.
    291 With seperate compilation a function has no way of knowing what its callers
    292 are so it can't know how large those frames are.
    293 Without altering the main code path it is also hard to pass that work off
    294 to the caller.
     406With separate compilation,
     407a function does not know its callers nor their frame layout.
     408Even using the return address, that information is encoded in terms of
     409actions in code, intermixed with the actions required finish the function.
     410Without changing the main code path it is impossible to select one of those
     411two groups of actions at the return site.
    295412
    296413The traditional unwinding mechanism for C is implemented by saving a snap-shot
     
    302419This approach is fragile and requires extra work in the surrounding code.
    303420
    304 With respect to the extra work in the surounding code,
     421With respect to the extra work in the surrounding code,
    305422many languages define clean-up actions that must be taken when certain
    306423sections of the stack are removed. Such as when the storage for a variable
    307 is removed from the stack or when a try statement with a finally clause is
     424is removed from the stack, possibly requiring a destructor call,
     425or when a try statement with a finally clause is
    308426(conceptually) popped from the stack.
    309 None of these should be handled by the user --- that would contradict the
     427None of these cases should be handled by the user --- that would contradict the
    310428intention of these features --- so they need to be handled automatically.
    311429
     
    348466In plain C (which \CFA currently compiles down to) this
    349467flag only handles the cleanup attribute:
     468%\label{code:cleanup}
    350469\begin{cfa}
    351470void clean_up( int * var ) { ... }
     
    355474in this case @clean_up@, run when the variable goes out of scope.
    356475This feature is enough to mimic destructors,
    357 but not try statements which can effect
     476but not try statements that affect
    358477the unwinding.
    359478
    360479To get full unwinding support, all of these features must be handled directly
    361 in assembly and assembler directives; partiularly the cfi directives
     480in assembly and assembler directives; particularly the cfi directives
    362481\snake{.cfi_lsda} and \snake{.cfi_personality}.
    363482
     
    399518@_UA_FORCE_UNWIND@ specifies a forced unwind call. Forced unwind only performs
    400519the cleanup phase and uses a different means to decide when to stop
    401 (see \vref{s:ForcedUnwind}).
     520(see \autoref{s:ForcedUnwind}).
    402521\end{enumerate}
    403522
    404523The @exception_class@ argument is a copy of the
    405524\code{C}{exception}'s @exception_class@ field,
    406 which is a number that identifies the exception handling mechanism
     525which is a number that identifies the EHM
    407526that created the exception.
    408527
     
    494613needs its own exception context.
    495614
    496 The exception context should be retrieved by calling the function
     615The current exception context should be retrieved by calling the function
    497616\snake{this_exception_context}.
    498617For sequential execution, this function is defined as
     
    519638The first step of a termination raise is to copy the exception into memory
    520639managed by the exception system. Currently, the system uses @malloc@, rather
    521 than reserved memory or the stack top. The exception handling mechanism manages
     640than reserved memory or the stack top. The EHM manages
    522641memory for the exception as well as memory for libunwind and the system's own
    523642per-exception storage.
     
    554673\newsavebox{\stackBox}
    555674\begin{lrbox}{\codeBox}
    556 \begin{lstlisting}[language=CFA,{moredelim=**[is][\color{red}]{@}{@}}]
     675\begin{cfa}
    557676unsigned num_exceptions = 0;
    558677void throws() {
     
    573692    throws();
    574693}
    575 \end{lstlisting}
     694\end{cfa}
    576695\end{lrbox}
    577696
    578697\begin{lrbox}{\stackBox}
    579698\begin{lstlisting}
    580 | try-finally
    581 | try-catch (Example)
     699| finally block (Example)
     700| try block
    582701throws()
    583 | try-finally
    584 | try-catch (Example)
     702| finally block (Example)
     703| try block
    585704throws()
    586 | try-finally
    587 | try-catch (Example)
     705| finally block (Example)
     706| try block
    588707throws()
    589708main()
     
    598717\label{f:MultipleExceptions}
    599718\end{figure}
    600 \todo*{Work on multiple exceptions code sample.}
    601719
    602720All exceptions are stored in nodes, which are then linked together in lists
     
    618736\subsection{Try Statements and Catch Clauses}
    619737The try statement with termination handlers is complex because it must
    620 compensate for the C code-generation versus
     738compensate for the C code-generation versus proper
    621739assembly-code generated from \CFA. Libunwind
    622740requires an LSDA and personality function for control to unwind across a
    623741function. The LSDA in particular is hard to mimic in generated C code.
    624742
    625 The workaround is a function called @__cfaehm_try_terminate@ in the standard
    626 library. The contents of a try block and the termination handlers are converted
    627 into functions. These are then passed to the try terminate function and it
    628 calls them.
     743The workaround is a function called \snake{__cfaehm_try_terminate} in the
     744standard \CFA library. The contents of a try block and the termination
     745handlers are converted into nested functions. These are then passed to the
     746try terminate function and it calls them, appropriately.
    629747Because this function is known and fixed (and not an arbitrary function that
    630 happens to contain a try statement), the LSDA can be generated ahead
     748happens to contain a try statement), its LSDA can be generated ahead
    631749of time.
    632750
    633 Both the LSDA and the personality function are set ahead of time using
     751Both the LSDA and the personality function for \snake{__cfaehm_try_terminate}
     752are set ahead of time using
    634753embedded assembly. This assembly code is handcrafted using C @asm@ statements
    635754and contains
    636 enough information for a single try statement the function repersents.
     755enough information for the single try statement the function represents.
    637756
    638757The three functions passed to try terminate are:
     
    646765decides if a catch clause matches the termination exception. It is constructed
    647766from the conditional part of each handler and runs each check, top to bottom,
    648 in turn, first checking to see if the exception type matches and then if the
    649 condition is true. It takes a pointer to the exception and returns 0 if the
     767in turn, to see if the exception matches this handler.
     768The match is performed in two steps, first a virtual cast is used to check
     769if the raised exception is an instance of the declared exception type or
     770one of its descendant types, and then the condition is evaluated, if
     771present.
     772The match function takes a pointer to the exception and returns 0 if the
    650773exception is not handled here. Otherwise the return value is the id of the
    651774handler that matches the exception.
     
    660783All three functions are created with GCC nested functions. GCC nested functions
    661784can be used to create closures,
    662 in other words functions that can refer to the state of other
    663 functions on the stack. This approach allows the functions to refer to all the
     785in other words,
     786functions that can refer to variables in their lexical scope even
     787those variables are part of a different function.
     788This approach allows the functions to refer to all the
    664789variables in scope for the function containing the @try@ statement. These
    665790nested functions and all other functions besides @__cfaehm_try_terminate@ in
     
    669794
    670795\autoref{f:TerminationTransformation} shows the pattern used to transform
    671 a \CFA try statement with catch clauses into the approprate C functions.
    672 \todo{Explain the Termination Transformation figure.}
     796a \CFA try statement with catch clauses into the appropriate C functions.
    673797
    674798\begin{figure}
     
    728852\caption{Termination Transformation}
    729853\label{f:TerminationTransformation}
    730 \todo*{Improve (compress?) Termination Transformations.}
    731854\end{figure}
    732855
     
    738861Instead of storing the data in a special area using assembly,
    739862there is just a linked list of possible handlers for each stack,
    740 with each node on the list reperenting a try statement on the stack.
     863with each node on the list representing a try statement on the stack.
    741864
    742865The head of the list is stored in the exception context.
     
    744867to the head of the list.
    745868Instead of traversing the stack, resumption handling traverses the list.
    746 At each node, the EHM checks to see if the try statement the node repersents
     869At each node, the EHM checks to see if the try statement the node represents
    747870can handle the exception. If it can, then the exception is handled and
    748871the operation finishes, otherwise the search continues to the next node.
    749872If the search reaches the end of the list without finding a try statement
    750 that can handle the exception, the default handler is executed and the
    751 operation finishes.
     873with a handler clause
     874that can handle the exception, the default handler is executed.
     875If the default handler returns, control continues after the raise statement.
    752876
    753877Each node has a handler function that does most of the work.
    754878The handler function is passed the raised exception and returns true
    755879if the exception is handled and false otherwise.
    756 
    757880The handler function checks each of its internal handlers in order,
    758881top-to-bottom, until it funds a match. If a match is found that handler is
     
    760883If no match is found the function returns false.
    761884The match is performed in two steps, first a virtual cast is used to see
    762 if the thrown exception is an instance of the declared exception or one of
    763 its descendant type, then check to see if passes the custom predicate if one
    764 is defined. This ordering gives the type guarantee used in the predicate.
     885if the raised exception is an instance of the declared exception type or one
     886of its descendant types, if so then it is passed to the custom predicate
     887if one is defined.
     888% You need to make sure the type is correct before running the predicate
     889% because the predicate can depend on that.
    765890
    766891\autoref{f:ResumptionTransformation} shows the pattern used to transform
    767 a \CFA try statement with catch clauses into the approprate C functions.
    768 \todo{Explain the Resumption Transformation figure.}
     892a \CFA try statement with catchResume clauses into the appropriate
     893C functions.
    769894
    770895\begin{figure}
     
    807932\caption{Resumption Transformation}
    808933\label{f:ResumptionTransformation}
    809 \todo*{Improve (compress?) Resumption Transformations.}
    810934\end{figure}
    811935
     
    814938(see \vpageref{s:ResumptionMarking}), which ignores parts of
    815939the stack
    816 already examined, is accomplished by updating the front of the list as the
    817 search continues. Before the handler at a node is called, the head of the list
     940already examined, and is accomplished by updating the front of the list as
     941the search continues.
     942Before the handler is called at a matching node, the head of the list
    818943is updated to the next node of the current node. After the search is complete,
    819944successful or not, the head of the list is reset.
     
    822947been checked are not on the list while a handler is run. If a resumption is
    823948thrown during the handling of another resumption, the active handlers and all
    824 the other handler checked up to this point are not checked again.
     949the other handlers checked up to this point are not checked again.
    825950% No paragraph?
    826951This structure also supports new handlers added while the resumption is being
     
    830955
    831956\begin{figure}
     957\centering
    832958\input{resumption-marking}
    833959\caption{Resumption Marking}
    834960\label{f:ResumptionMarking}
    835 \todo*{Label Resumption Marking to aid clarity.}
    836961\end{figure}
    837962
     
    851976\section{Finally}
    852977% Uses destructors and GCC nested functions.
    853 A finally clause is placed into a GCC nested-function with a unique name,
    854 and no arguments or return values.
    855 This nested function is then set as the cleanup
    856 function of an empty object that is declared at the beginning of a block placed
    857 around the context of the associated @try@ statement.
    858 
    859 The rest is handled by GCC. The try block and all handlers are inside this
    860 block. At completion, control exits the block and the empty object is cleaned
     978
     979%\autoref{code:cleanup}
     980A finally clause is handled by converting it into a once-off destructor.
     981The code inside the clause is placed into GCC nested-function
     982with a unique name, and no arguments or return values.
     983This nested function is
     984then set as the cleanup function of an empty object that is declared at the
     985beginning of a block placed around the context of the associated try
     986statement (see \autoref{f:FinallyTransformation}).
     987
     988\begin{figure}
     989\begin{cfa}
     990try {
     991        // TRY BLOCK
     992} finally {
     993        // FINALLY BLOCK
     994}
     995\end{cfa}
     996
     997\transformline
     998
     999\begin{cfa}
     1000{
     1001        void finally(void *__hook){
     1002                // FINALLY BLOCK
     1003        }
     1004        __attribute__ ((cleanup(finally)))
     1005        struct __cfaehm_cleanup_hook __finally_hook;
     1006        {
     1007                // TRY BLOCK
     1008        }
     1009}
     1010\end{cfa}
     1011
     1012\caption{Finally Transformation}
     1013\label{f:FinallyTransformation}
     1014\end{figure}
     1015
     1016The rest is handled by GCC.
     1017The TRY BLOCK
     1018contains the try block itself as well as all code generated for handlers.
     1019Once that code has completed,
     1020control exits the block and the empty object is cleaned
    8611021up, which runs the function that contains the finally code.
    8621022
     
    8871047passed to the forced-unwind function. The general pattern of all three stop
    8881048functions is the same: continue unwinding until the end of stack and
    889 then preform the appropriate transfer.
     1049then perform the appropriate transfer.
    8901050
    8911051For main stack cancellation, the transfer is just a program abort.
Note: See TracChangeset for help on using the changeset viewer.